From: Arnaud Giersch Date: Mon, 27 Nov 2023 08:42:04 +0000 (+0100) Subject: Add new entry in Release_Notes. X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/HEAD?hp=196b543c8e909828b40e851eaf4443ee28f76c70 Add new entry in Release_Notes. --- diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 71a1fe1e7c..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,73 +0,0 @@ -# This file automatize the testing of SimGrid on Windows using the appveyor.com continuous integration service -# -# Build logs: https://ci.appveyor.com/project/simgrid/simgrid - -# Documentation: https://www.appveyor.com/docs/ -# https://www.appveyor.com/docs/installed-software/ - -image: - - Visual Studio 2019 -# - Ubuntu - -version: "{build}" -clone_depth: 1 - -# scripts that are called at very beginning, before repo cloning -init: -- git config --global core.longpaths true -- git config --global core.autocrlf input - -branches: - only: - - master - - appveyor - -environment: - global: - BOOST_ROOT: C:\Libraries\boost_1_77_0 - -install: -# Strawberry perl is the one to work with gcc; AppVeyor provides ActiveState perl, which is the one to work with visual. -# This package is so outdated and broken that we cannot use it anymore. So we build without perl -# - choco install --limit-output strawberryperl --version 5.20.1.1 -# - SET PATH=C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;%PATH% -# We need python v3 -- cmd: SET PATH=C:\Python37-x64;%PATH% # We need python v3 -# Ugly hack to ignore versions 3.8 and later of Python -- rename "C:\Python38-x64\python.exe" "python-ignored.exe" -- rename "C:\Python39-x64\python.exe" "python-ignored.exe" -- rename "C:\Python310-x64\python.exe" "python-ignored.exe" -# Use the mingw-w64 provided by Appveyor (must be placed before Perl in the path) -- cmd: SET PATH=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin\;%PATH% -# Work around a bug on appveyor where the default sh is not the one I expect -- rename "C:\Program Files\Git\usr\bin\sh.exe" "sh-ignored.exe" -# We need pybind11. SimGrid will pick it automatically if the subdir is here -- cmd: git clone --branch stable --depth=1 https://github.com/pybind/pybind11.git - -before_build: - - cmd: if not exist C:\"Program Files"\Eigen\include\eigen3\Eigen\Core ( - curl -LO https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz && - cmake -E tar zxf eigen-3.4.0.tar.gz && - cd eigen-3.4.0 && - mkdir build && - cd build && - cmake -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:\projects .. && - cmake --build . --target install && - cd ..\.. - ) else (echo Using cached Eigen3) - -build_script: -- cmake -G "MinGW Makefiles" -Denable_documentation=OFF -Denable_java=ON -Denable_msg=ON -Denable_smpi=OFF -Denable_mallocators=OFF -Denable_lto=OFF . -- mingw32-make.exe VERBOSE=1 java-all python-bindings # Only the Java and Python parts -- ctest --output-on-failure -R java -- ctest --output-on-failure -R python - -artifacts: -- path: simgrid.jar - name: jarfile - -# IRC notifications, even if https://github.com/appveyor/ci/issues/88 is not closed yet -on_failure: - - "python tools/appveyor-irc-notify.py simgrid [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_red}Failed,Details: {build_url},Commit: {commit_url}" -#on_success: -# - "python tools/appveyor-irc-notify.py simgrid [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_green}Succeeded,Details: {build_url},Commit: {commit_url}" diff --git a/.circleci/config.yml b/.circleci/config.yml index c1ce16b090..b505615c32 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,6 @@ # This is the configuration file for the https://circleci.com/ continuous integration server # -# Copyright (c) 2017-2022. The SimGrid team. All rights reserved. +# Copyright (c) 2017-2023. The SimGrid team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -19,5 +19,5 @@ jobs: name: Configure, build and test da stuff command: | mkdir _build && cd _build - cmake -Denable_documentation=OFF -Denable_coverage=ON -Denable_java=ON -Denable_msg=ON -Denable_model-checking=OFF -Denable_compile_optimizations=OFF -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=OFF -Denable_compile_warnings=ON .. + cmake -Denable_documentation=OFF -Denable_coverage=OFF -Denable_model-checking=OFF -Denable_compile_optimizations=OFF -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=OFF -Denable_compile_warnings=ON .. make -j4 tests && ctest -j4 --output-on-failure diff --git a/.classpath b/.classpath deleted file mode 100644 index 32ea6c5391..0000000000 --- a/.classpath +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/.github/workflows/ci-batsim.yml b/.github/workflows/ci-batsim.yml index 78ac34738d..f519b1e78b 100644 --- a/.github/workflows/ci-batsim.yml +++ b/.github/workflows/ci-batsim.yml @@ -12,7 +12,7 @@ jobs: container: simgrid/unstable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build and test BatSim run: | set -e diff --git a/.github/workflows/ci-bigdft.yml b/.github/workflows/ci-bigdft.yml index 581e733bcc..bb44643ecf 100644 --- a/.github/workflows/ci-bigdft.yml +++ b/.github/workflows/ci-bigdft.yml @@ -14,7 +14,7 @@ jobs: options: --user 0 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build and test BigDFT run: | set -e diff --git a/.github/workflows/ci-starpu.yml b/.github/workflows/ci-starpu.yml index 6b6323837b..fbca937b27 100644 --- a/.github/workflows/ci-starpu.yml +++ b/.github/workflows/ci-starpu.yml @@ -12,7 +12,7 @@ jobs: container: simgrid/unstable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build and test StarPU run: | set -e diff --git a/.github/workflows/ci-wrench.yml b/.github/workflows/ci-wrench.yml index 224b03e4a9..1a580b4a9e 100644 --- a/.github/workflows/ci-wrench.yml +++ b/.github/workflows/ci-wrench.yml @@ -12,7 +12,7 @@ jobs: container: simgrid/unstable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build and test WRENCH run: | set -e diff --git a/.github/workflows/docker-stable.yml b/.github/workflows/docker-stable.yml index 43de9e3ed8..c0a0ea890e 100644 --- a/.github/workflows/docker-stable.yml +++ b/.github/workflows/docker-stable.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Login against a Docker registry except on PR # https://github.com/docker/login-action @@ -39,15 +39,15 @@ jobs: grep SIMGRID_VERSION_PATCH CMakeLists.txt| grep -q 'SIMGRID_VERSION_PATCH "0"' || (echo "Only run this action on stable source";exit 1) cd tools/docker make stable - docker push simgrid/stable + docker push --all-tags simgrid/stable - name: Create the failure Message if: ${{ failure() }} run: | - ver=$(git describe --tags --abbrev=0) echo "{\"attachments\": [{\"color\": \"#FF0000\", \"text\":\"Failure when building STABLE docker image $ver! See ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json + ver=$(grep set.SIMGRID_VERSION_MINOR CMakeLists.txt|sed 's/[^"]*"//'|sed 's/".*$//') echo "{\"attachments\": [{\"color\": \"#FF0000\", \"text\":\"Failure when building STABLE docker image v3.$ver! See ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json - name: Create the success Message if: ${{ success() }} run: | - ver=$(git describe --tags --abbrev=0) echo "{\"attachments\": [{\"color\": \"#00FF00\", \"text\":\"Docker STABLE image $ver built and pushed successfully! ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json + ver=$(grep set.SIMGRID_VERSION_MINOR CMakeLists.txt|sed 's/[^"]*"//'|sed 's/".*$//') echo "{\"attachments\": [{\"color\": \"#00FF00\", \"text\":\"Docker STABLE image v3.$ver built and pushed successfully! ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json - uses: mattermost/action-mattermost-notify@master env: MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }} @@ -65,7 +65,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Login against a Docker registry except on PR # https://github.com/docker/login-action @@ -104,7 +104,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Login against a Docker registry except on PR # https://github.com/docker/login-action diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 17f6084765..5471cea5b6 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Login against a Docker registry except on PR # https://github.com/docker/login-action @@ -59,7 +59,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Login against a Docker registry except on PR # https://github.com/docker/login-action diff --git a/.github/workflows/git.yml b/.github/workflows/git.yml new file mode 100644 index 0000000000..eb6bc035ab --- /dev/null +++ b/.github/workflows/git.yml @@ -0,0 +1,98 @@ +name: Git builds + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# Only trigger manually +on: workflow_dispatch + +jobs: + simgrid-regular-ubuntu: + runs-on: ${{ matrix.config.os }}-latest + strategy: + matrix: + config: + - { name: "Ubuntu gcc", os: ubuntu, cc: "gcc", cxx: "g++", generator: "Unix Makefiles", cmake_extra_options: "-DLTO_EXTRA_FLAG=auto" } + - { name: "MacOS clang", os: macos, cc: "clang", cxx: "clang++", generator: "Unix Makefiles", cmake_extra_options: "-DLTO_EXTRA_FLAG=auto" } + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Init options + run: | + echo "CC=${{ matrix.config.cc }}" >> $GITHUB_ENV + echo "CXX=${{ matrix.config.cxx }}" >> GITHUB_ENV + - name: prepare for ubuntu + if: matrix.config.os == 'ubuntu' + run: | + sudo apt-get update && sudo apt-get install ninja-build libboost-dev libboost-context-dev pybind11-dev + - name: prepare for macos + if: matrix.config.os == 'macos' + run: brew install boost eigen pybind11 ninja + - name: build + run: | + mkdir build ; cd build + cmake -GNinja -Denable_debug=ON -Denable_documentation=OFF -Denable_coverage=OFF \ + -Denable_compile_optimizations=ON -Denable_compile_warnings=ON \ + -Denable_model-checking=OFF -Denable_testsuite_smpi_MBI=OFF \ + -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=ON \ + -DCMAKE_DISABLE_SOURCE_CHANGES=ON -DLTO_EXTRA_FLAG="auto" .. + ninja tests + ctest --output-on-failure -j$(nproc) + - name: Create the failure Message + if: ${{ failure() }} + run: | + ver=$(grep set.SIMGRID_VERSION_MINOR CMakeLists.txt|sed 's/[^"]*"//'|sed 's/".*$//') echo "{\"attachments\": [{\"color\": \"#FF0000\", \"text\":\"Failure when building simgrid on ${{ matrix.config.name }}! See ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json + - name: Create the success Message + if: ${{ success() }} + run: | + ver=$(grep set.SIMGRID_VERSION_MINOR CMakeLists.txt|sed 's/[^"]*"//'|sed 's/".*$//') echo "{\"attachments\": [{\"color\": \"#00FF00\", \"text\":\"SimGrid built successfully on ${{ matrix.config.name }}! ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json + - uses: komarnitskyi/action-mattermost-notification@v0.1.2-beta + if: ${{ always() }} + env: + webhook: ${{ secrets.MATTERMOST_WEBHOOK_URL }} + channel: ${{ secrets.MATTERMOST_CHANNEL}} + json: mattermost.json + + simgrid-modelcheck-ubuntu: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: build + run: | + sudo apt-get update && sudo apt-get install ninja-build libboost-dev libboost-context-dev pybind11-dev libevent-dev + mkdir build ; cd build + cmake -GNinja -Denable_debug=ON -Denable_documentation=OFF -Denable_coverage=OFF \ + -Denable_compile_optimizations=ON -Denable_compile_warnings=ON \ + -Denable_model-checking=ON -Denable_testsuite_smpi_MBI=OFF \ + -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=OFF \ + -Denable_ns3=OFF \ + -DCMAKE_DISABLE_SOURCE_CHANGES=ON -DLTO_EXTRA_FLAG="auto" .. + ninja tests + ctest --output-on-failure -j$(nproc) + - name: Create the failure Message + if: ${{ failure() }} + run: | + ver=$(grep set.SIMGRID_VERSION_MINOR CMakeLists.txt|sed 's/[^"]*"//'|sed 's/".*$//') echo "{\"attachments\": [{\"color\": \"#FF0000\", \"text\":\"Failure when building simgrid Modelchecker on ubuntu-stable! See ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json + - name: Create the success Message + if: ${{ success() }} + run: | + ver=$(grep set.SIMGRID_VERSION_MINOR CMakeLists.txt|sed 's/[^"]*"//'|sed 's/".*$//') echo "{\"attachments\": [{\"color\": \"#00FF00\", \"text\":\"Simgrid Modelchecker built successfully on ubuntu-stable! ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json + - uses: komarnitskyi/action-mattermost-notification@v0.1.2-beta + if: ${{ always() }} + env: + webhook: ${{ secrets.MATTERMOST_WEBHOOK_URL }} + channel: ${{ secrets.MATTERMOST_CHANNEL}} + json: mattermost.json diff --git a/.github/workflows/jarfile.yml b/.github/workflows/jarfile.yml deleted file mode 100644 index d8408e5654..0000000000 --- a/.github/workflows/jarfile.yml +++ /dev/null @@ -1,123 +0,0 @@ -name: Jar build - -on: - workflow_dispatch: - schedule: - # * is a special character in YAML so you have to quote this string - - cron: '0 18 * * 0' -jobs: - build: - runs-on: ${{ matrix.config.os }}-latest - strategy: - matrix: - config: - - { name: "Windows MingW", os: windows, cc: "gcc", cxx: "g++", generator: "MinGW Makefiles", cmake_extra_options: '-Denable_lto=OFF -DCMAKE_PREFIX_PATH="C:/Program Files/Eigen3/"' } - - { name: "Ubuntu gcc", os: ubuntu, cc: "gcc", cxx: "g++", generator: "Unix Makefiles", cmake_extra_options: "-DLTO_EXTRA_FLAG=auto" } - - { name: "MacOS clang", os: macos, cc: "clang", cxx: "clang++", generator: "Unix Makefiles", cmake_extra_options: "-DLTO_EXTRA_FLAG=auto" } - steps: - - uses: actions/checkout@v2 - # install dependencies - - name: Init options - run: | - echo "CC=${{ matrix.config.cc }}" >> $GITHUB_ENV - echo "CXX=${{ matrix.config.cxx }}" >> GITHUB_ENV - - name: Install boost and eigen on ubuntu - if: matrix.config.os == 'ubuntu' - run: sudo apt-get update && sudo apt-get install -yq libboost-dev libeigen3-dev - - name: Install boost and eigen on macos - if: matrix.config.os == 'macos' - run: brew install boost eigen - - name: Install boost, eigen, and gcc on windows - if: matrix.config.os == 'windows' - run: | - iwr -useb get.scoop.sh -outfile 'install.ps1' - .\install.ps1 -RunAsAdmin - scoop install gcc --global - If ((Test-Path "C:\hostedtoolcache\windows\Boost") -eq $False){ - # Use the boost-1.72.0-win32-msvc14.1-x86_64.tar.gz for Windows 2016 - $url = "https://github.com/actions/boost-versions/releases/download/1.72.0-20200608.4/boost-1.72.0-win32-msvc14.2-x86_64.tar.gz" - (New-Object System.Net.WebClient).DownloadFile($url, "$env:TEMP\boost.tar.gz") - 7z.exe x "$env:TEMP\boost.tar.gz" -o"$env:TEMP\boostArchive" -y | Out-Null - 7z.exe x "$env:TEMP\boostArchive" -o"$env:TEMP\boost" -y | Out-Null - Push-Location -Path "$env:TEMP\boost" - Invoke-Expression .\setup.ps1 - } - echo "BOOST_ROOT=C:\hostedtoolcache\windows\Boost\1.72.0\x86_64" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append - echo "BOOST_INCLUDEDIR=C:\hostedtoolcache\windows\Boost\1.72.0\x86_64\boost\include" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append - echo "BOOST_LIBRARYDIR=C:\hostedtoolcache\windows\Boost\1.72.0\x86_64\lib" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append - $url = "https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz" - (New-Object System.Net.WebClient).DownloadFile($url, "$env:TEMP\eigen.tar.gz") - Push-Location -Path "$env:TEMP" - cmake -E tar zxf "$env:TEMP\eigen.tar.gz" - mkdir "$env:TEMP\eigen-3.4.0\build" - cd "$env:TEMP\eigen-3.4.0\build" - cmake -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX="C:\Program Files\Eigen3" .. - cmake --build . --target install - - name: Build and test jar with Cmake - run: | - mkdir build - cd build - cmake -Denable_documentation=OFF -Denable_java=ON -Denable_msg=ON -Denable_lib_in_jar=ON -Dminimal-bindings=ON -Denable_compile_optimizations=ON -Denable_smpi=OFF ${{ matrix.config.cmake_extra_options }} -G "${{ matrix.config.generator }}" .. - make -j2 simgrid-java_jar java-all - ctest -R java --output-on-failure - - name: Upload jar - uses: actions/upload-artifact@v2 - with: - name: jar-${{ matrix.config.os }} - path: build/simgrid.jar - - name: Create the failure Message - if: ${{ failure() }} - run: | - echo "{\"attachments\": [{\"color\": \"#FF0000\", \"text\":\"Failure when building JAR file on ${{ matrix.config.name }}! See ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json - - uses: mattermost/action-mattermost-notify@master - if: ${{ failure() }} - env: - MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }} - MATTERMOST_CHANNEL: ${{ secrets.MATTERMOST_CHANNEL}} - create_jar: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Download all jars from ubuntu - uses: actions/download-artifact@v2 - - name: Build final jar - run: | - patch=$(grep -r set\(SIMGRID_VERSION_PATCH ./CMakeLists.txt | sed 's/.*"\([[:digit:]]\+\)".*/\1/g') - major=$(grep -r set\(SIMGRID_VERSION_MAJOR ./CMakeLists.txt | sed 's/.*"\([[:digit:]]\+\)".*/\1/g') - minor=$(grep -r set\(SIMGRID_VERSION_MINOR ./CMakeLists.txt | sed 's/.*"\([[:digit:]]\+\)".*/\1/g') - if [ $patch -ne 0 ]; then - version="$major.$minor.$patch" - else - version="$major.$minor" - fi - mkdir content - cd content - for j in ubuntu macos windows ; do unzip -n ../jar-$j/simgrid.jar ; done - strip NATIVE/*/*/*.so - x86_64-linux-gnu-strip NATIVE/*/*/lib*dll - zip -r ../simgrid-${version}.jar * - - name: Upload jar - uses: actions/upload-artifact@v2 - with: - name: jar-final - path: simgrid-*.jar - - name: cleanup artifacts - uses: geekyeggo/delete-artifact@v1 - with: - name: | - jar-ubuntu - jar-windows - jar-macos - - name: Create the failure Message - if: ${{ failure() }} - run: | - echo "{\"attachments\": [{\"color\": \"#FF0000\", \"text\":\"Failure when assembling JAR file ! See ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json - - name: Create the success Message - if: ${{ success() }} - run: | - echo "{\"attachments\": [{\"color\": \"#00FF00\", \"text\":\"JAR file built successfully ! You can get it on: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} \"}]}" > mattermost.json - - uses: mattermost/action-mattermost-notify@master - env: - MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }} - MATTERMOST_CHANNEL: ${{ secrets.MATTERMOST_CHANNEL}} diff --git a/.gitignore b/.gitignore index a7c3963e1d..97d5571cbb 100644 --- a/.gitignore +++ b/.gitignore @@ -35,10 +35,9 @@ CTestResults.xml ### Maintainer mode src/dag/dax_dtd.l -src/surf/xml/simgrid_dtd.l +src/kernel/xml/simgrid_dtd.l ### Libraries links [Ss]im[Gg]rid-*.tar.gz -simgrid.jar ### Generated files _*.c include/simgrid/config.h @@ -63,7 +62,6 @@ manpages/ build_*/ build/ ### Documentation -docs/source/java docs/source/_ext/__pycache__/ doc/allclasses-frame.html doc/allclasses-noframe.html @@ -76,10 +74,8 @@ doc/org/ doc/overview-frame.html doc/overview-summary.html doc/overview-tree.html -doc/package-list doc/resources/ doc/serialized-form.html -doc/stylesheet.css doc/all_bib.html doc/logcategories.sh doc/realtoc.sh @@ -94,12 +90,10 @@ doc/html doc/index.php doc/simgrid.tag doc/doxygen/logcategories.doc -doc/javadoc doc/example_lists/ ### Specific of project .settings/ .csettings/ -examples/deprecated/java/.classpath .anjuta .anjuta_sym_db.db simgrid.anjuta @@ -110,6 +104,10 @@ tags callgrind.out.* ### Examples and traces *.exe +examples/c/activityset-testany/c-activityset-testany +examples/c/activityset-waitall/c-activityset-waitall +examples/c/activityset-waitallfor/c-activityset-waitallfor +examples/c/activityset-waitany/c-activityset-waitany examples/c/actor-create/c-actor-create examples/c/actor-daemon/c-actor-daemon examples/c/actor-exiting/c-actor-exiting @@ -149,6 +147,10 @@ examples/c/platform-failures/c-platform-failures examples/c/platform-properties/c-platform-properties examples/c/plugin-host-load/c-plugin-host-load examples/c/synchro-semaphore/c-synchro-semaphore +examples/cpp/activityset-testany/s4u-activityset-testany +examples/cpp/activityset-waitall/s4u-activityset-waitall +examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor +examples/cpp/activityset-waitany/s4u-activityset-waitany examples/cpp/actor-create/s4u-actor-create examples/cpp/actor-daemon/s4u-actor-daemon examples/cpp/actor-exiting/s4u-actor-exiting @@ -181,8 +183,11 @@ examples/cpp/comm-waitall/s4u-comm-waitall examples/cpp/comm-waitany/s4u-comm-waitany examples/cpp/comm-waituntil/s4u-comm-waituntil examples/cpp/dag-comm/s4u-dag-comm +examples/cpp/dag-tuto/s4u-dag-tuto examples/cpp/dag-failure/s4u-dag-failure examples/cpp/dag-from-dax/s4u-dag-from-dax +examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple +examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple examples/cpp/dag-from-dot/s4u-dag-from-dot examples/cpp/dag-io/s4u-dag-io examples/cpp/dag-scheduling/s4u-dag-scheduling @@ -245,6 +250,13 @@ examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil examples/cpp/synchro-mutex/s4u-synchro-mutex examples/cpp/synchro-semaphore/s4u-synchro-semaphore +examples/cpp/task-dispatch/s4u-task-dispatch +examples/cpp/task-io/s4u-task-io +examples/cpp/task-microservice/s4u-task-microservice +examples/cpp/task-parallelism/s4u-task-parallelism +examples/cpp/task-simple/s4u-task-simple +examples/cpp/task-storm/s4u-task-storm +examples/cpp/task-switch-host/s4u-task-switch-host examples/cpp/torus-multicpu/ examples/cpp/trace-categories/s4u-trace-categories examples/cpp/trace-host-user-variables/s4u-trace-host-user-variables @@ -287,8 +299,6 @@ examples/smpi/trace/smpi_trace teshsuite/kernel/context-defaults/context-defaults teshsuite/kernel/simcall-generic/simcall-generic teshsuite/kernel/stack-overflow/stack-overflow -teshsuite/java/semaphoregc/java-semaphoregc_compiled -teshsuite/java/sleephostoff/java-sleephostoff_compiled teshsuite/mc/dwarf/dwarf teshsuite/mc/dwarf-expression/dwarf-expression teshsuite/mc/mutex-handling/mutex-handling @@ -298,7 +308,6 @@ teshsuite/models/cloud-sharing/cloud-sharing teshsuite/models/ptask_L07_usage/ptask_L07_usage teshsuite/models/wifi_usage/wifi_usage teshsuite/models/wifi_usage_decay/wifi_usage_decay -teshsuite/msg/task_destroy_cancel/task_destroy_cancel teshsuite/platforms/flatifier teshsuite/s4u/activity-lifecycle/activity-lifecycle teshsuite/s4u/actor/actor @@ -850,10 +859,10 @@ teshsuite/smpi/type-hvector/type-hvector teshsuite/smpi/type-indexed/type-indexed teshsuite/smpi/type-struct/type-struct teshsuite/smpi/type-vector/type-vector -teshsuite/surf/lmm_usage/lmm_usage -teshsuite/surf/maxmin_bench/maxmin_bench -teshsuite/surf/surf_usage/surf_usage -teshsuite/surf/surf_usage2/surf_usage2 +teshsuite/models/lmm_usage/lmm_usage +teshsuite/models/maxmin_bench/maxmin_bench +teshsuite/models/core_usage/core_usage +teshsuite/models/core_usage2/core_usage2 teshsuite/xbt/cmdline/cmdline teshsuite/xbt/log_large/log_large teshsuite/xbt/log_usage/log_usage @@ -863,15 +872,7 @@ teshsuite/xbt/parmap_bench/parmap_bench teshsuite/xbt/parmap_test/parmap_test teshsuite/xbt/signals/signals unit-tests -######################################### -## files touched to track the dependencies of java examples -examples/deprecated/java/*/*/*_compiled -examples/deprecated/java/*/*_compiled /CMakeCache.txt -simgrid.jar_finalized -simgrid_full.jar -src/bindings/java/MANIFEST.MF -NATIVE/ VERSION include/smpi/mpif.h include/smpi/mpi.mod diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cb45b58b17..bbf969ba45 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,14 +4,14 @@ stages: - build - deploy -ctest: +ctest-debug: stage: build except: - stable script: - apt-get --allow-releaseinfo-change update - - apt install -y xsltproc - - cmake -Denable_model-checking=OFF -Denable_documentation=OFF -Denable_coverage=OFF -Denable_compile_optimizations=ON -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=ON -Denable_compile_warnings=ON -DLTO_EXTRA_FLAG="auto" . + - apt install -y binutils xsltproc + - cmake -Denable_model-checking=OFF -Denable_documentation=OFF -Denable_coverage=OFF -Denable_compile_optimizations=ON -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=ON -Denable_testsuite_McMini=ON -Denable_compile_warnings=ON -DLTO_EXTRA_FLAG="auto" . - make -j$(nproc) VERBOSE=1 all tests - ctest -T Test -j$(nproc) --output-on-failure - xsltproc ./tools/jenkins/ctest2junit.xsl Testing/"$( head -n 1 < Testing/TAG )"/Test.xml > CTestResults.xml @@ -24,6 +24,35 @@ ctest: expire_in: 1 week when: always +ctest-modelchecking: + stage: build + except: + - stable + script: + - apt-get --allow-releaseinfo-change update + - apt install -y binutils xsltproc clang + - cmake -Denable_model-checking=ON -Denable_documentation=OFF -Denable_coverage=OFF -Denable_compile_optimizations=ON -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=OFF -Denable_testsuite_McMini=OFF -Denable_compile_warnings=ON -DLTO_EXTRA_FLAG="auto" -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ . + - make -j$(nproc) VERBOSE=1 all tests + - ctest -T Test -j$(nproc) --output-on-failure + - xsltproc ./tools/jenkins/ctest2junit.xsl Testing/"$( head -n 1 < Testing/TAG )"/Test.xml > CTestResults.xml + artifacts: + paths: + - lib/ + reports: + junit: + - CTestResults.xml + expire_in: 1 week + when: always + +ctest-distcheck: + stage: build + only: + - merge_requests + script: + - apt-get --allow-releaseinfo-change update + - apt install -y binutils + - cmake . + - make distcheck-configure release: stage: build @@ -31,26 +60,11 @@ release: - stable script: - apt-get --allow-releaseinfo-change update - - apt install -y binutils-x86-64-linux-gnu wget unzip zip - # Build the linux version of the jarfile without the boost dependency - - cmake -Denable_documentation=OFF -Denable_java=ON -Denable_msg=ON -Denable_lib_in_jar=ON -Dminimal-bindings=ON -Denable_compile_optimizations=ON -Denable_smpi=OFF -DLTO_EXTRA_FLAG="auto" . - - make VERBOSE=1 -j$(nproc) dist simgrid simgrid-java_jar -# This cannot work anymore because Java is now built by the modelchecker jenkins configuration, that is not on macosx -# Please use the github action instead -# - make VERBOSE=1 -j$(nproc) dist simgrid simgrid-java_jar -# # Get the foreign architectures -# - wget https://ci.appveyor.com/api/projects/mquinson/simgrid/artifacts/simgrid.jar -O simgrid-windows.jar -# - export SGVER=`grep SimGrid ChangeLog|head -n1|sed -e 's/SimGrid (//' -e 's/).*//'` -# - wget https://ci.inria.fr/simgrid/job/SimGrid/build_mode=Debug,node=macos/lastSuccessfulBuild/artifact/build/simgrid-${SGVER}/build/simgrid.jar -O simgrid-mac.jar -# # Open all jar files, and strip them -# - mkdir content ; cd content -# - for j in ../simgrid.jar ../simgrid-windows.jar ../simgrid-mac.jar ; do unzip -n $j ; done -# - strip NATIVE/*/*/*.so -# - x86_64-linux-gnu-strip NATIVE/*/*/lib*dll -# - zip -r ../simgrid-${SGVER}.jar * + - apt install -y binutils wget unzip zip + - cmake -Denable_documentation=OFF -Dminimal-bindings=ON -Denable_compile_optimizations=ON -Denable_smpi=OFF -DLTO_EXTRA_FLAG="auto" . + - make VERBOSE=1 -j$(nproc) dist artifacts: paths: -# - simgrid-*.jar - simgrid-*.tar.gz pip: @@ -72,21 +86,19 @@ pip: pages: stage: deploy script: - - pip3 install --requirement docs/requirements.txt - - cd docs/source/_ext/javasphinx; python3 setup.py build; python3 setup.py install - - cd ../../.. + - apt install -y python3-breathe python3-sphinx python3-sphinx-rtd-theme python3-sphinx-copybutton python3-sphinx-tabs + # - pip3 install --requirement docs/requirements.txt # Forbidden in Debian:12 + - cd docs - LC_ALL=C.UTF-8 ./Build.sh - mv build/html ../public # - The CSS contains a reference to a font or something, not something we gonna fix on our side - # - The javasphinx output does not exist in the git, so the "edit on FramaGit" link is broken. - # I'd like to report this as a bug, but javasphinx seems abandonned upstream. -#not installed - linkchecker --ignore-url='.*\.css$' --ignore-url=public/java/org ../public +# not installed - linkchecker --ignore-url='.*\.css$' ../public # From time to time, we should check external links with the # following, but it has a lot of false positive - # - linkchecker --ignore-url='.*\.css$' --ignore-url=public/java/org --check-extern ../public + # - linkchecker --ignore-url='.*\.css$' --check-extern ../public artifacts: paths: - public only: - master - needs: ["ctest"] + needs: ["ctest-debug"] diff --git a/.lgtm.yml b/.lgtm.yml deleted file mode 100644 index 38efb28101..0000000000 --- a/.lgtm.yml +++ /dev/null @@ -1,14 +0,0 @@ -########################################################################################## -# Customize file classifications. # -# Results from files under any classifier will be excluded from LGTM # -# statistics. # -########################################################################################## - -########################################################################################## -# Use the `path_classifiers` block to define changes to the default classification of # -# files. # -########################################################################################## - -path_classifiers: - smpi_colls: - - src/smpi/colls/ diff --git a/.mailmap b/.mailmap index c279754c58..2e99416804 100644 --- a/.mailmap +++ b/.mailmap @@ -39,7 +39,9 @@ Clément Courageux-Sudan Augustin Degomme Augustin Degomme <13270544+adegomme@users.noreply.github.com> +Augustin Degomme <26892-adegomme@users.noreply.framagit.org> Augustin Degomme +Augustin Degomme Augustin Degomme Augustin Degomme Augustin Degomme @@ -75,6 +77,7 @@ Arnaud Giersch Adrien Gougeon Adrien Gougeon +Alexander Grund Loic Guegan Marion Guthmuller Ahmed Harbaoui @@ -83,6 +86,7 @@ Christian Heinrich Takahiro Hirofuchi Sascha Hunold +Mathieu Laurent Adrien Lèbre Adrien Lèbre Adrien Lèbre @@ -108,6 +112,7 @@ Pierre Navarro Pierre Navarro Pierre Navarro Pierre Navarro +Lucas Nesi Lucas Nussbaum Tien-Dat Phan Martin Quinson <(no author)@48e7efb5-ca39-0410-a469-dd3cf9ba447f> @@ -149,5 +154,5 @@ Pedro Velho Pedro Velho Flavien Vernier Matthieu Volat -Steven Whatelse +Steven Quinito Masnada Chidambar Zinnoury diff --git a/AUTHORS b/AUTHORS index 5e867f9765..c8ce721be0 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,4 @@ -Simgrid Core Team +SimGrid Core Team _________________ SimGrid is a joint project. Its main authors are (alphabetic order): diff --git a/BuildSimGrid.sh b/BuildSimGrid.sh index 68432faee8..410d1ddb70 100755 --- a/BuildSimGrid.sh +++ b/BuildSimGrid.sh @@ -3,7 +3,7 @@ # This little script rebuilds and runs the SimGrid archive in parallel, extracting a log # This is almost a personal script, but others may find this useful # -# Copyright (c) 2017-2022 The SimGrid Team. Licence: LGPL of WDFPL, as you want. +# Copyright (c) 2017-2023 The SimGrid Team. Licence: LGPL of WDFPL, as you want. if [ ! -e Makefile ] && [ ! -e build.ninja ]; then if [ -e build/default/Makefile ] ; then @@ -15,8 +15,9 @@ if [ ! -e Makefile ] && [ ! -e build.ninja ]; then fi fi -target=tests +target=examples ncores=$(grep -c processor /proc/cpuinfo) +halfcores=$(expr $ncores / 2 + 1) install_path=$(sed -n 's/^CMAKE_INSTALL_PREFIX:PATH=//p' CMakeCache.txt) if [ -e ${install_path} ] && [ -d ${install_path} ] && [ -x ${install_path} ] && [ -w ${install_path} ] ; then @@ -32,7 +33,8 @@ fi ( echo "install_path: ${install_path}" echo "Target: ${target}" - echo "Cores: ${ncores}" - (nice ${builder} -j${ncores} ${target} tests || make ${target} tests) && nice ctest -j${ncores} --output-on-failure ; date + echo "Cores to build: ${ncores}" + echo "Cores to test: ${halfcores}" + (nice ${builder} -j${ncores} ${target} tests || ${builder} ${target} tests) && nice ctest -j${halfcores} --output-on-failure ; date ) 2>&1 | tee BuildSimGrid.sh.log diff --git a/CMakeLists.txt b/CMakeLists.txt index b03c59570a..6889a1299a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # Build the version number set(SIMGRID_VERSION_MAJOR "3") -set(SIMGRID_VERSION_MINOR "31") +set(SIMGRID_VERSION_MINOR "35") set(SIMGRID_VERSION_PATCH "1") # odd => git branch; even => stable release or released snapshot if(${SIMGRID_VERSION_PATCH} EQUAL "0") @@ -10,19 +10,20 @@ else() set(release_version "${SIMGRID_VERSION_MAJOR}.${SIMGRID_VERSION_MINOR}.${SIMGRID_VERSION_PATCH}") endif() +if(WIN32 OR MINGW) + message(FATAL_ERROR "SimGrid does not build on native windows, nor with MinGW. Please use WSL2 instead.") +endif() + message(STATUS "Configuring SimGrid v${release_version}") set(SIMGRID_VERSION_STRING "SimGrid version ${release_version}") set(libsimgrid_version "${release_version}") -set(libsimgrid-java_version "${release_version}") # Basic checks on cmake -cmake_minimum_required(VERSION 3.5) -#for lto, to avoid warning (should be removed when switching to requiring cmake >= 3.9) -if(NOT CMAKE_VERSION VERSION_LESS "3.9") - cmake_policy(SET CMP0069 NEW) -endif() +cmake_minimum_required(VERSION 3.12) +# once we move CMake to >= 3.13, we should use target_link_option in examples/sthread +# once we move CMake to >= 3.13.1, we could get rid of _Boost_STACKTRACE_BACKTRACE_HEADERS message(STATUS "Cmake version ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_HOME_DIRECTORY}/tools/cmake/Modules) @@ -34,12 +35,8 @@ include(GNUInstallDirs) #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Check for the compiler # #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# -## -## Check the C/C++ standard that we need -## See also tools/cmake/Flags.cmake that sets our paranoid warning flags -INCLUDE(CheckCCompilerFlag) -CHECK_C_COMPILER_FLAG(-fstack-cleaner HAVE_C_STACK_CLEANER) +INCLUDE(CheckCCompilerFlag) ## Request full debugging flags set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3") @@ -52,7 +49,7 @@ if (CMAKE_COMPILER_IS_GNUCC) endif() endif() -## We need a decent support of the C++14 and C11 standards +## We need a decent support of the C++17 and C11 standards set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -76,7 +73,7 @@ if ((NOT DEFINED enable_smpi) OR enable_smpi) # configuration where it was saved as smpiff unset(CMAKE_Fortran_COMPILER) - SET(SMPI_FORTRAN 0) + SET(SMPI_FORTRAN OFF) if(enable_fortran) enable_language(Fortran OPTIONAL) endif() @@ -105,7 +102,7 @@ if ((NOT DEFINED enable_smpi) OR enable_smpi) ## Request debugging flags for Fortran too set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g") - set(SMPI_FORTRAN 1) + set(SMPI_FORTRAN ON) endif(CMAKE_Fortran_COMPILER) endif() @@ -113,9 +110,6 @@ endif() ### SET THE LIBRARY EXTENSION if(APPLE) set(LIB_EXE "dylib") -elseif(WIN32) - set(LIB_EXE "a") - set(BIN_EXE ".exe") else() set(LIB_EXE "so") endif() @@ -130,22 +124,12 @@ if(NOT PERL_FOUND) message(FATAL_ERROR "Please install Perl to compile SimGrid.") endif() -# tesh.py needs python 3 (or the module python-subprocess32 on python2.8+) -if(CMAKE_VERSION VERSION_LESS "3.12") - set(PythonInterp_FIND_VERSION 3) - set(PythonInterp_FIND_VERSION_COUNT 1) - set(PythonInterp_FIND_VERSION_MAJOR 3) - include(FindPythonInterp) - if(NOT PYTHONINTERP_FOUND) - message(FATAL_ERROR "Please install Python (version 3 or higher) to compile SimGrid.") - endif() -else() - find_package(Python3 COMPONENTS Interpreter Development) - if(NOT Python3_Interpreter_FOUND) - message(FATAL_ERROR "Please install Python (version 3 or higher) to compile SimGrid.") - endif() - set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) +# tesh.py needs python 3 +find_package(Python3 COMPONENTS Interpreter) +if(NOT Python3_Interpreter_FOUND) + message(FATAL_ERROR "Please install Python (version 3 or higher) to compile SimGrid.") endif() +set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) @@ -161,7 +145,6 @@ include_directories( set(INTERNAL_INCLUDES ${CMAKE_BINARY_DIR} ${CMAKE_HOME_DIRECTORY} - ${CMAKE_HOME_DIRECTORY}/src/include ) if(enable_smpi) @@ -172,41 +155,33 @@ if(NOT CMAKE_CROSSCOMPILING AND EXISTS /usr/include/) set(INTERNAL_INCLUDES ${INTERNAL_INCLUDES} /usr/include/) endif() -if(WIN32) - set(CMAKE_INCLUDE_WIN "${CMAKE_C_COMPILER}") - set(CMAKE_LIB_WIN "${CMAKE_C_COMPILER}") - string(REGEX REPLACE "/bin/gcc.*" "/include" CMAKE_INCLUDE_WIN "${CMAKE_INCLUDE_WIN}") - string(REGEX REPLACE "/bin/gcc.*" "/lib" CMAKE_LIB_WIN "${CMAKE_LIB_WIN}") - set(INTERNAL_INCLUDES ${INTERNAL_INCLUDES} ${CMAKE_INCLUDE_WIN}) - unset(CMAKE_INCLUDE_WIN) -endif() - # library dependency cannot start with a space (CMP0004), so initialize it with something that is never deactivated. set(SIMGRID_DEP "-lm") ### Determine the assembly flavor that we need today set(HAVE_RAW_CONTEXTS 0) include(CMakeDetermineSystem) +foreach(arch i686 x86_64 arm64) + set(SIMGRID_PROCESSOR_${arch} 0) +endforeach() IF(CMAKE_SYSTEM_PROCESSOR MATCHES ".86|AMD64|amd64") IF(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 bits message(STATUS "System processor: i686 (${CMAKE_SYSTEM_PROCESSOR}, 32 bits)") set(SIMGRID_PROCESSOR_i686 1) - set(SIMGRID_PROCESSOR_x86_64 0) ELSE() message(STATUS "System processor: x86_64 (${CMAKE_SYSTEM_PROCESSOR}, 64 bits)") - set(SIMGRID_PROCESSOR_i686 0) set(SIMGRID_PROCESSOR_x86_64 1) ENDIF() - if (WIN32) - message(STATUS "Disable fast raw contexts on Windows.") - elseif(CMAKE_SIZEOF_VOID_P EQUAL 4 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") message(STATUS "Disable fast raw contexts on x32 ABI.") else() set(HAVE_RAW_CONTEXTS 1) endif() +ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") + message(STATUS "System processor: arm64 (${CMAKE_SYSTEM_PROCESSOR}, 64 bits)") + set(SIMGRID_PROCESSOR_arm64 1) ELSE() - set(SIMGRID_PROCESSOR_i686 0) - set(SIMGRID_PROCESSOR_x86_64 0) + message(STATUS "System processor (${CMAKE_SYSTEM_PROCESSOR}) not explicitly accounted for") ENDIF() include(CheckFunctionExists) @@ -216,21 +191,21 @@ include(CheckIncludeFiles) include(CheckLibraryExists) include(CheckSymbolExists) -set(HAVE_GRAPHVIZ 0) +set(HAVE_GRAPHVIZ OFF) if(minimal-bindings) message(STATUS "Don't even look for graphviz, as we build minimal binding libraries.") else() include(FindGraphviz) endif() -set(SIMGRID_HAVE_NS3 0) +set(SIMGRID_HAVE_NS3 OFF) if(enable_ns3) include(FindNS3) if (SIMGRID_HAVE_NS3) if (NOT NS3_VERSION EQUAL "3-dev" AND NS3_VERSION VERSION_LESS "3.28") message(FATAL_ERROR "SimGrid needs ns-3 in version 3.28 or higher. Please upgrade or disable that cmake option.") endif() - set(SIMGRID_HAVE_NS3 1) + set(SIMGRID_HAVE_NS3 ON) set(SIMGRID_DEP "${SIMGRID_DEP} ${NS3_LIBRARIES}") else() message(FATAL_ERROR "Cannot find ns-3. Please install it (apt-get install ns3 libns3-dev) or disable that cmake option") @@ -238,37 +213,50 @@ if(enable_ns3) endif() ### Check for Eigen library -set(SIMGRID_HAVE_EIGEN3 0) -find_package (Eigen3 3.3 CONFIG - HINTS ${EIGEN3_HINT}) -if (Eigen3_FOUND) - set(SIMGRID_HAVE_EIGEN3 1) - message(STATUS "Found Eigen3: ${EIGEN3_INCLUDE_DIR}") - include_directories(${EIGEN3_INCLUDE_DIR}) - if ("3.3.4" VERSION_EQUAL EIGEN3_VERSION_STRING AND CMAKE_COMPILER_IS_GNUCC) - message(STATUS "Avoid build error of Eigen3 v3.3.4 using -Wno-error=int-in-bool-context") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=int-in-bool-context") +if ((NOT DEFINED EIGEN3_HINT) OR (NOT EIGEN3_HINT STRLESS_EQUAL "OFF")) + set(SIMGRID_HAVE_EIGEN3 OFF) + find_package (Eigen3 3.3 CONFIG + HINTS ${EIGEN3_HINT}) + if (Eigen3_FOUND) + set(SIMGRID_HAVE_EIGEN3 ON) + message(STATUS "Found Eigen3: ${EIGEN3_INCLUDE_DIR}") + include_directories(${EIGEN3_INCLUDE_DIR}) + if ("3.3.4" VERSION_EQUAL EIGEN3_VERSION_STRING AND CMAKE_COMPILER_IS_GNUCC) + message(STATUS "Avoid build error of Eigen3 v3.3.4 using -Wno-error=int-in-bool-context") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=int-in-bool-context") + endif() + else() + message(STATUS "Disabling model BMF because Eigen3 was not found. If it's installed, use EIGEN3_HINT to hint cmake about the location of Eigen3Config.cmake") endif() + mark_as_advanced(Eigen3_DIR) else() - message(STATUS "Disabling model BMF because Eigen3 was not found. If it's installed, use EIGEN3_HINT to hint cmake about the location of Eigen3Config.cmake") -endif() - -set(SIMGRID_HAVE_MSG 0) -if(enable_msg) - set(SIMGRID_HAVE_MSG 1) -endif() - -if(WIN32) - set(Boost_USE_STATIC_LIBS 1) + message(STATUS "Disabling Eigen3 as requested by the user (EIGEN3_HINT is set to 'OFF')") +endif() + +# Check for our JSON dependency +set(SIMGRID_HAVE_JSON 0) +find_package(nlohmann_json 3.7 + HINTS ${nlohmann_json_HINT}) +if (nlohmann_json_FOUND) + set(SIMGRID_HAVE_JSON 1) + if (NOT NLOHMANN_JSON_INCLUDE_DIR) + get_target_property(NLOHMANN_JSON_INCLUDE_DIR nlohmann_json::nlohmann_json INTERFACE_INCLUDE_DIRECTORIES) + list(REMOVE_DUPLICATES NLOHMANN_JSON_INCLUDE_DIR) + else() + include_directories(${NLOHMANN_JSON_INCLUDE_DIR}) + endif() + message(STATUS "Found nlohmann_json: ${NLOHMANN_JSON_INCLUDE_DIR}") endif() +mark_as_advanced(nlohmann_json_DIR) -set(HAVE_PAPI 0) +set(HAVE_PAPI OFF) if(enable_smpi_papi) include(FindPAPI) if (NOT HAVE_PAPI) message(FATAL_ERROR "Cannot find PAPI. Please install it (apt-get install papi-tools libpapi-dev) or disable PAPI bindings.") endif() endif() +mark_as_advanced(PAPI_PREFIX) # But we do need the core of Boost # cmake before 3.13.1 does not know about stacktrace components. Fix it. @@ -277,7 +265,7 @@ set(_Boost_STACKTRACE_HEADERS "boost/stacktrace.hpp") set(_Boost_STACKTRACE_BACKTRACE_HEADERS "boost/stacktrace.hpp") set(_Boost_STACKTRACE_ADDR2LINE_HEADERS "boost/stacktrace.hpp") - if(minimal-bindings) # When we want a minimal jarfile, don't even search for boost optional components + if(minimal-bindings) # When we want a minimal python library, don't even search for boost optional components message(STATUS "Don't even look for boost optional components, as we build minimal binding libraries.") find_package(Boost 1.48) else() @@ -306,10 +294,10 @@ set(_Boost_STACKTRACE_ADDR2LINE_HEADERS "boost/stacktrace.hpp") if(Boost_CONTEXT_FOUND) message (STATUS " context: found. Activating Boost contexts.") - set(HAVE_BOOST_CONTEXTS 1) + set(HAVE_BOOST_CONTEXTS ON) else() message (STATUS " context: MISSING. Install libboost-context-dev for this optional feature.") - set(HAVE_BOOST_CONTEXTS 0) + set(HAVE_BOOST_CONTEXTS OFF) endif() endif() else() @@ -325,6 +313,10 @@ set(_Boost_STACKTRACE_ADDR2LINE_HEADERS "boost/stacktrace.hpp") endif() endif() endif() +mark_as_advanced(Boost_CONTEXT_LIBRARY_RELEASE) +mark_as_advanced(Boost_INCLUDE_DIR) +mark_as_advanced(Boost_STACKTRACE_ADDR2LINE_LIB) +mark_as_advanced(Boost_STACKTRACE_BACKTRACE_LIB) # Checks for header libraries functions. CHECK_LIBRARY_EXISTS(rt clock_gettime "" HAVE_POSIX_GETTIME) @@ -333,10 +325,6 @@ CHECK_INCLUDE_FILE("pthread_np.h" HAVE_PTHREAD_NP_H) # for pthread_setaffinity_n if(CMAKE_SYSTEM_NAME MATCHES "Darwin") set(CMAKE_REQUIRED_DEFINITIONS "-D_XOPEN_SOURCE=700 -D_DARWIN_C_SOURCE") -elseif(MINGW) - # Use the GNU version of unusual modifiers like PRIx64 - add_definitions(-D__USE_MINGW_ANSI_STDIO=1) - set(CMAKE_REQUIRED_DEFINITIONS "-D__USE_MINGW_ANSI_STDIO=1") else() set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE") endif() @@ -349,17 +337,13 @@ CHECK_FUNCTION_EXISTS(dlfunc HAVE_DLFUNC) CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY) CHECK_FUNCTION_EXISTS(nanosleep HAVE_NANOSLEEP) CHECK_FUNCTION_EXISTS(sysconf HAVE_SYSCONF) +if(NOT HAVE_SYSCONF) + message(FATAL_ERROR "Cannot build without sysconf.") +endif() CHECK_FUNCTION_EXISTS(process_vm_readv HAVE_PROCESS_VM_READV) -CHECK_FUNCTION_EXISTS(mmap HAVE_MMAP) CHECK_FUNCTION_EXISTS(mremap HAVE_MREMAP) CHECK_SYMBOL_EXISTS(vasprintf stdio.h HAVE_VASPRINTF) -if(MINGW) - # The detection of vasprintf fails on MinGW, assumingly because it's - # defined as an inline function in stdio.h instead of a regular - # function. So force the result to be 1 despite of the test. - set(HAVE_VASPRINTF 1) -endif() CHECK_INCLUDE_FILE("sys/sendfile.h" HAVE_SENDFILE_H) CHECK_FUNCTION_EXISTS(sendfile HAVE_SENDFILE) @@ -369,73 +353,33 @@ else() set(SG_HAVE_SENDFILE 0) endif() -if(enable_model-checking AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux|FreeBSD") - message(WARNING "Support for model-checking has not been enabled on ${CMAKE_SYSTEM}: disabling it") - set(enable_model-checking FALSE) -endif() - -if(enable_model-checking AND minimal-bindings) - message(FATAL_ERROR "Compile-time option 'minimal-bindings' cannot be enabled with 'model-checking'") -endif() - -if(HAVE_MMAP) - SET(HAVE_MMALLOC 1) -else() - SET(HAVE_MMALLOC 0) - if(enable_model-checking) - message(STATUS "Warning: support for model-checking has been disabled because you are missing either mmap or __thread.") - endif() - SET(enable_model-checking 0) -endif() - if(enable_mallocators) SET(SIMGRID_HAVE_MALLOCATOR 1) else() SET(SIMGRID_HAVE_MALLOCATOR 0) endif() +SET(SIMGRID_HAVE_MC OFF) + if(enable_model-checking) - include(FindLibunwind) - if(HAVE_LIBUNWIND) - SET(SIMGRID_DEP "${SIMGRID_DEP} ${LIBUNWIND_LIBRARIES}") + find_package(Libevent) + if(Libevent_FOUND) + message(STATUS "Found libevent. The stateless model-checking can be enabled.") + include_directories(${LIBEVENT_INCLUDE_DIR}) + set(SIMGRID_DEP "${SIMGRID_DEP} ${LIBEVENT_LIBRARIES}") + SET(SIMGRID_HAVE_MC ON) else() - message(FATAL_ERROR "Please install libunwind-dev libdw-dev libelf-dev libevent-dev if you want to compile the SimGrid model checker.") + message(STATUS "libevent not found. Please install libevent-dev to enable the SimGrid model checker.") endif() - find_package(Libdw REQUIRED) - find_package(Libelf REQUIRED) - find_package(Libevent REQUIRED) - include_directories(${LIBDW_INCLUDE_DIR} ${LIBELF_INCLUDE_DIR} ${LIBEVENT_INCLUDE_DIR}) - set(SIMGRID_DEP "${SIMGRID_DEP} ${LIBEVENT_LIBRARIES} ${LIBELF_LIBRARIES} ${LIBDW_LIBRARIES}") - set(SIMGRID_HAVE_MC 1) - if("${CMAKE_SYSTEM}" MATCHES "FreeBSD" AND enable_java) - message(WARNING "FreeBSD + Model-Checking + Java = too much for now. Disabling the Java bindings.") - set(enable_java FALSE) - endif() -else() - SET(SIMGRID_HAVE_MC 0) - set(HAVE_MMALLOC 0) -endif() -mark_as_advanced(PATH_LIBDW_H) -mark_as_advanced(PATH_LIBDW_LIB) - -if(enable_java AND NOT enable_msg) - message(FATAL_ERROR "Cannot activate the Java bindings without the MSG module. Either add -Denable_msg=ON or -Denable_java=OFF") -endif() - -if (enable_model-checking AND enable_ns3) - message(WARNING "Activating both model-checking and ns-3 bindings is considered experimental.") + mark_as_advanced(LIBEVENT_LIBRARY) + mark_as_advanced(LIBEVENT_THREADS_LIBRARY) endif() if(enable_smpi) - SET(HAVE_SMPI 1) - if(WIN32) - message (STATUS "Warning: no support for SMPI automatic privatization on Windows.") - SET(HAVE_PRIVATIZATION 0) - else() - SET(HAVE_PRIVATIZATION 1) - endif() + SET(HAVE_SMPI ON) + SET(HAVE_PRIVATIZATION ON) else() - SET(HAVE_SMPI 0) + SET(HAVE_SMPI OFF) endif() #-------------------------------------------------------------------------------------------------- @@ -453,27 +397,27 @@ else() OUTPUT_VARIABLE compile_makecontext_output) #If can have both context - if(compile_makecontext) - set(HAVE_UCONTEXT_CONTEXTS 1) - message(STATUS "Support for ucontext factory ok.") - else() + if(NOT compile_makecontext) message(STATUS "Error: exists, but makecontext is not compilable. Compilation output:\n ${compile_makecontext_output}") message(STATUS "No ucontext factory: makecontext() is not compilable.") - endif() - - # Stack setup (size and address) - try_run(RUN_makecontext_VAR COMPILE_makecontext_VAR - ${CMAKE_BINARY_DIR} ${CMAKE_HOME_DIRECTORY}/tools/cmake/test_prog/prog_stacksetup.c - RUN_OUTPUT_VARIABLE stack_setup) - - LIST(LENGTH stack_setup stack_setup_len) - if("${stack_setup_len}" STREQUAL "2") - LIST(GET stack_setup 0 makecontext_addr) - LIST(GET stack_setup 1 makecontext_size) - set(sg_makecontext_stack_addr "#define sg_makecontext_stack_addr(skaddr) (${makecontext_addr})") - set(sg_makecontext_stack_size "#define sg_makecontext_stack_size(sksize) (${makecontext_size})") else() - message(FATAL_ERROR "Could not figure out the stack setup. Compil: ${RUN_makecontext_VAR}. Exec: ${COMPILE_makecontext_VAR}. Output: ${stack_setup}") + message(STATUS "Support for ucontext factory ok.") + set(HAVE_UCONTEXT_CONTEXTS 1) + + # Stack setup (size and address) + try_run(RUN_makecontext_VAR COMPILE_makecontext_VAR + ${CMAKE_BINARY_DIR} ${CMAKE_HOME_DIRECTORY}/tools/cmake/test_prog/prog_stacksetup.c + RUN_OUTPUT_VARIABLE stack_setup) + + LIST(LENGTH stack_setup stack_setup_len) + if("${stack_setup_len}" STREQUAL "2") + LIST(GET stack_setup 0 makecontext_addr) + LIST(GET stack_setup 1 makecontext_size) + set(sg_makecontext_stack_addr "#define sg_makecontext_stack_addr(skaddr) (${makecontext_addr})") + set(sg_makecontext_stack_size "#define sg_makecontext_stack_size(sksize) (${makecontext_size})") + else() + message(FATAL_ERROR "Could not figure out the stack setup. Compil: ${RUN_makecontext_VAR}. Exec: ${COMPILE_makecontext_VAR}. Output: ${stack_setup}") + endif() endif() endif() @@ -498,7 +442,7 @@ else() endif() endif() # If the test ran well, remove the test binary -file(REMOVE test_stackgrowth) +file(REMOVE ${CMAKE_BINARY_DIR}/test_stackgrowth) #-------------------------------------------------------------------------------------------------- ############### @@ -570,6 +514,7 @@ if(SMPI_FORTRAN) set(MODULE_MPIF_OUT "end module mpi") configure_file(${CMAKE_HOME_DIRECTORY}/include/smpi/mpif.h.in ${CMAKE_BINARY_DIR}/src/smpi/mpif.f90.generated @ONLY) execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/src/smpi/mpif.f90.generated ${CMAKE_BINARY_DIR}/src/smpi/mpif.f90) + file(REMOVE ${CMAKE_BINARY_DIR}/src/smpi/mpif.f90.generated) set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/include/smpi) add_library(mpi SHARED ${CMAKE_BINARY_DIR}/src/smpi/mpif.f90) endif() @@ -596,12 +541,10 @@ foreach(script cc cxx ff f90 run) configure_file(${CMAKE_HOME_DIRECTORY}/src/smpi/smpi${script}.in ${CMAKE_BINARY_DIR}/smpi_script/bin/smpi${script} @ONLY) endforeach() -if(NOT WIN32) - foreach(script cc cxx ff f90 run) - execute_process(COMMAND chmod a=rwx ${CMAKE_BINARY_DIR}/bin/smpi${script}) - execute_process(COMMAND chmod a=rwx ${CMAKE_BINARY_DIR}/smpi_script/bin/smpi${script}) - endforeach() -endif() +foreach(script cc cxx ff f90 run) + execute_process(COMMAND chmod a=rwx ${CMAKE_BINARY_DIR}/bin/smpi${script}) + execute_process(COMMAND chmod a=rwx ${CMAKE_BINARY_DIR}/smpi_script/bin/smpi${script}) +endforeach() set(generated_headers_to_install ${CMAKE_CURRENT_BINARY_DIR}/include/smpi/mpif.h @@ -619,7 +562,6 @@ set(generated_files_to_clean ${CMAKE_BINARY_DIR}/bin/smpiff ${CMAKE_BINARY_DIR}/bin/smpif90 ${CMAKE_BINARY_DIR}/bin/smpirun - ${CMAKE_BINARY_DIR}/bin/colorize ${CMAKE_BINARY_DIR}/bin/simgrid_update_xml ${CMAKE_BINARY_DIR}/examples/smpi/tracing/smpi_traced.trace ) @@ -780,20 +722,16 @@ SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES add_custom_target(tests COMMENT "Recompiling the tests") add_custom_target(tests-mc COMMENT "Recompiling the MC tests and tools.") add_dependencies(tests tests-mc) +add_custom_target(tests-ns3 COMMENT "Recompiling the ns3 tests and tools.") +add_dependencies(tests tests-ns3) +add_custom_target(examples COMMENT "Recompiling all examples") +add_dependencies(examples tests) ### Build some Maintainer files include(${CMAKE_HOME_DIRECTORY}/tools/cmake/MaintainerMode.cmake) ### Make Libs -if(NOT WIN32) - include(${CMAKE_HOME_DIRECTORY}/tools/cmake/MakeLib.cmake) -else() - include(${CMAKE_HOME_DIRECTORY}/tools/cmake/MakeLibWin.cmake) -endif() - -if(enable_java) - include(${CMAKE_HOME_DIRECTORY}/tools/cmake/Java.cmake) -endif() +include(${CMAKE_HOME_DIRECTORY}/tools/cmake/MakeLib.cmake) # Python binding (with pybind11) ################ @@ -815,22 +753,22 @@ if((NOT DEFINED enable_python) OR enable_python) set(pybind11_FOUND OFF) endif() endif() - - if(NOT PYTHONLIBS_FOUND AND NOT Python3_Development_FOUND) - message(STATUS "Python libs not found. Turn pybind11 off.") - - set(pybind11_FOUND OFF) - endif() endif() -option(enable_python "Whether the Python bindings are activated." ${pybind11_FOUND}) # ON by default if dependencies are met - -if("${CMAKE_SYSTEM}" MATCHES "FreeBSD" AND enable_model-checking AND enable_python) - message(WARNING "FreeBSD + Model-Checking + Python = too much for now. Disabling the Python bindings.") - set(enable_python FALSE) +find_package(Python3 COMPONENTS Development) +if(NOT Python3_Development_FOUND OR NOT pybind11_FOUND) + message(STATUS "SimGrid Python bindings cannot be built on this system.") + set(default_enable_python OFF) +else() + set(default_enable_python ON) endif() +option(enable_python "Whether the Python bindings are activated." ${default_enable_python}) # ON by default if dependencies are met + if(enable_python) + if(NOT Python3_Development_FOUND) + message(FATAL_ERROR "Please install the development components of Python (python3-dev on Debian) to build the Python bindings (or disable that option).") + endif() if(pybind11_FOUND) message(STATUS "Found pybind11.") if(NOT enable_lto) @@ -927,11 +865,6 @@ message(" version .............: ${CMAKE_C_COMPILER_VERSION}") message(" is gnu ..............: ${CMAKE_COMPILER_IS_GNUCC}") message(" Compiler: C++ ...............: ${CMAKE_CXX_COMPILER} (id: ${CMAKE_CXX_COMPILER_ID})") message(" version .............: ${CMAKE_CXX_COMPILER_VERSION}") -if(${Java_FOUND}) - message(" Compiler: Javac .............: ${Java_JAVAC_EXECUTABLE}") - message(" version .............: ${Java_VERSION_STRING}") - message(" runtime .............: ${Java_JAVA_EXECUTABLE}") -endif() if(CMAKE_Fortran_COMPILER) message(" Compiler: Fortran ...........: ${SMPI_Fortran_COMPILER} (id: ${CMAKE_Fortran_COMPILER_ID})") message(" version .............: ${CMAKE_Fortran_COMPILER_VERSION}") @@ -946,24 +879,12 @@ message(" LDFlags .....................: ${CMAKE_C_LINK_FLAGS}") message(" with LTO ....................: ${enable_lto}") message("") -if (SIMGRID_HAVE_MSG) - message(" Compile MSG .................: ON") -else() - message(" Compile MSG .................: OFF") -endif() - if (SIMGRID_HAVE_NS3) message(" Compile ns-3 ................: ON (path: ${NS3_PATH})") else() message(" Compile ns-3 ................: OFF (hint: ${NS3_HINT})") endif() -if (${Java_FOUND}) - message(" Compile Java ................: ON") - message(" Native lib in jar .........: ${enable_lib_in_jar}") -else() - message(" Compile Java ................: OFF") -endif() if(pybind11_FOUND) message(" Compile Python bindings .....: ${enable_python}") message(" module ....................: ${PYTHON_MODULE_PREFIX}simgrid${PYTHON_MODULE_EXTENSION}") @@ -971,30 +892,37 @@ if(pybind11_FOUND) else() message(" Compile Python bindings .....: OFF (disabled, or pybind11 not found)") endif() -if(Eigen3_FOUND) +if(SIMGRID_HAVE_EIGEN3) message(" Eigen3 library ..............: ${EIGEN3_VERSION_STRING} in ${EIGEN3_INCLUDE_DIR}") else() - message(" Eigen3 library ..............: not found (EIGEN3_HINT='${EIGEN3_HINT}').") + message(" Eigen3 library ..............: not found (EIGEN3_HINT='${EIGEN3_HINT}')") +endif() +if(SIMGRID_HAVE_JSON) + message(" JSON library ................: ${nlohmann_json_VERSION} in ${NLOHMANN_JSON_INCLUDE_DIR}") +else() + message(" JSON library ................: not found (nlohmann_json_HINT='${nlohmann_json_HINT}')") endif() message(" Compile Smpi ................: ${HAVE_SMPI}") message(" Smpi fortran ..............: ${SMPI_FORTRAN}") -message(" MPICH3 testsuite ..........: ${enable_smpi_MPICH3_testsuite}") -message(" MBI testsuite .............: ${enable_smpi_MBI_testsuite}") +message(" MPICH3 testsuite ..........: ${enable_testsuite_smpi_MPICH3}") +message(" MBI testsuite .............: ${enable_testsuite_smpi_MBI}") message(" Privatization .............: ${HAVE_PRIVATIZATION}") -message(" PAPI support...............: ${HAVE_PAPI}") +message(" PAPI support ..............: ${HAVE_PAPI}") message(" Compile Boost.Context support: ${HAVE_BOOST_CONTEXTS}") message("") -message(" Maintainer mode .............: ${enable_maintainer_mode}") -message(" Documentation................: ${enable_documentation}") message(" Model checking ..............: ${SIMGRID_HAVE_MC}") +message(" MBI testsuite .............: ${enable_testsuite_smpi_MBI}") +message(" McMini testsuite ..........: ${enable_testsuite_McMini}") +message("") +message(" Maintainer mode .............: ${enable_maintainer_mode}") +message(" Documentation ...............: ${enable_documentation}") message(" Graphviz mode ...............: ${HAVE_GRAPHVIZ}") message(" Mallocators .................: ${enable_mallocators}") message("") -message(" Simgrid dependencies ........: ${SIMGRID_DEP}") +message(" SimGrid dependencies ........: ${SIMGRID_DEP}") message("") execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/Testing/Notes/) file(WRITE ${PROJECT_BINARY_DIR}/Testing/Notes/Build "GIT version : ${GIT_VERSION}\n") file(APPEND ${PROJECT_BINARY_DIR}/Testing/Notes/Build "Release : simgrid-${release_version}\n") -INCLUDE(Dart) diff --git a/COPYING b/COPYING index ae29638321..7a8526690a 100644 --- a/COPYING +++ b/COPYING @@ -3,7 +3,7 @@ Upstream-Name: SimGrid Source: https://simgrid.org/ Files: * -Copyright: 2003-2022. The SimGrid team. All rights reserved. +Copyright: 2003-2023. The SimGrid team. All rights reserved. License: LGPL-2.1-only Files: src/xbt/snprintf.c @@ -11,13 +11,6 @@ Copyright: 1999, Mark Martinec FramaGit bugs; FG!.. -> FG merge requests) + (FG: issues on Framagit; GH: issues on GitHub) + - FG#18: Java bindings should be redone or removed + - FG!118: Wi-Fi callback mechanism + - FG!119: SMPI: add option to inject a barrier before every collective call + - GH#383: Segfault when adding a disk after load_platform(xml) + +---------------------------------------------------------------------------- + +SimGrid (3.32) October 3. 2022. + +The Wiedervereinigung release. Germany was reunited 32 years ago. + +General: + - SimGrid now requires a compiler with C++17 support to compile the lib. + Our public headers still allow the user code to be compiled in C++14. + - Support graphviz v3 and ns-3 v3.36 (older versions are still supported). + - Tested with clang (v11, v13, v14 and v16), gcc (v7 to v13) and IntelCC v2022.2 + +S4U: + - API evolutions: + - kill signal Comm::on_completion that was not working anyway. + - Expose signals Activity::on_suspend and Activity::on_resume + - New macro xbt_enforce(): similar to xbt_assert(), but throws an AssertionError + instead of calling abort(). + - New: s4u::Exec::get_thread_count() + - Various cleanups around virtual machines: + - host_by_name() and friends now only return hosts. VMs are now excluded. + - It is now impossible to search a VM by name globally. + You can only search VM by name on a given PM, so either you know + the PM on which your VM runs and you can search by name, or you need + to manually iterate over all PMs to search this VM. + - The s4u::VirtualMachine constructor is now deprecated. + Please use s4u::Host::create_vm() instead. + - Rename s4u::VirtualMachine::on_creation() to on_vm_creation() to + avoid confusion with s4u:Host::on_creation() that is inherited. + Also s4u::VirtualMachine::on_destruction -> on_vm_destruction(). + - Bug fixes: + - One-sided communications (Comm::sendto) can now be detached, + and should now be more resilient to network and host faults. + +Python: + - Added the following bindings / examples: + - Comm (now 100% covers the C++ interface): + - Comm.dst_data_size, Comm.mailbox, Comm.sender, Comm.start_time, Comm.finish_time + - Comm.state_str [examples: examples/python/comm-failure/, examples/python/comm-host2host/] + - Comm.remaining [examples: examples/python/comm-host2host/, examples/python/comm-suspend/] + - Comm.set_payload_size [example: examples/python/comm-host2host/] + - Comm.set_rate [example: examples/python/comm-throttling/] + - Comm.sendto, Comm.sendto_init, Comm.sendto_async [example: examples/python/comm-host2host/] + - Comm.start, Comm.suspend, Comm.resume [example: examples/python/comm-host2host/] + - Comm.test_any [example: examples/python/comm-testany/] + - Comm.wait_until [example: examples/python/comm-waituntil/] + - Engine: + - Engine.host_by_name [example: examples/python/comm-host2host/] + - Engine.mailbox_by_name_or_create [example: examples/python/comm-pingpong/] + - Engine.set_config + - Mailbox: Mailbox.ready [example: examples/python/comm-ready/] + - Ptask [example: examples/python/exec-ptask/]: + - this_actor.exec_init + - this_actor.parallel_execute + - Exec.suspend + - Exec.wait_for + - Added an AssertionError exception that may be thrown in case of error. + For instance, creating two hosts with the same name will now throw this exception + instead of killing the interpreter. + +SMPI: + - Implement MPI_File_get_type_extent(), MPI_File_s/get_atomicity() and + MPI_File_get_byte_offset() + - Intercept getpid() calls to return the simulated ones. + - Fix various bugs in MPI IO. Platform description & visualization: - - More robust sanity checks for platforms, to reject unallowed topologies with - a proper error message. - - One new C++ platform example, supernode.cpp. A Python script (supernode.py) - demonstrates how we can generate a nice graphical representation of the - platform. - -General: - - Modified the host_by_name functions: - - Now, they return only hosts, not VMs, and in a much more efficient way. - - If one wants to find a VM by name, he now needs to know the host on - which it runs and call vm_by_name (or manually iterate over the list of hosts) - -Tools: - - Enhancements to the graphicator tool: - - Allow to dump the platform topology as a CSV file representing the edges - of the graph (in addition to the DOT format). - - Fix graphicator for "cluster" topologies (e.g. fat-tree, dragonfly). + - More robust sanity checks for platforms, to reject forbidden topologies with + a proper error message. + - New platform example: supernode.cpp and supernode.py. + The Python version generates a nice graphical representation of the platform. + - Bug fixes around fat-tree topologies. + - Allow to dump the platform topology as a CSV file representing the graph edges + with platform_graph_export_csv() (similar to the DOT export). + - Fix graphicator for "cluster" topologies (e.g. fat-tree, dragonfly). + +Models: + - Fix a bug when using ptasks with multicores (FG!111). + +Model-Checker: + - First bits of sthread, that intercepts pthread operations at runtime. + The intend is to use it together with simgrid-mc, but it is TBD. + - Sync MBI generators with upstream changes. + - Various cosmetics, small bug fixes and inner refactorings Fixed bugs (FG#.. -> FramaGit bugs; FG!.. -> FG merge requests) (FG: issues on Framagit; GH: issues on GitHub) - FG#105: "Variable penalty should not be negative!" with in-flight messages and bandwidth profiles - FG#109: Application time reported by --cfg=smpi/display-timing:yes is wrong - - FG!109: Trigger new engine solve upon host events such as host on/off - FG#110: Wait_any does not trigger new model solve when host events occur + - FG#111: Wrong execution time in rare cases when using multicore + - FG!98: Re-enable the tests for legacy stochastic profiles + - FG!109: Trigger new engine solve upon host events such as host on/off + - FG!116: SMPI/replay: Fix issue with recv of size =0 ---------------------------------------------------------------------------- -S4U: - - kill signal Comm::on_completion that was not working anyway. - - Expose signals Activity::on_suspend and Activity::on_resume - SimGrid (3.31) March 22. 2022. The ненасильство release. We stand against war. @@ -106,7 +338,7 @@ MSG: New plugin: the Chaos Monkey (killing actors at any time) - Along with the new simgrid-monkey script, it tests whether your simulation resists resource failures at any possible timestamp in your simulation. - - It is mostly intended to test the simgrid core in extreme conditions, + - It is mostly intended to test the SimGrid core in extreme conditions, but some users may find it interesting too. Models: @@ -544,7 +776,7 @@ The Release release (the French lockdown was eased today). Important user-visible changes: - SimGrid now requires a compiler with C++14 support. - Sibling projects should upgrade their FindSimgrid.cmake + Sibling projects should upgrade their FindSimGrid.cmake - Surf precision default value is now 1e-9, instead of 1e-5. This was changed as several users had difficulties to understand issues when using high bandwidth or small latency events. The new value was already the default for SMPI and @@ -870,7 +1102,7 @@ General: - Network model 'NS3' was renamed into 'ns-3'. Python: - - Simgrid can now hopefully be installed with pip. + - SimGrid can now hopefully be installed with pip. S4U: - wait_any can now be used for asynchronous executions too. @@ -1918,7 +2150,7 @@ SimGrid (3.12) stable; urgency=low - InfiniBand network model added: Based on the works of Jerome Vienne http://mescal.imag.fr/membres/jean-marc.vincent/index.html/PhD/Vienne.pdf - When smpi/display_timing is set, also display global simulation time and application times - - Have smpirun, smpicc and friends display the simgrid git hash version on --git-version + - Have smpirun, smpicc and friends display the SimGrid git hash version on --git-version * Collective communications - SMP-aware algorithms are now dynamically handled. An internal communicator is created for each node, and an external one to handle communications between "leaders" of each node - MVAPICH2 (1.9) collective algorithms selector: normal and SMP algorithms are handled, and selection logic is based on the one used on TACC's Stampede cluster (https://www.tacc.utexas.edu/stampede/). @@ -2659,8 +2891,8 @@ SimGrid (3.6.2) stable; urgency=low Portability * Create an installer for windows with nsis (amd64 and win32) - - Add an hello world project to illustrate simgrid project creation. - - Embed libpcre into the Simgrid installer to avoid + - Add an hello world project to illustrate SimGrid project creation. + - Embed libpcre into the SimGrid installer to avoid its compilation burden * The raw execution contexts should work on Apple now * Port to Windows 64 bits @@ -2693,7 +2925,7 @@ SimGrid (3.6.1) stable; urgency=low SimGrid-java (3.6) unstable; urgency=low * Initial release. - * Split of every thing from simgrid v3.5 into a separate package. + * Split of every thing from SimGrid v3.5 into a separate package. -- 2011-10-05 Da SimGrid team @@ -3207,7 +3439,7 @@ SimGrid (3.4) stable; urgency=low * Greatly improved our cdash/ctest interactions Check http://cdash.inria.fr/CDash/index.php?project=Simgrid * Added memory checking tests with valgrind; lot of memleak fixing. - This may be the first release of simgrid with so few memory issues + This may be the first release of SimGrid with so few memory issues * Added code coverage tests. Our coverage is still improvable, but at least we see it on cdash. @@ -3513,7 +3745,7 @@ SimGrid (3.3.2) stable; urgency=low Timing report of this version: This version seem to be more than 5% faster than 3.3.1 (on linux - 64bits with contextes). The gain is less than expected, we are + 64bits with contexts). The gain is less than expected, we are investigating this for next release. -- Da SimGrid team Wed, 19 Aug 2009 17:07:12 +0200 @@ -3606,7 +3838,7 @@ SimGrid (3.3.1) stable; urgency=low - Linux(debian)/amd64/context - Linux(debian)/amd64/pthreads These targets fail about 1/10 of times on gras/pmm, but we believe - that this is because of the test, not because of simgrid. + that this is because of the test, not because of SimGrid. amok/saturate_sg fails even more rarely, and the test may not be the problem. @@ -3663,7 +3895,7 @@ SimGrid (3.3) stable; urgency=high is really less memory-demanding, which should allow you to use larger files in SimGrid [AL]. - * Inform valgrind about our contextes, so that it becomes usable + * Inform valgrind about our contexts, so that it becomes usable with the default (and more effecient) version of SimGrid [contributed by Sékou Diakite, many thanks] diff --git a/FindSimGrid.cmake b/FindSimGrid.cmake index e14aeceac1..eec2f92ed5 100644 --- a/FindSimGrid.cmake +++ b/FindSimGrid.cmake @@ -1,6 +1,6 @@ # CMake find module to search for the SimGrid library. -# Copyright (c) 2016-2022. The SimGrid Team. +# Copyright (c) 2016-2023. The SimGrid Team. # # This file is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -23,19 +23,11 @@ # Either by copying it in your tree, or (recommended) by using the # version automatically installed by SimGrid. # -# 2. Afterward, if you have CMake >= 2.8.12, this will define a -# target called 'SimGrid::Simgrid'. Use it as: +# 2. This will define a target called 'SimGrid::Simgrid'. Use it as: # target_link_libraries(your-simulator SimGrid::SimGrid) # -# With older CMake (< 2.8.12), it simply defines several variables: -# SimGrid_INCLUDE_DIR - the SimGrid include directories -# SimGrid_LIBRARY - link your simulator against it to use SimGrid -# Use as: -# include_directories("${SimGrid_INCLUDE_DIR}" SYSTEM) -# target_link_libraries(your-simulator ${SimGrid_LIBRARY}) -# -# In both cases, it also define a SimGrid_VERSION macro, that you -# can use to deal with API evolutions as follows: +# It also defines a SimGrid_VERSION macro, that you can use to deal with API +# evolutions as follows: # # #if SimGrid_VERSION < 31800 # (code to use if the installed version is lower than v3.18) @@ -45,9 +37,21 @@ # (code to use with SimGrid v3.19+) # #endif # -# Since SimGrid header files require C++14, so we set CMAKE_CXX_STANDARD to 14. +# Since SimGrid header files require C++17, so we set CMAKE_CXX_STANDARD to 17. # Change this variable in your own file if you need a later standard. +# DEVELOPPERS OF MPI PROGRAMS USING SIMGRID +# You should use smpi_c_target() on the targets that are intended to run in SMPI. +# ${SMPIRUN} is correctly set if it's installed. +# +# Example: +# add_executable(roundtrip roundtrip.c) +# smpi_c_target(roundtrip) +# +# enable_testing() +# add_test(NAME Roundtrip +# COMMAND ${SMPIRUN} -platform ${CMAKE_SOURCE_DIR}/../cluster_backbone.xml -np 2 ./roundtrip) + # # IMPROVING THIS FILE # ------------------- @@ -56,9 +60,9 @@ # https://cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file # https://github.com/boostcon/cppnow_presentations_2017/blob/master/05-19-2017_friday/effective_cmake__daniel_pfeifer__cppnow_05-19-2017.pdf -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.5) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_path(SimGrid_INCLUDE_DIR @@ -110,33 +114,41 @@ find_package_handle_standard_args(SimGrid VERSION_VAR SimGrid_VERSION ) -if (SimGrid_FOUND AND NOT CMAKE_VERSION VERSION_LESS 2.8.12) +if (SimGrid_FOUND) + + find_program(SMPIRUN smpirun + HINTS ${SimGrid_PATH}/bin /opt/simgrid/bin) + + MACRO(smpi_c_target NAME) + target_compile_options(${NAME} PUBLIC "-include;smpi/smpi_helpers.h;-fPIC;-shared;-Wl,-z,defs") + target_link_options(${NAME} PUBLIC "-fPIC;-shared;-Wl,-z,defs;-lm") + target_link_libraries(${NAME} PUBLIC ${SimGrid_LIBRARY}) + target_include_directories(${NAME} PUBLIC "${SimGrid_INCLUDE_DIR};${SimGrid_INCLUDE_DIR}/smpi") + ENDMACRO() + add_library(SimGrid::SimGrid SHARED IMPORTED) set_target_properties(SimGrid::SimGrid PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${SimGrid_INCLUDE_DIR} INTERFACE_COMPILE_FEATURES cxx_alias_templates IMPORTED_LOCATION ${SimGrid_LIBRARY} ) - # We need C++14, so check for it just in case the user removed it since compiling SimGrid + # We need C++17, so check for it just in case the user removed it since compiling SimGrid if (NOT CMAKE_VERSION VERSION_LESS 3.8) - # 3.8+ allows us to simply require C++14 (or higher) - set_property(TARGET SimGrid::SimGrid PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_14) - elseif (NOT CMAKE_VERSION VERSION_LESS 3.1) - # 3.1+ is similar but for certain features. We pick just one - set_property(TARGET SimGrid::SimGrid PROPERTY INTERFACE_COMPILE_FEATURES cxx_attribute_deprecated) + # 3.8+ allows us to simply require C++17 (or higher) + set_property(TARGET SimGrid::SimGrid PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_17) else () - # Old CMake can't do much. Just check the CXX_FLAGS and inform the user when a C++14 feature does not work + # Old CMake can't do much. Just check the CXX_FLAGS and inform the user when a C++17 feature does not work include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS}") check_cxx_source_compiles(" -#if __cplusplus < 201402L +#if __cplusplus < 201703L #error #else int main(){} #endif -" _SIMGRID_CXX14_ENABLED) - if (NOT _SIMGRID_CXX14_ENABLED) - message(WARNING "C++14 is required to use SimGrid. Enable it with e.g. -std=c++14") +" _SIMGRID_CXX17_ENABLED) + if (NOT _SIMGRID_CXX17_ENABLED) + message(WARNING "C++17 is required to use SimGrid. Enable it with e.g. -std=c++17") endif () unset(_SIMGRID_CXX14_ENABLED CACHE) endif () diff --git a/MANIFEST.in b/MANIFEST.in index 09a068e084..a7c5668748 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,10 +1,14 @@ # This file lists the content of the python source package # Prepared in tools/cmake/Distrib.cmake -include doc/webcruft/Paje_MSG_screenshot.jpg -include doc/webcruft/Paje_MSG_screenshot_thn.jpg -include doc/webcruft/eclipseScreenShot.png -include doc/webcruft/output.goal.pdf +include examples/c/activityset-testany/activityset-testany.c +include examples/c/activityset-testany/activityset-testany.tesh +include examples/c/activityset-waitall/activityset-waitall.c +include examples/c/activityset-waitall/activityset-waitall.tesh +include examples/c/activityset-waitallfor/activityset-waitallfor.c +include examples/c/activityset-waitallfor/activityset-waitallfor.tesh +include examples/c/activityset-waitany/activityset-waitany.c +include examples/c/activityset-waitany/activityset-waitany.tesh include examples/c/actor-create/actor-create.c include examples/c/actor-create/actor-create.tesh include examples/c/actor-create/actor-create_d.xml @@ -69,12 +73,6 @@ include examples/c/comm-wait/comm-wait2_d.xml include examples/c/comm-wait/comm-wait3_d.xml include examples/c/comm-wait/comm-wait4_d.xml include examples/c/comm-wait/comm-wait_d.xml -include examples/c/comm-waitall/comm-waitall.c -include examples/c/comm-waitall/comm-waitall.tesh -include examples/c/comm-waitall/comm-waitall_d.xml -include examples/c/comm-waitany/comm-waitany.c -include examples/c/comm-waitany/comm-waitany.tesh -include examples/c/comm-waitany/comm-waitany_d.xml include examples/c/dht-kademlia/answer.c include examples/c/dht-kademlia/answer.h include examples/c/dht-kademlia/common.h @@ -106,8 +104,6 @@ include examples/c/exec-dvfs/exec-dvfs.c include examples/c/exec-dvfs/exec-dvfs.tesh include examples/c/exec-remote/exec-remote.c include examples/c/exec-remote/exec-remote.tesh -include examples/c/exec-waitany/exec-waitany.c -include examples/c/exec-waitany/exec-waitany.tesh include examples/c/io-disk-raw/io-disk-raw.c include examples/c/io-disk-raw/io-disk-raw.tesh include examples/c/io-file-remote/io-file-remote.c @@ -124,10 +120,14 @@ include examples/c/plugin-host-load/plugin-host-load.c include examples/c/plugin-host-load/plugin-host-load.tesh include examples/c/synchro-semaphore/synchro-semaphore.c include examples/c/synchro-semaphore/synchro-semaphore.tesh -include examples/cpp/activity-testany/s4u-activity-testany.cpp -include examples/cpp/activity-testany/s4u-activity-testany.tesh -include examples/cpp/activity-waitany/s4u-activity-waitany.cpp -include examples/cpp/activity-waitany/s4u-activity-waitany.tesh +include examples/cpp/activityset-testany/s4u-activityset-testany.cpp +include examples/cpp/activityset-testany/s4u-activityset-testany.tesh +include examples/cpp/activityset-waitall/s4u-activityset-waitall.cpp +include examples/cpp/activityset-waitall/s4u-activityset-waitall.tesh +include examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.cpp +include examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.tesh +include examples/cpp/activityset-waitany/s4u-activityset-waitany.cpp +include examples/cpp/activityset-waitany/s4u-activityset-waitany.tesh include examples/cpp/actor-create/s4u-actor-create.cpp include examples/cpp/actor-create/s4u-actor-create.tesh include examples/cpp/actor-create/s4u-actor-create_d.xml @@ -166,6 +166,19 @@ include examples/cpp/app-masterworkers/s4u-app-masterworkers.tesh include examples/cpp/app-masterworkers/s4u-app-masterworkers_d.xml include examples/cpp/app-token-ring/s4u-app-token-ring.cpp include examples/cpp/app-token-ring/s4u-app-token-ring.tesh +include examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.cpp +include examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.tesh +include examples/cpp/battery-connector/s4u-battery-connector.cpp +include examples/cpp/battery-connector/s4u-battery-connector.tesh +include examples/cpp/battery-degradation/plot_battery_degradation.py +include examples/cpp/battery-degradation/s4u-battery-degradation.cpp +include examples/cpp/battery-degradation/s4u-battery-degradation.tesh +include examples/cpp/battery-energy/s4u-battery-energy.cpp +include examples/cpp/battery-energy/s4u-battery-energy.tesh +include examples/cpp/battery-simple/s4u-battery-simple.cpp +include examples/cpp/battery-simple/s4u-battery-simple.tesh +include examples/cpp/chiller-simple/s4u-chiller-simple.cpp +include examples/cpp/chiller-simple/s4u-chiller-simple.tesh include examples/cpp/cloud-capping/s4u-cloud-capping.cpp include examples/cpp/cloud-capping/s4u-cloud-capping.tesh include examples/cpp/cloud-migration/s4u-cloud-migration.cpp @@ -185,34 +198,35 @@ include examples/cpp/comm-pingpong/s4u-comm-pingpong.cpp include examples/cpp/comm-pingpong/s4u-comm-pingpong.tesh include examples/cpp/comm-ready/s4u-comm-ready.cpp include examples/cpp/comm-ready/s4u-comm-ready.tesh -include examples/cpp/comm-serialize/s4u-comm-serialize.cpp -include examples/cpp/comm-serialize/s4u-comm-serialize.tesh include examples/cpp/comm-suspend/s4u-comm-suspend.cpp include examples/cpp/comm-suspend/s4u-comm-suspend.tesh -include examples/cpp/comm-testany/s4u-comm-testany.cpp -include examples/cpp/comm-testany/s4u-comm-testany.tesh include examples/cpp/comm-throttling/s4u-comm-throttling.cpp include examples/cpp/comm-throttling/s4u-comm-throttling.tesh include examples/cpp/comm-wait/s4u-comm-wait.cpp include examples/cpp/comm-wait/s4u-comm-wait.tesh -include examples/cpp/comm-waitall/s4u-comm-waitall.cpp -include examples/cpp/comm-waitall/s4u-comm-waitall.tesh -include examples/cpp/comm-waitany/s4u-comm-waitany.cpp -include examples/cpp/comm-waitany/s4u-comm-waitany.tesh include examples/cpp/comm-waituntil/s4u-comm-waituntil.cpp include examples/cpp/comm-waituntil/s4u-comm-waituntil.tesh include examples/cpp/dag-comm/s4u-dag-comm.cpp include examples/cpp/dag-comm/s4u-dag-comm.tesh include examples/cpp/dag-failure/s4u-dag-failure.cpp include examples/cpp/dag-failure/s4u-dag-failure.tesh +include examples/cpp/dag-from-dax-simple/dag.xml +include examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple.cpp +include examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple.tesh include examples/cpp/dag-from-dax/s4u-dag-from-dax.cpp include examples/cpp/dag-from-dax/s4u-dag-from-dax.tesh include examples/cpp/dag-from-dax/simple_dax_with_cycle.xml include examples/cpp/dag-from-dax/smalldax.xml +include examples/cpp/dag-from-dot-simple/dag.dot +include examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.cpp +include examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.tesh include examples/cpp/dag-from-dot/dag.dot include examples/cpp/dag-from-dot/dag_with_cycle.dot include examples/cpp/dag-from-dot/s4u-dag-from-dot.cpp include examples/cpp/dag-from-dot/s4u-dag-from-dot.tesh +include examples/cpp/dag-from-json-simple/dag.json +include examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.cpp +include examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.tesh include examples/cpp/dag-io/s4u-dag-io.cpp include examples/cpp/dag-io/s4u-dag-io.tesh include examples/cpp/dag-scheduling/Montage_25.xml @@ -220,6 +234,8 @@ include examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp include examples/cpp/dag-scheduling/s4u-dag-scheduling.tesh include examples/cpp/dag-simple/s4u-dag-simple.cpp include examples/cpp/dag-simple/s4u-dag-simple.tesh +include examples/cpp/dag-tuto/s4u-dag-tuto.cpp +include examples/cpp/dag-tuto/s4u-dag-tuto.tesh include examples/cpp/dht-chord/s4u-dht-chord-node.cpp include examples/cpp/dht-chord/s4u-dht-chord.cpp include examples/cpp/dht-chord/s4u-dht-chord.hpp @@ -279,8 +295,6 @@ include examples/cpp/exec-threads/s4u-exec-threads.cpp include examples/cpp/exec-threads/s4u-exec-threads.tesh include examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp include examples/cpp/exec-unassigned/s4u-exec-unassigned.tesh -include examples/cpp/exec-waitany/s4u-exec-waitany.cpp -include examples/cpp/exec-waitany/s4u-exec-waitany.tesh include examples/cpp/exec-waitfor/s4u-exec-waitfor.cpp include examples/cpp/exec-waitfor/s4u-exec-waitfor.tesh include examples/cpp/io-async/s4u-io-async.cpp @@ -300,24 +314,19 @@ include examples/cpp/io-priority/s4u-io-priority.cpp include examples/cpp/io-priority/s4u-io-priority.tesh include examples/cpp/maestro-set/s4u-maestro-set.cpp include examples/cpp/maestro-set/s4u-maestro-set.tesh -include examples/cpp/mc-bugged1-liveness/promela_bugged1_liveness -include examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner -include examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh -include examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp -include examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh include examples/cpp/mc-bugged1/s4u-mc-bugged1.cpp include examples/cpp/mc-bugged1/s4u-mc-bugged1.tesh -include examples/cpp/mc-bugged2-liveness/promela_bugged2_liveness -include examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.cpp -include examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.tesh include examples/cpp/mc-bugged2/s4u-mc-bugged2.cpp include examples/cpp/mc-bugged2/s4u-mc-bugged2.tesh include examples/cpp/mc-centralized-mutex/s4u-mc-centralized-mutex.cpp include examples/cpp/mc-centralized-mutex/s4u-mc-centralized-mutex.tesh include examples/cpp/mc-electric-fence/s4u-mc-electric-fence.cpp include examples/cpp/mc-electric-fence/s4u-mc-electric-fence.tesh +include examples/cpp/mc-failing-assert/s4u-mc-failing-assert-nodpor.tesh include examples/cpp/mc-failing-assert/s4u-mc-failing-assert.cpp include examples/cpp/mc-failing-assert/s4u-mc-failing-assert.tesh +include examples/cpp/mess-wait/s4u-mess-wait.cpp +include examples/cpp/mess-wait/s4u-mess-wait.tesh include examples/cpp/network-factors/s4u-network-factors.cpp include examples/cpp/network-factors/s4u-network-factors.tesh include examples/cpp/network-nonlinear/s4u-network-nonlinear.cpp @@ -331,10 +340,13 @@ include examples/cpp/network-ns3/crosstraffic_d.xml include examples/cpp/network-ns3/dogbone_d.xml include examples/cpp/network-ns3/one_cluster_d.xml include examples/cpp/network-ns3/onelink_d.xml +include examples/cpp/network-ns3/s4u-network-ns3-notime.tesh +include examples/cpp/network-ns3/s4u-network-ns3-timed.tesh include examples/cpp/network-ns3/s4u-network-ns3.cpp -include examples/cpp/network-ns3/s4u-network-ns3.tesh include examples/cpp/network-wifi/s4u-network-wifi.cpp include examples/cpp/network-wifi/s4u-network-wifi.tesh +include examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.cpp +include examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.tesh include examples/cpp/platform-failures/s4u-platform-failures.cpp include examples/cpp/platform-failures/s4u-platform-failures.tesh include examples/cpp/platform-failures/s4u-platform-failures_d.xml @@ -344,6 +356,8 @@ include examples/cpp/platform-properties/s4u-platform-properties.cpp include examples/cpp/platform-properties/s4u-platform-properties.tesh include examples/cpp/plugin-host-load/s4u-plugin-host-load.cpp include examples/cpp/plugin-host-load/s4u-plugin-host-load.tesh +include examples/cpp/plugin-jbod/s4u-plugin-jbod.cpp +include examples/cpp/plugin-jbod/s4u-plugin-jbod.tesh include examples/cpp/plugin-link-load/s4u-plugin-link-load.cpp include examples/cpp/plugin-link-load/s4u-plugin-link-load.tesh include examples/cpp/plugin-prodcons/s4u-plugin-prodcons.cpp @@ -361,6 +375,8 @@ include examples/cpp/replay-io/s4u-replay-io.txt include examples/cpp/replay-io/s4u-replay-io_d.xml include examples/cpp/routing-get-clusters/s4u-routing-get-clusters.cpp include examples/cpp/routing-get-clusters/s4u-routing-get-clusters.tesh +include examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp +include examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh include examples/cpp/synchro-barrier/s4u-mc-synchro-barrier.tesh include examples/cpp/synchro-barrier/s4u-synchro-barrier.cpp include examples/cpp/synchro-barrier/s4u-synchro-barrier.tesh @@ -374,6 +390,22 @@ include examples/cpp/synchro-mutex/s4u-synchro-mutex.tesh include examples/cpp/synchro-semaphore/s4u-mc-synchro-semaphore.tesh include examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp include examples/cpp/synchro-semaphore/s4u-synchro-semaphore.tesh +include examples/cpp/task-dispatch/s4u-task-dispatch.cpp +include examples/cpp/task-dispatch/s4u-task-dispatch.tesh +include examples/cpp/task-io/s4u-task-io.cpp +include examples/cpp/task-io/s4u-task-io.tesh +include examples/cpp/task-microservice/s4u-task-microservice.cpp +include examples/cpp/task-microservice/s4u-task-microservice.tesh +include examples/cpp/task-parallelism/s4u-task-parallelism.cpp +include examples/cpp/task-parallelism/s4u-task-parallelism.tesh +include examples/cpp/task-simple/s4u-task-simple.cpp +include examples/cpp/task-simple/s4u-task-simple.tesh +include examples/cpp/task-storm/s4u-task-storm.cpp +include examples/cpp/task-storm/s4u-task-storm.tesh +include examples/cpp/task-switch-host/s4u-task-switch-host.cpp +include examples/cpp/task-switch-host/s4u-task-switch-host.tesh +include examples/cpp/task-variable-load/s4u-task-variable-load.cpp +include examples/cpp/task-variable-load/s4u-task-variable-load.tesh include examples/cpp/trace-categories/s4u-trace-categories.cpp include examples/cpp/trace-categories/s4u-trace-categories.tesh include examples/cpp/trace-host-user-variables/s4u-trace-host-user-variables.cpp @@ -388,119 +420,14 @@ include examples/cpp/trace-process-migration/s4u-trace-process-migration.cpp include examples/cpp/trace-process-migration/s4u-trace-process-migration.tesh include examples/cpp/trace-route-user-variables/s4u-trace-route-user-variables.cpp include examples/cpp/trace-route-user-variables/s4u-trace-route-user-variables.tesh -include examples/deprecated/java/app/bittorrent/Common.java -include examples/deprecated/java/app/bittorrent/Connection.java -include examples/deprecated/java/app/bittorrent/Main.java -include examples/deprecated/java/app/bittorrent/MessageTask.java -include examples/deprecated/java/app/bittorrent/Peer.java -include examples/deprecated/java/app/bittorrent/Tracker.java -include examples/deprecated/java/app/bittorrent/TrackerTask.java -include examples/deprecated/java/app/bittorrent/app-bittorrent.tesh -include examples/deprecated/java/app/bittorrent/bittorrent.xml -include examples/deprecated/java/app/bittorrent/generate.py -include examples/deprecated/java/app/centralizedmutex/Coordinator.java -include examples/deprecated/java/app/centralizedmutex/GrantTask.java -include examples/deprecated/java/app/centralizedmutex/Main.java -include examples/deprecated/java/app/centralizedmutex/Node.java -include examples/deprecated/java/app/centralizedmutex/ReleaseTask.java -include examples/deprecated/java/app/centralizedmutex/RequestTask.java -include examples/deprecated/java/app/centralizedmutex/app-centralizedmutex.tesh -include examples/deprecated/java/app/centralizedmutex/centralizedmutex.xml -include examples/deprecated/java/app/masterworker/Main.java -include examples/deprecated/java/app/masterworker/Master.java -include examples/deprecated/java/app/masterworker/README -include examples/deprecated/java/app/masterworker/Worker.java -include examples/deprecated/java/app/masterworker/app-masterworker.tesh -include examples/deprecated/java/app/masterworker/masterworker.xml -include examples/deprecated/java/app/pingpong/Main.java -include examples/deprecated/java/app/pingpong/PingPongTask.java -include examples/deprecated/java/app/pingpong/Receiver.java -include examples/deprecated/java/app/pingpong/Sender.java -include examples/deprecated/java/app/pingpong/app-pingpong.tesh -include examples/deprecated/java/app/tokenring/Main.java -include examples/deprecated/java/app/tokenring/RelayRunner.java -include examples/deprecated/java/app/tokenring/app-tokenring.tesh -include examples/deprecated/java/async/dsend/Main.java -include examples/deprecated/java/async/dsend/Receiver.java -include examples/deprecated/java/async/dsend/Sender.java -include examples/deprecated/java/async/dsend/async-dsend.tesh -include examples/deprecated/java/async/waitall/Main.java -include examples/deprecated/java/async/waitall/Receiver.java -include examples/deprecated/java/async/waitall/Sender.java -include examples/deprecated/java/async/waitall/async-waitall.tesh -include examples/deprecated/java/async/yield/Main.java -include examples/deprecated/java/async/yield/Yielder.java -include examples/deprecated/java/async/yield/async-yield.tesh -include examples/deprecated/java/cloud/masterworker/Main.java -include examples/deprecated/java/cloud/masterworker/Master.java -include examples/deprecated/java/cloud/masterworker/Worker.java -include examples/deprecated/java/cloud/masterworker/cloud-masterworker.tesh -include examples/deprecated/java/cloud/migration/Daemon.java -include examples/deprecated/java/cloud/migration/Main.java -include examples/deprecated/java/cloud/migration/README -include examples/deprecated/java/cloud/migration/Test.java -include examples/deprecated/java/cloud/migration/XVM.java -include examples/deprecated/java/cloud/migration/cloud-migration.tesh -include examples/deprecated/java/dht/chord/ChordTask.java -include examples/deprecated/java/dht/chord/Common.java -include examples/deprecated/java/dht/chord/FindSuccessorAnswerTask.java -include examples/deprecated/java/dht/chord/FindSuccessorTask.java -include examples/deprecated/java/dht/chord/GetPredecessorAnswerTask.java -include examples/deprecated/java/dht/chord/GetPredecessorTask.java -include examples/deprecated/java/dht/chord/Main.java -include examples/deprecated/java/dht/chord/Node.java -include examples/deprecated/java/dht/chord/NotifyTask.java -include examples/deprecated/java/dht/chord/chord.xml -include examples/deprecated/java/dht/chord/dht-chord.tesh -include examples/deprecated/java/dht/kademlia/Answer.java -include examples/deprecated/java/dht/kademlia/Bucket.java -include examples/deprecated/java/dht/kademlia/Common.java -include examples/deprecated/java/dht/kademlia/Contact.java -include examples/deprecated/java/dht/kademlia/FindNodeAnswerTask.java -include examples/deprecated/java/dht/kademlia/FindNodeTask.java -include examples/deprecated/java/dht/kademlia/KademliaTask.java -include examples/deprecated/java/dht/kademlia/Main.java -include examples/deprecated/java/dht/kademlia/Node.java -include examples/deprecated/java/dht/kademlia/RoutingTable.java -include examples/deprecated/java/dht/kademlia/dht-kademlia.tesh -include examples/deprecated/java/dht/kademlia/kademlia.xml -include examples/deprecated/java/energy/consumption/EnergyConsumer.java -include examples/deprecated/java/energy/consumption/Main.java -include examples/deprecated/java/energy/consumption/energy-consumption.tesh -include examples/deprecated/java/energy/pstate/Main.java -include examples/deprecated/java/energy/pstate/PstateRunner.java -include examples/deprecated/java/energy/pstate/energy-pstate.tesh -include examples/deprecated/java/energy/vm/EnergyVMRunner.java -include examples/deprecated/java/energy/vm/Main.java -include examples/deprecated/java/energy/vm/energy-vm.tesh -include examples/deprecated/java/hostload/LoadRunner.java -include examples/deprecated/java/hostload/Main.java -include examples/deprecated/java/hostload/hostload.tesh -include examples/deprecated/java/process/kill/Killer.java -include examples/deprecated/java/process/kill/Main.java -include examples/deprecated/java/process/kill/Victim.java -include examples/deprecated/java/process/kill/process-kill.tesh -include examples/deprecated/java/process/migration/Emigrant.java -include examples/deprecated/java/process/migration/Main.java -include examples/deprecated/java/process/migration/Policeman.java -include examples/deprecated/java/process/migration/process-migration.tesh -include examples/deprecated/java/process/startkilltime/Main.java -include examples/deprecated/java/process/startkilltime/Sleeper.java -include examples/deprecated/java/process/startkilltime/process-startkilltime.tesh -include examples/deprecated/java/process/startkilltime/startkilltime.xml -include examples/deprecated/java/process/suspend/DreamMaster.java -include examples/deprecated/java/process/suspend/LazyGuy.java -include examples/deprecated/java/process/suspend/Main.java -include examples/deprecated/java/process/suspend/process-suspend.tesh -include examples/deprecated/java/task/priority/Main.java -include examples/deprecated/java/task/priority/Test.java -include examples/deprecated/java/task/priority/priority.xml -include examples/deprecated/java/task/priority/task-priority.tesh -include examples/deprecated/java/trace/pingpong/Main.java -include examples/deprecated/java/trace/pingpong/PingPongTask.java -include examples/deprecated/java/trace/pingpong/Receiver.java -include examples/deprecated/java/trace/pingpong/Sender.java -include examples/deprecated/java/trace/pingpong/trace-pingpong.tesh +include examples/python/activityset-testany/activityset-testany.py +include examples/python/activityset-testany/activityset-testany.tesh +include examples/python/activityset-waitall/activityset-waitall.py +include examples/python/activityset-waitall/activityset-waitall.tesh +include examples/python/activityset-waitallfor/activityset-waitallfor.py +include examples/python/activityset-waitallfor/activityset-waitallfor.tesh +include examples/python/activityset-waitany/activityset-waitany.py +include examples/python/activityset-waitany/activityset-waitany.tesh include examples/python/actor-create/actor-create.py include examples/python/actor-create/actor-create.tesh include examples/python/actor-daemon/actor-daemon.py @@ -529,52 +456,52 @@ include examples/python/comm-pingpong/comm-pingpong.py include examples/python/comm-pingpong/comm-pingpong.tesh include examples/python/comm-ready/comm-ready.py include examples/python/comm-ready/comm-ready.tesh -include examples/python/comm-serialize/comm-serialize.py -include examples/python/comm-serialize/comm-serialize.tesh include examples/python/comm-suspend/comm-suspend.py include examples/python/comm-suspend/comm-suspend.tesh -include examples/python/comm-testany/comm-testany.py -include examples/python/comm-testany/comm-testany.tesh include examples/python/comm-throttling/comm-throttling.py include examples/python/comm-throttling/comm-throttling.tesh include examples/python/comm-wait/comm-wait.py include examples/python/comm-wait/comm-wait.tesh -include examples/python/comm-waitall/comm-waitall.py -include examples/python/comm-waitall/comm-waitall.tesh -include examples/python/comm-waitallfor/comm-waitallfor.py -include examples/python/comm-waitallfor/comm-waitallfor.tesh -include examples/python/comm-waitany/comm-waitany.py -include examples/python/comm-waitany/comm-waitany.tesh -include examples/python/comm-waitfor/comm-waitfor.py -include examples/python/comm-waitfor/comm-waitfor.tesh include examples/python/comm-waituntil/comm-waituntil.py include examples/python/comm-waituntil/comm-waituntil.tesh include examples/python/exec-async/exec-async.py include examples/python/exec-async/exec-async.tesh include examples/python/exec-basic/exec-basic.py include examples/python/exec-basic/exec-basic.tesh -include examples/python/exec-basic/exec-ptask.py -include examples/python/exec-basic/exec-ptask.tesh include examples/python/exec-cpu-nonlinear/exec-cpu-nonlinear.py include examples/python/exec-cpu-nonlinear/exec-cpu-nonlinear.tesh include examples/python/exec-dvfs/exec-dvfs.py include examples/python/exec-dvfs/exec-dvfs.tesh +include examples/python/exec-ptask/exec-ptask.py +include examples/python/exec-ptask/exec-ptask.tesh include examples/python/exec-remote/exec-remote.py include examples/python/exec-remote/exec-remote.tesh include examples/python/io-degradation/io-degradation.py include examples/python/io-degradation/io-degradation.tesh include examples/python/network-nonlinear/network-nonlinear.py include examples/python/network-nonlinear/network-nonlinear.tesh +include examples/python/platform-comm-serialize/platform-comm-serialize.py +include examples/python/platform-comm-serialize/platform-comm-serialize.tesh include examples/python/platform-failures/platform-failures.py include examples/python/platform-failures/platform-failures.tesh include examples/python/platform-profile/platform-profile.py include examples/python/platform-profile/platform-profile.tesh +include examples/python/plugin-host-load/plugin-host-load.py +include examples/python/plugin-host-load/plugin-host-load.tesh include examples/python/synchro-barrier/synchro-barrier.py include examples/python/synchro-barrier/synchro-barrier.tesh include examples/python/synchro-mutex/synchro-mutex.py include examples/python/synchro-mutex/synchro-mutex.tesh include examples/python/synchro-semaphore/synchro-semaphore.py include examples/python/synchro-semaphore/synchro-semaphore.tesh +include examples/python/task-io/task-io.py +include examples/python/task-io/task-io.tesh +include examples/python/task-simple/task-simple.py +include examples/python/task-simple/task-simple.tesh +include examples/python/task-switch-host/task-switch-host.py +include examples/python/task-switch-host/task-switch-host.tesh +include examples/python/task-variable-load/task-variable-load.py +include examples/python/task-variable-load/task-variable-load.tesh include examples/smpi/NAS/DGraph.c include examples/smpi/NAS/DGraph.h include examples/smpi/NAS/README.install @@ -595,22 +522,14 @@ include examples/smpi/gemm/gemm.c include examples/smpi/gemm/gemm.tesh include examples/smpi/hostfile include examples/smpi/mc/bugged1.c -include examples/smpi/mc/bugged1_liveness.c include examples/smpi/mc/bugged2.c include examples/smpi/mc/hostfile_bugged1 -include examples/smpi/mc/hostfile_bugged1_liveness include examples/smpi/mc/hostfile_bugged2 include examples/smpi/mc/hostfile_mutual_exclusion -include examples/smpi/mc/hostfile_non_termination include examples/smpi/mc/hostfile_only_send_deterministic include examples/smpi/mc/mutual_exclusion.c -include examples/smpi/mc/non_termination1.c -include examples/smpi/mc/non_termination2.c -include examples/smpi/mc/non_termination3.c -include examples/smpi/mc/non_termination4.c include examples/smpi/mc/only_send_deterministic.c include examples/smpi/mc/only_send_deterministic.tesh -include examples/smpi/mc/promela_bugged1_liveness include examples/smpi/mc/sendsend.c include examples/smpi/mc/sendsend.tesh include examples/smpi/replay/actions0.txt @@ -712,13 +631,22 @@ include examples/smpi/trace_call_location/trace_call_location.c include examples/smpi/trace_call_location/trace_call_location.tesh include examples/smpi/trace_simple/trace_simple.c include examples/smpi/trace_simple/trace_simple.tesh +include examples/sthread/pthread-mc-mutex-recursive.tesh +include examples/sthread/pthread-mc-mutex-simple.tesh +include examples/sthread/pthread-mc-mutex-simpledeadlock.tesh +include examples/sthread/pthread-mc-producer-consumer.tesh +include examples/sthread/pthread-mutex-recursive.c +include examples/sthread/pthread-mutex-recursive.tesh include examples/sthread/pthread-mutex-simple.c +include examples/sthread/pthread-mutex-simple.tesh +include examples/sthread/pthread-mutex-simpledeadlock.c +include examples/sthread/pthread-producer-consumer.c +include examples/sthread/pthread-producer-consumer.tesh +include examples/sthread/stdobject/stdobject.cpp +include examples/sthread/stdobject/stdobject.tesh include examples/sthread/sthread-mutex-simple.c -include src/include/catch_simgrid.hpp -include teshsuite/java/semaphoregc/SemaphoreGC.java -include teshsuite/java/semaphoregc/semaphoregc.tesh -include teshsuite/java/sleephostoff/SleepHostOff.java -include teshsuite/java/sleephostoff/sleephostoff.tesh +include examples/sthread/sthread-mutex-simple.tesh +include teshsuite/catch_simgrid.hpp include teshsuite/kernel/context-defaults/context-defaults.cpp include teshsuite/kernel/context-defaults/factory_boost.tesh include teshsuite/kernel/context-defaults/factory_raw.tesh @@ -726,14 +654,53 @@ include teshsuite/kernel/context-defaults/factory_thread.tesh include teshsuite/kernel/context-defaults/factory_ucontext.tesh include teshsuite/kernel/stack-overflow/stack-overflow.cpp include teshsuite/kernel/stack-overflow/stack-overflow.tesh -include teshsuite/mc/dwarf-expression/dwarf-expression.cpp -include teshsuite/mc/dwarf-expression/dwarf-expression.tesh -include teshsuite/mc/dwarf/dwarf.cpp -include teshsuite/mc/dwarf/dwarf.tesh +include teshsuite/mc/mcmini/barber_shop_deadlock.c +include teshsuite/mc/mcmini/barber_shop_deadlock.tesh +include teshsuite/mc/mcmini/barber_shop_ok.c +include teshsuite/mc/mcmini/barber_shop_ok.tesh +include teshsuite/mc/mcmini/philosophers_mutex_deadlock.c +include teshsuite/mc/mcmini/philosophers_mutex_deadlock.tesh +include teshsuite/mc/mcmini/philosophers_mutex_ok.c +include teshsuite/mc/mcmini/philosophers_mutex_ok.tesh +include teshsuite/mc/mcmini/philosophers_semaphores_deadlock.c +include teshsuite/mc/mcmini/philosophers_semaphores_deadlock.tesh +include teshsuite/mc/mcmini/philosophers_semaphores_ok.c +include teshsuite/mc/mcmini/philosophers_semaphores_ok.tesh +include teshsuite/mc/mcmini/producer_consumer_deadlock.c +include teshsuite/mc/mcmini/producer_consumer_deadlock.tesh +include teshsuite/mc/mcmini/producer_consumer_ok.c +include teshsuite/mc/mcmini/producer_consumer_ok.tesh +include teshsuite/mc/mcmini/simple_barrier_deadlock.c +include teshsuite/mc/mcmini/simple_barrier_deadlock.tesh +include teshsuite/mc/mcmini/simple_barrier_ok.c +include teshsuite/mc/mcmini/simple_barrier_ok.tesh +include teshsuite/mc/mcmini/simple_barrier_with_threads_deadlock.c +include teshsuite/mc/mcmini/simple_barrier_with_threads_deadlock.tesh +include teshsuite/mc/mcmini/simple_barrier_with_threads_ok.c +include teshsuite/mc/mcmini/simple_barrier_with_threads_ok.tesh +include teshsuite/mc/mcmini/simple_mutex_deadlock.c +include teshsuite/mc/mcmini/simple_mutex_deadlock.tesh +include teshsuite/mc/mcmini/simple_mutex_ok.c +include teshsuite/mc/mcmini/simple_mutex_ok.tesh +include teshsuite/mc/mcmini/simple_mutex_with_threads_deadlock.c +include teshsuite/mc/mcmini/simple_mutex_with_threads_deadlock.tesh +include teshsuite/mc/mcmini/simple_mutex_with_threads_ok.c +include teshsuite/mc/mcmini/simple_mutex_with_threads_ok.tesh +include teshsuite/mc/mcmini/simple_semaphore_deadlock.c +include teshsuite/mc/mcmini/simple_semaphore_deadlock.tesh +include teshsuite/mc/mcmini/simple_semaphores_deadlock.c +include teshsuite/mc/mcmini/simple_semaphores_deadlock.tesh +include teshsuite/mc/mcmini/simple_semaphores_ok.c +include teshsuite/mc/mcmini/simple_semaphores_ok.tesh +include teshsuite/mc/mcmini/simple_semaphores_with_threads_deadlock.c +include teshsuite/mc/mcmini/simple_semaphores_with_threads_deadlock.tesh +include teshsuite/mc/mcmini/simple_semaphores_with_threads_ok.c +include teshsuite/mc/mcmini/simple_semaphores_with_threads_ok.tesh +include teshsuite/mc/mcmini/simple_threads_ok.c +include teshsuite/mc/mcmini/simple_threads_ok.tesh include teshsuite/mc/mutex-handling/mutex-handling.cpp include teshsuite/mc/mutex-handling/mutex-handling.tesh include teshsuite/mc/mutex-handling/without-mutex-handling.tesh -include teshsuite/mc/random-bug/random-bug-nocrash.tesh include teshsuite/mc/random-bug/random-bug-replay.tesh include teshsuite/mc/random-bug/random-bug.cpp include teshsuite/mc/random-bug/random-bug.tesh @@ -742,8 +709,20 @@ include teshsuite/models/cloud-sharing/cloud-sharing.tesh include teshsuite/models/cm02-set-lat-bw/cm02-set-lat-bw-bmf.tesh include teshsuite/models/cm02-set-lat-bw/cm02-set-lat-bw.cpp include teshsuite/models/cm02-set-lat-bw/cm02-set-lat-bw.tesh +include teshsuite/models/cm02-tcpgamma/cm02-tcpgamma.cpp +include teshsuite/models/cm02-tcpgamma/cm02-tcpgamma.tesh +include teshsuite/models/core_usage/core_usage.cpp +include teshsuite/models/core_usage/core_usage.tesh +include teshsuite/models/core_usage2/core_usage2.cpp +include teshsuite/models/core_usage2/core_usage2.tesh include teshsuite/models/issue105/issue105.cpp include teshsuite/models/issue105/issue105.tesh +include teshsuite/models/lmm_usage/lmm_usage.cpp +include teshsuite/models/lmm_usage/lmm_usage.tesh +include teshsuite/models/maxmin_bench/maxmin_bench.cpp +include teshsuite/models/maxmin_bench/maxmin_bench_large.tesh +include teshsuite/models/maxmin_bench/maxmin_bench_medium.tesh +include teshsuite/models/maxmin_bench/maxmin_bench_small.tesh include teshsuite/models/ptask-subflows/ptask-subflows.cpp include teshsuite/models/ptask-subflows/ptask-subflows.tesh include teshsuite/models/ptask_L07_usage/ptask_L07_usage.cpp @@ -752,8 +731,6 @@ include teshsuite/models/wifi_usage/wifi_usage.cpp include teshsuite/models/wifi_usage/wifi_usage.tesh include teshsuite/models/wifi_usage_decay/wifi_usage_decay.cpp include teshsuite/models/wifi_usage_decay/wifi_usage_decay.tesh -include teshsuite/msg/task_destroy_cancel/task_destroy_cancel.c -include teshsuite/msg/task_destroy_cancel/task_destroy_cancel.tesh include teshsuite/platforms/Dijkstra.xml include teshsuite/platforms/bob.trace include teshsuite/platforms/bogus_missing_dst_gateway.xml @@ -844,6 +821,8 @@ include teshsuite/s4u/host-on-off/host-on-off.cpp include teshsuite/s4u/host-on-off/host-on-off.tesh include teshsuite/s4u/io-set-bw/io-set-bw.cpp include teshsuite/s4u/io-set-bw/io-set-bw.tesh +include teshsuite/s4u/io-stream/io-stream.cpp +include teshsuite/s4u/io-stream/io-stream.tesh include teshsuite/s4u/is-router/is-router.cpp include teshsuite/s4u/is-router/is-router.tesh include teshsuite/s4u/issue71/issue71.cpp @@ -886,10 +865,6 @@ include teshsuite/s4u/vm-live-migration/vm-live-migration.cpp include teshsuite/s4u/vm-live-migration/vm-live-migration.tesh include teshsuite/s4u/vm-suicide/vm-suicide.cpp include teshsuite/s4u/vm-suicide/vm-suicide.tesh -include teshsuite/s4u/wait-all-for/wait-all-for.cpp -include teshsuite/s4u/wait-all-for/wait-all-for.tesh -include teshsuite/s4u/wait-any-for/wait-any-for.cpp -include teshsuite/s4u/wait-any-for/wait-any-for.tesh include teshsuite/smpi/MBI/CollArgGenerator.py include teshsuite/smpi/MBI/CollComGenerator.py include teshsuite/smpi/MBI/CollLocalConcurrencyGenerator.py @@ -897,20 +872,26 @@ include teshsuite/smpi/MBI/CollMatchingGenerator.py include teshsuite/smpi/MBI/CollP2PMatchingGenerator.py include teshsuite/smpi/MBI/CollP2PMessageRaceGenerator.py include teshsuite/smpi/MBI/CollTopoGenerator.py +include teshsuite/smpi/MBI/InputHazardGenerator.py include teshsuite/smpi/MBI/MBI.py include teshsuite/smpi/MBI/MBIutils.py include teshsuite/smpi/MBI/MissingWaitandStartGenerator.py include teshsuite/smpi/MBI/P2PArgGenerator.py +include teshsuite/smpi/MBI/P2PBufferingGenerator.py include teshsuite/smpi/MBI/P2PComGenerator.py include teshsuite/smpi/MBI/P2PInvalidComGenerator.py include teshsuite/smpi/MBI/P2PLocalConcurrencyGenerator.py include teshsuite/smpi/MBI/P2PMatchingANYSRCGenerator.py include teshsuite/smpi/MBI/P2PMatchingGenerator.py +include teshsuite/smpi/MBI/P2PMessageRaceGenerator.py +include teshsuite/smpi/MBI/P2PMessageRaceTagsGenerator.py include teshsuite/smpi/MBI/P2PProbeGenerator.py +include teshsuite/smpi/MBI/P2PSendrecvArgGenerator.py include teshsuite/smpi/MBI/RMAArgGenerator.py include teshsuite/smpi/MBI/RMAInvalidArgGenerator.py include teshsuite/smpi/MBI/RMALocalLocalConcurrencyGenerator.py include teshsuite/smpi/MBI/RMAP2PGlobalConcurrencyGenerator.py +include teshsuite/smpi/MBI/RMAP2PLocalConcurrencyGenerator.py include teshsuite/smpi/MBI/RMARemoteLocalConcurrencyGenerator.py include teshsuite/smpi/MBI/RMARemoteRemoteConcurrencyGenerator.py include teshsuite/smpi/MBI/RMAReqLifecycleGenerator.py @@ -937,7 +918,6 @@ include teshsuite/smpi/coll-allreduce/coll-allreduce.tesh include teshsuite/smpi/coll-alltoall/clusters.tesh include teshsuite/smpi/coll-alltoall/coll-alltoall.c include teshsuite/smpi/coll-alltoall/coll-alltoall.tesh -include teshsuite/smpi/coll-alltoall/griffon.tesh include teshsuite/smpi/coll-alltoallv/coll-alltoallv.c include teshsuite/smpi/coll-alltoallv/coll-alltoallv.tesh include teshsuite/smpi/coll-barrier/coll-barrier.c @@ -985,6 +965,7 @@ include teshsuite/smpi/macro-shared/macro-shared.c include teshsuite/smpi/macro-shared/macro-shared.tesh include teshsuite/smpi/mpich3-test/README include teshsuite/smpi/mpich3-test/attr/attr2type.c +include teshsuite/smpi/mpich3-test/attr/attrdelete.c include teshsuite/smpi/mpich3-test/attr/attrdeleteget.c include teshsuite/smpi/mpich3-test/attr/attrend.c include teshsuite/smpi/mpich3-test/attr/attrend2.c @@ -1019,6 +1000,8 @@ include teshsuite/smpi/mpich3-test/coll/allred3.c include teshsuite/smpi/mpich3-test/coll/allred4.c include teshsuite/smpi/mpich3-test/coll/allred5.c include teshsuite/smpi/mpich3-test/coll/allred6.c +include teshsuite/smpi/mpich3-test/coll/allred_derived.c +include teshsuite/smpi/mpich3-test/coll/allred_float.c include teshsuite/smpi/mpich3-test/coll/allredmany.c include teshsuite/smpi/mpich3-test/coll/alltoall1.c include teshsuite/smpi/mpich3-test/coll/alltoallv.c @@ -1046,6 +1029,7 @@ include teshsuite/smpi/mpich3-test/coll/exscan2.c include teshsuite/smpi/mpich3-test/coll/gather.c include teshsuite/smpi/mpich3-test/coll/gather2.c include teshsuite/smpi/mpich3-test/coll/gather_big.c +include teshsuite/smpi/mpich3-test/coll/gatherv.c include teshsuite/smpi/mpich3-test/coll/iallred.c include teshsuite/smpi/mpich3-test/coll/ibarrier.c include teshsuite/smpi/mpich3-test/coll/icallgather.c @@ -1098,6 +1082,7 @@ include teshsuite/smpi/mpich3-test/coll/scatterv.c include teshsuite/smpi/mpich3-test/coll/testlist include teshsuite/smpi/mpich3-test/coll/uoplong.c include teshsuite/smpi/mpich3-test/comm/cmfree.c +include teshsuite/smpi/mpich3-test/comm/cmfree2.c include teshsuite/smpi/mpich3-test/comm/cmsplit.c include teshsuite/smpi/mpich3-test/comm/cmsplit2.c include teshsuite/smpi/mpich3-test/comm/cmsplit_type.c @@ -1114,6 +1099,7 @@ include teshsuite/smpi/mpich3-test/comm/comm_idup_mul.c include teshsuite/smpi/mpich3-test/comm/comm_idup_nb.c include teshsuite/smpi/mpich3-test/comm/comm_idup_overlap.c include teshsuite/smpi/mpich3-test/comm/comm_info.c +include teshsuite/smpi/mpich3-test/comm/comm_info2.c include teshsuite/smpi/mpich3-test/comm/commcreate1.c include teshsuite/smpi/mpich3-test/comm/commname.c include teshsuite/smpi/mpich3-test/comm/ctxalloc.c @@ -1365,7 +1351,6 @@ include teshsuite/smpi/mpich3-test/include/mpicolltest.h include teshsuite/smpi/mpich3-test/include/mpitest.h include teshsuite/smpi/mpich3-test/include/mpitestconf.h include teshsuite/smpi/mpich3-test/include/mpitestcxx.h -include teshsuite/smpi/mpich3-test/include/mpithreadtest.h include teshsuite/smpi/mpich3-test/include/mtest_datatype.h include teshsuite/smpi/mpich3-test/info/infodel.c include teshsuite/smpi/mpich3-test/info/infodup.c @@ -1446,21 +1431,28 @@ include teshsuite/smpi/mpich3-test/pt2pt/dtype_send.c include teshsuite/smpi/mpich3-test/pt2pt/eagerdt.c include teshsuite/smpi/mpich3-test/pt2pt/greq1.c include teshsuite/smpi/mpich3-test/pt2pt/huge_anysrc.c +include teshsuite/smpi/mpich3-test/pt2pt/huge_dupcomm.c +include teshsuite/smpi/mpich3-test/pt2pt/huge_ssend.c include teshsuite/smpi/mpich3-test/pt2pt/huge_underflow.c include teshsuite/smpi/mpich3-test/pt2pt/icsend.c include teshsuite/smpi/mpich3-test/pt2pt/inactivereq.c include teshsuite/smpi/mpich3-test/pt2pt/isendirecv.c +include teshsuite/smpi/mpich3-test/pt2pt/isendrecv.c +include teshsuite/smpi/mpich3-test/pt2pt/isendrecv_replace.c include teshsuite/smpi/mpich3-test/pt2pt/isendself.c include teshsuite/smpi/mpich3-test/pt2pt/isendselfprobe.c include teshsuite/smpi/mpich3-test/pt2pt/issendselfcancel.c include teshsuite/smpi/mpich3-test/pt2pt/large_message.c +include teshsuite/smpi/mpich3-test/pt2pt/large_tag.c include teshsuite/smpi/mpich3-test/pt2pt/many_isend.c include teshsuite/smpi/mpich3-test/pt2pt/manylmt.c include teshsuite/smpi/mpich3-test/pt2pt/mprobe.c +include teshsuite/smpi/mpich3-test/pt2pt/multi_psend_derived.c include teshsuite/smpi/mpich3-test/pt2pt/pingping.c include teshsuite/smpi/mpich3-test/pt2pt/probe-unexp.c include teshsuite/smpi/mpich3-test/pt2pt/probenull.c include teshsuite/smpi/mpich3-test/pt2pt/pscancel.c +include teshsuite/smpi/mpich3-test/pt2pt/pssend.c include teshsuite/smpi/mpich3-test/pt2pt/rcancel.c include teshsuite/smpi/mpich3-test/pt2pt/recv_any.c include teshsuite/smpi/mpich3-test/pt2pt/rqfreeb.c @@ -1655,16 +1647,6 @@ include teshsuite/smpi/type-struct/type-struct.c include teshsuite/smpi/type-struct/type-struct.tesh include teshsuite/smpi/type-vector/type-vector.c include teshsuite/smpi/type-vector/type-vector.tesh -include teshsuite/surf/lmm_usage/lmm_usage.cpp -include teshsuite/surf/lmm_usage/lmm_usage.tesh -include teshsuite/surf/maxmin_bench/maxmin_bench.cpp -include teshsuite/surf/maxmin_bench/maxmin_bench_large.tesh -include teshsuite/surf/maxmin_bench/maxmin_bench_medium.tesh -include teshsuite/surf/maxmin_bench/maxmin_bench_small.tesh -include teshsuite/surf/surf_usage/surf_usage.cpp -include teshsuite/surf/surf_usage/surf_usage.tesh -include teshsuite/surf/surf_usage2/surf_usage2.cpp -include teshsuite/surf/surf_usage2/surf_usage2.tesh include teshsuite/xbt/cmdline/cmdline.c include teshsuite/xbt/cmdline/cmdline.tesh include teshsuite/xbt/log_large/log_large.c @@ -1672,9 +1654,6 @@ include teshsuite/xbt/log_large/log_large.tesh include teshsuite/xbt/log_usage/log_usage.c include teshsuite/xbt/log_usage/log_usage.tesh include teshsuite/xbt/log_usage/log_usage_ndebug.tesh -include teshsuite/xbt/mmalloc/mmalloc_32.tesh -include teshsuite/xbt/mmalloc/mmalloc_64.tesh -include teshsuite/xbt/mmalloc/mmalloc_test.cpp include teshsuite/xbt/parallel_log_crashtest/parallel_log_crashtest.cpp include teshsuite/xbt/parallel_log_crashtest/parallel_log_crashtest.tesh include teshsuite/xbt/parmap_bench/parmap_bench.cpp @@ -1683,11 +1662,8 @@ include teshsuite/xbt/parmap_test/parmap_test.cpp include teshsuite/xbt/parmap_test/parmap_test.tesh include teshsuite/xbt/signals/signals.cpp include teshsuite/xbt/signals/signals.tesh -include tools/MSG_visualization/colorize.pl -include tools/MSG_visualization/trace2fig.pl include tools/address_sanitizer.supp include tools/fix-paje-trace.sh -include tools/generate-dwarf-functions include tools/graphicator/graphicator.cpp include tools/graphicator/graphicator.tesh include tools/normalize-pointers.py @@ -1733,15 +1709,9 @@ include MANIFEST.in.in include NEWS include README.md include doc/doxygen/FAQ.doc -include doc/doxygen/inside.doc -include doc/doxygen/inside_cmake.doc include doc/doxygen/inside_extending.doc include doc/doxygen/inside_release.doc -include doc/doxygen/inside_tests.doc -include doc/doxygen/module-index.doc -include doc/doxygen/module-surf.doc include doc/doxygen/outcomes_vizu.doc -include doc/doxygen/platform.doc include doc/doxygen/uhood.doc include doc/doxygen/uhood_switch.doc include docs/Build.sh @@ -1758,9 +1728,11 @@ include docs/manpages/tesh.pod include docs/requirements.txt include docs/source/Calibrating_the_models.rst include docs/source/Configuring_SimGrid.rst +include docs/source/Contributors_Documentation.rst include docs/source/Deploying_your_application.rst include docs/source/Design_goals.rst include docs/source/Doxyfile +include docs/source/Examples.rst include docs/source/Experimental_setup.rst include docs/source/Installing_SimGrid.rst include docs/source/Introduction.rst @@ -1776,38 +1748,33 @@ include docs/source/Release_Notes.rst include docs/source/Start_your_own_project.rst include docs/source/The_XBT_toolbox.rst include docs/source/Tutorial_Algorithms.rst +include docs/source/Tutorial_DAG.rst include docs/source/Tutorial_MPI_Applications.rst include docs/source/Tutorial_Model-checking.rst include docs/source/XML_reference.rst -include docs/source/_ext/javasphinx/LICENSE -include docs/source/_ext/javasphinx/MANIFEST.in -include docs/source/_ext/javasphinx/README.md -include docs/source/_ext/javasphinx/doc/conf.py -include docs/source/_ext/javasphinx/doc/index.rst -include docs/source/_ext/javasphinx/javasphinx/__init__.py -include docs/source/_ext/javasphinx/javasphinx/apidoc.py -include docs/source/_ext/javasphinx/javasphinx/compiler.py -include docs/source/_ext/javasphinx/javasphinx/domain.py -include docs/source/_ext/javasphinx/javasphinx/extdoc.py -include docs/source/_ext/javasphinx/javasphinx/formatter.py -include docs/source/_ext/javasphinx/javasphinx/htmlrst.py -include docs/source/_ext/javasphinx/javasphinx/util.py -include docs/source/_ext/javasphinx/setup.py include docs/source/_ext/showfile.css include docs/source/_ext/showfile.js include docs/source/_ext/showfile.py include docs/source/_static/css/custom.css include docs/source/_templates/breadcrumbs.html -include docs/source/app_msg.rst include docs/source/app_s4u.rst include docs/source/app_smpi.rst include docs/source/application.rst include docs/source/community.rst include docs/source/conf.py +include docs/source/img/battery_degradation.svg +include docs/source/img/dag.svg +include docs/source/img/dag1.svg +include docs/source/img/dag2.svg +include docs/source/img/design-scheduling-parallel.svg +include docs/source/img/design-scheduling-simulatedtime.svg +include docs/source/img/design-scheduling-wallclock.svg include docs/source/img/eclipseScreenShot.png include docs/source/img/extlink.png include docs/source/img/extlink.svg include docs/source/img/graphical-toc.svg +include docs/source/img/lmm-overview.svg +include docs/source/img/plugin-energy.svg include docs/source/img/smpi_simgrid_alltoall_pair_16.png include docs/source/img/smpi_simgrid_alltoall_ring_16.png include docs/source/img/starzone.drawio @@ -1832,12 +1799,12 @@ include docs/source/tuto_disk/fig/griffon_write_dhist.png include docs/source/tuto_disk/fig/simgrid_results.png include docs/source/tuto_disk/init.el include docs/source/tuto_disk/tuto_disk.cpp +include docs/source/tuto_mc/ndet-receive-mpi.c +include docs/source/tuto_mc/ndet-receive-s4u.cpp include docs/source/tuto_network_calibration/CMakeLists.txt include docs/source/tuto_network_calibration/Dockerfile include docs/source/tuto_network_calibration/Utils.cpp include docs/source/tuto_network_calibration/Utils.hpp -include docs/source/tuto_network_calibration/clustering_ckmeans.ipynb -include docs/source/tuto_network_calibration/clustering_dhist.ipynb include docs/source/tuto_network_calibration/dahu_platform_ckmeans.cpp include docs/source/tuto_network_calibration/dahu_platform_dhist.cpp include docs/source/tuto_network_calibration/fig/pingpong_real.drawio @@ -1885,7 +1852,6 @@ include docs/source/tuto_smpi/roundtrip.c include examples/README.rst include examples/c/CMakeLists.txt include examples/cpp/CMakeLists.txt -include examples/deprecated/java/CMakeLists.txt include examples/platforms/CMakeLists.txt include examples/platforms/bypassRoute.xml include examples/platforms/bypassZoneRoute.xml @@ -1965,6 +1931,7 @@ include examples/platforms/two_peers.xml include examples/platforms/vivaldi.xml include examples/platforms/wifi.xml include examples/platforms/wifi_energy.xml +include examples/platforms/wifi_large_cell.xml include examples/platforms/wifi_ns3.xml include examples/python/CMakeLists.txt include examples/python/actor-create/actor-create_d.xml @@ -1979,6 +1946,7 @@ include examples/smpi/replay_multiple_manual_deploy/CMakeLists.txt include examples/smpi/smpi_s4u_masterworker/CMakeLists.txt include examples/sthread/CMakeLists.txt include include/simgrid/Exception.hpp +include include/simgrid/activity_set.h include include/simgrid/actor.h include include/simgrid/barrier.h include include/simgrid/chrono.hpp @@ -1995,7 +1963,6 @@ include include/simgrid/kernel/ProfileBuilder.hpp include include/simgrid/kernel/Timer.hpp include include/simgrid/kernel/resource/Action.hpp include include/simgrid/kernel/resource/Model.hpp -include include/simgrid/kernel/resource/NetworkModelIntf.hpp include include/simgrid/kernel/routing/ClusterZone.hpp include include/simgrid/kernel/routing/DijkstraZone.hpp include include/simgrid/kernel/routing/DragonflyZone.hpp @@ -2013,17 +1980,21 @@ include include/simgrid/kernel/routing/WifiZone.hpp include include/simgrid/link.h include include/simgrid/mailbox.h include include/simgrid/modelchecker.h -include include/simgrid/msg.h include include/simgrid/mutex.h include include/simgrid/plugins/ProducerConsumer.hpp +include include/simgrid/plugins/battery.hpp +include include/simgrid/plugins/chiller.hpp include include/simgrid/plugins/dvfs.h include include/simgrid/plugins/energy.h include include/simgrid/plugins/file_system.h +include include/simgrid/plugins/jbod.hpp include include/simgrid/plugins/live_migration.h include include/simgrid/plugins/load.h include include/simgrid/plugins/ns3.hpp +include include/simgrid/plugins/solar_panel.hpp include include/simgrid/s4u.hpp include include/simgrid/s4u/Activity.hpp +include include/simgrid/s4u/ActivitySet.hpp include include/simgrid/s4u/Actor.hpp include include/simgrid/s4u/Barrier.hpp include include/simgrid/s4u/Comm.hpp @@ -2035,12 +2006,14 @@ include include/simgrid/s4u/Host.hpp include include/simgrid/s4u/Io.hpp include include/simgrid/s4u/Link.hpp include include/simgrid/s4u/Mailbox.hpp +include include/simgrid/s4u/Mess.hpp +include include/simgrid/s4u/MessageQueue.hpp include include/simgrid/s4u/Mutex.hpp include include/simgrid/s4u/NetZone.hpp include include/simgrid/s4u/Semaphore.hpp +include include/simgrid/s4u/Task.hpp include include/simgrid/s4u/VirtualMachine.hpp include include/simgrid/semaphore.h -include include/simgrid/simix.h include include/simgrid/simix.hpp include include/simgrid/version.h.in include include/simgrid/vm.h @@ -2054,14 +2027,11 @@ include include/smpi/smpi_extended_traces.h include include/smpi/smpi_extended_traces_fortran.h include include/smpi/smpi_helpers.h include include/smpi/smpi_helpers_internal.h -include include/smpi/smpi_main.h include include/xbt.h include include/xbt/Extendable.hpp include include/xbt/PropertyHolder.hpp include include/xbt/asserts.h include include/xbt/asserts.hpp -include include/xbt/automaton.h -include include/xbt/automaton.hpp include include/xbt/backtrace.hpp include include/xbt/base.h include include/xbt/config.h @@ -2093,63 +2063,12 @@ include include/xbt/utility.hpp include include/xbt/virtu.h include include/xbt/xbt_os_time.h include setup.py -include src/bindings/java/JavaContext.cpp -include src/bindings/java/JavaContext.hpp -include src/bindings/java/MANIFEST.in -include src/bindings/java/jmsg.cpp -include src/bindings/java/jmsg.hpp -include src/bindings/java/jmsg_as.cpp -include src/bindings/java/jmsg_as.hpp -include src/bindings/java/jmsg_comm.cpp -include src/bindings/java/jmsg_comm.h -include src/bindings/java/jmsg_host.cpp -include src/bindings/java/jmsg_host.h -include src/bindings/java/jmsg_process.cpp -include src/bindings/java/jmsg_process.h -include src/bindings/java/jmsg_synchro.cpp -include src/bindings/java/jmsg_synchro.h -include src/bindings/java/jmsg_task.cpp -include src/bindings/java/jmsg_task.h -include src/bindings/java/jmsg_vm.cpp -include src/bindings/java/jmsg_vm.h -include src/bindings/java/jtrace.cpp -include src/bindings/java/jtrace.h -include src/bindings/java/jxbt_utilities.cpp -include src/bindings/java/jxbt_utilities.hpp -include src/bindings/java/org/simgrid/NativeLib.java -include src/bindings/java/org/simgrid/msg/As.java -include src/bindings/java/org/simgrid/msg/Comm.java -include src/bindings/java/org/simgrid/msg/Host.java -include src/bindings/java/org/simgrid/msg/HostFailureException.java -include src/bindings/java/org/simgrid/msg/HostNotFoundException.java -include src/bindings/java/org/simgrid/msg/JniException.java -include src/bindings/java/org/simgrid/msg/Msg.java -include src/bindings/java/org/simgrid/msg/MsgException.java -include src/bindings/java/org/simgrid/msg/Mutex.java -include src/bindings/java/org/simgrid/msg/Process.java -include src/bindings/java/org/simgrid/msg/ProcessKilledError.java -include src/bindings/java/org/simgrid/msg/ProcessNotFoundException.java -include src/bindings/java/org/simgrid/msg/Semaphore.java -include src/bindings/java/org/simgrid/msg/Task.java -include src/bindings/java/org/simgrid/msg/TaskCancelledException.java -include src/bindings/java/org/simgrid/msg/TimeoutException.java -include src/bindings/java/org/simgrid/msg/TransferFailureException.java -include src/bindings/java/org/simgrid/msg/VM.java -include src/bindings/java/org/simgrid/trace/Trace.java +include src/3rd-party/catch.hpp include src/bindings/python/simgrid_python.cpp include src/dag/dax.dtd include src/dag/dax_dtd.c include src/dag/dax_dtd.h include src/dag/loaders.cpp -include src/include/catch.hpp -include src/include/mc/datatypes.h -include src/include/mc/mc.h -include src/include/simgrid/sg_config.hpp -include src/include/xbt/coverage.h -include src/include/xbt/mmalloc.h -include src/include/xbt/parmap.hpp -include src/include/xbt/xbt_modinter.h -include src/include/xxhash.hpp include src/instr/instr_config.cpp include src/instr/instr_interface.cpp include src/instr/instr_paje_containers.cpp @@ -2182,6 +2101,10 @@ include src/kernel/activity/IoImpl.cpp include src/kernel/activity/IoImpl.hpp include src/kernel/activity/MailboxImpl.cpp include src/kernel/activity/MailboxImpl.hpp +include src/kernel/activity/MessImpl.cpp +include src/kernel/activity/MessImpl.hpp +include src/kernel/activity/MessageQueueImpl.cpp +include src/kernel/activity/MessageQueueImpl.hpp include src/kernel/activity/MutexImpl.cpp include src/kernel/activity/MutexImpl.hpp include src/kernel/activity/SemaphoreImpl.cpp @@ -2227,11 +2150,17 @@ include src/kernel/resource/CpuImpl.cpp include src/kernel/resource/CpuImpl.hpp include src/kernel/resource/DiskImpl.cpp include src/kernel/resource/DiskImpl.hpp +include src/kernel/resource/FactorSet.cpp +include src/kernel/resource/FactorSet.hpp +include src/kernel/resource/HostImpl.cpp +include src/kernel/resource/HostImpl.hpp include src/kernel/resource/LinkImpl.hpp include src/kernel/resource/Model.cpp include src/kernel/resource/NetworkModel.cpp include src/kernel/resource/NetworkModel.hpp -include src/kernel/resource/NetworkModelIntf_test.cpp +include src/kernel/resource/NetworkModelFactors.cpp +include src/kernel/resource/NetworkModelFactors.hpp +include src/kernel/resource/NetworkModelFactors_test.cpp include src/kernel/resource/Resource.hpp include src/kernel/resource/SplitDuplexLinkImpl.cpp include src/kernel/resource/SplitDuplexLinkImpl.hpp @@ -2242,6 +2171,26 @@ include src/kernel/resource/VirtualMachineImpl.cpp include src/kernel/resource/VirtualMachineImpl.hpp include src/kernel/resource/WifiLinkImpl.cpp include src/kernel/resource/WifiLinkImpl.hpp +include src/kernel/resource/models/cpu_cas01.cpp +include src/kernel/resource/models/cpu_cas01.hpp +include src/kernel/resource/models/cpu_ti.cpp +include src/kernel/resource/models/cpu_ti.hpp +include src/kernel/resource/models/disk_s19.cpp +include src/kernel/resource/models/disk_s19.hpp +include src/kernel/resource/models/host_clm03.cpp +include src/kernel/resource/models/host_clm03.hpp +include src/kernel/resource/models/network_cm02.cpp +include src/kernel/resource/models/network_cm02.hpp +include src/kernel/resource/models/network_constant.cpp +include src/kernel/resource/models/network_constant.hpp +include src/kernel/resource/models/network_ib.cpp +include src/kernel/resource/models/network_ib.hpp +include src/kernel/resource/models/network_ns3.cpp +include src/kernel/resource/models/network_ns3.hpp +include src/kernel/resource/models/ns3/ns3_simulator.cpp +include src/kernel/resource/models/ns3/ns3_simulator.hpp +include src/kernel/resource/models/ptask_L07.cpp +include src/kernel/resource/models/ptask_L07.hpp include src/kernel/resource/profile/Event.hpp include src/kernel/resource/profile/FutureEvtSet.cpp include src/kernel/resource/profile/FutureEvtSet.hpp @@ -2274,115 +2223,123 @@ include src/kernel/routing/TorusZone_test.cpp include src/kernel/routing/VivaldiZone.cpp include src/kernel/routing/WifiZone.cpp include src/kernel/timer/Timer.cpp -include src/mc/AddressSpace.hpp -include src/mc/ModelChecker.cpp -include src/mc/ModelChecker.hpp -include src/mc/Session.cpp -include src/mc/Session.hpp -include src/mc/VisitedState.cpp -include src/mc/VisitedState.hpp -include src/mc/api.cpp -include src/mc/api.hpp +include src/kernel/xml/platf.hpp +include src/kernel/xml/platf_private.hpp +include src/kernel/xml/platf_sax_cb.cpp +include src/kernel/xml/sg_platf.cpp +include src/kernel/xml/simgrid.dtd +include src/kernel/xml/simgrid_dtd.c +include src/kernel/xml/simgrid_dtd.h +include src/mc/api/ActorState.hpp +include src/mc/api/ClockVector.cpp +include src/mc/api/ClockVector.hpp +include src/mc/api/RemoteApp.cpp +include src/mc/api/RemoteApp.hpp include src/mc/api/State.cpp include src/mc/api/State.hpp -include src/mc/compare.cpp +include src/mc/api/strategy/BasicStrategy.hpp +include src/mc/api/strategy/MaxMatchComm.hpp +include src/mc/api/strategy/MinMatchComm.hpp +include src/mc/api/strategy/Strategy.hpp +include src/mc/api/strategy/UniformStrategy.hpp +include src/mc/datatypes.h include src/mc/explo/CommunicationDeterminismChecker.cpp include src/mc/explo/DFSExplorer.cpp include src/mc/explo/DFSExplorer.hpp +include src/mc/explo/Exploration.cpp include src/mc/explo/Exploration.hpp -include src/mc/explo/LivenessChecker.cpp -include src/mc/explo/LivenessChecker.hpp include src/mc/explo/UdporChecker.cpp include src/mc/explo/UdporChecker.hpp +include src/mc/explo/odpor/ClockVector_test.cpp +include src/mc/explo/odpor/Execution.cpp +include src/mc/explo/odpor/Execution.hpp +include src/mc/explo/odpor/Execution_test.cpp +include src/mc/explo/odpor/WakeupTree.cpp +include src/mc/explo/odpor/WakeupTree.hpp +include src/mc/explo/odpor/WakeupTreeIterator.cpp +include src/mc/explo/odpor/WakeupTreeIterator.hpp +include src/mc/explo/odpor/WakeupTree_test.cpp +include src/mc/explo/odpor/odpor_forward.hpp +include src/mc/explo/odpor/odpor_tests_private.hpp include src/mc/explo/simgrid_mc.cpp -include src/mc/inspect/DwarfExpression.cpp -include src/mc/inspect/DwarfExpression.hpp -include src/mc/inspect/Frame.cpp -include src/mc/inspect/Frame.hpp -include src/mc/inspect/LocationList.cpp -include src/mc/inspect/LocationList.hpp -include src/mc/inspect/ObjectInformation.cpp -include src/mc/inspect/ObjectInformation.hpp -include src/mc/inspect/Type.hpp -include src/mc/inspect/Variable.hpp -include src/mc/inspect/mc_dwarf.cpp -include src/mc/inspect/mc_dwarf.hpp -include src/mc/inspect/mc_dwarf_attrnames.cpp -include src/mc/inspect/mc_dwarf_tagnames.cpp -include src/mc/inspect/mc_member.cpp -include src/mc/inspect/mc_unw.cpp -include src/mc/inspect/mc_unw.hpp -include src/mc/inspect/mc_unw_vmread.cpp +include src/mc/explo/udpor/Comb.hpp +include src/mc/explo/udpor/Configuration.cpp +include src/mc/explo/udpor/Configuration.hpp +include src/mc/explo/udpor/Configuration_test.cpp +include src/mc/explo/udpor/EventSet.cpp +include src/mc/explo/udpor/EventSet.hpp +include src/mc/explo/udpor/EventSet_test.cpp +include src/mc/explo/udpor/ExtensionSetCalculator.cpp +include src/mc/explo/udpor/ExtensionSetCalculator.hpp +include src/mc/explo/udpor/ExtensionSet_test.cpp +include src/mc/explo/udpor/History.cpp +include src/mc/explo/udpor/History.hpp +include src/mc/explo/udpor/History_test.cpp +include src/mc/explo/udpor/Unfolding.cpp +include src/mc/explo/udpor/Unfolding.hpp +include src/mc/explo/udpor/UnfoldingEvent.cpp +include src/mc/explo/udpor/UnfoldingEvent.hpp +include src/mc/explo/udpor/UnfoldingEvent_test.cpp +include src/mc/explo/udpor/Unfolding_test.cpp +include src/mc/explo/udpor/maximal_subsets_iterator.cpp +include src/mc/explo/udpor/maximal_subsets_iterator.hpp +include src/mc/explo/udpor/udpor_forward.hpp +include src/mc/explo/udpor/udpor_tests_private.hpp +include src/mc/mc.h include src/mc/mc_base.cpp include src/mc/mc_base.hpp include src/mc/mc_client_api.cpp include src/mc/mc_config.cpp include src/mc/mc_config.hpp +include src/mc/mc_environ.h include src/mc/mc_exit.hpp include src/mc/mc_forward.hpp include src/mc/mc_global.cpp -include src/mc/mc_hash.cpp -include src/mc/mc_hash.hpp -include src/mc/mc_ignore.hpp include src/mc/mc_mmu.hpp -include src/mc/mc_pattern.hpp include src/mc/mc_private.hpp include src/mc/mc_record.cpp include src/mc/mc_record.hpp include src/mc/mc_replay.hpp -include src/mc/mc_safety.hpp -include src/mc/mc_smx.cpp include src/mc/remote/AppSide.cpp include src/mc/remote/AppSide.hpp include src/mc/remote/Channel.cpp include src/mc/remote/Channel.hpp include src/mc/remote/CheckerSide.cpp include src/mc/remote/CheckerSide.hpp -include src/mc/remote/RemoteProcess.cpp -include src/mc/remote/RemoteProcess.hpp include src/mc/remote/RemotePtr.hpp include src/mc/remote/mc_protocol.h -include src/mc/sosp/ChunkedData.cpp -include src/mc/sosp/ChunkedData.hpp -include src/mc/sosp/PageStore.cpp -include src/mc/sosp/PageStore.hpp -include src/mc/sosp/PageStore_test.cpp -include src/mc/sosp/Region.cpp -include src/mc/sosp/Region.hpp -include src/mc/sosp/Snapshot.cpp -include src/mc/sosp/Snapshot.hpp -include src/mc/sosp/Snapshot_test.cpp include src/mc/transition/Transition.cpp include src/mc/transition/Transition.hpp +include src/mc/transition/TransitionActor.cpp +include src/mc/transition/TransitionActor.hpp include src/mc/transition/TransitionAny.cpp include src/mc/transition/TransitionAny.hpp include src/mc/transition/TransitionComm.cpp include src/mc/transition/TransitionComm.hpp +include src/mc/transition/TransitionObjectAccess.cpp +include src/mc/transition/TransitionObjectAccess.hpp include src/mc/transition/TransitionRandom.cpp include src/mc/transition/TransitionRandom.hpp include src/mc/transition/TransitionSynchro.cpp include src/mc/transition/TransitionSynchro.hpp -include src/mc/udpor_global.cpp -include src/mc/udpor_global.hpp -include src/msg/msg_comm.cpp -include src/msg/msg_global.cpp -include src/msg/msg_legacy.cpp -include src/msg/msg_private.hpp -include src/msg/msg_process.cpp -include src/msg/msg_task.cpp include src/plugins/ProducerConsumer.cpp +include src/plugins/battery.cpp include src/plugins/chaos_monkey.cpp +include src/plugins/chiller.cpp include src/plugins/file_system/s4u_FileSystem.cpp include src/plugins/host_dvfs.cpp include src/plugins/host_energy.cpp include src/plugins/host_load.cpp +include src/plugins/jbod.cpp include src/plugins/link_energy.cpp include src/plugins/link_energy_wifi.cpp include src/plugins/link_load.cpp +include src/plugins/solar_panel.cpp include src/plugins/vm/VmLiveMigration.cpp include src/plugins/vm/VmLiveMigration.hpp include src/plugins/vm/dirty_page_tracking.cpp include src/s4u/s4u_Activity.cpp +include src/s4u/s4u_ActivitySet.cpp include src/s4u/s4u_Actor.cpp include src/s4u/s4u_Barrier.cpp include src/s4u/s4u_Comm.cpp @@ -2394,16 +2351,21 @@ include src/s4u/s4u_Host.cpp include src/s4u/s4u_Io.cpp include src/s4u/s4u_Link.cpp include src/s4u/s4u_Mailbox.cpp +include src/s4u/s4u_Mess.cpp +include src/s4u/s4u_MessageQueue.cpp include src/s4u/s4u_Mutex.cpp include src/s4u/s4u_Netzone.cpp include src/s4u/s4u_Semaphore.cpp +include src/s4u/s4u_Task.cpp include src/s4u/s4u_VirtualMachine.cpp include src/simgrid/Exception.cpp +include src/simgrid/math_utils.h +include src/simgrid/module.cpp +include src/simgrid/module.hpp include src/simgrid/sg_config.cpp +include src/simgrid/sg_config.hpp include src/simgrid/sg_version.cpp include src/simgrid/util.hpp -include src/simix/libsmx.cpp -include src/simix/smx_context.cpp include src/smpi/bindings/smpi_f77.cpp include src/smpi/bindings/smpi_f77_coll.cpp include src/smpi/bindings/smpi_f77_comm.cpp @@ -2590,55 +2552,16 @@ include src/smpi/smpif90.in include src/smpi/smpiff.in include src/smpi/smpirun.in include src/smpi/smpitools.sh +include src/sthread/ObjectAccess.cpp include src/sthread/sthread.c include src/sthread/sthread.h include src/sthread/sthread_impl.cpp -include src/surf/HostImpl.cpp -include src/surf/HostImpl.hpp -include src/surf/cpu_cas01.cpp -include src/surf/cpu_cas01.hpp -include src/surf/cpu_ti.cpp -include src/surf/cpu_ti.hpp -include src/surf/disk_s19.cpp -include src/surf/disk_s19.hpp -include src/surf/host_clm03.cpp -include src/surf/host_clm03.hpp -include src/surf/network_cm02.cpp -include src/surf/network_cm02.hpp -include src/surf/network_constant.cpp -include src/surf/network_constant.hpp -include src/surf/network_ib.cpp -include src/surf/network_ib.hpp -include src/surf/network_ns3.cpp -include src/surf/network_ns3.hpp -include src/surf/network_smpi.cpp -include src/surf/network_smpi.hpp -include src/surf/ns3/ns3_simulator.cpp -include src/surf/ns3/ns3_simulator.hpp -include src/surf/ptask_L07.cpp -include src/surf/ptask_L07.hpp -include src/surf/sg_platf.cpp -include src/surf/surf_interface.cpp -include src/surf/surf_interface.hpp -include src/surf/xml/platf.hpp -include src/surf/xml/platf_private.hpp -include src/surf/xml/simgrid.dtd -include src/surf/xml/simgrid_dtd.c -include src/surf/xml/simgrid_dtd.h -include src/surf/xml/surfxml_parseplatf.cpp -include src/surf/xml/surfxml_sax_cb.cpp include src/xbt/OsSemaphore.hpp include src/xbt/PropertyHolder.cpp -include src/xbt/automaton/automaton.c -include src/xbt/automaton/automaton_lexer.yy.c -include src/xbt/automaton/automatonparse_promela.c -include src/xbt/automaton/parserPromela.lex -include src/xbt/automaton/parserPromela.tab.cacc -include src/xbt/automaton/parserPromela.tab.hacc -include src/xbt/automaton/parserPromela.yacc include src/xbt/backtrace.cpp include src/xbt/config.cpp include src/xbt/config_test.cpp +include src/xbt/coverage.h include src/xbt/dict.cpp include src/xbt/dict_cursor.c include src/xbt/dict_elm.c @@ -2654,40 +2577,33 @@ include src/xbt/mallocator.c include src/xbt/mallocator_private.h include src/xbt/memory_map.cpp include src/xbt/memory_map.hpp -include src/xbt/mmalloc/mfree.c -include src/xbt/mmalloc/mm.c -include src/xbt/mmalloc/mm_legacy.c -include src/xbt/mmalloc/mm_module.c -include src/xbt/mmalloc/mmalloc.c -include src/xbt/mmalloc/mmalloc.info -include src/xbt/mmalloc/mmalloc.texi -include src/xbt/mmalloc/mmorecore.c -include src/xbt/mmalloc/mmprivate.h -include src/xbt/mmalloc/mrealloc.c -include src/xbt/mmalloc/swag.c -include src/xbt/mmalloc/swag.h include src/xbt/parmap.cpp +include src/xbt/parmap.hpp include src/xbt/random.cpp include src/xbt/random_test.cpp include src/xbt/snprintf.c include src/xbt/string.cpp include src/xbt/unit-tests_main.cpp +include src/xbt/utils/iter/LazyKSubsets.hpp +include src/xbt/utils/iter/LazyPowerset.hpp +include src/xbt/utils/iter/iterator_wrapping.hpp +include src/xbt/utils/iter/powerset.hpp +include src/xbt/utils/iter/subsets.hpp +include src/xbt/utils/iter/subsets_tests.cpp +include src/xbt/utils/iter/variable_for_loop.hpp include src/xbt/xbt_log_appender_file.cpp include src/xbt/xbt_log_layout_format.cpp include src/xbt/xbt_log_layout_simple.cpp -include src/xbt/xbt_main.cpp +include src/xbt/xbt_misc.cpp include src/xbt/xbt_os_file.cpp include src/xbt/xbt_os_time.c include src/xbt/xbt_parse_units.cpp include src/xbt/xbt_replay.cpp include src/xbt/xbt_str.cpp include src/xbt/xbt_str_test.cpp -include src/xbt/xbt_virtu.cpp -include teshsuite/java/CMakeLists.txt include teshsuite/kernel/CMakeLists.txt include teshsuite/mc/CMakeLists.txt include teshsuite/models/CMakeLists.txt -include teshsuite/msg/CMakeLists.txt include teshsuite/platforms/CMakeLists.txt include teshsuite/python/CMakeLists.txt include teshsuite/s4u/CMakeLists.txt @@ -2725,7 +2641,6 @@ include teshsuite/smpi/mpich3-test/perf/CMakeLists.txt include teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt include teshsuite/smpi/mpich3-test/rma/CMakeLists.txt include teshsuite/smpi/mpich3-test/topo/CMakeLists.txt -include teshsuite/surf/CMakeLists.txt include teshsuite/xbt/CMakeLists.txt include tools/CMakeLists.txt include tools/cmake/CTestConfig.cmake @@ -2734,27 +2649,23 @@ include tools/cmake/DefinePackages.cmake include tools/cmake/Distrib.cmake include tools/cmake/Documentation.cmake include tools/cmake/Flags.cmake -include tools/cmake/Java.cmake include tools/cmake/MaintainerMode.cmake include tools/cmake/MakeLib.cmake -include tools/cmake/MakeLibWin.cmake include tools/cmake/Modules/FindGraphviz.cmake -include tools/cmake/Modules/FindLibdw.cmake -include tools/cmake/Modules/FindLibelf.cmake include tools/cmake/Modules/FindLibevent.cmake -include tools/cmake/Modules/FindLibunwind.cmake include tools/cmake/Modules/FindNS3.cmake include tools/cmake/Modules/FindPAPI.cmake include tools/cmake/Modules/FindValgrind.cmake +include tools/cmake/Modules/nlohmann_jsonConfig.cmake include tools/cmake/Modules/pybind11Config.cmake include tools/cmake/Option.cmake include tools/cmake/Tests.cmake -include tools/cmake/cross-mingw.cmake include tools/cmake/scripts/fixup_simgrid_dtd_l.pl include tools/cmake/scripts/my_valgrind.pl include tools/cmake/scripts/update_tesh.pl include tools/cmake/test_prog/prog_asan.cpp include tools/cmake/test_prog/prog_makecontext.c +include tools/cmake/test_prog/prog_ns3.cpp include tools/cmake/test_prog/prog_stackgrowth.c include tools/cmake/test_prog/prog_stacksetup.c include tools/cmake/test_prog/prog_tsan.cpp diff --git a/NEWS b/NEWS index f610e53ab1..bbe6e5f6ae 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,61 @@ + + _ _____ _____ __ +__ _____ _ __ ___(_) ___ _ __ |___ / |___ / / /_ +\ \ / / _ \ '__/ __| |/ _ \| '_ \ |_ \ |_ \| '_ \ + \ V / __/ | \__ \ | (_) | | | | ___) | ___) | (_) | + \_/ \___|_| |___/_|\___/|_| |_| |____(_)____/ \___/ + (not released yet) + + + _ _____ _________ +__ _____ _ __ ___(_) ___ _ __ |___ / |___ / ___| +\ \ / / _ \ '__/ __| |/ _ \| '_ \ |_ \ |_ \___ \ + \ V / __/ | \__ \ | (_) | | | | ___) | ___) |__) | + \_/ \___|_| |___/_|\___/|_| |_| |____(_)____/____/ + November 23. 2023 + +The "Thanks Giving up stateful model-checking" release. Stateless model checking remains. + + * Maint: liveness checking is gone. It was fragile and buggy. + * API: ActivitySet make it easier to manage sets of activities. + * Plugins chiller, photovoltaic and battery revamped and improved. + * Performance improvements, both in time and memory. + * (+ internal refactoring, usability improvements and bug fixes) + _ _____ _____ _ _ +__ _____ _ __ ___(_) ___ _ __ |___ / |___ /| || | +\ \ / / _ \ '__/ __| |/ _ \| '_ \ |_ \ |_ \| || |_ + \ V / __/ | \__ \ | (_) | | | | ___) | ___) |__ _| + \_/ \___|_| |___/_|\___/|_| |_| |____(_)____/ |_| + June 26. 2023 + +Save the planet, skip a release: 3.33 was due 6 months ago, so skip directly to 3.34. + + * Maint: MSG and Java are gone (EOL was scheduled for 2020), move to C++17, + and drop 32bits support. + * Model: Introduce a fluid I/O model, mixing I/O and network, to represent + streaming from disk + * API: DAG/workflow loader; Introducing Tasks which are activities that can + be fired several times. + * Doc: Several new documentation sections, and a new tutorial on DAGs. + * MC: Safety properties now portable to every OS, activated by default + in all builds. + * MC: Introduction ODPOR/SDPOR reductions and guiding strategies (better + state space traversal). + * (+ internal refactoring, bug fixes and documentation improvement) + _ _____ _________ __ _____ _ __ ___(_) ___ _ __ |___ / |___ /___ \ \ \ / / _ \ '__/ __| |/ _ \| '_ \ |_ \ |_ \ __) | \ V / __/ | \__ \ | (_) | | | | ___) | ___) / __/ \_/ \___|_| |___/_|\___/|_| |_| |____(_)____/_____| - (unreleased) + October 3. 2022 + +The Wiedervereinigung release. Germany was reunited 32 years ago. + + * Various cleanups around the virtual machines API + * Improved Python platform generation (more robust, easier to use) + * Further complete Python bindings (Comm, Engine, ptasks) + * (+ internal refactoring, MANY bug fixes and documentation improvement) _ _____ _____ _ __ _____ _ __ ___(_) ___ _ __ |___ / |___ // | @@ -17,7 +69,8 @@ The ненасильство release. We stand against war. * Refactoring the model-checker, enabling synchronization objects and future improvements * Introducing BMF sharing, enabling ptasks in regular models (experimental) * Further complete Python bindings (Mutex, Semaphore and Barrier) - * (+ internal refactoring, many bug fixes and documentation improvement) + * (+ internal refactoring, many bug fixes and documentation improvement) + _ _____ _____ ___ __ _____ _ __ ___(_) ___ _ __ |___ / |___ / / _ \ \ \ / / _ \ '__/ __| |/ _ \| '_ \ |_ \ |_ \| | | | diff --git a/README.coding b/README.coding deleted file mode 100644 index e3eed4041c..0000000000 --- a/README.coding +++ /dev/null @@ -1,103 +0,0 @@ -** -** Source tree organization -** -****************************************************** - - examples/ -> Supposed to be copy/pastable by the user, so keep it clear and - avoid any kind of trick. In particular, do only include the - public headers here. - - teshsuite/ -> The more test the better. Put in there any strange test - doing things that the users are not supposed to do, - just to see if our framework is robust to incorrect and - unusual behaviors. All tests written in this section - should leverage our tesh(1) utility. - -** -** NEW type naming standard in SimGrid4 -** -***************************************************** - -SimGrid4 will follow the these rules: - - - filenames are unique in the whole project - (because of a bug in Sonar coverage computation) - C++ - - fields, methods and variables are in snake_case() - - Classes and Enum names are in UpperCamelCase - - Enum values are in UPPER_SNAKE_CASE (as constants) - - public filenames: api_Class.cpp and api/Class.hpp. - - Example: src/s4u/s4u_ConditionVariable.cpp and - include/simgrid/s4u/ConditionVariable.hpp - - If you prefer api_class.cpp, that's OK, too. Breath and relax. - Example: src/s4u/s4u_actor.cpp and include/simgrid/s4u/Actor.hpp - - internal/kernel filenames: Class.cpp and Class.hpp - - Example: src/kernel/activity/Activity.cpp - include/simgrid/activity/Activity.hpp - C - - Field getters are named sg_object_get_field() e.g. sg_link_get_name() - Field setters are named sg_object_set_field() e.g. sg_link_set_data() - - variables and functions are in snake_case() - - typedefs do not hide the pointers, i.e. * must be explicit - char* sg_host_get_name(sg_host_t* host); - - -This is different from the old convention (described below), that -should not be used in S4U and its bindings, nor in the kernel. - -** -** Commenting the source: doxygen -** -**************************************************** - -The global structure of the documentation is in doc/modules.doc - -The structure of each module (xbt, msg, etc) is in doc/module-.doc - -The structure of a module is in its public header. This way, you're sure to -see all the public interface (and only it). The different parts of the -interface are grouped using the @name construct, even if it's buggy. Since -parts often get reordered, it's better to add numbers to the parts (so that -users can see the intended order). - -The documentation of each type and macro are also in the public header since -this is were they live. - -The documentation of each function must be in the C++ file were it lives. - -Any public element (function, type and macro) must have a @brief part. - -We use @ as a command marker, not \ (so, use @brief not \brief) - -** -** OLD Type naming standard in SimGrid3 -** -***************************************************** - -SimGrid3 legacy interface (ie, MSG) is following these rules: - - - ???_t is a valid type (built with typedef) - - s_toto_t is a structure (access to fields with .) - - s_toto is a structure needing 'struct' keyword to be used - - e_toto_t is an enum - - u_toto_t is an union - - u_toto is an union needing 'union' keyword to be used - - toto_t is an 'object' (struct*) - -Please to not call toto_t something else than an 'object' (ie, something you -have to call _new and _free on it). - -Example: - typedef struct s_toto {} s_toto_t, *toto_t; - typedef enum {} e_toto_t; - -Moreover, only toto_t (and e_toto_t) are public. The rest (mainly s_toto_t) -is private. - - -* -* SimGrid Hacker Survival Guide (FIXME: should be betterly placed) -******************************** -* When you add/remove files, and/or make changes in the lists of files to build, - please check that "make distcheck" still succeeds. This is needed to ensure - that the generated archive is consistent. diff --git a/README.md b/README.md index 8c81d3e4f6..1c0a668c1d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) [![Build Status](https://ci.inria.fr/simgrid/buildStatus/icon?job=SimGrid)](https://ci.inria.fr/simgrid/job/SimGrid/) -[![AppVeyor Status](https://ci.appveyor.com/api/projects/status/gvcssh340fwtoc35?svg=true)](https://ci.appveyor.com/project/mquinson/simgrid) [![SonarCloud Status](https://sonarcloud.io/api/project_badges/measure?project=simgrid_simgrid&metric=alert_status)](https://sonarcloud.io/dashboard/?id=simgrid_simgrid) [![Doc](https://readthedocs.org/projects/pip/badge/?version=stable)](https://simgrid.org/doc/latest/) [![License: LGPL v2.1][license-badge]](COPYING) diff --git a/contrib/benchmarking_code_block/bench.h b/contrib/benchmarking_code_block/bench.h index 3c879ba520..97c76b4f70 100644 --- a/contrib/benchmarking_code_block/bench.h +++ b/contrib/benchmarking_code_block/bench.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/contrib/benchmarking_code_block/inject.h b/contrib/benchmarking_code_block/inject.h index d3c0546a19..12083cca90 100644 --- a/contrib/benchmarking_code_block/inject.h +++ b/contrib/benchmarking_code_block/inject.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/doc/doxygen/FAQ.doc b/doc/doxygen/FAQ.doc index db3f7cbceb..4f8f178d99 100644 --- a/doc/doxygen/FAQ.doc +++ b/doc/doxygen/FAQ.doc @@ -1,138 +1,6 @@ -/*! @page FAQ MSG Frequently Asked Questions +/*! @page FAQ Frequently Asked Questions -@tableofcontents - -This document is the FAQ of the MSG interface. Some entries are a bit aging and it should be refreshed at some point. - -@section faq_simgrid I'm new to SimGrid. I have some questions. Where should I start? - -You are at the right place... To understand what you can do or -cannot do with SimGrid, you should read the -tutorial -slides from the SimGrid's website. You may find more up-to-date -material on the -blog of -Martin Quinson. - -Another great source of inspiration can be found in the @ref s4u_examples. - -If you are stuck at any point and if this FAQ cannot help you, please drop us a -mail to the user mailing list: . - -@subsection faq_visualization Visualizing and analyzing the results - -It is sometime convenient to "see" how the agents are behaving. If you -like colors, you can use tools/MSG_visualization/colorize.pl -as a filter to your MSG outputs. It works directly with INFO. Beware, -INFO() prints on stderr. Do not forget to redirect if you want to -filter (e.g. with bash): -@verbatim -./msg_test small_platform.xml small_deployment.xml 2>&1 | ../../tools/MSG_visualization/colorize.pl -@endverbatim - -We also have a more graphical output. Have a look at section @ref options_tracing. - -@section faq_howto Feature related questions - -@subsection faq_MIA "Could you please add (your favorite feature here) to SimGrid?" - -Here is the deal. The whole SimGrid project (MSG, SURF, ...) is -meant to be kept as simple and generic as possible. We cannot add -functions for everybody's needs when these functions can easily be -built from the ones already in the API. Most of the time, it is -possible and when it was not possible we always have upgraded the API -accordingly. When somebody asks us a question like "How to do that? -Is there a function in the API to simply do this?", we're always glad -to answer and help. However if we don't need this code for our own -need, there is no chance we're going to write it... it's your job! :) -The counterpart to our answers is that once you come up with a neat -implementation of this feature (task duplication, RPC, thread -synchronization, ...), you should send it to us and we will be glad to -add it to the distribution. Thus, other people will take advantage of -it (and we don't have to answer this question again and again ;). - -You'll find in this section a few "Missing In Action" features. Many -people have asked about it and we have given hints on how to simply do -it with MSG. Feel free to contribute... - -@subsection faq_MIA_MSG MSG features - -@subsubsection faq_MIA_thread_synchronization How to synchronize my user processes? - -It depends on why you want to synchronize them. If you just want to -have a shared state between your processes, then you probably don't -need to do anything. User processes never get forcefully interrupted -in SimGrid (unless you explicitly request the parallel execution of -user processes -- see @ref options_virt_parallel). - -Even if several processes are executed at the exact same time within -the simulation, they are linearized in reality by default: one process -always run in an exclusive manner, atomic, uninterrupted until it does -a simcall (until it ask a service from the simulation kernel). This is -surprising at first, but things are much easier this way, both for the -user (who don't have to protect her shared data) and for the kernel -(that avoid many synchronization issues too). Processes are executed -concurrently in the simulated realm, but you don't need to bother with -this in the real realm. - -If you really need to synchronize your processes (because it's what -you are studying or to create an atomic section that spans over -several simcalls), you obviously cannot use regular synchronization -mechanisms (pthread_mutexes in C or the synchronized keyword in Java). -This is because the SimGrid kernel locks all processes and unlock them -one after the other when they are supposed to run, until they give the -control back in their simcall. If one of them gets locked by the OS -before returning the control to the kernel, that's definitively a -deadlock. - -Instead, you should use the synchronization mechanism provided by the -simulation kernel. This could with a SimGrid mutex, a SimGrid -condition variables or a SimGrid semaphore, as described in @ref -msg_synchro (in Java, only semaphores are available). But actually, -many synchronization patterns can be encoded with communication on -mailboxes. Typically, if you need one process to notify another one, -you could use a condition variable or a semaphore, but sending a -message to a specific mailbox does the trick in most cases. - -@subsubsection faq_MIA_communication_time How can I get the *real* communication time? - -Communications are synchronous and thus if you simply get the time -before and after a communication, you'll only get the transmission -time and the time spent to really communicate (it will also take into -account the time spent waiting for the other party to be -ready). However, getting the *real* communication time is not really -hard either. The following solution is a good starting point. - -@code -int sender() -{ - m_task_t task = MSG_task_create("Task", task_comp_size, task_comm_size, - calloc(1,sizeof(double))); - *((double*) task->data) = MSG_get_clock(); - MSG_task_put(task, workers[i % workers_count], PORT_22); - XBT_INFO("Send completed"); - return 0; -} -int receiver() -{ - m_task_t task = NULL; - double time1,time2; - - time1 = MSG_get_clock(); - a = MSG_task_get(&(task), PORT_22); - time2 = MSG_get_clock(); - if(time1<*((double *)task->data)) - time1 = *((double *) task->data); - XBT_INFO("Communication time : \"%f\" ", time2-time1); - free(task->data); - MSG_task_destroy(task); - return 0; -} -@endcode - -@subsection faq_MIA_SimDag SimDag related questions - -@subsubsection faq_SG_comm Implementing communication delays between tasks. +@subsubsection Implementing communication delays between SimDAG tasks. A classic question of SimDag newcomers is about how to express a communication delay between tasks. The thing is that in SimDag, both @@ -157,114 +25,4 @@ comprising the workstations on which t1 and t2 are scheduled (w1 and w2 for example) and build a communication matrix that should look like [0;amount ; 0; 0]. -@subsubsection faq_SG_DAG How to implement a distributed dynamic scheduler of DAGs. - -Distributed is somehow "contagious". If you start making distributed -decisions, there is no way to handle DAGs directly anymore (unless I -am missing something). You have to encode your DAGs in term of -communicating process to make the whole scheduling process -distributed. Here is an example of how you could do that. Assume T1 -has to be done before T2. - -@code - int your_agent(int argc, char *argv[] { - ... - T1 = MSG_task_create(...); - T2 = MSG_task_create(...); - ... - while(1) { - ... - if(cond) MSG_task_execute(T1); - ... - if((MSG_task_get_remaining_computation(T1)=0.0) && (you_re_in_a_good_mood)) - MSG_task_execute(T2) - else { - /* do something else */ - } - } - } -@endcode - -If you decide that the distributed part is not that much important and that -DAG is really the level of abstraction you want to work with, then you should -give a try to @ref SD_API. - -@subsection faq_MIA_generic Generic features - -@subsubsection faq_MIA_batch_scheduler Is there a native support for batch schedulers in SimGrid? - -No, there is no native support for batch schedulers and none is -planned because this is a very specific need (and doing it in a -generic way is thus very hard). However some people have implemented -their own batch schedulers. Vincent Garonne wrote one during his PhD -and put his code in the contrib directory of our SVN so that other can -keep working on it. You may find inspiring ideas in it. - -@subsection faq_platform Platform building and Dynamic resources - -@subsubsection faq_platform_synthetic Generating synthetic but realistic platforms - -Another possibility to get a platform file is to generate synthetic -platforms. Getting a realistic result is not a trivial task, and -moreover, nobody is really able to define what "realistic" means when -speaking of topology files. You can find some more thoughts on this -topic in these -slides. - -If you are looking for an actual tool, there we have a little tool to -annotate Tiers-generated topologies. This perl-script is in -tools/platform_generation/ directory of the SVN. Dinda et Al. -released a very comparable tool, and called it GridG. - - -The specified computing power will be available to up to 6 sequential -tasks without sharing. If more tasks are placed on this host, the -resource will be shared accordingly. For example, if you schedule 12 -tasks on the host, each will get half of the computing power. Please -note that although sound, this model were never scientifically -assessed. Please keep this fact in mind when using it. - -@section faq_troubleshooting Troubleshooting - -@subsection faq_surf_network_latency I get weird timings when I play with the latencies. - -OK, first of all, remember that units should be Bytes, Flops and -Seconds. If you don't use such units, some SimGrid constants (e.g. the -SG_TCP_CTE_GAMMA constant used in most network models) won't have the -right unit and you'll end up with weird results. - -Here is what happens with a single transfer of size L on a link -(bw,lat) when nothing else happens. - -@verbatim -0-----lat--------------------------------------------------t -|-----|**** real_bw =min(bw,SG_TCP_CTE_GAMMA/(2*lat)) *****| -@endverbatim - -In more complex situations, this min is the solution of a complex -max-min linear system. Have a look -here -and read the two threads "Bug in SURF?" and "Surf bug not -fixed?". You'll have a few other examples of such computations. You -can also read "A Network Model for Simulation of Grid Application" by -Henri Casanova and Loris Marchal to have all the details. The fact -that the real_bw is smaller than bw is easy to understand. The fact -that real_bw is smaller than SG_TCP_CTE_GAMMA/(2*lat) is due to the -window-based congestion mechanism of TCP. With TCP, you can't exploit -your huge network capacity if you don't have a good round-trip-time -because of the acks... - -Anyway, what you get is t=lat + L/min(bw,SG_TCP_CTE_GAMMA/(2*lat)). - - * if I you set (bw,lat)=(100 000 000, 0.00001), you get t = 1.00001 (you fully -use your link) - * if I you set (bw,lat)=(100 000 000, 0.0001), you get t = 1.0001 (you're on the -limit) - * if I you set (bw,lat)=(100 000 000, 0.001), you get t = 10.001 (ouch!) - -This bound on the effective bandwidth of a flow is not the only thing -that may make your result be unexpected. For example, two flows -competing on a saturated link receive an amount of bandwidth inversely -proportional to their round trip time. - */ diff --git a/doc/doxygen/inside.doc b/doc/doxygen/inside.doc deleted file mode 100644 index 5428876f42..0000000000 --- a/doc/doxygen/inside.doc +++ /dev/null @@ -1,148 +0,0 @@ -/*! @page uhood_tech Coding Standard and Technical Considerations - -This page describes the software infrastructure behind the SimGrid -project. This is not the components' organisation (described in @ref -uhood_arch) but information on how to extend the framework, how the -automatic tests are run, and so on. These information are split on -several pages, as follows: - - - @ref uhood_tech_inside - - @subpage inside_tests - - @subpage inside_doxygen - - @subpage inside_extending - - @subpage inside_cmake - - @subpage inside_release - -@section uhood_tech_inside Insiders Considerations - -@subsection uhood_tech_inside_config Extra configuration - -The default build configuration of SimGrid fits the user needs, but -they are not adapted to the ones actually working on SimGrid. See @ref -install_src_config for more information. Note that this is very -different from runtime configuration. - -In particular, the build is configured by default to produce highly -optimized binaries, at the price of high compilation time. The -rationale is that users will compile SimGrid only once, and use it many -times. This is exactly the contrary for the insiders, so you want to -turn off \b enable_compile_optimizations. - -Symmetrically, \b enable_compile_warnings is off for the users because -we don't want to bother them with compiler warnings (that abort the -build in SimGrid), but any insider must turn this option on, or your -code will be refused from the main repository. - -@verbatim - cmake -Denable_compile_optimizations=OFF \ - -Denable_compile_warnings=ON . -@endverbatim - -@subsection uhood_tech_inside_commit Interacting with git - -During the Gran Refactoring to SimGrid4, things are evolving rather -quickly, and some changes impact a large amount of files. You should -thus not have long-standing branches, because they will rot very -quickly and you will suffer to merge them back. Instead, you should -work as much as possible with incremental changes that do not break -things, and get them directly in master. - -Your commit message should follow the git habits, explained in this -blog -post, or in the - -git styleguide of Atom. - - -@subsection uhood_tech_inside_codstand Automatically Enforcing our Coding Standards - -If you plan to commit code to the SimGrid project, you definitely need -to install the relevant tool to ensure that your changes follow our -coding standards: - -@verbatim -# install clang-format -sudo apt-get install clang-format-3.9 # debian - -# tell git to call the script on each commit -ln -s $(realpath tools/git-hooks/clang-format.pre-commit) .git/hooks/pre-commit -@endverbatim - -This will add an extra verification before integrating any commit that -you could prepare. If your code does not respects our formatting code, -git will say so, and provide a ready to use patch that you can apply -to improve your commit. Just carefully read the error message you get -to find the exact command with git-apply to fix your formatting. - -If you find that for a specific commit, the formatter does a very bad -job, then add --no-verify to your git commit command line. - -@subsection uhood_tech_tricks Random Tricks - -Over the years, we accumulated a few tricks that make it easier to -work with SimGrid. Here is a somewhat unsorted list of such tricks. - -### Easy testing - -Launching all tests can be very time consuming, so you want to build -and run the tests in parallel. Also, you want to save the build output -to disk, for further reference. This is exactly what the -BuildSimGrid.sh script does. It is upper-cased so that the shell -completion works and allows one to run it in 4 key press: `./B` - -Note that if you build out of tree (as you should, see below), the -script builds the build/default directory. I usually copy the file in -each build/ subdir to test each of them separately. - -### Easy out of tree builds - -It is easy to break one build configuration or another. That's -perfectly OK and we will not point fingers if it happens. But it is -somewhat forbidden to leave the tree broken for more than one working -day. Monitor the build daemons after you push something, and strive to -fix any breakage ASAP. - -To easily switch between the configs without rebuilding everything, -create a set of out of tree builds (as explained in @ref -install_cmake_outsrc) in addition to your main build tree. -To not mess with git, you want to put your build tree under the build/ -directory, which is ignored by git. For example, I have the following -directories: build/clang build/java build/full -(but YMMV). - -Then, the problem is that when you traverse these directories, you -cannot edit the sources (that are in the srcdir, while you're in -bindir). This makes it difficult to launch the tests and everything. - -To solve that issue, just call `make hardlinks` from your build dir. -This will create hard links allowing to share every source files into -the build dir. They are not copied, but hard linked. It means that -each file is accessible under several names, from the srcdir and from -the bindirs. If you edit a source file found under bindir, the srcdir -version (visible to git) will also be changed (that's the same file, -after all). - -Note that the links sometimes broken by git or others. Relaunching -`make hardlinks` may help if you're getting incoherent build results. - -### Unsorted hints - -* If you want to debug memory allocation problems, here are a few hints: - - disable compiler optimizations, to have better backtraces; - - disable the mallocators, or it will be hard to match malloc's with free's; - - disable model checking, unless your problem lies in the model - checker part of SimGrid (MC brings its own malloc implementation, - which valgrind does not really love). - All this is configured with: - - cmake -Denable_model-checking=OFF - -Denable_mallocators=OFF - -Denable_compile_optimizations=OFF . - -* If you break the logs, you want to define XBT_LOG_MAYDAY at the - beginning of log.h. It deactivates the whole logging mechanism, - switching to printfs instead. SimGrid becomes incredibly verbose - when doing so, but it you let you fixing things. - - -*/ diff --git a/doc/doxygen/inside_cmake.doc b/doc/doxygen/inside_cmake.doc deleted file mode 100644 index 25dbb36be9..0000000000 --- a/doc/doxygen/inside_cmake.doc +++ /dev/null @@ -1,40 +0,0 @@ -/*! -@page inside_cmake Adding source files or examples - -@tableofcontents - -SimGrid uses CMake which is a family of tools designed to build, test, and package software. - -@section inside_cmake_addsrc How to add source files? - -If you want to rename, add, or delete source file(s) in the SimGrid distribution, you have to edit the -tools/cmake/DefinePackages.cmake configuration file. Files are organized in sections, then find -the section you are interested in and modify it. - -Once you're done, test your changes with ``make distcheck``. - -@section inside_cmake_examples How to add an example? - -The first rule is that the content of examples/ must be interesting to the users. It is expected that the users will -take one of these examples and start editing it to make it fit their needs. So, it should be self-contained, -informative, and should use only the public APIs. - -To ensure that all examples actually work as expected, every example is also used as an integration test (see -@ref inside_tests), but you should still strive to keep the code under examples/ as informative as possible for the -users. In particular, torture test cases should be placed in teshsuite/, not examples/, so that the users don't stumble -upon them by error. - -The examples/ directory is organized as follows: - - examples/cpp/ for examples using the S4U API - - examples/smpi/ or examples using the SMPI API - - examples/platforms/ only contains platforms descriptions in the XML format (see @ref platform for details) - - examples/deprecated/java/ for examples using the Java bindings to the MSG API. This directory contains packages (app, async, - cloud, ...) which in turn contain individual examples. If your new example fits in an existing package, add it here, - or create a new package otherwise. - -In each of these directories, there is a CMakeLists.txt file that has -to be edited to include the new examples. - -Once you're done, test your changes with ``make distcheck``. - -*/ diff --git a/doc/doxygen/inside_extending.doc b/doc/doxygen/inside_extending.doc index 24c8e8d6a3..dfd7e5784a 100644 --- a/doc/doxygen/inside_extending.doc +++ b/doc/doxygen/inside_extending.doc @@ -3,64 +3,7 @@ @tableofcontents -@section simgrid_dev_guide_simcall How to add a new simcall? - -First of all you might want to avoid defining a new simcall if possible: -@ref simgrid_dev_guide_generic_simcall. - -A simcall is used to go from user mode to kernel mode. There is some -sort of popping dance involved, as we want to isolate the user -contextes from their environment (so that they can run in parallel and -so that we can model-check them). - -In short, just add a line to src/simix/simcalls.in and run the -src/simix/simcalls.py script. It will guide you about how to implement -your simcall. Please keep reading this section (only) if you want to -understand how it goes. - - -The workflow of a simcall is the following: - -- ` simcall_()` - - `simcall_BODY_()` - - Initializes the simcall (store the arguments in position) - - If maestro, executes the simcall directly (and return) - - If not, call `ActorImpl::yield` to give back the control to maestro - - ========== KERNEL MODE ========== - - `ActorImpl::simcall_handle` large switch (on simcall) doing for each: - - `simcall_HANDLER_(simcall, )` (the manual code handling the simcall) - - If the simcall is not marked as "blocking" in its definition, - call `ActorImpl::simcall_answer()` that adds back the issuer - process to the list of processes to run in the next scheduling round. - It is thus the responsibility of the blocking simcalls to call - `ActorImpl::simcall_answer()` themselves in their handler. - -Note that empty HANDLERs can be omitted. These functions usually do -some parameter checking, or retrieve some information about the -simcall issuer, but when there no need for such things, the handler -can be omitted. In that case, we directly call the function -`simcall_()`. - -To simplify the simcall creation, a python script generates most of -the code and give helpers for the remaining stuff. That script reads -the simcall definitions from src/simix/simcalls.in, checks that both -`simcall_()` and `simcall_HANDLER()` are defined somewhere, and -generates the following files: - -- popping_accessors.hpp: - Helper functions to get and set simcall arguments and results -- popping_bodies.cpp: - The BODY function of each simcall -- popping_enum.hpp: - Definition of type `enum class Simcall` (one value per existing simcall) -- popping_generated.cpp: - Definitions of `simcall_names[]` (debug name of each simcall), and - ActorImpl::simcall_handle() that deals with the simcall from within the kernel - -The simcall.in file list all the simcalls in sections. A line starting by "##" -define a new section which will be replace by a "ifdef" in the generated code. - -@section simgrid_dev_guide_generic_simcall How to avoid adding a new simcall? +@section simgrid_dev_guide_generic_simcall The modern SimCall interface We now have some generic simcalls which can be used to interface with the Maestro without creating new simcalls. You might want to use them instead of @@ -139,9 +82,4 @@ catch (std::runtime_error& e) { Note: `kernel_sync(f)` could be implemented as `kernel_async(f).get()`. -@section simgrid_dev_guide_tag What is How to add a new tag for xml files? - -You should not do something like that. Please work instead to make XML -avoidable, ie to make the C++ interface nice and usable. - */ diff --git a/doc/doxygen/inside_release.doc b/doc/doxygen/inside_release.doc index 1620515cca..d7e84f0e91 100644 --- a/doc/doxygen/inside_release.doc +++ b/doc/doxygen/inside_release.doc @@ -14,7 +14,6 @@ Please apply the following checklist before releasing. - ChangeLog file - All changes are documented - The release date is indicated below the changes - - The release is marked as stable above the changes (remove the UNRELEASED marker) - The release dub name matches the one given in NEWS file - NEWS - The most notable changes of the version are documented @@ -26,22 +25,22 @@ Please apply the following checklist before releasing. - The date of the release is marked in the title - Tests - The "make distcheck" target works (tested by jenkins) - - All tests pass on everything on ci + AppVeyor + - All tests pass on everything on ci - Tutorials and derivative projects build correctly https://framagit.org/simgrid/simgrid-template-s4u/pipelines https://framagit.org/simgrid/external-projects-ci/pipelines - The python module builds (see below). - - The java jarfile builds from the github action @subsection inside_release_c_releasing Actually releasing SimGrid - Update the version number in: + - ChangeLog header - CMakeLists.txt (in macros SIMGRID_VERSION_*) - sonar-project.properties - docs/source/conf.py - setup.py - Commit and push to both framagit and github -- Wait for both appveyor and jenkins/osX to complete the build +- Wait for jenkins/osX to complete the build - If it's not successful, fix it and push again - Once it's successful everywhere: merge 'master' into 'stable' and push it to framagit - You can interrupt the build on jenkins, as it was tested just before @@ -49,14 +48,13 @@ Please apply the following checklist before releasing. - Download the simgrid-doc-3.X.Y (artefact of pipeline 'pages' on framagit) Download the tgz file (artefact of the pipeline 'stable' on framagit) - Build the jar file using the github action - Tag the git repository v3.XX.X and push it to framagit and ghub - Document the tag on framagit and ghub - - Upload the files simgrid-3.XX.tar.gz, simgrid-3_XX.jar and simgrid-doc-3_XX.zip + - Upload the files simgrid-3.XX.tar.gz and simgrid-doc-3_XX.zip - Add a link to the version of the ChangeLog that comes with this tag. - https://framagit.org/simgrid/simgrid/-/blob/v3.29/ChangeLog + https://framagit.org/simgrid/simgrid/-/blob/v3.35/ChangeLog - Update the website - - emacs org/org-templates/level-0.org to change the release version, the tgz link and the jar link. + - emacs org/org-templates/level-0.org to change the release version and the tgz link. - jed .gitlab-ci.yml - Change the link to the simgrid-doc-3_XX.zip file - Only keep 2 old versions so that people don't find older ones in google @@ -69,7 +67,7 @@ Please apply the following checklist before releasing. rm -rf /tmp/pysimgrid && mkdir /tmp/pysimgrid && cp dist/simgrid-*.tar.gz /tmp/pysimgrid (cd /tmp/pysimgrid && tar xfz simgrid*.tar.gz && cd simgrid-*/ && python3 setup.py build) - Upload it to pypi (WARNING: you cannot modify uploaded files, ever) - twine upload dist/simgrid-*.tar.gz + twine upload dist/simgrid-*.tar.gz # User and password should be located in ~/.pypirc @subsection inside_release_c_publishing Publishing the release if it's a stable one (3.XX not 3.XX.Y) @@ -81,15 +79,17 @@ Please apply the following checklist before releasing. - Link to the ChangeLog on framagit (the version of that tag) - Also mail some other lists (G5K users) - Release the debian package - - rm -f ../simgrid_3.*+dfsg.orig.tar.xz + - rm -f ../simgrid_3.*.orig.tar.xz - uscan # download the new version - - gbp import-orig ../simgrid_3.*+dfsg.orig.tar.xz + - gbp import-orig ../simgrid_3.*.orig.tar.xz - dch -i "New upstream release" # + copy the NEWS into debian/changelog - git mv debian/libsimgrid3.XX.install debian/libsimgrid3.XY.install - edit debian/control: s/simgrid3.XX/simgrid3.XY/ - Update the simgrid/package.py for spack: https://gitlab.inria.fr/solverstack/spack-repo - Push the stable branch to github to rebuild and push the stable Docker images - - It downloads the latest tag on framagit + - It downloads the latest tag on framagit, but sometimes gets out of synch. + Make sure that it's really the latest stable, as it sometimes rebuilds the previous release. + If this happens, just rerun the docker-stable action. Nothing should get hurt by the rebuild. - Doing the same manually: cd tools/docker && make stable && make tuto-s4u tuto-smpi (tuto-mc is not based on simgrid/stable but rebuilds from the git) - Once the new images are built, trigger a rebuild of the simgrid-template-{s4u,smpi} repositories on framagit @@ -114,11 +114,11 @@ Release numbering semantic: - We have 4 named releases per year (for each equinox and solstice) - The ChangeLog and NEWS are complete and informative - All tests pass on all ci systems (or the workarounds are documented) - - We provide and store a source .tar.gz and a full jarfile on framagit + - We provide and store a source .tar.gz on framagit - Deprecated symbols remain usable for at least 3 named releases (~1 year) - These releases are announced to the users - 3.X.Y where Y is even: dot release of 3.X, prerelease of 3.(X+1) - - We provide and store a source .tar.gz and a full jarfile on framagit + - We provide and store a source .tar.gz on framagit - These releases are NOT announced publicly, nor really documented. The idea is to have something close to a rolling release. - External projects can depend on dot releases to loosen their diff --git a/doc/doxygen/inside_tests.doc b/doc/doxygen/inside_tests.doc deleted file mode 100644 index abda87d5b5..0000000000 --- a/doc/doxygen/inside_tests.doc +++ /dev/null @@ -1,239 +0,0 @@ -/*! -@page inside_tests Testing SimGrid - -This page will teach you how to run the tests, selecting the ones you -want, and how to add new tests to the archive. - -@tableofcontents - -SimGrid code coverage is usually between 70% and 80%, which is much -more than most projects out there. This is because we consider SimGrid -to be a rather complex project, and we want to modify it with less fear. - -We have two sets of tests in SimGrid: Each of the 10,000+ unit tests -check one specific case for one specific function, while the 500+ -integration tests run a given simulation specifically intended to -exercise a larger amount of functions together. Every example provided -in examples/ is used as an integration test, while some other torture -tests and corner cases integration tests are located in teshsuite/. -For each integration test, we ensure that the output exactly matches -the defined expectations. Since SimGrid displays the timestamp of -every logged line, this ensures that every change of the models' -prediction will be noticed. All these tests should ensure that SimGrid -is safe to use and to depend on. - -@section inside_tests_runintegration Running the tests - -Running the tests is done using the ctest binary that comes with -cmake. These tests are run for every commit and the result is publicly -available. - -@verbatim -ctest # Launch all tests -ctest -R msg # Launch only the tests which name match the string "msg" -ctest -j4 # Launch all tests in parallel, at most 4 at the same time -ctest --verbose # Display all details on what's going on -ctest --output-on-failure # Only get verbose for the tests that fail - -ctest -R msg- -j5 --output-on-failure # You changed MSG and want to check that you didn't break anything, huh? - # That's fine, I do so all the time myself. -@endverbatim - -@section inside_tests_rununit Running the unit tests - -All unit tests are packed into the unit-tests binary, that lives at the -source root. These tests are run when you launch ctest, don't worry. - -@verbatim -make unit-tests # Rebuild the test runner on need -./unit-tests # Launch all tests -./unit-tests --help # revise how it goes if you forgot -@endverbatim - - -@section inside_tests_add_units Adding unit tests - -Our unit tests are written using the Catch2 library, that is included -in the source tree. Please check for examples, listed at the end of -tools/cmake/Tests.cmake. - -It is important to keep your tests fast. We run them very very often, -and you should strive to make them as fast as possible, to not bother -the other developers. Do not hesitate to stress test your code, but -make sure that it runs reasonably fast, or nobody will run "ctest" -before committing code. - -@section inside_tests_add_integration Adding integration tests - -TESH (the TEsting SHell) is the test runner that we wrote for our -integration tests. It is distributed with the SimGrid source file, and -even comes with a man page. TESH ensures that the output produced by a -command perfectly matches the expected output. This is very precious -to ensure that no change modifies the timings computed by the models -without notice. - -To add a new integration test, you thus have 3 things to do: - - - Write the code exercising the feature you target. You should - strive to make this code clear, well documented and informative for - the users. If you manage to do so, put this somewhere under - examples/ and modify the cmake files as explained on this page: - @ref inside_cmake_examples. If you feel like you should write a - torture test that is not interesting to the users (because nobody - would sanely write something similar in user code), then put it under - teshsuite/ somewhere. - - - Write the tesh file, containing the command to run, the - provided input (if any, but almost no SimGrid test provide such an - input) and the expected output. Check the tesh man page for more - details.@n - Tesh is sometimes annoying as you have to ensure that the expected - output will always be exactly the same. In particular, your should - not output machine dependent information such as absolute data - path, nor memory addresses as they would change on each run. Several - steps can be used here, such as the obfucation of the memory - addresses unless the verbose logs are displayed (using the - #XBT_LOG_ISENABLED() macro), or the modification of the log formats - to hide the timings when they depend on the host machine.@n - The script located in /tools/tesh/generate_tesh can - help you a lot in particular if the output is large (though a smaller output is preferable). - There are also example tesh files in the /tools/tesh/ directory, that can be useful to understand the tesh syntax. - - - Add your test in the cmake infrastructure. For that, modify - the following file: - @verbatim - /teshsuite//CMakeLists.txt - @endverbatim - Make sure to pick a wise name for your test. It is often useful to - check a category of tests together. The only way to do so in ctest - is to use the -R argument that specifies a regular expression that - the test names must match. For example, you can run all MSG test - with "ctest -R msg". That explains the importance of the test - names. - -Once the name is chosen, create a new test by adding a line similar to -the following (assuming that you use tesh as expected). - -@verbatim -# Usage: ADD_TEST(test-name ${CMAKE_BINARY_DIR}/bin/tesh ) -# option --setenv bindir set the directory containing the binary -# --setenv srcdir set the directory containing the source file -# --cd set the working directory -ADD_TEST(my-test-name ${CMAKE_BINARY_DIR}/bin/tesh - --setenv bindir=${CMAKE_BINARY_DIR}/examples/my-test/ - --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/my-test/ - --cd ${CMAKE_HOME_DIRECTORY}/examples/my-test/ - ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/io/io.tesh -) -@endverbatim - -As usual, you must run "make distcheck" after modifying the cmake files, -to ensure that you did not forget any files in the distributed archive. - -@section inside_tests_ci Continuous Integration - -We use several systems to automatically test SimGrid with a large set -of parameters, across as many platforms as possible. -We use Jenkins on Inria -servers as a workhorse: it runs all of our tests for many -configurations. It takes a long time to answer, and it often reports -issues but when it's green, then you know that SimGrid is very fit! -We use AppVeyor -to build and somehow test SimGrid on windows. - -@subsection inside_tests_jenkins Jenkins on the Inria CI servers - -You should not have to change the configuration of the Jenkins tool -yourself, although you could have to change the slaves' configuration -using the CI interface of INRIA -- -refer to the CI documentation. - -The result can be seen here: https://ci.inria.fr/simgrid/ - -We have 2 interesting projects on Jenkins: -@li SimGrid - is the main project, running the tests that we spoke about.@n It is - configured (on Jenkins) to run the script tools/jenkins/build.sh -@li SimGrid-DynamicAnalysis - should be called "nightly" because it does not only run dynamic - tests, but a whole bunch of long lasting tests: valgrind (memory - errors), gcovr (coverage), Sanitizers (bad pointer usage, threading - errors, use of unspecified C constructs) and the clang static analyzer.@n It is configured - (on Jenkins) to run the script tools/jenkins/DynamicAnalysis.sh - -In each case, SimGrid gets built in -/builds/workspace/$PROJECT/build_mode/$CONFIG/label/$SERVER/build -with $PROJECT being for instance "SimGrid", $CONFIG "DEBUG" or -"ModelChecker" and $SERVER for instance "simgrid-fedora20-64-clang". - -If some configurations are known to fail on some systems (such as -model-checking on non-linux systems), go to your Project and click on -"Configuration". There, find the field "combination filter" (if your -interface language is English) and tick the checkbox; then add a -groovy-expression to disable a specific configuration. For example, in -order to disable the "ModelChecker" build on host -"small-netbsd-64-clang", use: - -@verbatim -(label=="small-netbsd-64-clang").implies(build_mode!="ModelChecker") -@endverbatim - -Just for the record, the slaves were created from the available -template with the following commands: -@verbatim -#debian/ubuntu -apt-get install gcc g++ gfortran automake cmake libboost-dev openjdk-8-jdk openjdk-8-jre libxslt-dev libxml2-dev libevent-dev libunwind-dev libdw-dev htop git python3 xsltproc libboost-context-dev -#for dynamicanalysis: -apt-get install jacoco libjacoco-java libns3-dev pcregrep gcovr ant sloccount - -#fedora -dnf install libboost-devel openjdk-8-jdk openjdk-8-jre libxslt-devel libxml2-devel xsltproc git python3 libdw-devel libevent-devel libunwind-devel htop - -#netbsd -pkg_add cmake gcc7 boost boost-headers automake openjdk8 libxslt libxml2 libunwind git htop python36 - -#opensuse -zypper install cmake automake clang boost-devel java-1_8_0-openjdk-devel libxslt-devel libxml2-devel xsltproc git python3 libdw-devel libevent-devel libunwind-devel htop binutils ggc7-fortran - -#freebsd -pkg install boost-libs cmake openjdk8 automake libxslt libxml2 libunwind git htop python3 automake gcc6 flang elfutils libevent -#+ clang-devel from ports - -#osx -brew install cmake boost libunwind-headers libxslt git python3 -@endverbatim - -@subsection inside_tests_appveyor AppVeyor - -Our configuration is in the file appveyor.yml as it should -be, and the result is here: https://ci.appveyor.com/project/mquinson/simgrid - -We use @c Choco as a package manager on AppVeyor, and it is sufficient -for us. In the future, we will probably move to the ubuntu subsystem -of Windows 10: SimGrid performs very well under these settings, as -tested on Inria's CI servers. For the time being having a native -library is still useful for the Java users that don't want to install -anything beyond Java on their windows. - -@subsection inside_tests_debian Debian builders - -Since SimGrid is packaged in Debian, we benefit from their huge -testing infrastructure. That's an interesting torture test for our -code base. The downside is that it's only for the released versions of -SimGrid. That is why the Debian build does not stop when the tests -fail: post-releases fixes do not fit well in our workflow and we fix -only the most important breakages. - -The build results are here: -https://buildd.debian.org/status/package.php?p=simgrid - -@subsection inside_tests_sonarqube SonarQube - -SonarQube is an open-source code quality analysis solution. Their nice -code scanners are provided as plugin. The one for C++ is not free, but -open-source project can use it at no cost. That is what we are doing. - -Don't miss the great looking dashboard here: -https://sonarcloud.io/dashboard?id=simgrid_simgrid - -*/ diff --git a/doc/doxygen/module-index.doc b/doc/doxygen/module-index.doc deleted file mode 100644 index 0f252d6d61..0000000000 --- a/doc/doxygen/module-index.doc +++ /dev/null @@ -1,101 +0,0 @@ -/** -@defgroup XBT_API XBT: SimGrid core toolbox -@brief The core toolbox of SimGrid, containing useful datatypes and friends -*/ - -/** -@defgroup TRACE_API TRACING -@brief Gather data about your simulation for later analysis - -SimGrid can trace the resource (of hosts and links) utilization using -any of its programming interfaces (MSG, SimDAG and SMPI). This means -that the tracing will register how much power is used for each host -and how much bandwidth is used for each link of the platform. - -The idea of the tracing facilities is to give SimGrid users to -possibility to classify MSG and SimDAG tasks by category, tracing the -platform utilization (hosts and links) for each of the categories. -The API enables the declaration of categories and a function to -associate them to the tasks (MSG and SD). The tasks that are not -classified according to a category are not traced. If no categories -are specified, simulations can still be traced using a special -parameter in the command line (see @ref outcomes_vizu for details). -*/ - -/** @defgroup ROUTING_API Routing: Determining the communication paths - @brief Organize the platform to determine the links used by each communication - -@section routing_basics Basic Concepts - -The purpose of the simgrid::kernel::routing module is to retrieve the -routing path between two points in a time- and space-efficient manner. -Indeed, the network model needs both the list of links that the convey -the created communication, and the summed latency that these links -represent. This operation is clearly on the critical path of most -SimGrid simulations. - -When defining how the information is routed in the simulated network, -it is certainly very tempting to use a formalism somehow similar to -how it is defined on real network. One would have to define the -routing tables of each routers interconnections sub-networks, just -like in the real life. Given the daunting amount of configuration -required, we could complete the information given by the user with -classical protocols such as BGP and RIP. Many network simulator take -such configuration as an input, for good reasons. - -This is not the way it goes in SimGrid: the network routing is defined -in a global and compact way instead. This eases the modeling of very -large systems, and allows highly optimized datastructures and -algorithms in the simulator. The proposed description mechanism is -thus much more convenient and efficient. In addition, it is more -expressive than the classical solution based on forwarding tables on -each host and router. - -The price to pay is that this representation of networks is very -specific to SimGrid, so you will have to read further to understand -it, even if you already know how real networks work. - -The central notion here are @b Networking @b Zones. NetZones represent -network areas in which the routing is done in an homogeneous way. -Conceptually, netzones generalize from the ideas of local networks -(such as Ethernet switched networks) and Autonomous System. The -network as a whole is represented as a single hierarchy of netzones, -meaning that every netzone is part of another netzone (but the @c -NetRoot, which is the top-level netzone). - -The main goal of the routing module is to provide a list of links -traversed by a given communication and/or a latency to apply. These -information are then used by the network model to compute the time -that this communication takes. This information is retrieved by three -combined algorithms: intra-zone routing, inter-zone routing, and the -bypass mechanism. - -The intra-zone level is naturally handled by the netzones. Each -netzone have to specify the routing algorithm it uses for that. -@ref simgrid::kernel::routing::FullZone "FullZone" netzones have complete matrix where matrix(a,b) -represents the full path (the list of links) between the hosts a and -b. @ref simgrid::kernel::routing::FloydZone "FloydZone" apply the Floyd-Warshall algorithm to compute the -paths. @ref simgrid::kernel::routing::ClusterZone "ClusterZone" model classical switched or hub networks, -where each component is connected through a private link onto a common -backbone. Many other routing algorithms are provided to model the -classical needs, but you can naturally define your own routing if the -provided ones do not fit your needs. - -The inter-zone algorithm is used when the communication -traverses more than one zone. The overall path goes from the source up -in the netzones' tree, until the first common ancestor zone, and moves -down to the destination. It crawls the differing netzones on its path -according to the user-defined inter-zone routes, moving from gateway -to gateway. - -You can also use the bypass mechanism to specify manually some -shortcuts that directly provide the list of links interconnecting two -given processes. - -@section routing_declaring Declaring a platform - -For now, you can only declare a platform from an XML file, but we are -working to make it possible from the C++ code (or even from bindings -in other languages). Until then, please head to @ref platform. - -*/ diff --git a/doc/doxygen/module-surf.doc b/doc/doxygen/module-surf.doc deleted file mode 100644 index 32d997f76b..0000000000 --- a/doc/doxygen/module-surf.doc +++ /dev/null @@ -1,46 +0,0 @@ -/** @defgroup SURF_build_api Create a new API - @ingroup SURF_API - @brief How to build a new API on top of SURF - - SURF provides the functionalities to simulate the platform. There are two main data types in SURF: - the actions and the resources. Several types of resources exist: - - the host resource, - - the network resource, - - the CPU resource, - - the timer resource. - - The implementation of these resources depends on the platform - models you choose. You can select your model by calling - #surf_host_model_init_current_default() (which will give you a - CLM03 model), or similar (see @ref SURF_models). - - To initialize SURF, call - #surf_host_model_init_current_default() or #surf_host_model_init_ptask_L07() - to create the platform. - - Then you can access the hosts with the @ref simgrid::s4u::Engine::get_all_hosts. - Some functions of the @ref SURF_host_interface and similar can give - you some information about: - - a host: get_speed(), get_available_speed(); - - a network link: get_link_name(), get_link_latency(), get_link_bandwidth(); - - a route: get_route(), get_route_size(). - - During the simulation, call @a surf_host_model->execute() to schedule a - computation task on a host, or @a surf_host_model->communicate() - to schedule a communication task between two hosts. You can also create parallel task - with @a surf_host_model->extension_public->execute_parallel_task(). These functions return - a new action that represents the task you have just created. - - To execute the actions created with @a execute(), @a communicate() or @a execute_parallel_task(), call - EngineImpl::solve(). This function is where the simulation takes place. It returns the - time elapsed to execute the actions. You can know what actions have changed their state thanks - to the states sets. For example, if your want to know what actions are finished, - extract them from @a surf_host_model->common_public->states.done_action_set. - Depending on these results, you can schedule other tasks and call solve() again. - - Have a look at the implementation of @ref MSG_API "MSG" and @ref SD_API "Simdag" to see how these module - interact with SURF. But if you want to create a new API on top of SURF, - we strongly recommend you to contact us before anyway. - -*/ - diff --git a/doc/doxygen/outcomes_vizu.doc b/doc/doxygen/outcomes_vizu.doc index f97248b8ba..b4fb66faf4 100644 --- a/doc/doxygen/outcomes_vizu.doc +++ b/doc/doxygen/outcomes_vizu.doc @@ -1,3 +1,22 @@ +/** +@defgroup TRACE_API TRACING +@brief Gather data about your simulation for later analysis + +SimGrid can trace the resource (of hosts and links) utilization using +any of its programming interfaces (S4U, SimDAG and SMPI). This means +that the tracing will register how much power is used for each host +and how much bandwidth is used for each link of the platform. + +The idea of the tracing facilities is to give SimGrid users to +possibility to classify S4U and SimDAG tasks by category, tracing the +platform utilization (hosts and links) for each of the categories. +The API enables the declaration of categories and a function to +associate them to the tasks (S4U and SD). The tasks that are not +classified according to a category are not traced. If no categories +are specified, simulations can still be traced using a special +parameter in the command line (see @ref outcomes_vizu for details). +*/ + /*! @page outcomes_vizu Visualization and Statistical Analysis SimGrid comes with an extensive support to trace and register what @@ -335,7 +354,7 @@ you should use to analyze your simulator. @li I want to trace the resource utilization of all hosts and links of the platform, and my simulator does not use the tracing API. For that, you can run a uncategorized trace -with the following parameters (it will work with any Simgrid +with the following parameters (it will work with any SimGrid simulator): @verbatim ./your_simulator @ diff --git a/doc/doxygen/platform.doc b/doc/doxygen/platform.doc deleted file mode 100644 index 83c8aab609..0000000000 --- a/doc/doxygen/platform.doc +++ /dev/null @@ -1,538 +0,0 @@ -/*! @page platform Describing the virtual platform - - -@section pf_res Resource description - -@subsection pf_res_computing Computing Resources - -@subsubsection pf_cabinet <cabinet> - -@note - This tag is only available when the routing mode of the network zone - is set to ``Cluster``. - -The ``<cabinet />`` tag is, like the @ref pf_tag_cluster "<cluster>" tag, -a meta-tag. This means that it is simply a shortcut for creating a set of (homogeneous) hosts and links quickly; -unsurprisingly, this tag was introduced to setup cabinets in data centers quickly. Unlike -<cluster>, however, the <cabinet> assumes that you create the backbone -and routers yourself; see our examples below. - -#### Attributes #### - -Attribute name | Mandatory | Values | Description ---------------- | --------- | ------ | ----------- -id | yes | string | The identifier of the cabinet. Facilitates referring to this cluster. -prefix | yes | string | Each node of the cabinet has to have a name. This name will be prefixed with this prefix. -suffix | yes | string | Each node of the cabinet will be suffixed with this suffix -radical | yes | string | Regexp used to generate cabinet nodes name. Syntax: "10-20" will give you 11 machines numbered from 10 to 20, "10-20;2" will give you 12 machines, one with the number 2, others numbered as before. The produced number is concatenated between prefix and suffix to form machine names. -speed | yes | int | Same as the ``speed`` attribute of the @ref pf_tag_host "<host>" tag. -bw | yes | int | Bandwidth for the links between nodes and backbone (if any). See the @ref pf_tag_link "link section" for syntax/details. -lat | yes | int | Latency for the links between nodes and backbone (if any). See the @ref pf_tag_link "link section" for syntax/details. - -@note - Please note that as of now, it is impossible to change attributes such as, - amount of cores (always set to 1), the sharing policy of the links (always set to @ref pf_sharing_policy_splitduplex "SPLITDUPLEX"). - -#### Example #### - -The following example was taken from ``examples/platforms/meta_cluster.xml`` and -shows how to use the cabinet tag. - -@verbatim - - - - - - - -@endverbatim - -@note - Please note that you must specify the @ref pf_backbone "<backbone>" - tag by yourself; this is not done automatically and there are no checks - that ensure this backbone was defined. - -The hosts generated in the above example are named host-1.cluster, host-2.cluster1 -etc. - - -@subsection pf_ne Network equipment - -There are two tags at all times available to represent network entities and -several other tags that are available only in certain contexts. -1. ````: - - -3. ````: This tag is only available when the containing network zone is - used as a cluster (i.e., mode="Cluster") - -@remark - If you want to represent an entity like a switch, you must use ```` (see section). Routers are used - to run some routing algorithm and determine routes (see Section @ref pf_routing for details). - -@subsubsection pf_backbone - -@note - This tag is only available when the containing network zone uses the "Cluster" routing mode! - -Using this tag, you can designate an already existing link to be a backbone. - -Attribute name | Mandatory | Values | Description ---------------- | --------- | ------ | ----------- -id | yes | string | Name of the link that is supposed to act as a backbone. - - - -@section pf_routing Routing - - -@subsubsection pf_routing_model_simple Simple/fast models - -| Name | Description | -| ---------------------------------------- | ------------------------------------------------------------------------------ | -| @ref pf_routing_model_cluster "Cluster" | This is specific to the @ref pf_tag_cluster "<cluster/>" tag and should not be used by the user, as several assumptions are made. | -| @ref pf_routing_model_none "None" | No routing at all. Unless you know what you're doing, avoid using this mode in combination with a non-constant network model. | -| @ref pf_routing_model_vivaldi "Vivaldi" | Perfect when you want to use coordinates. Also see the corresponding @ref pf_P2P_tags "P2P section" below. | - -@anchor pf_routing_model_cluster -### Cluster ### - -@note - In this mode, the @ref pf_cabinet "<cabinet/>" tag is available. - -#### Example platform files #### - -This is an automatically generated list of example files that use the Cluster -routing model (the path is given relative to SimGrid's source directory): - -@verbinclude example_filelist_routing_cluster - -@anchor pf_routing_model_none - -### None ### - -This model does exactly what it's name advertises: Nothing. There is no routing -available within this model and if you try to communicate within the zone that -uses this model, SimGrid will fail unless you have explicitly activated the -@ref options_model_select_network_constant "Constant Network Model" (this model charges -the same for every single communication). It should -be noted, however, that you can still attach an @ref pf_tag_zoneroute "ZoneRoute", -as is demonstrated in the example below: - -@verbinclude platforms/cluster_and_one_host.xml - -#### Example platform files #### - -This is an automatically generated list of example files that use the None -routing model (the path is given relative to SimGrid's source directory): - -@verbinclude example_filelist_routing_none - - - - -@anchor pf_routing_model_vivaldi -### Vivaldi ### - -For more information on how to use the [Vivaldi Coordinates](https://en.wikipedia.org/wiki/Vivaldi_coordinates), -see also Section @ref pf_P2P_tags "P2P tags". - -Note that it is possible to combine the Vivaldi routing model with other routing models; -an example can be found in the file @c examples/platforms/cloud.xml. This -examples models a NetZone using Vivaldi that contains other NetZones that use different -routing models. - -#### Example platform files #### - -This is an automatically generated list of example files that use the None -routing model (the path is given relative to SimGrid's source directory): - -@verbinclude example_filelist_routing_vivaldi - - -@subsection ps_dec Defining routes - -There are currently four different ways to define routes: - -| Name | Description | -| ------------------------------------------------- | ----------------------------------------------------------------------------------- | -| @ref pf_tag_route "route" | Used to define route between host/router | -| @ref pf_tag_zoneroute "zoneRoute" | Used to define route between different zones | -| @ref pf_tag_bypassroute "bypassRoute" | Used to supersede normal routes as calculated by the network model between host/router; e.g., can be used to use a route that is not the shortest path for any of the shortest-path routing models. | -| @ref pf_tag_bypassasroute "bypassZoneRoute" | Used in the same way as bypassRoute, but for zones | - -Basically all those tags will contain an (ordered) list of references -to link that compose the route you want to define. - -Consider the example below: - -@subsubsection pf_tag_bypassasroute bypasszoneroute - -As said before, once you choose -a model, it (most likely; the constant network model, for example, doesn't) calculates routes for you. But maybe you want to -define some of your routes, which will be specific. You may also want -to bypass some routes defined in lower level zone at an upper stage: -bypasszoneroute is the tag you're looking for. It allows one to -bypass routes defined between already defined between zone (if you want -to bypass route for a specific host, you should just use byPassRoute). -The principle is the same as zoneroute: bypasszoneroute contains -list of links that are in the path between src and dst. - -#### Attributes #### - -| Attribute name | Mandatory | Values | Description | -| --------------- | --------- | ---------------------- | ----------- | -| src | yes | String | The value given to the source zone's "id" attribute | -| dst | yes | String | The value given to the destination zone's "id" attribute. | -| gw_src | yes | String | The value given to the source gateway's "id" attribute; this can be any host or router within the src zone | -| gw_dst | yes | String | The value given to the destination gateway's "id" attribute; this can be any host or router within the dst zone| -| symmetrical | no | YES@| NO (Default: YES) | If this route is symmetric, the opposite route (from dst to src) will also be declared implicitly. | - -#### Example #### - -@verbatim - - - -@endverbatim - -This example shows that link @c link_tmp (definition not displayed here) directly -connects the router @c my_cluster_1_router in the source cluster to the router -@c my_cluster_2_router in the destination router. Additionally, as the @c symmetrical -attribute was not given, this route is presumed to be symmetrical. - -@subsubsection pf_tag_bypassroute bypassRoute - -As said before, once you choose -a model, it (most likely; the constant network model, for example, doesn't) calculates routes for you. But maybe you want to -define some of your routes, which will be specific. You may also want -to bypass some routes defined in lower level zone at an upper stage: -bypassRoute is the tag you're looking for. It allows one to bypass -routes defined between host/router. The principle is the same -as route: bypassRoute contains list of links references of -links that are in the path between src and dst. - -#### Attributes #### - -| Attribute name | Mandatory | Values | Description | -| --------------- | --------- | ---------------------- | ----------- | -| src | yes | String | The value given to the source zone's "id" attribute | -| dst | yes | String | The value given to the destination zone's "id" attribute. | -| symmetrical | no | YES @| NO (Default: YES) | If this route is symmetric, the opposite route (from dst to src) will also be declared implicitly. | - -#### Examples #### - -@verbatim - - - -@endverbatim - -This example shows that link @c link_tmp (definition not displayed here) directly -connects host @c host_1 to host @c host_2. Additionally, as the @c symmetrical -attribute was not given, this route is presumed to be symmetrical. - -@section pf_other Other tags - -The following tags can be used inside a @ tag even if they are not -directly describing the platform: - - - @ref pf_tag_config passes configuration options, e.g. to change the network model; - - @ref pf_tag_prop gives user-defined properties to various elements - -@subsection pf_trace trace and trace_connect - -Both tags are an alternate way to pass files containing information on -availability, state etc. to an entity. (See also @ref howto_churn). -Instead of referring to the file directly in the host, link, or -cluster tag, you proceed by defining a trace with an id corresponding -to a file, later a host/link/cluster, and finally using trace_connect -you say that the file trace must be used by the entity. - - -#### Example #### - -@verbatim - - - - - -@endverbatim - -@note - The order here is important. @c trace_connect must come - after the elements @c trace and @c host, as both the host - and the trace definition must be known when @c trace_connect - is parsed; the order of @c trace and @c host is arbitrary. - - -#### @c trace attributes #### - - -| Attribute name | Mandatory | Values | Description | -| --------------- | --------- | ---------------------- | ----------- | -| id | yes | String | Identifier of this trace; this is the name you pass on to @c trace_connect. | -| file | no | String | Filename of the file that contains the information - the path must follow the style of your OS. You can omit this, but then you must specify the values inside of <trace> and </trace> - see the example below. | -| trace_periodicity | yes | String | This is the same as for @ref pf_tag_host "hosts" (see there for details) | - -Here is an example of trace when no file name is provided: - -@verbatim - - 0.0 1.0 - 11.0 0.5 - 20.0 0.8 - -@endverbatim - -#### @c trace_connect attributes #### - -| Attribute name | Mandatory | Values | Description | -| --------------- | --------- | ---------------------- | ----------- | -| kind | no | HOST_AVAIL@|POWER@|
LINK_AVAIL@|BANDWIDTH@|LATENCY (Default: HOST_AVAIL) | Describes the kind of trace. | -| trace | yes | String | Identifier of the referenced trace (specified of the trace's @c id attribute) | -| element | yes | String | The identifier of the referenced entity as given by its @c id attribute | - -@section pf_hints Hints, tips and frequently requested features - -Now you should know at least the syntax and be able to create a -platform by your own. However, after having ourselves wrote some platforms, there -are some best practices you should pay attention to in order to -produce good platform and some choices you can make in order to have -faster simulations. Here's some hints and tips, then. - -@subsection pf_hints_search Finding the platform example that you need - -Most platform files that we ship are in the @c examples/platforms -folder. The good old @c grep tool can find the examples you need when -wondering on a specific XML tag. Here is an example session searching -for @ref pf_trace "trace_connect": - -@verbatim -% cd examples/platforms -% grep -R -i -n --include="*.xml" "trace_connect" . -./two_hosts_platform_with_availability_included.xml:26: -./two_hosts_platform_with_availability_included.xml:27: -./two_hosts_platform_with_availability_included.xml:28: -./two_hosts.xml:17: -@endverbatim - -@subsection pf_hint_generating How to generate different platform files? - -This is actually a good idea to search for a better platform file, -that better fit the need of your study. To be honest, the provided -examples are not representative of anything. They exemplify our XML -syntax, but that's all. small_platform.xml for example was generated -without much thought beyond that. - -The best thing to do when possible is to write your own platform file, -that model the platform on which you run your code. For that, you -could use our -calibration scripts. This leads to very good fits between the -platform, the model and the needs. The g5k.xml example resulted of -such an effort, which also lead to an -ongoing attempt to automatically extract the SimGrid platform from -the Grid'5000 experimental platform. -But it's hard to come up with generic models. Don't take these files -too seriously. Actually, you should always challenge our models and -your instantiation if the accuracy really matters to you (see this discussion). - -But such advices only hold if you have a real platform and a real -application at hand. It's moot for more abstract studies working on -ideas and algorithms instead of technical artefacts. Well, in this -case, there unfortunately is nothing better than this old and rusty -simulacrum. -This project is dormant since over 10 years (and you will have to -update the generated platforms with bin/simgrid_update_xml to -use them), but that's the best we have for this right now.... - -@subsection pf_zone_h Zone Hierarchy -The network zone design allows SimGrid to go fast, because computing route is -done only for the set of resources defined in the current zone. If you're using -only a big zone containing all resource with no zone into it and you're -using Full model, then ... you'll loose all interest into it. On the -other hand, designing a binary tree of zone with, at the lower level, -only one host, then you'll also loose all the good zone hierarchy can -give you. Remind you should always be "reasonable" in your platform -definition when choosing the hierarchy. A good choice if you try to -describe a real life platform is to follow the zone described in -reality, since this kind of trade-off works well for real life -platforms. - -@subsection pf_exit_zone Exit Zone: why and how -Users that have looked at some of our platforms may have notice a -non-intuitive schema ... Something like that: - - -@verbatim - - - - - - - - - - - - - - - - - - - - - - - -@endverbatim - -In the zone_4, you have an exitzone_4 defined, containing only one router, -and routes defined to that zone from all other zone (as cluster is only a -shortcut for a zone, see cluster description for details). If there was -an upper zone, it would define routes to and from zone_4 with the gateway -router_4. It's just because, as we did not allowed (for performances -issues) to have routes from a zone to a single host/router, you have to -enclose your gateway, when you have zone included in your zone, within a -zone to define routes to it. - -@subsection pf_routing_howto_choose_wisely Choosing wisely the routing model to use - - -Choosing wisely the routing model to use can significantly fasten your -simulation/save your time when writing the platform/save tremendous -disk space. Here is the list of available model and their -characteristics (lookup: time to resolve a route): - -@li Full: Full routing data (fast, large memory requirements, - fully expressive) -@li Floyd: Floyd routing data (slow initialization, fast - lookup, lesser memory requirements, shortest path routing only). - Calculates all routes at once at the beginning. -@li Dijkstra: Dijkstra routing data (fast initialization, slow - lookup, small memory requirements, shortest path routing only). - Calculates a route when necessary. -@li DijkstraCache: Dijkstra routing data (fast initialization, - fast lookup, small memory requirements, shortest path routing - only). Same as Dijkstra, except it handles a cache for latest used - routes. -@li None: No routing (usable with Constant network only). - Defines that there is no routes, so if you try to determine a - route without constant network within this zone, SimGrid will raise - an exception. -@li Vivaldi: Vivaldi routing, so when you want to use coordinates -@li Cluster: Cluster routing, specific to cluster tag, should - not be used. - -@subsection pf_loopback I want to specify the characteristics of the loopback link! - -Each routing model automatically adds a loopback link for each declared host, i.e., -a network route from the host to itself, if no such route is declared in the XML -file. This default link has a bandwidth of 498 Mb/s, a latency of 15 microseconds, -and is not shared among network flows. - -If you want to specify the characteristics of the loopback link for a given host, you -just have to specify a route from this host to itself with the desired characteristics -in the XML file. This will prevent the routing model to add and use the default -loopback link. - -@subsection pf_switch I want to describe a switch but there is no switch tag! - -Actually we did not include switch tag. But when you're trying to -simulate a switch, assuming -fluid bandwidth models are used (which SimGrid uses by default unless -ns-3 or constant network models are activated), the limiting factor is -switch backplane bandwidth. So, essentially, at least from -the simulation perspective, a switch is similar to a -link: some device that is traversed by flows and with some latency and -so,e maximum bandwidth. Thus, you can simply simulate a switch as a -link. Many links -can be connected to this "switch", which is then included in routes just -as a normal link. - - -@subsection pf_multicabinets I want to describe multi-cabinets clusters! - -You have several possibilities, as usual when modeling things. If your -cabinets are homogeneous and the intercabinet network negligible for -your study, you should just create a larger cluster with all hosts at -the same layer. - -In the rare case where your hosts are not homogeneous between the -cabinets, you can create your cluster completely manually. For that, -create an As using the Cluster routing, and then use one -<cabinet> for each cabinet. This cabinet tag can only be used an -As using the Cluster routing schema, and creating - -Be warned that creating a cluster manually from the XML with -<cabinet>, <backbone> and friends is rather tedious. The -easiest way to retrieve some control of your model without diving into -the <cluster> internals is certainly to create one separate -<cluster> per cabinet and interconnect them together. This is -what we did in the G5K example platform for the Graphen cluster. - -@subsection pf_platform_multipath I want to express multipath routing in platform files! - -It is unfortunately impossible to express the fact that there is more -than one routing path between two given hosts. Let's consider the -following platform file: - -@verbatim - - - - - - - - - -@endverbatim - -Although it is perfectly valid, it does not mean that data traveling -from A to C can either go directly (using link 3) or through B (using -links 1 and 2). It simply means that the routing on the graph is not -trivial, and that data do not following the shortest path in number of -hops on this graph. Another way to say it is that there is no implicit -in these routing descriptions. The system will only use the routes you -declare (such as <route src="A" dst="C"><link_ctn -id="3"/></route>), without trying to build new routes by aggregating -the provided ones. - -You are also free to declare platform where the routing is not -symmetrical. For example, add the following to the previous file: - -@verbatim - - - - -@endverbatim - -This makes sure that data from C to A go through B where data from A -to C go directly. Don't worry about realism of such settings since -we've seen ways more weird situation in real settings (in fact, that's -the realism of very regular platforms which is questionable, but -that's another story). - -*/ diff --git a/doc/doxygen/uhood.doc b/doc/doxygen/uhood.doc index 6c5e0ff01e..1d2d163398 100644 --- a/doc/doxygen/uhood.doc +++ b/doc/doxygen/uhood.doc @@ -86,116 +86,6 @@ using ActorPtr = Actor::Ptr; It uses the `simgrid::simix::Process` as an opaque pimple: -~~~ -class Process { -private: - std::atomic_int_fast32_t refcount_ { 1 }; - // The lifetime of the s4u::Actor is bound to the lifetime of the Process: - simgrid::s4u::Actor actor_; -public: - Process() : actor_(this) {} - - // Reference count: - friend void intrusive_ptr_add_ref(Process* process) - { - // Atomic operation! Do not split in two instructions! - auto previous = (process->refcount_)++; - xbt_assert(previous != 0); - (void) previous; - } - friend void intrusive_ptr_release(Process* process) - { - // Atomic operation! Do not split in two instructions! - auto count = --(process->refcount_); - if (count == 0) - delete process; - } - - // [...] -}; - -smx_process_t SIMIX_process_ref(smx_process_t process) -{ - if (process != nullptr) - intrusive_ptr_add_ref(process); - return process; -} - -/** Decrease the refcount for this process */ -void SIMIX_process_unref(smx_process_t process) -{ - if (process != nullptr) - intrusive_ptr_release(process); -} -~~~ - -@section simgrid_uhood_async Asynchronous operations - -@subsection simgrid_uhood_futures Futures - -The `simgrid::kernel::Future` class has been added to SimGrid as an abstraction -to represent asynchronous operations in the SimGrid maestro. Its API is based -on `std::experimental::future` from the [C++ Extensions for Concurrency Technical -Specification](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0159r0.html): - - - `simgrid::kernel::Future` represents the result an asynchronous operations - in the simulation inside the SimGrid maestro/kernel; - - - `simgrid::kernel::Promise` can be used to set the value of an assocaiated - `simgrid::kernel::Future`. - -The expected way to work with `simgrid::kernel::Future` is to add a -completion handler/continuation: - -~~~ -// This code is executed in the maestro context, we cannot block for the result -// to be ready: -simgrid::kernel::Future> result = simgrid::kernel::readFile(file); - -// Add a completion handler: -result.then([file](simgrid::kernel::Future> result) { - // At this point, the operation is complete and we can safely call .get(): - xbt_assert(result.is_ready()); - try { - std::vector data = result.get(); - XBT_DEBUG("Finished reading file %s: length %zu", file.c_str(), data.size()); - } - // If the operation failed, .get() throws an exception: - catch (std::runtime_error& e) { - XBT_ERROR("Could not read file %s", file.c_str()); - } -}); -~~~ - -The SimGrid kernel cannot block so calling `.get()` or `.wait()` on a -`simgrid::kernel::Future` which is not ready will deadlock. In practice, the -simulator detects this and aborts after reporting an error. - -In order to generate your own future, you might need to use a -`simgrid::kernel::Promise`. The promise is a one-way channel which can be -used to set the result of an associated `simgrid::kernel::Future` -(with either `.set_value()` or `.set_exception()`): - -~~~ -simgrid::kernel::Future kernel_wait_until(double date) -{ - auto promise = std::make_shared>(); - auto future = promise->get_future(); - simgrid::simix::Timer::set(date, [promise] { promise->set_value(); }); - return future; -} -~~~ - -Like the experimental futures, we support chaining `.then()` methods with -automatic future unwrapping. -You might want to look at some [tutorial on C++ futures](https://www.youtube.com/watch?v=mPxIegd9J3w&list=PLHTh1InhhwT75gykhs7pqcR_uSiG601oh&index=43) -for more details and examples. Some operations of the proposed experimental -futures are currently not implemented in our futures however such as -`.wait_for()`, `.wait_until()`, -[`shared_future`](http://en.cppreference.com/w/cpp/thread/shared_future), -[`when_any()`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0159r0.html#futures.when_any). - -@subsection simgrid_uhood_timer Timers @section simgrid_uhood_mc Model Checker diff --git a/doc/doxygen/uhood_switch.doc b/doc/doxygen/uhood_switch.doc index dc4036766b..98d55a9c47 100644 --- a/doc/doxygen/uhood_switch.doc +++ b/doc/doxygen/uhood_switch.doc @@ -411,7 +411,7 @@ type and properly handles exceptions: @code{cpp} template -typename std::result_of::type kernelImmediate(F&& code) +typename std::result_of_t kernelImmediate(F&& code) { // If we are in the simulation kernel, we take the fast path and // execute the code directly without simcall @@ -421,7 +421,7 @@ typename std::result_of::type kernelImmediate(F&& code) // If we are in the application, pass the code to the simulation // kernel which executes it for us and reports the result: - typedef typename std::result_of::type R; + typedef typename std::result_of_t R; simgrid::xbt::Result result; simcall_run_kernel([&]{ xbt_assert(SIMIX_is_maestro(), "Not in maestro"); diff --git a/src/simix/simix_network.tla b/doc/simix_network.tla similarity index 99% rename from src/simix/simix_network.tla rename to doc/simix_network.tla index ecd1bcd6a1..7275c929dd 100644 --- a/src/simix/simix_network.tla +++ b/doc/simix_network.tla @@ -1,5 +1,5 @@ ---- MODULE simix_network ---- -(* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. *) +(* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. *) (* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. *) diff --git a/doc/webcruft/Paje_MSG_screenshot.jpg b/doc/webcruft/Paje_MSG_screenshot.jpg deleted file mode 100644 index 96394d8dda..0000000000 Binary files a/doc/webcruft/Paje_MSG_screenshot.jpg and /dev/null differ diff --git a/doc/webcruft/Paje_MSG_screenshot_thn.jpg b/doc/webcruft/Paje_MSG_screenshot_thn.jpg deleted file mode 100644 index 323d6674ee..0000000000 Binary files a/doc/webcruft/Paje_MSG_screenshot_thn.jpg and /dev/null differ diff --git a/doc/webcruft/eclipseScreenShot.png b/doc/webcruft/eclipseScreenShot.png deleted file mode 100644 index 4111737ad6..0000000000 Binary files a/doc/webcruft/eclipseScreenShot.png and /dev/null differ diff --git a/doc/webcruft/output.goal.pdf b/doc/webcruft/output.goal.pdf deleted file mode 100644 index 06e6302410..0000000000 Binary files a/doc/webcruft/output.goal.pdf and /dev/null differ diff --git a/docs/Build.sh b/docs/Build.sh index 1311132a98..8aa516b1c9 100755 --- a/docs/Build.sh +++ b/docs/Build.sh @@ -1,6 +1,6 @@ #! /bin/bash # -# Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -32,35 +32,7 @@ else set +x fi -if [ "x$1" != 'xjava' ] && [ -e source/java ] ; then - echo "javasphinx not rerun: 'java' was not provided as an argument" -else - set -x - rm -rf source/java - - # Use that script without installing javasphinx: javasphinx-apidoc --force -o source/java/ ../src/bindings/java/org/simgrid/msg - PYTHONPATH=${PYTHONPATH}:source/_ext/javasphinx python3 - --force -o source/java/ ../src/bindings/java/org/simgrid/msg <tmp - mv tmp $f - sed -i 's/==/========================/' $f # That's the right length knowing that I add 'class org.simgrid.msg.' - done -# sed -i 's/^.. java:type:: public class /.. java:type:: public class org.simgrid.msg/' source/java/org/simgrid/msg/* - echo "javasphinx relaunched" -fi - -PYTHONPATH=../lib:source/_ext/javasphinx sphinx-build -M html source build ${SPHINXOPTS} 2>&1 +PYTHONPATH=../lib sphinx-build -M html source build ${SPHINXOPTS} 2>&1 set +x @@ -85,7 +57,7 @@ done set +e # Don't fail if [ -e /usr/bin/linkchecker ] ; then - linkchecker --no-status -o csv --ignore-url='.*\.css$' --ignore-url=build/html/_modules --ignore-url=public/java/org build/html \ + linkchecker --no-status -o csv --ignore-url='.*\.css$' --ignore-url=build/html/_modules build/html \ | grep -v '^#' \ | grep -v 'urlname;parentname;baseref;result;warningstring' echo "done." @@ -93,3 +65,5 @@ else echo "Install linkchecker to have it executed when you build the doc." fi +echo "Undocumented symbols:" +./find-missing.py 2>&1 diff --git a/docs/bin/extract_logs_hierarchy.pl b/docs/bin/extract_logs_hierarchy.pl index bccc67fcd3..40c74f8760 100755 --- a/docs/bin/extract_logs_hierarchy.pl +++ b/docs/bin/extract_logs_hierarchy.pl @@ -1,6 +1,6 @@ #!/usr/bin/env perl -# Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -22,7 +22,7 @@ print "This is the list of all categories existing in the SimGrid implementation my %ancestor; my %desc; # $ancestor{"toto"} is the ancestor of the toto channel as declared by XBT_LOG_NEW_SUBCATEGORY and -# XBT_LOG_NEW_DEFAULT_SUBCATEGORY ie, when the channel toto is initialized (does not work under windows) +# XBT_LOG_NEW_DEFAULT_SUBCATEGORY ie, when the channel toto is initialized # $desc{"toto"} is its description diff --git a/docs/default.nix b/docs/default.nix index 7ba4219008..3e2622d164 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -20,7 +20,6 @@ let pythonPackages.sphinx pythonPackages.sphinx_rtd_theme pythonPackages.breathe - javasphinx sphinx-tabs ]; phases = [ "unpackPhase" "buildPhase" "installPhase" ]; @@ -35,37 +34,6 @@ let ''; }; - # sphinx extensions (and their dependencies) shenanigans - javalang = buildPythonPackage rec { - pname = "javalang"; - version = "0.13.0"; - src = pythonPackages.fetchPypi { - inherit pname version; - sha256 = "0k22ldm4xn0sb26qclp5zz0fc9dy589zvvby5ba1d0d5h2jab08n"; - }; - buildInputs = with pythonPackages; [ six ]; - doCheck = false; - }; - - javasphinx = buildPythonPackage rec { - pname = "javasphinx"; - version = "0.9.15+simgrid"; - src = pkgs.fetchFromGitHub { - owner = "simgrid"; - repo = pname; - rev = "659209069603a5f221596dd039e724cb89b31b82"; - sha256 = "1nbz822zd2ikzzmpyqsrrpqvlpng72qvl86wcqfn89szbp85c20a"; - }; - propagatedBuildInputs = with pythonPackages; [ - beautifulsoup4 - docutils - javalang - future - lxml - sphinx - ]; - }; - sphinx-tabs = pythonPackages.buildPythonPackage rec { pname = "sphinx-tabs"; version = "3.1.0"; diff --git a/docs/find-missing.ignore b/docs/find-missing.ignore index 1f263180fd..bd2d73068c 100644 --- a/docs/find-missing.ignore +++ b/docs/find-missing.ignore @@ -20,6 +20,7 @@ It is only used by find-missing, that will not report any definition linked here # These are used to make the C++ objects visible from the C world .. doxygentypedef:: s4u_Actor +.. doxygentypedef:: s4u_ActivitySet .. doxygentypedef:: s4u_Barrier .. doxygentypedef:: s4u_Comm .. doxygentypedef:: s4u_ConditionVariable @@ -33,3 +34,6 @@ It is only used by find-missing, that will not report any definition linked here .. doxygentypedef:: s4u_NetZone .. doxygentypedef:: s4u_Semaphore .. doxygentypedef:: s4u_VM +.. doxygentypedef:: s4u_Activity +.. doxygentypedef:: s4u_ActivitySet +.. doxygentypedef:: s4u_MessageQueue \ No newline at end of file diff --git a/docs/find-missing.py b/docs/find-missing.py index 9ee58b4dbd..ac61890030 100755 --- a/docs/find-missing.py +++ b/docs/find-missing.py @@ -1,7 +1,7 @@ #! /usr/bin/env python3 # -*- coding: utf-8 -*- -# Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -48,7 +48,6 @@ xml_files = [ 'build/xml/host_8h.xml', 'build/xml/link_8h.xml', 'build/xml/mailbox_8h.xml', - 'build/xml/msg_8h.xml', 'build/xml/mutex_8h.xml', 'build/xml/semaphore_8h.xml', 'build/xml/vm_8h.xml', @@ -95,6 +94,9 @@ def handle_python_module(fullname, englobing, elm): elif isinstance(elm, (int, str)): # We do have such a data, directly in the SimGrid top module found_decl("data", fullname) # print('.. autodata:: {}'.format(fullname)) + elif inspect.isclass(type(elm)): # Enum classes are of that kind + found_decl("data", fullname) + #print('.. autodata:: {}'.format(fullname)) elif inspect.ismodule(elm) or inspect.isclass(elm): for name, data in inspect.getmembers(elm): if name.startswith('__'): @@ -102,7 +104,7 @@ def handle_python_module(fullname, englobing, elm): # print("Recurse on {}.{}".format(fullname, name)) handle_python_module("{}.{}".format(fullname, name), elm, data) else: - print('UNHANDLED TYPE {} : {!r} Type: {}'.format(fullname, elm, type(elm))) + print('UNHANDLED TYPE {} : {!r} Type: {} Englobing: {} str: {} Members: \n{}\n'.format(fullname, elm, type(elm), englobing, str(elm), inspect.getmembers(elm))) # Start the recursion on the provided Python modules for name in python_modules: diff --git a/docs/manpages/smpicc.1 b/docs/manpages/smpicc.1 index 91f12ea240..536a7ffab7 100644 --- a/docs/manpages/smpicc.1 +++ b/docs/manpages/smpicc.1 @@ -10,7 +10,7 @@ All environment variables taken into account by the underlying compiler will be .SH AUTHORS The SimGrid team .SH COPYRIGHT AND LICENCE -Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. +Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. This program is free software; you may redistribute it and/or modify it under the terms of GNU LGPL (v2.1) license. .SH SEE ALSO diff --git a/docs/manpages/smpicxx.1 b/docs/manpages/smpicxx.1 index 4ef27ff9fc..bd01556841 100644 --- a/docs/manpages/smpicxx.1 +++ b/docs/manpages/smpicxx.1 @@ -10,7 +10,7 @@ All environment variables taken into account by the underlying compiler will be .SH AUTHORS The SimGrid team .SH COPYRIGHT AND LICENCE -Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. +Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. This program is free software; you may redistribute it and/or modify it under the terms of GNU LGPL (v2.1) license. .SH SEE ALSO diff --git a/docs/manpages/smpif90.1 b/docs/manpages/smpif90.1 index cf6e50ac8a..801f4e8362 100644 --- a/docs/manpages/smpif90.1 +++ b/docs/manpages/smpif90.1 @@ -10,7 +10,7 @@ All environment variables taken into account by the underlying compiler will be .SH AUTHORS The SimGrid team .SH COPYRIGHT AND LICENCE -Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. +Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. This program is free software; you may redistribute it and/or modify it under the terms of GNU LGPL (v2.1) license. .SH SEE ALSO diff --git a/docs/manpages/smpiff.1 b/docs/manpages/smpiff.1 index 658f6bce98..2bb9a3c744 100644 --- a/docs/manpages/smpiff.1 +++ b/docs/manpages/smpiff.1 @@ -10,7 +10,7 @@ All environment variables taken into account by the underlying compiler will be .SH AUTHORS The SimGrid team .SH COPYRIGHT AND LICENCE -Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. +Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. This program is free software; you may redistribute it and/or modify it under the terms of GNU LGPL (v2.1) license. .SH SEE ALSO diff --git a/docs/manpages/smpirun.1 b/docs/manpages/smpirun.1 index 0af518b1c3..57f972e032 100644 --- a/docs/manpages/smpirun.1 +++ b/docs/manpages/smpirun.1 @@ -109,7 +109,7 @@ Disable the simulation of all computation chunks (that are still executed on the .SH AUTHORS The SimGrid team .SH COPYRIGHT AND LICENCE -Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. +Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. This program is free software; you may redistribute it and/or modify it under the terms of GNU LGPL (v2.1) license. diff --git a/docs/requirements.txt b/docs/requirements.txt index 2d4f477f06..d6238d6ed9 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,9 +1,8 @@ breathe>=4.26 -sphinx>=3.4.3,<4.0 +sphinx sphinx_rtd_theme>=0.5.2 # sphinx_tabs v1.2.1 is required for Sphinx 2 sphinx_tabs>=1.2.1 sphinx_copybutton -javalang beautifulsoup4 lxml diff --git a/docs/source/Calibrating_the_models.rst b/docs/source/Calibrating_the_models.rst index 55e90ea9a2..3e2937219c 100644 --- a/docs/source/Calibrating_the_models.rst +++ b/docs/source/Calibrating_the_models.rst @@ -25,7 +25,7 @@ parameters that are used to instantiate particular simulated activities (e.g., a typically defines volumes of computation, communication, and time to pass to methods such as :cpp:func:`execute() `, :cpp:func:`put() `, or :cpp:func:`sleep_for() `). Regardless of the potential accuracy of the simulation models, if they are -instantiated with unrealistic parameter values, then the simulation will be inaccurate. +instantiated with unrealistic parameter values, then the simulation will be inaccurate. Given the above, an integral and crucial part of simulation-driven research is **simulation calibration**: the process by which one picks simulation parameter values based on observed real-world executions so that simulated executions have high diff --git a/docs/source/Configuring_SimGrid.rst b/docs/source/Configuring_SimGrid.rst index f907c9dd30..d06882f609 100644 --- a/docs/source/Configuring_SimGrid.rst +++ b/docs/source/Configuring_SimGrid.rst @@ -58,7 +58,7 @@ file: A last solution is to pass your configuration directly in your program -with :cpp:func:`simgrid::s4u::Engine::set_config` or :cpp:func:`MSG_config`. +with :cpp:func:`simgrid::s4u::Engine::set_config`. .. code-block:: cpp @@ -105,23 +105,17 @@ Existing Configuration Items - **host/model:** :ref:`options_model_select` -- **maxmin/precision:** :ref:`cfg=maxmin/precision` - **maxmin/concurrency-limit:** :ref:`cfg=maxmin/concurrency-limit` -- **msg/debug-multiple-use:** :ref:`cfg=msg/debug-multiple-use` - - **model-check:** :ref:`options_modelchecking` -- **model-check/checkpoint:** :ref:`cfg=model-check/checkpoint` - **model-check/communications-determinism:** :ref:`cfg=model-check/communications-determinism` - **model-check/dot-output:** :ref:`cfg=model-check/dot-output` - **model-check/max-depth:** :ref:`cfg=model-check/max-depth` -- **model-check/property:** :ref:`cfg=model-check/property` - **model-check/reduction:** :ref:`cfg=model-check/reduction` - **model-check/replay:** :ref:`cfg=model-check/replay` - **model-check/send-determinism:** :ref:`cfg=model-check/send-determinism` -- **model-check/termination:** :ref:`cfg=model-check/termination` +- **model-check/setenv:** :ref:`cfg=model-check/setenv` - **model-check/timeout:** :ref:`cfg=model-check/timeout` -- **model-check/visited:** :ref:`cfg=model-check/visited` - **network/bandwidth-factor:** :ref:`cfg=network/bandwidth-factor` - **network/crosstraffic:** :ref:`cfg=network/crosstraffic` @@ -141,20 +135,21 @@ Existing Configuration Items - **storage/max_file_descriptors:** :ref:`cfg=storage/max_file_descriptors` -- **surf/precision:** :ref:`cfg=surf/precision` +- **precision/timing:** :ref:`cfg=precision/timing` +- **precision/work-amount:** :ref:`cfg=precision/work-amount` - **For collective operations of SMPI,** please refer to Section :ref:`cfg=smpi/coll-selector` - **smpi/auto-shared-malloc-thresh:** :ref:`cfg=smpi/auto-shared-malloc-thresh` - **smpi/async-small-thresh:** :ref:`cfg=smpi/async-small-thresh` +- **smpi/barrier-finalization:** :ref:`cfg=smpi/barrier-finalization` +- **smpi/barrier-collectives:** :ref:`cfg=smpi/barrier-collectives` - **smpi/buffering:** :ref:`cfg=smpi/buffering` -- **smpi/bw-factor:** :ref:`cfg=smpi/bw-factor` - **smpi/coll-selector:** :ref:`cfg=smpi/coll-selector` - **smpi/comp-adjustment-file:** :ref:`cfg=smpi/comp-adjustment-file` - **smpi/cpu-threshold:** :ref:`cfg=smpi/cpu-threshold` - **smpi/display-allocs:** :ref:`cfg=smpi/display-allocs` - **smpi/display-timing:** :ref:`cfg=smpi/display-timing` - **smpi/errors-are-fatal:** :ref:`cfg=smpi/errors-are-fatal` -- **smpi/finalization-barrier:** :ref:`cfg=smpi/finalization-barrier` - **smpi/grow-injected-times:** :ref:`cfg=smpi/grow-injected-times` - **smpi/host-speed:** :ref:`cfg=smpi/host-speed` - **smpi/IB-penalty-factors:** :ref:`cfg=smpi/IB-penalty-factors` @@ -162,7 +157,6 @@ Existing Configuration Items - **smpi/iprobe-cpu-usage:** :ref:`cfg=smpi/iprobe-cpu-usage` - **smpi/init:** :ref:`cfg=smpi/init` - **smpi/keep-temps:** :ref:`cfg=smpi/keep-temps` -- **smpi/lat-factor:** :ref:`cfg=smpi/lat-factor` - **smpi/ois:** :ref:`cfg=smpi/ois` - **smpi/or:** :ref:`cfg=smpi/or` - **smpi/os:** :ref:`cfg=smpi/os` @@ -230,30 +224,20 @@ models for all existing resources. `_. - **ns-3** (only available if you compiled SimGrid accordingly): Use the packet-level network - simulators as network models (see :ref:`model_ns3`). + simulators as network models (see :ref:`models_ns3`). This model can be :ref:`further configured `. -- ``cpu/model``: specify the used CPU model. We have only one model - for now: +- ``cpu/model``: specify the used CPU model. We have only one model for now: - **Cas01:** Simplistic CPU model (time=size/speed) -- ``host/model``: The host concept is the aggregation of a CPU with a - network card. Three models exists, but actually, only 2 of them are - interesting. The "compound" one is simply due to the way our - internal code is organized, and can easily be ignored. So at the - end, you have two host models: The default one allows aggregation of - an existing CPU model with an existing network model, but does not - allow parallel tasks because these beasts need some collaboration - between the network and CPU model. - - - **default:** Default host model. Currently, CPU:Cas01 and - network:LV08 (with cross traffic enabled) - - **compound:** Host model that is automatically chosen if - you change the network and CPU models - - **ptask_L07:** Host model somehow similar to Cas01+CM02 but - allowing "parallel tasks", that are intended to model the moldable - tasks of the grid scheduling literature. +- ``host/model``: we have two such models for now. + + - **default:** Default host model. It simply uses the otherwise configured models for cpu, disk and network (i.e. CPU:Cas01, + disk:S19 and network:LV08 by default) + - **ptask_L07:** This model is mandatory if you plan to use parallel tasks (and useless otherwise). ptasks are intended to + model the moldable tasks of the grid scheduling literature. A specific host model is necessary because each such activity + has a both compute and communicate components, so the CPU and network models must be mixed together. - ``storage/model``: specify the used storage model. Only one model is provided so far. @@ -270,7 +254,7 @@ Solver The different models rely on a linear inequalities solver to share the underlying resources. SimGrid allows you to change the solver, but be cautious, **don't change it unless you are 100% sure**. - + - items ``cpu/solver``, ``network/solver``, ``disk/solver`` and ``host/solver`` allow you to change the solver for each model: @@ -315,14 +299,14 @@ configurations. and slow pattern that follows the actual dependencies. .. _cfg=bmf/precision: -.. _cfg=maxmin/precision: -.. _cfg=surf/precision: +.. _cfg=precision/timing: +.. _cfg=precision/work-amount: Numerical Precision ................... -**Option** ``maxmin/precision`` **Default:** 1e-5 (in flops or bytes) |br| -**Option** ``surf/precision`` **Default:** 1e-9 (in seconds) |br| +**Option** ``precision/timing`` **Default:** 1e-9 (in seconds) |br| +**Option** ``precision/work-amount`` **Default:** 1e-5 (in flops or bytes) |br| **Option** ``bmf/precision`` **Default:** 1e-12 (no unit) The analytical models handle a lot of floating point values. It is @@ -375,54 +359,91 @@ Maximal TCP Window Size **Option** ``network/TCP-gamma`` **Default:** 4194304 -The analytical models need to know the maximal TCP window size to take -the TCP congestion mechanism into account. On Linux, this value can -be retrieved using the following commands. Both give a set of values, -and you should use the last one, which is the maximal size. +The analytical models need to know the maximal TCP window size to take the TCP congestion mechanism into account (see +:ref:`this page ` for details). On Linux, this value can be retrieved using the following commands. +Both give a set of values, and you should use the last one, which is the maximal size. .. code-block:: console $ cat /proc/sys/net/ipv4/tcp_rmem # gives the sender window $ cat /proc/sys/net/ipv4/tcp_wmem # gives the receiver window +If you want to disable the TCP windowing mechanism, set this parameter to 0. + .. _cfg=network/bandwidth-factor: .. _cfg=network/latency-factor: .. _cfg=network/weight-S: -Correcting Important Network Parameters -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -SimGrid can take network irregularities such as a slow startup or -changing behavior depending on the message size into account. You -should not change these values unless you really know what you're -doing. The corresponding values were computed through data fitting -one the timings of packet-level simulators, as described in `Accuracy -Study and Improvement of Network Simulation in the SimGrid Framework -`_. - -- **network/latency-factor**: apply a multiplier to latency. - Models the TCP slow-start mechanism. -- **network/bandwidth-factor**: actual bandwidth perceived by the - user. -- **network/weight-S**: bottleneck sharing constant parameter. Used - to calculate RTT. - -These parameters are the same for all communications in your simulation, -independently of message size or source/destination hosts. A more flexible -mechanism based on callbacks was introduced in SimGrid. It provides the user -a callback that will be called for each communication, allowing the user -to set different latency and bandwidth factors, based on the message size, links used -or zones traversed. To more details of how to use it, please look at the -`examples/cpp/network-factors/s4u-network-factors.cpp `_. - - -If you are using the SMPI model, these correction coefficients are -themselves corrected by constant values depending on the size of the -exchange. By default SMPI uses factors computed on the Stampede -Supercomputer at TACC, with optimal deployment of processes on -nodes. Again, only hardcore experts should bother about this fact. -For more details, see SMPI sections about :ref:`cfg=smpi/bw-factor` and :ref:`cfg=smpi/lat-factor`. +Manual calibration factors +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SimGrid can take network irregularities such as a slow startup or changing behavior depending on the message size into account. +The values provided by default were computed a long time ago through data fitting one the timings of either packet-level +simulators or direct experiments on real platforms. These default values should be OK for most users, but if simulation realism +is really important to you, you probably want to recalibrate the models (i.e., devise sensible values for your specific +settings). This section only describes how to pass new values to the models while the calibration process involved in the +computation of these values is described :ref:`in the relevant chapter `. + +We found out that many networking effects can be realistically accounted for with the three following correction factors. They +were shown to be enough to capture slow-start effects, the different transmission modes of MPI systems (eager vs. rendez-vous +mode), or the non linear effects of wifi sharing. + +**Option** ``network/latency-factor`` **Default:** 1.0, but overridden by most models + +This option specifies a multiplier to apply to the *physical* latency (i.e., the one described in the platform) of the set of +links involved in a communication. The factor can either be a constant to apply to any communication, or it may depend on the +message size. The ``CM02`` model does not use any correction factor, so the latency-factor remains to 1. The ``LV08`` model sets +it to 13.01 to model slow-start, while the ``SMPI`` model has several possible values depending on the interval in which the +message size falls. The default SMPI setting given below specifies for example that a message smaller than 257 bytes will get a +latency multiplier of 2.01467 while a message whose size is in [15424, 65472] will get a latency multiplier of 3.48845. The +``wifi`` model goes further and uses a callback in the program to compute the factor that must be non-linear in this case. + +This multiplier is applied to the latency computed from the platform, that is the sum of all link *physical* latencies over the +:ref:`network path ` used by the considered communication, to derive the *effective* end-to-end latency. + +Constant factors are easy to express, but the interval-based syntax used in SMPI is somewhat complex. It expects a set of +factors separated by semicolons, each of the form ``boundary:factor``. For example if your specification is +``0:1;1000:2;5000:3``, it means that on [0, 1000) the factor is 1. On [1000,5000), the factor is 2 while the factor is 3 for +5000 and beyond. If your first interval does include size=0, then the default value of 1 is used before. Changing the factor +callback is not possible from the command line and must be done from your code, as shown in `this example +`_. Note that the chosen +model only provides some default settings. You may pick a ``LV08`` model to get some of the settings, and override the latency +with interval-based values. + +SMPI default value: 65472:11.6436; 15424:3.48845; 9376:2.59299; 5776:2.18796; 3484:1.88101; 1426:1.61075; 732:1.9503; +257:1.95341;0:2.01467 (interval boundaries are sorted automatically). These values were computed by data fitting on the Stampede +Supercomputer at TACC, with optimal deployment of processes on nodes. To accurately model your settings, you should redo the +:ref:`calibration `. + +**Option** ``network/bandwidth-factor`` **Default:** 1.0, but overridden by most models + +Setting this option automatically adjusts the *effective* bandwidth (i.e., the one perceived by the application) used by any +given communication. As with latency-factor above, the value can be a constant (``CM02`` uses 1 -- no correction -- while +``LV08`` uses 0.97 to discount TCP headers while computing the payload bandwidth), interval-based (as the default provided by +the ``SMPI``), or using in-program callbacks (as with ``wifi``). + +SMPI default value: 65472:0.940694;15424:0.697866;9376:0.58729;5776:1.08739;3484:0.77493;1426:0.608902;732:0.341987;257:0.338112;0:0.812084 +This was also computed on the Stampede Supercomputer. + +**Option** ``network/weight-S`` **Default:** depends on the model + +Value used to account for RTT-unfairness when sharing a bottleneck (network connections with a large RTT are generally penalized +against those with a small one). See :ref:`models_TCP` and also this scientific paper: `Accuracy Study and Improvement of Network +Simulation in the SimGrid Framework `_ + +Default values for ``CM02`` is 0. ``LV08`` sets it to 20537 while both ``SMPI`` and ``IB`` set it to 8775. + +.. _cfg=network/loopback: + +Configuring loopback link +^^^^^^^^^^^^^^^^^^^^^^^^^ +Several network models provide an implicit loopback link to account for local +communication on a host. By default it has a 10GBps bandwidth and a null latency. +This can be changed with ``network/loopback-lat`` and ``network/loopback-bw`` +items. Note that this loopback is conveniently modeled with a :ref:`single FATPIPE link ` +for the whole platform. If modeling contention inside nodes is important then you should +rather add such loopback links (one for each host) yourself. .. _cfg=smpi/IB-penalty-factors: @@ -430,8 +451,8 @@ Infiniband model ^^^^^^^^^^^^^^^^ InfiniBand network behavior can be modeled through 3 parameters -``smpi/IB-penalty-factors:"βe;βs;γs"``, as explained in `this PhD -thesis +``smpi/IB-penalty-factors:"βe;βs;γs"``, as explained in `the PhD +thesis of Jérôme Vienne `_ (in French) or more concisely in `this paper `_, even if that paper does only describe models for myrinet and ethernet. @@ -497,30 +518,18 @@ can be set to 0 (disable this feature) or 1 (enable it). Note that with the default host model this option is activated by default. -.. _cfg=network/loopback: - -Configuring loopback link -^^^^^^^^^^^^^^^^^^^^^^^^^ - -Several network model provide an implicit loopback link to account for local -communication on a host. By default it has a 10GBps bandwidth and a null latency. -This can be changed with ``network/loopback-lat`` and ``network/loopback-bw`` -items. - .. _cfg=smpi/async-small-thresh: Simulating Asynchronous Send ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -(this configuration item is experimental and may change or disappear) - It is possible to specify that messages below a certain size (in bytes) will be sent as soon as the call to MPI_Send is issued, without waiting for the correspondent receive. This threshold can be configured through the ``smpi/async-small-thresh`` item. The default value is 0. This behavior can also be manually set for mailboxes, by setting the receiving mode of the mailbox with a call to -:cpp:func:`MSG_mailbox_set_async`. After this, all messages sent to +:cpp:func:`sg_mailbox_set_receiver`. After this, all messages sent to this mailbox will have this behavior regardless of the message size. This value needs to be smaller than or equals to the threshold set at @@ -532,13 +541,12 @@ are meant to be detached as well. Configuring ns-3 ^^^^^^^^^^^^^^^^ -**Option** ``ns3/TcpModel`` **Default:** "default" (ns-3 default) +**Option** ``ns3/NetworkModel`` **Default:** "default" (ns-3 default TCP) -When using ns-3, there is an extra item ``ns3/TcpModel``, corresponding -to the ``ns3::TcpL4Protocol::SocketType`` configuration item in -ns-3. The only valid values (enforced on the SimGrid side) are -'default' (no change to the ns-3 configuration), 'NewReno' or 'Reno' or -'Tahoe'. +When using ns-3, the item ``ns3/NetworkModel`` can be used to switch between TCP or UDP, and switch the used TCP variante. If +the item is left unchanged, ns-3 uses the default TCP implementation. With a value of "UDP", ns-3 is set to use UDP instead. +With the value of either 'NewReno' or 'Cubic', the ``ns3::TcpL4Protocol::SocketType`` configuration item in ns-3 is set to the +corresponding protocol. **Option** ``ns3/seed`` **Default:** "" (don't set the seed in ns-3) @@ -619,9 +627,12 @@ receive call for small messages sent when the system buffers are empty. In SMPI, this depends on the message size, that is compared against two thresholds: - if (size < :ref:`smpi/async-small-thresh `) then - MPI_Send returns immediately, even if the corresponding receive has not be issued yet. -- if (:ref:`smpi/async-small-thresh ` < size < :ref:`smpi/send-is-detached-thresh `) then - MPI_Send returns as soon as the corresponding receive has been issued. This is known as the eager mode. + MPI_Send returns immediately, and the message is sent even if the + corresponding receive has not be issued yet. This is known as the eager mode. +- if (:ref:`smpi/async-small-thresh ` < size < + :ref:`smpi/send-is-detached-thresh `) then + MPI_Send also returns immediately, but SMPI waits for the corresponding + receive to be posted, in order to perform the communication operation. - if (:ref:`smpi/send-is-detached-thresh ` < size) then MPI_Send returns only when the message has actually been sent over the network. This is known as the rendez-vous mode. @@ -630,102 +641,50 @@ The ``smpi/buffering`` (only valid with MC) option gives an easier interface to - **zero:** means that buffering should be disabled. All communications are actually blocking. - **infty:** means that buffering should be made infinite. All communications are non-blocking. -.. _cfg=model-check/property: - -Specifying a liveness property -.............................. - -**Option** ``model-check/property`` **Default:** unset - -If you want to specify liveness properties, you have to pass them on -the command line, specifying the name of the file containing the -property, as formatted by the `ltl2ba `_ program. -Note that ltl2ba is not part of SimGrid and must be installed separately. - -.. code-block:: console - - $ simgrid-mc ./my_program --cfg=model-check/property: - -.. _cfg=model-check/checkpoint: - -Going for Stateful Verification -............................... - -By default, the system is backtracked to its initial state to explore -another path, instead of backtracking to the exact step before the fork -that we want to explore (this is called stateless verification). This -is done this way because saving intermediate states can rapidly -exhaust the available memory. If you want, you can change the value of -the ``model-check/checkpoint`` item. For example, -``--cfg=model-check/checkpoint:1`` asks to take a checkpoint every -step. Beware, this will certainly explode your memory. Larger values -are probably better, make sure to experiment a bit to find the right -setting for your specific system. - .. _cfg=model-check/reduction: Specifying the kind of reduction ................................ +**Option** model-check/reduction **Default:** "dpor" + The main issue when using the model-checking is the state space explosion. You can activate some reduction technique with ``--cfg=model-check/reduction:``. For now, this configuration variable can take 2 values: - - **none:** Do not apply any kind of reduction (mandatory for - liveness properties, as our current DPOR algorithm breaks cycles) - - **dpor:** Apply Dynamic Partial Ordering Reduction. Only valid if - you verify local safety properties (default value for safety - checks). - -Another way to mitigate the state space explosion is to search for -cycles in the exploration with the :ref:`cfg=model-check/visited` -configuration. Note that DPOR and state-equality reduction may not -play well together. You should choose between them. + - **none:** Do not apply any kind of reduction + - **dpor:** Apply Dynamic Partial Ordering Reduction. Only valid if you verify local safety properties (default value for + safety checks). + - **sdpor:** Source-set DPOR, as described in "Source Sets: A Foundation for Optimal Dynamic Partial Order Reduction" + by Abdulla et al. + - **odpor:** Optimal DPOR, as described in "Source Sets: A Foundation for Optimal Dynamic Partial Order Reduction" + by Abdulla et al. Our current DPOR implementation could be improved in may ways. We are currently improving its efficiency (both in term of reduction ability -and computational speed), and future work could make it compatible -with liveness properties. - -.. _cfg=model-check/visited: - -Size of Cycle Detection Set (state equality reduction) -...................................................... - -Mc SimGrid can be asked to search for cycles during the exploration, -i.e. situations where a new explored state is in fact the same state -than a previous one.. This can prove useful to mitigate the state -space explosion with safety properties, and this is the crux when -searching for counter-examples to the liveness properties. +and computational speed). -Note that this feature may break the current implementation of the -DPOR reduction technique. +.. _cfg=model-check/strategy: -The ``model-check/visited`` item is the maximum number of states, which -are stored in memory. If the maximum number of snapshotted state is -reached, some states will be removed from the memory and some cycles -might be missed. Small values can lead to incorrect verifications, but -large values can exhaust your memory and be CPU intensive as each new -state must be compared to that amount of older saved states. - -The default settings depend on the kind of exploration. With safety -checking, no state is snapshotted and cycles cannot be detected. With -liveness checking, all states are snapshotted because missing a cycle -could hinder the exploration soundness. - -.. _cfg=model-check/termination: - -Non-Termination Detection -......................... +Guiding strategy +................ -The ``model-check/termination`` configuration item can be used to -report if a non-termination execution path has been found. This is a -path with a cycle, which means that the program might never terminate. +**Option** model-check/strategy **Default:** "none" -This only works in safety mode, not in liveness mode. +Even after the DPOR's reduction, the state space that we have to explore remains huge. SimGrid provides several guiding +strategies aiming at converging faster toward bugs. By default, none of these strategy is enabled, and SimGrid does a regular +DFS exploration. -This options is disabled by default. + - **max_match_comm**: Try to minimize the number of in-fly communication by appairing matching send and receive. This tend to + produce nicer backtraces, in particular when a user-level ``send`` is broken down internally into a ``send_async`` + ``wait``. + This strategy will ensure that the ``wait`` occures as soon as possible, easing the understanding of the user who do not + expect her ``send`` to be split. + - **min_match_comm**: Try to maximize the number of in-fly communication by not appairing matching send and receive. This is + the exact opposite strategy, but it is still useful as it tend to explore first the branches where the risk of deadlock is + higher. + - **uniform**: this is a boring random strategy where choices are based on a uniform sampling of possible choices. + Surprisingly, it gives really really good results. .. _cfg=model-check/dot-output: @@ -734,8 +693,7 @@ Dot Output If set, the ``model-check/dot-output`` configuration item is the name of a file in which to write a dot file of the path leading to the -property violation discovered (safety or liveness violation), as well -as the cycle for liveness properties. This dot file can then be fed to the +property violation discovered (safety violation). This dot file can then be fed to the graphviz dot tool to generate a corresponding graphical representation. .. _cfg=model-check/max-depth: @@ -769,6 +727,15 @@ The ``model-check/communications-determinism`` and communication determinism mode of the model checker, which checks determinism properties of the communications of an application. +.. _cfg=model-check/setenv: + +Passing environment variables +............................. + +You can specify extra environment variables to be set in the verified application +with ``model-check/setenv``. For example, you can preload a library as follows: +``-cfg=model-check/setenv:LD_PRELOAD=toto;LD_LIBRARY_PATH=/tmp``. + .. _options_mc_perf: Verification Performance Considerations @@ -791,17 +758,14 @@ memory (see :ref:`contexts/guard-size `). Replaying buggy execution paths from the model checker ...................................................... -Debugging the problems reported by the model checker is challenging: -First, the application under verification cannot be debugged with gdb -because the model checker already traces it. Then, the model checker may -explore several execution paths before encountering the issue, making it -very difficult to understand the output. Fortunately, SimGrid provides +Debugging the problems reported by the model checker is challenging because +the model checker may explore several execution paths before encountering the issue, +the output very difficult to understand. Fortunately, SimGrid provides the execution path leading to any reported issue so that you can replay -this path reported by the model checker, enabling the usage of classical -debugging tools. +this path reported by the model checker, restoring a classical experience of debugging. When the model checker finds an interesting path in the application -execution graph (where a safety or liveness property is violated), it +execution graph (where a safety property is violated), it generates an identifier for this path. Here is an example of the output: .. code-block:: console @@ -822,10 +786,84 @@ The interesting line is ``Path = 1/3;1/4``, which means that you should use ``--cfg=model-check/replay:1/3;1/4`` to replay your application on the buggy execution path. All options (but the model checker related ones) must remain the same. In particular, if you ran your application with -``smpirun -wrapper simgrid-mc``, then do it again. Remove all +``smpirun -wrapper simgrid-mc``, then remove the ``-wrapper simgrid-mc`` part +(you may want to use valgrind or gdb as wrappers instead). Also remove all MC-related options, keep non-MC-related ones and add ``--cfg=model-check/replay:???``. +Things are very similar if you are using sthread. Simply drop ``simgrid-mc`` from your command line, as follows: + +.. code-block:: console + + $ LD_PRELOAD=../../lib/libsthread.so ./pthread-mutex-simpledeadlock --cfg=model-check/replay:'2;2;3;2;3;3' + sthread is intercepting the execution of ./pthread-mutex-simpledeadlock + [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/replay' to '2;2;3;2;3;3' + [0.000000] [mc_record/INFO] path=2;2;3;2;3;3 + All threads are started. + [0.000000] [mc_record/INFO] *********************************************************************************** + [0.000000] [mc_record/INFO] * Path chunk #1 '2/0' Actor thread 1(pid:2): MUTEX_ASYNC_LOCK(mutex_id:0 owner:none) + [0.000000] [mc_record/INFO] *********************************************************************************** + Backtrace (displayed in actor thread 1): + -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:26 + -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 + -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 + -> #3 thread_fun1 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:21 + + [0.000000] [mc_record/INFO] *********************************************************************************** + [0.000000] [mc_record/INFO] * Path chunk #2 '2/0' Actor thread 1(pid:2): MUTEX_WAIT(mutex_id:0 owner:2) + [0.000000] [mc_record/INFO] *********************************************************************************** + Backtrace (displayed in actor thread 1): + -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:29 + -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 + -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 + -> #3 thread_fun1 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:21 + + [0.000000] [mc_record/INFO] *********************************************************************************** + [0.000000] [mc_record/INFO] * Path chunk #3 '3/0' Actor thread 2(pid:3): MUTEX_ASYNC_LOCK(mutex_id:1 owner:none) + [0.000000] [mc_record/INFO] *********************************************************************************** + Backtrace (displayed in actor thread 2): + -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:26 + -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 + -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 + -> #3 thread_fun2 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:31 + + [0.000000] [mc_record/INFO] *********************************************************************************** + [0.000000] [mc_record/INFO] * Path chunk #4 '2/0' Actor thread 1(pid:2): MUTEX_ASYNC_LOCK(mutex_id:1 owner:3) + [0.000000] [mc_record/INFO] *********************************************************************************** + Backtrace (displayed in actor thread 1): + -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:26 + -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 + -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 + -> #3 thread_fun1 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:22 + + [0.000000] [mc_record/INFO] *********************************************************************************** + [0.000000] [mc_record/INFO] * Path chunk #5 '3/0' Actor thread 2(pid:3): MUTEX_WAIT(mutex_id:1 owner:3) + [0.000000] [mc_record/INFO] *********************************************************************************** + Backtrace (displayed in actor thread 2): + -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:29 + -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 + -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 + -> #3 thread_fun2 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:31 + + [0.000000] [mc_record/INFO] *********************************************************************************** + [0.000000] [mc_record/INFO] * Path chunk #6 '3/0' Actor thread 2(pid:3): MUTEX_ASYNC_LOCK(mutex_id:0 owner:2) + [0.000000] [mc_record/INFO] *********************************************************************************** + Backtrace (displayed in actor thread 2): + -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:26 + -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 + -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 + -> #3 thread_fun2 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:32 + + [0.000000] [mc_record/INFO] The replay of the trace is complete. DEADLOCK detected. + [0.000000] [ker_engine/INFO] 3 actors are still running, waiting for something. + [0.000000] [ker_engine/INFO] Legend of the following listing: "Actor (@): " + [0.000000] [ker_engine/INFO] Actor 1 (main thread@Lilibeth) simcall ActorJoin(pid:2) + [0.000000] [ker_engine/INFO] Actor 2 (thread 1@Lilibeth) simcall MUTEX_WAIT(mutex_id:1 owner:3) + [0.000000] [ker_engine/INFO] Actor 3 (thread 2@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2) + [0.000000] [sthread/INFO] All threads exited. Terminating the simulation. + [0.000000] ../../src/kernel/EngineImpl.cpp:265: [ker_engine/WARNING] Process called exit when leaving - Skipping cleanups + [0.000000] ../../src/kernel/EngineImpl.cpp:265: [ker_engine/WARNING] Process called exit when leaving - Skipping cleanups + Currently, if the path is of the form ``X;Y;Z``, each number denotes the actor's pid that is selected at each indecision point. If it's of the form ``X/a;Y/b``, the X and Y are the selected pids while the a @@ -862,11 +900,8 @@ should be the most effcient one (please report bugs if the auto-detection fails for you). They are approximately sorted here from the slowest to the most efficient: - - **thread:** very slow factory using full featured threads (either - pthreads or windows native threads). They are slow but very - standard. Some debuggers or profilers only work with this factory. - - **java:** Java applications are virtualized onto java threads (that - are regular pthreads registered to the JVM) + - **thread:** very slow factory using full featured, standard threads. + They are slow but very standard. Some debuggers or profilers only work with this factory. - **ucontext:** fast factory using System V contexts (Linux and FreeBSD only) - **boost:** This uses the `context implementation `_ @@ -925,7 +960,7 @@ model checker (see :ref:`options_mc_perf`). Disabling Stack Guard Pages ........................... -**Option** ``contexts/guard-size`` **Default** 1 page in most case (0 pages on Windows or with MC) +**Option** ``contexts/guard-size`` **Default** 1 page in most case (0 pages with MC) Unless you use the threads context factory (see :ref:`cfg=contexts/factory`), a stack guard page is usually used @@ -948,7 +983,7 @@ Running User Code in Parallel ............................. Parallel execution of the user code is only considered stable in -SimGrid v3.7 and higher, and mostly for MSG simulations. SMPI +SimGrid v3.7 and higher, and mostly for S4U simulations. SMPI simulations may well fail in parallel mode. It is described in `INRIA RR-7653 `_. @@ -988,7 +1023,7 @@ We detail here a simple way to get the traces working for you, even if you never used the tracing API. -- Any SimGrid-based simulator (MSG, SMPI, ...) and raw traces: +- Any SimGrid-based simulator (S4U, SMPI, ...) and raw traces: .. code-block:: none @@ -998,7 +1033,7 @@ you never used the tracing API. tells it to trace host and link utilization (without any categorization). -- MSG-based simulator and categorized traces (you need to +- S4U-based simulator and categorized traces (you need to declare categories and classify your tasks according to them) .. code-block:: none @@ -1038,27 +1073,11 @@ Please, use these two parameters (for comments) to make reproducible simulations. For additional details about this and all tracing options, check See the :ref:`tracing_tracing_options`. -Configuring MSG ---------------- - -.. _cfg=msg/debug-multiple-use: - -Debugging MSG Code -.................. - -**Option** ``msg/debug-multiple-use`` **Default:** off - -Sometimes your application may try to send a task that is still being -executed somewhere else, making it impossible to send this task. However, -for debugging purposes, one may want to know what the other host is/was -doing. This option shows a backtrace of the other process. - Configuring SMPI ---------------- The SMPI interface provides several specific configuration items. -These are not easy to see, since the code is usually launched through the -``smiprun`` script directly. +These are not easy to see with ``--help-cfg``, since SMPI binaries are usually launched through the ``smiprun`` script. .. _cfg=smpi/host-speed: .. _cfg=smpi/cpu-threshold: @@ -1157,26 +1176,12 @@ Please note that you must pass the ``-trace-call-location`` flag to smpicc or smpiff, respectively. This flag activates some internal macro definitions that help with obtaining the call location. -.. _cfg=smpi/bw-factor: - -Bandwidth Factors -................. - -**Option** ``smpi/bw-factor`` -|br| **Default:** 65472:0.940694;15424:0.697866;9376:0.58729;5776:1.08739;3484:0.77493;1426:0.608902;732:0.341987;257:0.338112;0:0.812084 - -The possible throughput of network links is often dependent on the -message sizes, as protocols may adapt to different message sizes. With -this option, a series of message sizes and factors are given, helping -the simulation to be more realistic. For instance, the current default -value means that messages with size 65472 bytes and more will get a total of -MAX_BANDWIDTH*0.940694, messages of size 15424 to 65471 will get -MAX_BANDWIDTH*0.697866, and so on (where MAX_BANDWIDTH denotes the -bandwidth of the link). +Bandwidth and latency factors +............................. -An experimental script to compute these factors is available online. See -https://framagit.org/simgrid/platform-calibration/ -https://simgrid.org/contrib/smpi-saturation-doc.html +Adapting the bandwidth and latency acurately to the network conditions is of a paramount importance to get realistic results. +This is done through the :ref:`network/bandwidth-factor ` and :ref:`network/latency-factor +` items. You probably also want to read the following section: :ref:`models_calibration`. .. _cfg=smpi/display-timing: @@ -1223,21 +1228,6 @@ profile your code. Indeed, the binary files are removed very early under the dlopen privatization schema, which tends to fool the debuggers. -.. _cfg=smpi/lat-factor: - -Latency factors -............... - -**Option** ``smpi/lat-factor`` |br| -**default:** 65472:11.6436;15424:3.48845;9376:2.59299;5776:2.18796;3484:1.88101;1426:1.61075;732:1.9503;257:1.95341;0:2.01467 - -The motivation and syntax for this option is identical to the motivation/syntax -of :ref:`cfg=smpi/bw-factor`. - -There is an important difference, though: While smpi/bw-factor `reduces` the -actual bandwidth (i.e., values between 0 and 1 are valid), latency factors -increase the latency, i.e., values larger than or equal to 1 are valid here. - .. _cfg=smpi/papi-events: Trace hardware counters with PAPI @@ -1351,14 +1341,40 @@ existing MPI libraries. The ``smpi/coll-selector`` item can be used to select the decision logic either of the OpenMPI or the MPICH libraries. (By default SMPI uses naive version of collective operations.) -Each collective operation can be manually selected with a -``smpi/collective_name:algo_name``. Available algorithms are listed in -:ref:`SMPI_use_colls`. +Each collective operation can be manually selected with a ``smpi/collective_name:algo_name``. For example, if you want to use +the Bruck algorithm for the Alltoall algorithm, you should use ``--cfg=smpi/alltoall:bruck`` on the command-line of smpirun. The +reference of all available algorithms are listed in :ref:`SMPI_use_colls`, and you can get the full list implemented in your +version using ``smpirun --help-coll``. + +.. _cfg=smpi/barrier-collectives: + +Add a barrier in all collectives +................................ + +**Option** ``smpi/barrier-collectives`` **default:** off + +This option adds a simple barrier in some collective operations to catch dangerous +code that may or may not work depending on the MPI implementation: Bcast, Exscan, +Gather, Gatherv, Scan, Scatter, Scatterv and Reduce. + +For example, the following code works with OpenMPI while it deadlocks in MPICH and +Intel MPI. Broadcast seem to be "fire and forget" in OpenMPI while other +implementations expect to receive a message. + +.. code-block:: C + + if (rank == 0) { + MPI_Bcast(buf1, buff_size, MPI_CHAR, 0, newcom); + MPI_Send(&buf2, buff_size, MPI_CHAR, 1, tag, newcom); + } else if (rank==1) { + MPI_Recv(&buf2, buff_size, MPI_CHAR, 0, tag, newcom, MPI_STATUS_IGNORE); + MPI_Bcast(buf1, buff_size, MPI_CHAR, 0, newcom); + } -.. TODO:: All available collective algorithms will be made available - via the ``smpirun --help-coll`` command. +The barrier is only simulated and does not involve any additional message (it is a S4U barrier). +This option is disabled by default, and activated by the `-analyze` flag of smpirun. -.. _cfg=smpi/finalization-barrier: +.. _cfg=smpi/barrier-finalization: Add a barrier in MPI_Finalize ............................. diff --git a/docs/source/Contributors_Documentation.rst b/docs/source/Contributors_Documentation.rst new file mode 100644 index 0000000000..da9640a0e9 --- /dev/null +++ b/docs/source/Contributors_Documentation.rst @@ -0,0 +1,202 @@ +.. _contrib_doc: + +Contributor's Documentation +=========================== + +This page describes the software infrastructure for SimGrid potential contributors. It is particularly interesting if you plan to send some patches for +inclusion in the project code. + +Enforcing the coding standards +------------------------------ + +If you plan to contribute code to the SimGrid project, you must ensure that your changes follow our coding standards. For that, simply install the relevant +tools and scripts. + +.. code-block:: console + + # install clang-format + sudo apt-get install clang-format # debian/ubuntu + + # tell git to call the script on each commit + ln -s $(realpath tools/git-hooks/clang-format.pre-commit) .git/hooks/pre-commit + +This will add an extra verification before integrating any commit that you could prepare. If your code does not respects our formatting code, git will say so, +and provide a ready to use patch that you can apply to improve your commit. Just read the error message you get to find how to apply the fix after review. + +If you prefer not to apply the fix on a specific commit (because the formatter fails on this case), then add ``--no-verify`` to your git commit command line. + +Interacting with cmake +---------------------- + +Configuring +^^^^^^^^^^^ + +The :ref:`default build configuration ` is intended for users, but contributors should change these settings for their comfort, and to +produce better code. In particular, the default is to build highly optimized binaries, at the price of high compilation time and somewhat harder debug sessions. +Instead, contributors want to disable the ``enable_compile_optimizations`` compile option. Likewise, ``enable_compile_warnings`` is off by default to not bother +the users, but the contributors should really enable it, as your code will not be integrated if it raises warnings from the compiler. + +.. code-block:: console + + cmake -Denable_compile_optimizations=OFF -Denable_compile_warnings=ON \ + -GNinja . + +As you can see, we advise to use Ninja instead of the good old Makefiles. In our experience, Ninja is a bit faster because it does not fork as many external +commands as make for basic operations. + +Adding a new file +^^^^^^^^^^^^^^^^^ + +The content of the archive is mostly built from the lists given in ``tools/cmake/DefinePackages.cmake``. The only exceptions are the files related to the +examples, that are listed in the relevant ``CMakeLists.txt`` file, e.g. ``examples/cpp/CMakeLists.txt``. This information is duplicated in ``MANIFEST.in`` for +the python building process, that does not use cmake to build the archive. + +When you add a new file, you should use the relevant build target to check that every files followed by git are included in the archive or properly excluded (by +being listed in ``tools/internal/check_dist_archive.exclude``), and that all settings are consistent. + +Interacting with the tests +-------------------------- + +Breaking tests once in a while is completely OK in SimGrid. We accept temporarily breakages because we want things to evolve, but if you break something, it is +your duty to fix it within 24 hours to not hinder the work of others. + +Understanding the existing tests +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We use unit tests based on `Catch2 `_, but most of our testing is done through integration tests that launch a specific +simulation example and enforce that the output remains unchanged. Since SimGrid displays the timestamp of every logged event, such integration tests ensure that +every change of the models' prediction will be noticed. We designed a specific tool for these integration tests, called TESH (the TEsting SHell). ``ctest`` is +used to run both unit and integration tests. You can :ref:`run only some of the tests ` if you prefer. To launch the unit tests out of ctest, +build and execute the ``./unit-tests`` binary (it accepts a ``--help`` parameter). To rebuild and run all tests, use the ``./BuildSimGrid.sh`` script. + +The SimGrid code base contains a lot of tests for a coverage well over 80%. We want the contributors to feel confident, and improve the code without fearing of +breaking something without noticing. Tests must be fast (because we run them very often), the should stress many aspects of the code (to actually catch problems) and +clear to read (understanding and debugging failures should be easy). + +In fact, our integration tests fall in two categories. The ones located in ``examples/`` are part of the documentation, so readability is utterly important +here. The goal is that novice users could grab some of the provided examples and assemble them to constitute a first version of their simulator. These files can +only load public header files, and we tend to avoid advanced C++ constructs that would hinder the readability of these files. On the other hand, the integration +tests located in ``teshsuite/`` are usually torture tests trying to exhaustively cover all cases. They may be less readable and some even rely on a small DSL to +describe all test cases and the expected result (check for example ``teshsuite/models/cloud-sharing``), but they should still be rather easy to debug on need. +For this reason, we tend to avoid random testing that is difficult to reproduce. For example, the tests under ``teshsuite/models/`` try to be very verbose to +make the model intend clear, and the code easier to debug on need. The WiFi tests seem to be a good example of that trend. + +Adding a test +^^^^^^^^^^^^^ + +We often say that a feature that is not tested is a feature that could soon disappear. So you want to write tests for the features you add. To add new unit +tests, please refer to the end of ``tools/cmake/Tests.cmake``) for some examples. Catch2 comes with a good documentation and many examples online. If you add a +new feature, you should add an integration test in ``examples/``. Your code should be instructive, documented, reusable, and its output must be perfectly +reproducible. Some debugging information can be hidden when run from TESH with the :c:macro:`XBT_LOG_ISENABLED` macro. You then need to write a tesh file, +following the syntax described in this man page: ``man -l manpages/tesh.1`` Finally, you should add your source code and tesh file to the cmake infrastructure +by modifying for example the ``examples/cpp/CMakeLists.txt`` file. The test name shall allow the filtering of tests with ``ctest -R``. Do not forget to run +``make distcheck`` once you're done to check that you did not forget to add your new files to the distribution. + +Noteworthy tests +^^^^^^^^^^^^^^^^ + +Here is a short list of some typical tests in SimGrid, in the hope that they can give you some inspiration for your own tests. +Note that good tests rarely involve randomness, which makes it difficult to understand and fix problems when they occur. + +* Several **model tests** display the full computation and expected results for some simple cases. Check for example the tesh files + of `teshsuite/models/cm02-tcpgamma/ `_ + (about the impact of the :ref:`cfg=network/TCP-gamma` parameter), `teshsuite/models/wifi_usage/ + `_ (on the wifi network model), + `teshsuite/models/wifi_usage_decay/ `_ + (on the decay component of the wifi model, for highly congestioned APs), or `teshsuite/models/ptask_L07_usage/ + `_ (on parallel tasks). The goal of these tests + is to be easy to understand just by reading their output. + + `teshsuite/models/cloud-sharing/ `_ is a + bit special here, because it introduces a mini-DSL. Its purpose is to test the CPU sharing between competing tasks with and + without VMs. The model is not very complex, but the corresponding code is somewhat intricated, thus the need for such an + extensive testing. In this test, ``( [o]2 )4`` denotes a test with only one task (only one ``o``) on a VM with two cores (``[ + ]2``), which is itself on a PM with four cores (``( )4``). Likewise, ``( [oo]1 [ ]1 )2`` tests 2 VMs with one core each, one of + them being empty and the other containing 2 active tasks. Both VMs are located on a PM with two cores. |br| + For each of these tests, we ensure that the performance delivered to each task matches our expectations, and that the reported + amount of used cores is also correct to ensure correct energy predictions. + +* We also have several **torture tests**, such as `teshsuite/s4u/comm-pt2pt/comm-pt2pt.cpp + `_ which tests exhaustively each + case of a communication matching when no error is involved. Regular, asynchronous, detached communications, and communications + with a permanent receiver declared are tests, both with the send first and with the receive first. Again, we have a tiny DSL + to specify the tests to do (see the ``usage()`` function). + + `teshsuite/s4u/activity-lifecycle/ `_ + tortures all kind of activities (sleep, exec, comm and direct-comm). It kills their ressource at several instants, kills the + host hosting the running actor, test the activity after death, etc. This time also, we have a little DSL but this time in the + code: the source is heavily loaded with templates to make it easier to write many such tests, at the expense of readability. + + SimGrid also features a `chaos monkey `_ to apply torture testing to complex + applications. It is composed of a plugin (embeeded in any SimGrid simulation) that can be used to get info about the resources + and the timestamps at which actions happens, or to kill a given resource at a given time. It also features `a script + `_ that uses this information to launch a given + simulation many times, killing each resource at each timestamp to see how SimGrid and your code react to these failures. The + monkey can even run your simulation in Valgrind to detect problems that would be silent otherwise. Try passing + ``--cfg=plugin:cmonkey`` to your simulations for more information. We currently have a master-workers example (in both C++ and + Python) and a semaphore example (in C++ only) in ``teshsuite/s4u``. + +Continuous integrations +^^^^^^^^^^^^^^^^^^^^^^^ + +We have many online build bots that launch the tests on various configurations and operating systems. The results are centralized on two Jenkins jobs: `the main +one `_ runs all tests on a variety of systems for each commit, while `Nightly +`_ runs some additional code analysis every night. Several sister projects built on top of SimGrid regularly +test our git too. The FramaGit project gathers some additional `build badges `_, and results are posted on the `bot-office +channel `_ on Mattermost. Our code quality is tested every night using `SonarQube +`_ , and the `Debian build daemon `_ test each +release on several CPU architectures. We maintain some scripts to interact with these tools under ``tools/cmake``. + +Interacting with git +-------------------- + +The SimGrid community is relatively small and active. We are not used to maintain long-standing branches but instead, we strive to do our changes in an +incremental way, commiting all intermediary steps to the main branch. The only thing is to ensure that you don't break things on the path, i.e. that all tests +pass for all commits. If you prefer to do a branch to accumulate some commits in a branch, you should strive to make so for a short period of time to reduce the +burden of the branch maintenance. Large changes happen from time to time to the SimGrid source code, and your branch may become hard to rebase. + +It is nice if your commit message could follow the git habits, explained in this `blog post +`_, or in the `style guide of Atom +`_. + +Type naming standard +-------------------- + +* Filenames shall be unique in the whole project (because of a bug in Sonar coverage computation). + +In C++: + +* Fields, methods and variables are in snake_case(); +* Classes and Enum names are in UpperCamelCase; +* Enum values are in UPPER_SNAKE_CASE, just as constants. + +* Files of public modules are usually named ``api_Class.cpp`` and ``api/Class.hpp`` (e.g. ``src/s4u/s4u_ConditionVariable.cpp`` and + ``include/simgrid/s4u/ConditionVariable.hpp``). +* Files of internal modules are usually named ``Class.cpp`` and ``Class.hpp`` (e.g. ``src/kernel/activity/Activity.cpp`` and + ``src/kernel/activity/Activity.hpp``) unless it raises name conflicts. + +In C: + +* Getters and setters are named ``sg_object_get_field()`` and ``sg_object_field()`` (e.g. ``sg_link_get_name()`` and ``sg_link_set_data()``); +* Variables and functions are snake_case(); +* Typedefs do not hide the pointers, i.e. the * must be explicit. ``char* sg_host_get_name(sg_host_t* host)``. + +Unsorted hints +-------------- + +* To thoroughly test your changes before pushing your commits, use several cmake configurations under sub-trees of ``build/`` + (that is ignored by git) as explained in :ref:`install_cmake_outsrc`. For example, I have the following directories: + build/clang build/full build/mc (but YMMV). + +* If you add or remove a file, you can check that everything is correctly setup with ``make distcheck``. + +* If everything gets crazy, as if it were not using the code that you actually compile, well, maybe it's using another version + of SimGrid on your disk. Use ``ldd`` on any simulator to check which library gets used. If you installed a SimGrid package, + you probably need to uninstall it. + +* If you break the logs, you want to define XBT_LOG_MAYDAY at the beginning of log.h. It deactivates the whole logging + mechanism, switching to printfs instead. SimGrid then becomes incredibly verbose, but it you let you fixing things. + +.. |br| raw:: html + +
diff --git a/docs/source/Deploying_your_application.rst b/docs/source/Deploying_your_application.rst index e3cece2b5a..4cd1287909 100644 --- a/docs/source/Deploying_your_application.rst +++ b/docs/source/Deploying_your_application.rst @@ -76,14 +76,6 @@ This tag starts a new actor executing the given function on a given host. with :cpp:func:`simgrid::s4u::Engine::register_actor` or with :cpp:func:`simgrid::s4u::Engine::register_function`. - If you are stuck with MSG, use :cpp:func:`MSG_process_create`, - :cpp:func:`MSG_process_create_with_arguments` or - :cpp:func:`MSG_process_create_with_environment`. - - There is nothing to do in Java, as SimGrid uses introspection abilities to - retrieve the classes from their names. You must then use the full class name - (including the package name) in your XML file. - :``start_time``: Useful to delay the start of your actor. -1 starts the actor immediately. diff --git a/docs/source/Design_goals.rst b/docs/source/Design_goals.rst index 956a23d18d..ba294568b3 100644 --- a/docs/source/Design_goals.rst +++ b/docs/source/Design_goals.rst @@ -1,161 +1,174 @@ -SimGrid's Design Goals +.. _design: + +SimGrid Design Goals ###################### -Any SimGrid simulation comes down to a set of **actors** using some -**resources** through **activities**. SimGrid provides several kinds of -resources (link, CPU, disk, and synchronization objects such as mutex -or semaphores) along with the corresponding activity kinds -(communication, execution, I/O, lock). SimGrid users provide a -platform instantiation (list of interconnected resources) and an +A SimGrid simulation boils down to a set of **actors** that use +**resources** by performing **activities**. SimGrid provides several kinds of +resources (link, CPU, disk, and synchronization objects such as mutexes +and semaphores) along with the corresponding kinds of activities +(communication, execution, I/O, synchronization). SimGrid users provide a +platform instantiation (sets of interconnected resources) and an application (the code executed by actors) along with the actors' placement on the platform. -The actors (ie, the user code) can only interact with the platform -through activities, that are somewhat similar to synchronizations. -Some are very natural (locking a mutex is a synchronization with the -other actors using the same mutex) while others activities constitute -more original synchronization: execution, communication, and I/O have a -quantitative component that depends on the resources. But still, -writing some data to disk is seen as a synchronization with the other -actors using the same disk. When you lock a mutex, you can proceed -only when that mutex gets unlocked by someone else. Similarly, when you -do an I/O, you can proceed once the disk delivered enough performance -to fulfill your demand (along with the concurrent demands of the other -actors occurring at the same time). Communication activities have both a -qualitative component (the actual communication starts only when both -the sender and receiver are ready to proceed) and a quantitative -component (consuming the communication power of the link resources). - -The design of SimGrid is shaped by several design goals: +The actors (i.e., the user code) can only interact with the platform +through activities, which are somewhat similar to synchronizations. Some +are very natural (locking a mutex is a synchronization with the other +actors that use the same mutex). Others activities implement more atypical +kinds of synchronization: execution, communication, and I/O have a +quantitative component that depends on the resources. Regardless, in +SimGrid writing some data to disk, for instance, is seen as a +synchronization with the other actors that use the same disk. When you lock +a mutex, you can proceed only when that mutex gets unlocked by someone +else. Similarly, when you do an I/O, you can proceed only once the disk +has delivered enough performance to fulfill your demand (while competing +with concurrent demands for that same disk made by other actors). +Communication activities have both a qualitative component (the actual +communication starts only when both the sender and receiver are ready to +proceed) and a quantitative component (consuming the communication power of +the link resources). + +The design of SimGrid is driven by several design goals: - **reproducibility**: re-executing the same simulation must lead to the exact same outcome, even if it runs on another computer or - operating system. When possible, this should also be true when you - use another version of SimGrid. - - **speed**: running a given simulation should be as fast as possible - - **versatility**: ability to simulate many kinds of distributed systems - and resource models. But the simulation should be parsimonious too, - to not hinder the tool's usability. SimGrid tries to provide sane + operating system. When possible, this should also be true across different + versions of SimGrid. + - **sweet spot between simulation accuracy and simulation speed**: running a given simulation should be as fast as possible but predict + correct performance trends (or even provide accurate predictions when correctly calibrated). + - **versatility**: ability to simulate many kinds of distributed system and application, while remaining parsimonious so as to not hinder usability. SimGrid tries to provide sane default settings along with the possibility to augment and modify - the provided models and their default settings. - - **scalability**: ability to deal with very large simulations. In the - number of actors, in the size of the platform, in the number of - events, or all together. + the provided models and their settings for each relevant use case. + - **scalability**: ability to deal with very large simulations in terms of the + number of actors, the size of the platform, the number of + events, or all all the above. Actors and activities ********************* -The first crux of the SimGrid design lays in the interaction between -each actor and the activities. For the sake of reproducibility, the -actors cannot interact directly with their environment: every -modification request is serialized through a central component that -processes them in a reproducible order. For the sake of speed, SimGrid -is designed as an operating system: the actors issue **simcalls** to a -simulation kernel that is called **maestro** (because it decides which -actors can proceed and which ones must wait). - -In practice, a SimGrid simulation is a suite of so-called **scheduling -rounds**, during which all actors that are not currently blocked on a -simcall get executed. For that, maestro passes the control flow to the -code of each actor, that are written in either C++, C, Fortran, Python, -or Java. The control flow then returns to the maestro when the actor -blocks on its next blocking simcall. Note that the time it takes to -execute the actor code has to be reported to the simulator using -execution activities. SMPI programs are automatically benchmarked -while these executions must be manually reported in S4U. The simulated +At the core of the SimGrid design lies the interactions between actors and +activities. For the sake of reproducibility, the actors cannot interact +directly with their environment: every interaction is serialized through a +central component that processes them in a reproducible order. For the sake +of speed, SimGrid is designed as an operating system: the actors issue +**simcalls** (akin to system calls) to a simulation kernel (akin to an OS +kernel) called the **maestro** that decides which actors can proceed and +which ones must wait. + +A SimGrid simulation proceeds as a sequence of **scheduling +rounds**. At each round, all actors that are not currently blocked on a +simcall get executed. This is done by the maestro, which passes the control flow to the +code of each actor, written by the user in either C++, C, Fortran or Python. +The control flow is returned to the maestro when the actor +blocks on its next simcall. If the time it takes to +execute the actor's code is of import to the simulator, it has to be the object +of execution activities. SMPI programs are automatically benchmarked, but +these execution activities must be manually created if using S4U. The simulated time is discrete in SimGrid and only progresses between scheduling -rounds, so all events occurring during a given scheduling round occur -at the exact same simulated timestamp, even if the actors are usually -executed sequentially on the real platform. +rounds. So all events occurring during a given scheduling round occur +at the exact same simulated time, even if the actors are usually +executed sequentially on a real platform. + +.. image:: img/design-scheduling-simulatedtime.svg + :scale: 80% + :align: center -To modify their environment, the actors issue either **immediate -simcalls** that take no time in the simulation (e.g.: spawning another -actor), or **blocking simcalls** that must wait for future events (e.g.: +To modify their environment actors issue either **immediate +simcalls** that take no time in the simulation (e.g., spawning another +actor), or **blocking simcalls** that must wait for future events (e.g., mutex locks require the mutex to be unlocked by its owner; -communications wait for the network to provide enough communication -performance to fulfill the demand). A given scheduling round is +communications wait for the network to provide have provided enough communication +bandwidth to transfer the data). A given scheduling round is usually composed of several sub-scheduling rounds during which immediate simcalls are resolved. This ends when all actors are either terminated or within a blocking simcall. The simulation models are -then used to compute the time at which the first next simcall -terminates. The time is advanced to that point, and a new scheduling -round begins with all actors that got unblocked at that timestamp. +then used to compute the time at which the first pending simcall +terminates. Time is advanced to that point, and a new scheduling +round begins with all actors that became unblocked at that timestamp. Context switching between the actors and maestro is highly optimized for the sake of simulation performance. SimGrid provides several implementations of this mechanism, called **context factories**. These implementations fall into two categories: Preemptive contexts are -based on full-fledged system threads such as pthread on Linux or Java -threads in the JVM. They are usually better supported by external +based on standard system threads from the libstdc library. +They are usually better supported by external debuggers and profiling tools, but less efficient. The most efficient factories use non-preemptive mechanisms, such as SysV's ucontexts, boost's context, or our own hand-tuned implementation, that is written in assembly language. This is possible because a given actor is never interrupted between consecutive simcalls in SimGrid. -For the sake of performance, actors can be executed in parallel using -several system threads for non-preemptive contexts. But in our -experience, this rarely leads to any performance improvement because -most applications simulated on top of SimGrid are fine-grained: when -the simulation performance really matters, the users tend to abstract -away any large computations to efficiently simulate the control flow -of their application. In addition, parallel simulation puts unpleasant -restrictions on the user code, that must be correctly isolated. To be -honest, most of the existing SMPI implementation cannot be used in -parallel yet. +.. image:: img/design-scheduling-wallclock.svg + :scale: 80% + :align: center + +For the sake of performance, actors can be executed in parallel using several system threads which execute all actors in +turn. In our experience, however, this rarely leads to significant performance improvement because most applications simulated with +SimGrid are fine-grained: it's often not worth simulating actors in parallel because the amount of work performed by each actor is too +small. This is because the users tend to abstract away any large computations to simulate the control flow of their +application efficiently. In addition, parallel simulation puts restrictions on the user's code. +For example, the existing SMPI implementation cannot be used in parallel yet. + +.. image:: img/design-scheduling-parallel.svg + :scale: 80% + :align: center Parsimonious model versatility ****************************** -Another orthogonal crux of the SimGrid design is the parsimonious -versatility in modeling. For that, we tend to unify all resource and -activity kinds. As you have seen, we parallel the classical notion of -**computational power** with the more original **communication power** and -**I/O power**. Asynchronous executions are less common than the -asynchronous communications that proliferate in MPI but they are still -provided for sake of symmetry: they even prove useful to efficiently -simulate thread pools. Note that asynchronous mutex locking is still to be -added to SimGrid atm. The notion of **pstate** was introduced to model -the stepwise variation of computational speed depending on the DVFS, -and was reused to model the bootup and shutdown phases of a CPU: the -computational speed is 0 at these specific pstates. This pstate notion -was extended to represent the fact that the bandwidth provided by a -wifi link to a given station depends on its signal-noise ratio (SNR). - -Further on this line, all provided resource models are very comparable -internally. They rely on linear inequation systems, stating for -example that the sum of the computational power received by all -computation activities located on a given CPU cannot overpass the -computational power provided by this resource. This extends nicely to -multi-resources activities such as communications using several links, -and also to the so-called parallel tasks (abstract activities -representing a parallel execution kernel consuming both the -communication and computational power of a set of machines). Specific -coefficients are added to the linear system to reflect how the real -resources are shared between concurrent usages. The resulting system -is then solved using a max-min objective function that maximizes the -minimum of all shares allocated to activities. Our experience shows -that this approach can successfully be used for fast yet accurate -simulations of complex phenomena, provided that the model's -coefficients and constants are carefully tailored and instantiated to -that phenomenon. +Another main design goal of SimGrid is parsimonious versatility in +modeling, that is, aiming to simulate very different things using the same +simulation abstractions. To achieve this goal, the SimGrid implementation +tends to unify all resource kinds and activity kinds. For instance, the +classical notion of **computational power** is mirrored for +**communication power** and **I/O power**. Asynchronous executions are less +common than the asynchronous communications that proliferate in MPI but +they are still provided for sake of symmetry: they even prove useful to +simulate thread pools efficiently. SimGrid also provides asynchronous mutex +locks for symmetry. The notion of **pstate** was introduced to model the +step-wise variation of computational speed depending on the DVFS, and was +reused to model the bootup and shutdown phases of a CPU: the computational +speed is 0 at these specific pstates. This pstate notion was extended to +represent the fact that the bandwidth provided by a wifi link to a given +station depends on its signal-noise ratio (SNR). In summary, simulation +abstractions are re-used and/or generalized as much as possible to serve a +wide range of purposes. + +Furthermore, all provided resource models are very similar internally. They +:ref:`rely on linear inequation systems `, stating for example +that the sum of the computational power received by all computation +activities located on a given CPU cannot exceed the computational power +provided by this CPU. This extends nicely to multi-resources activities +such as communications that use several links, and also to parallel tasks +(abstract activities representing a parallel execution kernel that consumes +both the communication and computational power of a set of machines) or +fluid I/O streams (abstract activities representing a data stream from disk +to disk through the network). Specific coefficients are added to the linear +system to mimic how the resources behavior in the real world. The resulting +system is then solved using a max-min objective function that maximizes the +minimum of all shares allocated to activities. Our experience shows that +this approach can successfully be used for fast yet accurate simulations of +complex phenomena, provided that the model's coefficients and constants are +carefully :ref:`calibrated `, i.e. tailored and +instantiated to that phenomenon. Model-checking ************** -Even if it was not in the original goals of SimGrid, the framework now +Even if it was not in its original goals, SimGrid now integrates a full-featured model-checker (dubbed MC or Mc SimGrid) that can exhaustively explore all execution paths that the application could experience. Conceptually, Mc SimGrid is built upon the ideas presented previously. Instead of using the resource models to compute -the order simcall terminations, it explores every order that is +the order of simcall terminations, it explores every order that is causally possible. In a simulation entailing only three concurrent events (i.e., simcalls) A, B, and C, it will first explore the -scenario where the activities order is ABC, then the ACB order, then +scenario where the activities order is ABC, then ACB, then BAC, then BCA, then CAB and finally CBA. Of course, the number of scenarios to explore grows exponentially with the number of simcalls in the simulation. Mc SimGrid leverages reduction techniques to avoid -re-exploring equivalent traces. +re-exploring redundant traces. In practice, Mc SimGrid can be used to verify classical `safety and liveness properties @@ -168,6 +181,5 @@ Reduction (DPOR) `_ and `state equality `_. -Mc SimGrid is far more experimental than other parts of the framework, -such as SMPI that can now be used to run many full-featured MPI codes -out of the box. +Mc SimGrid is more experimental than other parts of SimGrid, such as SMPI that can now be used to run many full-featured +MPI codes out of the box, but it's constantly improving. diff --git a/docs/source/Doxyfile b/docs/source/Doxyfile index c9ea8a311d..0e1decc2b3 100644 --- a/docs/source/Doxyfile +++ b/docs/source/Doxyfile @@ -2,14 +2,15 @@ INPUT = ../../include/simgrid/forward.h INPUT += ../../include/simgrid/plugins/ INPUT += ../../include/simgrid/s4u/ -INPUT += ../../include/simgrid/msg.h INPUT += ../../include/simgrid/actor.h +INPUT += ../../include/simgrid/activity_set.h INPUT += ../../src/s4u/s4u_Actor.cpp INPUT += ../../include/simgrid/barrier.h INPUT += ../../include/simgrid/comm.h INPUT += ../../include/simgrid/cond.h INPUT += ../../include/simgrid/engine.h INPUT += ../../include/simgrid/exec.h +INPUT += ../../include/simgrid/Exception.hpp INPUT += ../../include/simgrid/host.h INPUT += ../../src/s4u/s4u_Host.cpp #INPUT += ../../include/simgrid/instr.h @@ -19,10 +20,11 @@ INPUT += ../../include/simgrid/mutex.h INPUT += ../../include/simgrid/semaphore.h INPUT += ../../include/simgrid/vm.h INPUT += ../../include/simgrid/zone.h +INPUT += ../../include/smpi/smpi.h +INPUT += ../../include/xbt/function_types.h INPUT += ../../include/xbt/dynar.h INPUT += ../../src/xbt/dynar.cpp INPUT += ../../include/xbt/signal.hpp -INPUT += ../../src/msg/ INPUT += ../../src/plugins/ RECURSIVE = YES @@ -59,17 +61,13 @@ PREDEFINED += \ SG_END_DECL= \ SIMGRID_REGISTER_PLUGIN(id,desc,init)= \ XBT_PUBLIC= \ - XBT_EXPORT_NO_IMPORT= \ - XBT_IMPORT_NO_EXPORT= \ XBT_PUBLIC_DATA=extern \ - XBT_PUBLIC= \ - XBT_INLINE= \ - XBT_ALWAYS_INLINE= \ XBT_PRIVATE= \ + XBT_ALWAYS_INLINE= \ + XBT_ATTRIB_NOINLINE= \ XBT_ATTRIB_NORETURN= \ XBT_ATTRIB_UNUSED= \ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(cname,parent,desc)= \ - XBT_ATTRIB_DEPRECATED_v333(mesg)= \ - XBT_ATTRIB_DEPRECATED_v334(mesg)= \ - XBT_ATTRIB_DEPRECATED_v335(mesg)= \ - XBT_ATTRIB_DEPRECATED_v336(mesg)= + XBT_ATTRIB_DEPRECATED_v338(mesg)= \ + XBT_ATTRIB_DEPRECATED_v339(mesg)= \ + XBT_ATTRIB_DEPRECATED_v340(mesg)= diff --git a/docs/source/Examples.rst b/docs/source/Examples.rst new file mode 100644 index 0000000000..5dc41a6fc8 --- /dev/null +++ b/docs/source/Examples.rst @@ -0,0 +1 @@ +.. include:: ../../examples/README.rst \ No newline at end of file diff --git a/docs/source/Installing_SimGrid.rst b/docs/source/Installing_SimGrid.rst index 9d5d606ab1..39cc872e8f 100644 --- a/docs/source/Installing_SimGrid.rst +++ b/docs/source/Installing_SimGrid.rst @@ -1,4 +1,4 @@ -.. Copyright 2005-2022 +.. Copyright 2005-2023 .. _install: @@ -7,8 +7,7 @@ Installing SimGrid SimGrid should work out of the box on Linux, macOS, FreeBSD, and -Windows (under Windows, you need to install the Windows Subsystem -Linux to get more than the Java bindings). +Windows (with WSL). Pre-compiled Packages --------------------- @@ -22,7 +21,6 @@ following lines, or several lines if you need several languages. .. code-block:: console $ apt install libsimgrid-dev # if you want to develop in C or C++ - $ apt install simgrid-java # if you want to develop in Java $ apt install python3-simgrid # if you want to develop in Python If you use the Nix_ package manager, the latest SimGrid release is packaged as ``simgrid`` in Nixpkgs_. @@ -45,35 +43,16 @@ email. .. _simgrid AUR package: https://aur.archlinux.org/packages/simgrid/ .. _AUR official documentation: https://wiki.archlinux.org/title/Arch_User_Repository -.. _install_java_precompiled: - -Stable Java Package +Binaries from macOS ^^^^^^^^^^^^^^^^^^^ -The jar file can be retrieved from the `Release page -`_. This file is -self-contained, including the native components for Linux, macOS and -Windows. Copy it to your project's classpath and you're set. - -Nightly built Java Package -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Head to the corresponding `GitHub Action `_ -and pick the last green build. At the bottom of the build page, click on the ``jar-final`` artefact. -Open this zip file to find the jar you need. This jar can be used under Linux, Mac OSX or Windows, as you wish. - -Binary Java Troubleshooting -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +SimGrid can be found in the Homebrew package manager. Troubleshooting: -Here are some error messages that you may get when trying to use the -binary Java package. +warning: dylib (libsimgrid.dylib) was built for newer macOS version (14.0) than being linked (13.3) + This was reported with the SimGrid version from Homebrew on a Mac book air M1 (ARM). + The solution is simply to export this variable before the compilation of your binaries: -Your architecture is not supported by this jarfile - If your system is not supported, you should compile your - own jarfile :ref:`by compiling SimGrid ` from the source. -Library not found: boost-context - You should obviously install the ``boost-context`` library on your - machine, for example with ``apt``. + ``export MACOSX_DEPLOYMENT_TARGET=14.0`` .. _deprecation_policy: @@ -107,12 +86,14 @@ but that's even more so for these unreleased versions). Installing from the Source -------------------------- +.. _install_src_deps: + Getting the Dependencies ^^^^^^^^^^^^^^^^^^^^^^^^ C++ compiler (either g++, clang, or icc). - We use the C++14 standard, and older compilers tend to fail on - us. It seems that g++ 5.0 or higher is required nowadays (because of + We use the C++17 standard, and older compilers tend to fail on + us. It seems that g++ 7.0 or higher is required nowadays (because of boost). SimGrid compiles well with `clang` or `icc` too. Python 3. SimGrid should build without Python. That is only needed by our regression test suite. @@ -120,19 +101,26 @@ cmake (v3.5). ``ccmake`` provides a nicer graphical interface compared to ``cmake``. Press ``t`` in ``ccmake`` if you need to see absolutely all configuration options (e.g., if your Python installation is not standard). -boost (at least v1.48, v1.59 recommended) - - On Debian / Ubuntu: ``apt install libboost-dev libboost-context-dev`` - - On CentOS / Fedora: ``yum install boost-devel`` +boost mandatory components (at least v1.48, v1.59 recommended) + - On Debian / Ubuntu: ``apt install libboost-dev`` + - On CentOS / Fedora: ``dnf install boost-devel`` - On macOS with homebrew: ``brew install boost`` +boost recommended components (optional). + - boost-context may be used instead of our own fast context switching code which only works on amd64. + - boost-stacktrace is used to get nice stacktraces on errors in SimGrid. + - On Debian / Ubuntu: ``apt install libboost-context-dev libboost-stacktrace-dev`` +python bindings (optional): + - On Debian / Ubuntu: ``apt install pybind11-dev python3-dev`` +Model-checking mandatory dependencies + - On Debian / Ubuntu: ``apt install libevent-dev`` Eigen3 (optional) - On Debian / Ubuntu: ``apt install libeigen3-dev`` - - On CentOS / Fedora: ``yum install eigen3-devel`` + - On CentOS / Fedora: ``dnf install eigen3-devel`` - On macOS with homebrew: ``brew install eigen`` - - Use EIGEN3_HINT to specify where it's installed if cmake doesn't find it automatically. -Java (optional): - - Debian / Ubuntu: ``apt install default-jdk libgcj18-dev`` (or - any version of libgcj) - - macOS or Windows: Grab a `full JDK `_ + - Use EIGEN3_HINT to specify where it's installed if cmake doesn't find it automatically. Set EIGEN3_HINT=OFF to disable detection even if it could be found. +JSON (optional, for the DAG wfcommons loader) + - On Debian / Ubuntu: ``apt install nlohmann-json3-dev`` + - Use nlohmann_json_HINT to specify where it's installed if cmake doesn't find it automatically. For platform-specific details, please see below. @@ -146,7 +134,7 @@ Grab the last **stable release** from `FramaGit $ tar xf simgrid-3-XX.tar.gz $ cd simgrid-* - $ cmake -DCMAKE_INSTALL_PREFIX=/opt/simgrid -GNinja. + $ cmake -DCMAKE_INSTALL_PREFIX=/opt/simgrid -GNinja . $ make $ make install @@ -183,8 +171,7 @@ cmake itself. files in the tree, you may need to wipe out your complete tree and start with a fresh one when you install new dependencies. - Another (better) solution is to :ref:`build out of the source tree - `. + A better solution is to :ref:`build out of the source tree `. Generic build-time options """""""""""""""""""""""""" @@ -219,7 +206,7 @@ Note that the dot at the end is mandatory (see :ref:`install_cmake_outsrc`). .. code-block:: console - $ cmake -DCC=clang -DCXX=clang++ . + $ cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ . SimGrid compilation options """"""""""""""""""""""""""" @@ -253,13 +240,6 @@ enable_documentation (on/OFF) as easy as it used to be, and you should probably use the online version for now. -enable_java (on/OFF) - Generates the java bindings of SimGrid. You must also enable MSG for - this to work. - -enable_lib_in_jar (ON/off) - Embeds the native java bindings into the produced jar file. - enable_lto (ON/off) Enables the *Link Time Optimization* in the C++ compiler. This feature really speeds up the code produced, but it is fragile @@ -272,39 +252,39 @@ enable_mallocators (ON/off) Activates our internal memory caching mechanism. This produces faster code, but it may fool the debuggers. -enable_model-checking (on/OFF) - Activates the formal verification mode. This will **hinder - simulation speed** even when the model checker is not activated at - run time. - -enable_msg (on/OFF) - Activates the :ref:`MSG ` legacy interface. +enable_model-checking (ON/off) + Activates the verification mode. This should not impact the performance of your simulations if you build it but don't use it, + but you can still disable it to save some compilation time. enable_ns3 (on/OFF) - Activates the ns-3 bindings. See section :ref:`model_ns3`. + Activates the ns-3 bindings. See section :ref:`models_ns3`. enable_smpi (ON/off) Allows one to run MPI code on top of SimGrid. -enable_smpi_MBI_testsuite (on/OFF) - Adds many extra tests for the model checker module. +enable_testsuite_McMini (on/OFF) + Adds several extra tests for the model checker module (targeting threaded applications). + +enable_testsuite_smpi_MBI (on/OFF) + Adds many extra tests for the model checker module (targeting MPI applications). -enable_smpi_MPICH3_testsuite (on/OFF) +enable_testsuite_smpi_MPICH3 (on/OFF) Adds many extra tests for the MPI module. minimal-bindings (on/OFF) Take as few optional dependencies as possible, to get minimal - library bindings in Java and Python. + library bindings in Python. NS3_HINT (empty by default) Alternative path into which ns-3 should be searched for. EIGEN3_HINT (empty by default) Alternative path into which Eigen3 should be searched for. + Providing the value OFF as an hint will disable the detection alltogether. SIMGRID_PYTHON_LIBDIR (auto-detected) - Where to install the Python module library. By default, it is set to the cmake Python3_SITEARCH variable if installing to /usr, - and a modified version of that variable if installing to another path. Just force another value if the auto-detected default + Where to install the Python module library. By default, it is set to the cmake Python3_SITEARCH variable if installing to /usr, + and a modified version of that variable if installing to another path. Just force another value if the auto-detected default does not fit your setup. SMPI_C_FLAGS, SMPI_CXX_FLAGS, SMPI_Fortran_FLAGS (string) @@ -357,10 +337,9 @@ existing targets are not really for public consumption so don't worry if some do not work for you. - **make**: Build the core of SimGrid that gets installed, but not any example. -- **make tests**: Build the tests and examples. +- **make examples**: Build the examples, which are needed by the tests. - **make simgrid**: Build only the SimGrid library. Not any example nor the helper tools. - **make s4u-comm-pingpong**: Build only this example (works for any example) -- **make java-all**: Build all Java examples and their dependencies - **make python-bindings**: Build the Python bindings - **make clean**: Clean the results of a previous compilation - **make install**: Install the project (doc/ bin/ lib/ include/) @@ -434,25 +413,15 @@ Windows-specific instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The best solution to get SimGrid working on windows is to install the -Ubuntu subsystem of Windows 10. All of SimGrid (but the model checker) -works in this setting. - -Native builds not very well supported. Have a look to our `appveypor -configuration file -`_ to -see how we manage to use mingw-64 to build the DLL that the Java file -needs. - -The drawback of MinGW-64 is that the produced DLL are not compatible -with MS Visual C. Some clang-based tools seem promising to fix this, -but this is of rather low priority for us. It it's important for you -and if you get it working, please @ref community_contact "tell us". +Ubuntu subsystem of Windows 10. All of SimGrid +works in this setting. Native builds never really worked, and they are +disabled starting with SimGrid v3.33. Python-specific instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Once you have the Python development headers installed as well as a -recent version of the `pybind11 ` +recent version of the `pybind11 `_ module (version at least 2.4), recompiling the Python bindings from the source should be as easy as: @@ -468,68 +437,16 @@ simgrid without downloading the source with pip: $ pip install simgrid -Java-specific instructions -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Once you have the `full JDK `_ installed, -things should be as simple as: - -.. code-block:: console - - $ cmake -Denable_java=ON -Dminimal-bindings=ON . - $ make simgrid-java_jar # Only build the jarfile - -After the compilation, the file ```simgrid.jar``` is produced in the -root directory. - -**Troubleshooting Java Builds** - -Sometimes, the build system fails to find the JNI headers. First locate them as follows: +If you installed SimGrid to a non-standard directory (such as ``/opt/simgrid`` as advised earlier), you should tell python where +to find the libraries as follows (notice the elements suffixed to the configured prefix). .. code-block:: console - $ locate jni.h - /usr/lib/jvm/java-8-openjdk-amd64/include/jni.h - /usr/lib/jvm/java-9-openjdk-amd64/include/jni.h - /usr/lib/jvm/java-10-openjdk-amd64/include/jni.h + $ PYTHONPATH="/opt/simgrid/lib/python3/dist-packages" LD_LIBRARY_PATH="/opt/simgrid/lib" python your_script.py - -Then, set the JAVA_INCLUDE_PATH environment variable to the right -path, and relaunch cmake. If you have several versions of JNI installed -(as above), pick the one corresponding to the report of -``javac -version`` +You can add those variables to your bash profile to not specify it each time by adding these lines to your ``~/.profile``: .. code-block:: console - $ export JAVA_INCLUDE_PATH=/usr/lib/jvm/java-8-openjdk-amd64/include/ - $ cmake -Denable_java=ON . - $ make - -Note that the filename ```jni.h``` was removed from the path. - -Linux Multi-Arch specific instructions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -On a multiarch x86_64 Linux, it should be possible to compile a 32-bit -version of SimGrid with something like: - -.. code-block:: console - - $ CFLAGS=-m32 \ - CXXFLAGS=-m32 \ - FFLAGS=-m32 \ - PKG_CONFIG_LIBDIR=/usr/lib/i386-linux-gnu/pkgconfig/ \ - cmake . \ - -DCMAKE_SYSTEM_PROCESSOR=i386 \ - -DCMAKE_Fortran_COMPILER=/some/path/to/i686-linux-gnu-gfortran \ - -DGFORTRAN_EXE=/some/path/to/i686-linux-gnu-gfortran \ - -DSMPI_C_FLAGS=-m32 \ - -DSMPI_CXX_FLAGS=-m32 \ - -DSMPI_Fortran_FLAGS=-m32 - -If needed, implement ``i686-linux-gnu-gfortran`` as a script: - -.. code-block:: shell - - #!/usr/bin/env sh - exec gfortran -m32 "$@" + export PYTHONPATH="$PYTHONPATH:/opt/simgrid/lib/python3/dist-packages" + export LD_LIBRARY_PATH="$PYTHONPATH:/opt/simgrid/lib" diff --git a/docs/source/Introduction.rst b/docs/source/Introduction.rst index 572c6675cf..32975c934f 100644 --- a/docs/source/Introduction.rst +++ b/docs/source/Introduction.rst @@ -9,201 +9,90 @@ Introduction

-Main Concepts -------------- - -Typical Study based on SimGrid -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Any SimGrid study entails the following components: - - - The studied **application**. This can be either a distributed - algorithm described in our simple APIs or a full-featured real - parallel application using for example the MPI interface - :ref:`(more info) `. - - - The **simulated platform**. This is a description of a given - distributed system (machines, links, disks, clusters, etc). Most of - the platform files are written in XML but a new C++ programmatic - interface has recently been introduced. SimGrid makes it easy to - augment the Simulated Platform with a Dynamic Scenario where for - example the links are slowed down (because of external usage) or the - machines fail. You even have support to specify the applicative - workload that you want to feed to your application - :ref:`(more info) `. - - - The application's **deployment description**. In SimGrid - terminology, the application is an inert set of source files and - binaries. To make it run, you have to describe how your application - should be deployed on the simulated platform. You need to specify - which process is mapped onto which machine, along with their parameters - :ref:`(more info) `. - - - The **platform models**. They describe how the simulated platform - reacts to the actions of the application. For example, they compute - the time taken by a given communication on the simulated platform. - These models are already included in SimGrid, and you only need to - pick one and maybe tweak its configuration to get your results - :ref:`(more info) `. - -These components are put together to run a **simulation**, that is an -experiment or a probe. Simulations produce **outcomes** (logs, -visualization, or statistical analysis) that help to answer the -**question** targeted by this study. - -Here are some questions on which SimGrid is particularly relevant: - - - **Compare an Application to another**. This is the classical use - case for scientists, who use SimGrid to test how the solution that - they contribute to compares to the existing solutions from the - literature. - - - **Design the best [Simulated] Platform for a given Application.** - Tweaking the platform file is much easier than building a new real - platform for testing purposes. SimGrid also allows for the co-design - of the platform and the application by modifying both of them. - - - **Debug Real Applications**. With real systems, is sometimes - difficult to reproduce the exact run leading to the bug that you - are tracking. With SimGrid, you are *clairvoyant* about your - *reproducible experiments*: you can explore every part of the - system, and your probe will not change the simulated state. It also - makes it easy to mock some parts of the real system that are not - under study. - -Depending on the context, you may see some parts of this process as -less important, but you should pay close attention if you want to be -confident in the results coming out of your simulations. In -particular, you should not blindly trust your results but always -strive to double-check them. Likewise, :ref:`you should question the -realism of your input configuration `, and we even -encourage you to :ref:`doubt (and check) the provided performance models -`. - -To ease such questioning, you really should logically separate these -parts in your experimental setup. It is seen as a very bad practice to -merge the application, the platform, and the deployment altogether. -SimGrid is versatile and your mileage may vary, but you should start -with your Application specified as a C++ or Java program, using one of -the provided XML platform files, and with your deployment in a separate -XML file. - -SimGrid Execution Modes -^^^^^^^^^^^^^^^^^^^^^^^ - -Depending on the intended study, SimGrid can be run in several execution modes. - -**Simulation Mode**. This is the most common execution mode, where you want -to study how your application behaves on the simulated platform under -the experimental scenario. - -In this mode, SimGrid can provide information about the time taken by -your application, the amount of energy dissipated by the platform to -run your application, and the detailed usage of each resource. - -**Model-Checking Mode**. This can be seen as a sort of exhaustive -testing mode, where every possible outcome of your application is -explored. In some sense, this mode tests your application for all -possible platforms that you could imagine (and more). - -You just provide the application and its deployment (number of -processes and parameters), and the model checker will -explore all possible outcomes by testing all possible message -interleavings: if at some point a given process can either receive the -message A first or the message B depending on the platform -characteristics, the model checker will explore the scenario where A -arrives first, and then rewind to the same point to explore the -scenario where B arrives first. - -This is a very powerful mode, where you can evaluate the correctness of -your application. It can verify either **safety properties** (assertions) -or **liveness properties** stating for example that if a given event -occurs, then another given event will occur in a finite amount of -steps. This mode is not only usable with the abstract algorithms -developed on top of the SimGrid APIs, but also with real MPI -applications (to some extent). - -The main limit of Model Checking lies in the huge amount of scenarios -to explore. SimGrid tries to explore only non-redundant scenarios -thanks to classical reduction techniques (such as DPOR and stateful -exploration) but the exploration may well never finish if you don't -carefully adapt your application to this mode. - -A classical trap is that the Model Checker can only verify whether -your application fits the properties provided, which is useless if you -have a bug in your property. Remember also that one way for your -application to never violate a given assertion is to not start at all, -because of a stupid bug. - -Another limit of this mode is that it does not use the performance -models of the simulation mode. Time becomes discrete: You can say for -example that the application took 42 steps to run, but there is no way -to know how much time it took or the number of watts that were dissipated. - -Finally, the model checker only explores the interleavings of -computations and communications. Other factors such as thread -execution interleaving are not considered by the SimGrid model -checker. - -The model checker may well miss existing issues, as it computes the -possible outcomes *from a given initial situation*. There is no way to -prove the correctness of your application in full generality with this -tool. - -**Benchmark Recording Mode**. During debug sessions, continuous -integration testing, and other similar use cases, you are often only -interested in the control flow. If your application applies filters to -huge images split into small blocks, the filtered image is probably not -what you are interested in. You are probably looking for a way to run -each computational kernel only once, and record the time it takes to cache it. -This code block can then be skipped in simulation -and replaced by a synthetic block using the cached information. The -simulated platform will take this block into account without requesting -the actual hosting machine to benchmark it. +What is SimGrid +--------------- -SimGrid Limits -^^^^^^^^^^^^^^ +SimGrid is a framework for developing simulators of distributed application executions on distributed platforms. It can +be used to prototype, evaluate and compare relevant platform configurations, system designs, and algorithmic approaches. -This framework is by no means the holy grail, able to solve -every problem on Earth. +What SimGrid allows you to do +---------------------------- -**SimGrid scope is limited to distributed systems.** Real-time -multi-threaded systems are out of this scope. You could probably tweak -SimGrid for such studies (or the framework could be extended -in this direction), but another framework specifically targeting such a -use case would probably be more suited. +Here are some objectives for which SimGrid is particularly relevant and has been used extensively: -**There is currently no support for 5G or LoRa networks**. -The framework could certainly be improved in this direction, but this -still has to be done. + - **Compare designs**. This is a classical use case for researchers/developers, who use SimGrid to assess how their contributed solution (a platform, system, application, and/or algorithm design) compares to existing solutions from the literature. -**There is no perfect model, only models adapted to your study.** The SimGrid -models target fast and large studies, and yet they target realistic results. In -particular, our models abstract away parameters and phenomena that are often -irrelevant to reality in our context. + - **Design the best [Simulated] Platform for a given Application.** Modifying a platform file use to drive simulations is much easier than building + real-world platforms for testing purposes. SimGrid also allows for the co-design of the platform and the application, as both can be modified with little work. -SimGrid is obviously not intended for a study of any phenomenon that our -abstraction removes. Here are some **studies that you should not do with -SimGrid**: + - **Debug Real Applications**. With real systems it is often difficult to reproduce the exact run that would lead to a bug that is being tracked. + With SimGrid, you are *clairvoyant* about your *reproducible experiments*: you can explore every part of the + system, and your exploration will not change the simulated state. It also makes it easy to mock or abstract away parts of the real system that + are not under study. - - Studying the effect of L3 vs. L2 cache effects on your application - - Comparing kernel schedulers and policies - - Comparing variants of TCP - - Exploring pathological cases where TCP breaks down, resulting in - abnormal executions. - - Studying security aspects of your application, in presence of - malicious agents. + - **Formally assess an algorithm**. Inspired by model checking, SimGrid provides an execution mode that does not + quantify an application's performance behavior, but that instead explores all causally possible outcomes of the application so as to evaluate application correctness. This exhaustive + search is ideal for finding bugs that are difficult to trigger experimentally. But because it is exhaustive, there is a limit to the scale of the applications for which it can be used. + +Anatomy of a project that uses SimGrid +-------------------------------------- + +Any project that uses SimGrid as its simulation framework comprises the following components: + + - An **application**. An application consists of one or more process that can either implement distributed algorithms described using a simple API (either in C++, Python or + C) or be part of a full-featured real parallel application implemented with, for example, the MPI standard :ref:`(more info) `. + + - A **simulated platform**. This is a description (in either XML or C++) of a distributed system's hardware (machines, links, + disks, clusters, etc). SimGrid makes it straightforward to augment the simulated platform with dynamic behaviors where, for example, the + links are slowed down (because of external usage) or the machines fail :ref:`(more info) `. + + - An application's **deployment description**. To simulate the execution of the application on the platform, they way in which the application is + deployed on the platform must be described. This is done by specifying which process is mapped onto which machine :ref:`(more + info) `. + + - **Platform models**. SimGrid implements models that describe how the simulated platform reacts to the simulated activities performed my + application processes. SimGrid provides a range of documented models, + which the user can select and configure for their particular use case. A + big selling point of SimGrid, which sets it apart from its competitors, + is that it can accurately model the network contention that results from + concurrent communications. :ref:`(more info) `. + + +The above components are put together to run a **simulation experiment** +that produces **outcomes** (logs, visualization, statistics) that help +answer the user's research and development **question**. The outcomes +typically include a timeline of the application execution and information +about its energy consumption. + + +We work hard to make SimGrid easy to use, but you should not blindly trust your results and always strive to validate +the simulation outcomes. Assessing the realism of these outcomes will lead you to better :ref:`calibrate the models `, +which is the best way to achieved high simulation accuracy. Please refer to the section :ref:`howto_science`. + +Using SimGrid in practice +------------------------- + +SimGrid is versatile and can be used in many ways, but the most typical setup is to specify your algorithm as a C++ or Python +program using our API, along with one of the provided XML platform files as shown in the **first tutorial** on +:ref:`usecase_simalgo`. If your application is already written in MPI, then you are in luck because SimGrid comes with MPI support, +as explained in our **second tutorial** on :ref:`usecase_smpi`. The **third tutorial** is on +:ref:`usecase_modelchecking`. Docker images are provided to run these tutorials without installing any software, other than Docker, on your machine. + +SimGrid comes with :ref:`many examples `, so that you can quick-start your simulator by +assembling and modifying some of the provided examples (see :ref:`this section ` on how to get your own project +to compile with SimGrid). An extensive documentation is available from the left menu bar. If you want to get an idea of how +SimGrid works you can read about its :ref:`design goals `. SimGrid Success Stories -^^^^^^^^^^^^^^^^^^^^^^^ +----------------------- SimGrid was cited in over 3,000 scientific papers (according to Google Scholar). Among them, `over 500 publications `_ (written by hundreds of individuals) use SimGrid as a scientific -instrument to conduct their experimental evaluation. These -numbers do not include the articles contributing to SimGrid. -This instrument was used in many research communities, such as +instrument to conduct experimental evaluations. These +numbers do not include those articles that directly contribute to SimGrid itself. +SimGrid was used in many research communities, such as `High-Performance Computing `_, `Cloud Computing `_, `Workflow Scheduling `_, @@ -214,8 +103,7 @@ This instrument was used in many research communities, such as `Peer-to-Peer Computing `_, `Network Architecture `_, `Fog Computing `_, or -`Batch Scheduling `_ -`(more info) `_. +`Batch Scheduling `_. If your platform description is accurate enough (see `here `_ or @@ -223,15 +111,16 @@ If your platform description is accurate enough (see SimGrid can provide high-quality performance predictions. For example, we determined the speedup achieved by the Tibidabo ARM-based cluster before its construction -(`paper `_). In this case, -some differences between the prediction and the real timings were due to -misconfigurations with the real platform. To some extent, -SimGrid could even be used to debug the real platform :) +(`paper `_). Some +differences between the simulated and the real timings were observed, and +turned out to be due to +misconfigurations in the real platform! +SimGrid can thus even be used to debug a real platform :) SimGrid is also used to debug, improve, and tune several large applications. `BigDFT `_ (a massively parallel code -computing the electronic structure of chemical elements developed by +for computing the electronic structure of chemical elements developed by the CEA), `StarPU `_ (a Unified Runtime System for Heterogeneous Multicore Architectures developed by Inria Bordeaux), and @@ -239,4 +128,35 @@ developed by Inria Bordeaux), and key-value pair storage library developed at the University of Zurich). Some of these applications enjoy large user communities themselves. +SimGrid Limits +-------------- + +SimGrid is by no means the holy grail that is able to solve every conceivable simulation problem. + +**SimGrid's scope is limited to distributed systems.** Real-time +multi-threaded systems are out of this scope. You could probably use and/or +extend SimGrid for this purpose, but another framework that specifically +targets this use case would probably be more suitable. + +**There is currently no support for 5G or LoRa networks**. +SimGrid could certainly be extended with models for these networks, but this +yet to be done. + +**There is no perfect model, only models adapted to your purposes.** SimGrid's +models were designed to make it possible to run fast and accurate +simulations of large systems. As a result, the models abstract away many +parameters and phenomena that are often irrelevant for most use cases in the +field. This means that SimGrid cannot be used to study any phenomenon that our +model do not capture. Here are some **phenomena that you currently cannot study with +SimGrid**: + + - Studying the effect of L3 vs. L2 cache effects on your application; + - Comparing kernel schedulers and policies; + - Comparing variants of TCP; + - Exploring pathological cases where TCP breaks down, resulting in + abnormal executions; + - Studying security aspects of your application, in the presence of + malicious agents. + + .. LocalWords: SimGrid diff --git a/docs/source/Modeling_howtos.rst b/docs/source/Modeling_howtos.rst index 3772a67904..0840ceec50 100644 --- a/docs/source/Modeling_howtos.rst +++ b/docs/source/Modeling_howtos.rst @@ -93,6 +93,10 @@ Another possibility is to use the functions take a profile, that can be a fixed profile exhaustively listing the events, or something else if you wish. +For further reading, you could turn to :ref:`this example ` +on how to react to communication failures, or :ref:`this one ` +on how to attach a state profile to hosts and react to execution failures. + .. _howto_multicore: Modeling multicore machines @@ -152,13 +156,10 @@ programs actually die and restart during a reboot. Since there are many ways to model it, SimGrid does not do any modeling choice for you but the most obvious ones. -Any actor (or process in MSG) running on a host that is shut down -will be killed and all its activities (tasks in MSG) will be -automatically canceled. If the actor killed was marked as -auto-restartable (with -:cpp:func:`simgrid::s4u::Actor::set_auto_restart` or with -:cpp:func:`MSG_process_auto_restart_set`), it will start anew with the -same parameters when the host boots back up. +Any actor running on a host that is shut down will be killed and all +its activities will be automatically canceled. If the actor killed was +marked as auto-restartable (with :cpp:func:`simgrid::s4u::Actor::set_auto_restart`), +it will start anew with the same parameters when the host boots back up. By default, shutdowns and boots are instantaneous. If you want to add an extra delay, you have to do that yourself, for example from a diff --git a/docs/source/Models.rst b/docs/source/Models.rst index 2c87454a97..e8ee9016e5 100644 --- a/docs/source/Models.rst +++ b/docs/source/Models.rst @@ -1,21 +1,175 @@ +.. raw:: html + + + +
+
+ .. _models: -The SimGrid Models +The SimGrid models ################## -.. todo:: - - - Main existing models (contention, cste, LM07) - - Main concepts (Routing, LMM) + link to the papers - - How to switch on the command line +This page focuses on the **performance models** that compute the duration of :ref:`all activities ` +throughout the simulation, based on the platform characteristics and on the other activities that concurrently use the +resources. If you are looking for information on other kinds of models (such as routing models or compute model), please refer to :ref:`the +bottom of this page `. + +Modeled resources +***************** + +The primary objective of SimGrid is to provide simulated timing information +for the usage of three kinds of resources: networks, CPUs, and disks. + +The **network models** have been improved and regularly validated for almost 20 years. It should be possible to get +accurate simulations once you properly :ref:`calibrate the models for your settings`. As detailed +in the next sections, SimGrid provides several network models. Two plugins can also be used to compute the energy +consumption of the network: one for :ref:`wired networks` and another one for :ref:`Wi-Fi networks +`. Note that at first some users find the way in which SimGrid simulates :ref:`TCP performance` to be +counter-intuitive; in our experience this is due these users misunderstandings the (complex) behavior +of TCP in real networks. + +The **CPU models** are less developed in SimGrid. Through the S4U API, the user can specify amounts of +computational work (expressed in FLOPs, for floating point operations) that each computation "consumes", and the model +simply divides this amount by a CPU's FLOP rate to compute the duration of the computation +(accounting for number of cores and all concurrent computations with a time-sharing model). In SMPI, the user code +is automatically timed, and the :ref:`computing speed` of the host machine is used to evaluate +the corresponding amount of FLOPs. This model should be sufficient for most users, even though assuming a constant FLOP +rate for each machine remains a crude simplification (in reality, the FLOP rate varies because of I/O, memory, and +cache effects). It is possible to :ref:`overcome this simplification`, but the +required calibration process is rather intricate and not documented yet (feel free to +:ref:`contact the community`). +In the future, more advanced models may be added but the existing model have proven good enough +over the last two decades. The CPU energy consumption can be computed with the +:ref:`relevant plugin`. + +The **disk models** in SimGrid have been included more recently than those for networks and CPUs, but they should +still prove useful to most users. `Studies have shown `_ that these models are sensitive +to various conditions, and a :ref:`calibration process` is provided. As usual, you probably want to +assess simulation accuracy through an appropriate validation campaign. + +.. _models-lmm: + +LMM-based Models +**************** + +SimGrid aims at the sweet spot between simulation accuracy and simulation speed. In terms of accuracy, the goal is for simulations +to report correct +performance trends when comparing competing designs while placing minimal burden on the user. We also want to allow power users to +fine tune the simulation models to achieve simulation results that are within 5% or less of what would be observed +on a real platform. For example, we accurately determined the `speedup achieved by the Tibidabo ARM-based cluster `_ +before it was even built. In terms of simulation speed, the goal it to be fast and scalable enough to allow the study of modern IT systems +at scale. SimGrid was, for example, used to simulate `a Chord ring with millions of actors +`_ (even though results were not really more instructive than those obtained at smaller scales), +or `a qualification run at full-scale of the Stampede supercomputer +`_. + +Most SimGrid models are based on a linear max-min solver (LMM), as depicted below. The actors' activities are +represented by actions in the simulation kernel, accounting for both the initial amount of work of the corresponding +activity (in FLOPs for CPU activities or bytes for network and disk activities), and the currently remaining +amount of work to process. + +At each simulation step, the instantaneous speed for each action is computed according +to the model. A set of constraints is used to express resource capacity constraints, i.e., that the cumulative instantaneous consumption of a +given resource by a set actions must remain below the nominal capacity of that resource. In the example +below, it is stated that the compute speed :math:`\varrho_1` of activity 1 plus the compute speed :math:`\varrho_n` +of activity :math:`n`, which both run on host A, must remain smaller than that host's total compute speed :math:`C_A`. + +.. image:: img/lmm-overview.svg + +There are many valuations of :math:`\varrho_1, \ldots{}, \varrho_n` that must respect sets of constraints. +SimGrid usually computes the instantaneous speeds according to a Max-Min objective function, that is, maximizing the +minimum over all :math:`\varrho_i`. The coefficients associated to each variable in the inequalities are used to model +some performance effects, such as the fact that TCP tends to favor communications with small RTTs. These coefficients +are computed from both hard-coded values and :ref:`latency and bandwidth factors` (more +details on network performance modeling are given in the next section). + +Once the instantaneous speeds are computed for all acttions, the simulation kernel computes the earliest terminating action +given their respective speeds and remaining amounts of work. The simulated time is then updated along with remaning +amounts of work. At this point, some actions have no remaining work and are removed from the LMM. The corresponding activities thus terminate, which in turn +unblocks the corresponding actors that can then continue executing. + +Most of the SimGrid models build upon the LMM solver, which they adapt and configure in various ways. For CPU +and disk activities, the LMM-based models are respectively named **Cas01** and **S19**. The existing network models are +described in the next section. + +.. _models_TCP: + +The TCP models +************** + +SimGrid provides several network performance models that compute the time taken by each communication in isolation. +**CM02** is the simplest one. It captures TCP windowing effects, but does not introduce any correction factors. This +model should be used if you prefer human-understandable results over realistic ones. **LV08** (the default model) uses +constant factors that are intended to capture common effects such as slow-start, the fact that TCP headers reduce the +*effective* bandwidth, or TCP's ACK messages. **SMPI** uses more advanced factors that also capture the MPI-specific +effects such as the switch between the eager vs. rendez-vous communication modes. You can :ref:`choose the +model ` on via command-line arguments, and each model can be :ref:`further configured `. + +The LMM solver is then used as described above to compute the effect of contention on the communication time when using TCP. +For the sake of realism, the sharing on saturated links is not necessarily a fair sharing +(unless when ``weight-S=0``, in which case the following mechanism is disabled). +Instead, flows receive an amount of bandwidth inversely proportional to their round trip time. This is modeled +in the LMM as a priority that depends on the :ref:`weight-S ` parameter. More precisely, this +priority is computed for each flow as :math:`\displaystyle\sum_{l\in links}\left(Lat(l)+\frac{weightS}{Bandwidth(l)}\right)`, i.e., as the sum of the +latencies of all links traversed by the communication, plus the sum of `weight-S` over the bandwidth of each link along +the path. This dependency on the link bandwidths is for the model to account for the TCP protocol's reactivity. + +Regardless of the TCP model in used, the latency is paid beforehand. It is as if the communication only starts after a +small delay that corresponds to the end-to-end latency. During that time, the communication has no impact on the links (i.e., the other +communications are not slowed down, because there is no contention yet). + +As an alternative to the above LMM-based models, it is possible to use the :ref:`ns-3 simulator as a network model `. ns-3 performs +a much more detailed, packet-level simulation +than the above models. As a result is is much slower but will produce more accurate results. +Both simulators have time complexity that is linear in the size of their input, but ns-3 has a much larger input in case of large communications +because it considers individual network packets. +However, the above SimGrid models must be carefully :ref:`calibrated ` if +achieve very high accuracy is needed, while ns-3 is less demanding in this regard. + +.. _understanding_cm02: + +CM02 +==== + +This is a simple model of TCP performance, where the sender stops sending packets when its TCP window is full. If the +acknowledgment packets are returned in time to the sender, the TCP window has no impact on the performance, which is then +only limited by link bandwidths. Otherwise, late acknowledgments will reduce the data transfer rate. + +SimGrid models this mechanism as follows: :math:`real\_BW = min(physical\_BW, \frac{TCP\_GAMMA}{2\times latency})` The used +bandwidth is either the physical bandwidth that is configured in the platform, or a value that represents a bandwidth +limit due to late acknowledgments. This value is the maximal TCP window size (noted TCP Gamma in SimGrid) divided by the +round-trip time (i.e. twice the one-way latency). The default value of TCP Gamma is 4194304. This value can be changed with +the :ref:`network/TCP-gamma ` configuration item. + +If you want to disable this mechanism altogether (e.g.,to model UDP or memory operations), you should set TCP-gamma +to 0. Otherwise, the time it takes to send 10 Gib of data over a 10 Gib/s link that is otherwise unused is computed as +:math:`latency + \frac{size}{bandwidth}`, but the bandwidth in the denominator may be the physical +one (10Gb/s) or the one induced by the TCP window, depending on the latency: + + - If the link latency is 0, the communication, expectedly, takes one second. + - If the link latency is 0.00001s, :math:`\frac{gamma}{2\times lat}=209,715,200,000 \approx 209Gib/s` which is larger than the + physical bandwidth. So the physical bandwidth is used (the link is fully utilized) and the communication takes 1.00001s + - If the link latency is 0.001s, :math:`\frac{gamma}{2\times lat}=2,097,152,000 \approx 2Gib/s`, which is smaller than the + physical bandwidth. The communication thus fails to fully utilize the link and takes about 4.77s. + - With a link latency of 0.1s, :math:`gamma/2\times lat \approx 21Mb/s`, so the communication takes about 476.84 + 0.1 seconds! + - More cases are tested and their validity checked by the test ``teshsuite/models/cm02-tcpgamma/cm02-tcpgamma.tesh`` in our test suite. + +For more details, please refer to "A Network Model for Simulation of Grid Application" by Henri Casanova and Loris +Marchal (published in 2002, hence the model name). .. _understanding_lv08: -The default TCP model -********************* +LV08 (default) +============== -When simulating a data transfer between two hosts, you may be surprised -by the obtained simulation time. Lets consider the following platform: +This model builds on CM02 to model TCP windowing (see above). It also introduces corrections factors for further realism: +latency-factor is 13.01, bandwidth-factor is 0.97 while weight-S is 20537. Lets consider the following platform: .. code-block:: xml @@ -28,65 +182,178 @@ by the obtained simulation time. Lets consider the following platform: -If host `A` sends `100kB` (a hundred kilobytes) to host `B`, one could expect -that this communication would take `0.81` seconds to complete according to a -simple latency-plus-size-divided-by-bandwidth model (0.01 + 8e5/1e6 = 0.81). -However, the default TCP model of SimGrid is a bit more complex than that. It -accounts for three phenomena that directly impact the simulation time even -on such a simple example: - - - The size of a message at the application level (i.e., 100kB in this - example) is not the size that will actually be transferred over the - network. To mimic the fact that TCP and IP headers are added to each packet of - the original payload, the TCP model of SimGrid empirically considers that - `only 97% of the nominal bandwidth` are available. In other words, the - size of your message is increased by a few percents, whatever this size be. - - - In the real world, the TCP protocol is not able to fully exploit the - bandwidth of a link from the emission of the first packet. To reflect this - `slow start` phenomenon, the latency declared in the platform file is - multiplied by `a factor of 13.01`. Here again, this is an empirically - determined value that may not correspond to every TCP implementations on - every networks. It can be tuned when more realistic simulated times for - short messages are needed though. - - - When data is transferred from A to B, some TCP ACK messages travel in the - opposite direction. To reflect the impact of this `cross-traffic`, SimGrid - simulates a flow from B to A that represents an additional bandwidth - consumption of `0.05`. The route from B to A is implicitly declared in the - platform file and uses the same link `link1` as if the two hosts were - connected through a communication bus. The bandwidth share allocated to the - flow from A to B is then the available bandwidth of `link1` (i.e., 97% of - the nominal bandwidth of 1Mb/s) divided by 1.05 (i.e., the total consumption). - This feature, activated by default, can be disabled by adding the - `--cfg=network/crosstraffic:0` flag to command line. - -As a consequence, the time to transfer 100kB from A to B as simulated by the -default TCP model of SimGrid is not 0.81 seconds but +If host `A` sends ``100kB`` (a hundred kilobytes, that is, 8e5 bits) to host `B`, one can expect that this communication would +take `0.81` seconds to complete according to a simple latency-plus-size-divided-by-bandwidth model (0.01 + 8e5/1e6 = 0.81 -- the +size was converted from bytes to bits) since the latency is small enough to ensure that the physical bandwidth is used (see the +discussion on CM02 above). However, the LV08 model is more complex to account for three phenomena that directly impact the +simulation time: + + - The size of a message at the application level (i.e., 100kB in this example) is not the size that is actually + transferred over the network. To mimic the fact that TCP and IP headers are added to each packet of the original + payload, the TCP model of SimGrid empirically considers that `only 97% of the nominal bandwidth` are available. In + other words, the size of your message is increased by a few percents, whichever this size. + + - In the real world, the TCP protocol is not able to fully exploit the bandwidth of a link from the emission of the + first packet. To reflect this `slow start` phenomenon, the latency declared in the platform file is multiplied by + `a factor of 13.01`. Here again, this is an empirically determined value that may not correspond to every TCP + implementations on every networks. It can be tuned when more realistic simulated times for the transfer of short + messages are needed though. + + - When data is transferred from A to B, some TCP ACK messages travel in the opposite direction. To reflect the impact + of this `cross-traffic`, SimGrid simulates a flow from B to A that represents an additional bandwidth consumption + of `0.05%`. The route from B to A is implicitly declared in the platform file and uses the same link `link1` as if + the two hosts were connected through a communication bus. The bandwidth share allocated to a data transfer from A + to B is then the available bandwidth of `link1` (i.e., 97% of the nominal bandwidth of 1Mb/s) divided by 1.05 + (i.e., the total consumption). This feature, activated by default, can be disabled by adding the + ``--cfg=network/crosstraffic:0`` flag to the command line. + +As a consequence, the time to transfer 100kB from A to B as simulated by the default TCP model of SimGrid is not 0.81 +seconds but .. code-block:: python 0.01 * 13.01 + 800000 / ((0.97 * 1e6) / 1.05) = 0.996079 seconds. -.. _model_ns3: +For more details, please refer to "Accuracy study and improvement of network simulation in the SimGrid framework" by +Arnaud Legrand and Pedro Velho. + +.. _models_l07: + +Parallel tasks (L07) +******************** + +This model is rather different from the other LMM models because it uses another objective function, which is called *bottleneck*. +This is because this model is intended to be used for parallel tasks, that is sets of actions that mix flops and bytes, while the +Max-Min objective function requires that all variables be expressed using the same unit (which is why in the implementation +we have one LMM system per resource kind). + +Use the :ref:`relevant configuration ` to select this model in your simulation. + +.. _models_wifi: + +WiFi zones +********** + +In SimGrid, WiFi networks are modeled with WiFi zones, where a zone contains the access point of the WiFi network and +the hosts connected to it (called `stations` in the WiFi world). The network inside a WiFi zone is modeled by declaring +a single regular link with a specific attribute. This link is then added to the routes to and from the stations within +this WiFi zone. The main difference of WiFi networks, when compared to wired networks, is that performance is not determined by link bandwidths +and latencies but by both the access point WiFi characteristics and the distance between that access point and a given +station. + +In SimGrid, WiFi zones can be used with the LMM-based models or the ns-3-based model. + +Declaring a WiFi zone +===================== + +To declare a new WiFi network, simply declare a network zone with the ``WIFI`` routing attribute. + +.. code-block:: xml + + + +Inside this zone you must declare which host or router will be the access point of the WiFi network. + +.. code-block:: xml + + + +Then simply declare the stations (hosts) and routers inside the WiFi network. Remember that one must have the same name +as the "access point" property. + +.. code-block:: xml + + + + + +Finally, close the WiFi zone. + +.. code-block:: xml + + + +The WiFi zone may be connected to another zone using a traditional link and a zoneRoute. Note that the connection between two +zones is always wired. + +.. code-block:: xml + + + + + + + +WiFi network performance +======================== + +The performance of a wifi network is controlled by the three following properties: + + * ``mcs`` (`Modulation and Coding Scheme `_) + is a property of the WiFi zone. Roughly speaking, it defines the speed at which the access point exchanges data + with all the stations. It depends on the access point's model and configuration. Possible values for mcs can be + found on Wikipedia for example. + |br| By default, ``mcs=3``. + * ``nss`` (Number of Spatial Streams, or `number of antennas `_) is another property of the WiFi zone. It defines the amount of simultaneous data streams that the access + point can sustain. Not all values of MCS and NSS are valid nor compatible (cf. `802.11n standard `_). + |br| By default, ``nss=1``. + * ``wifi_distance`` is the distance from a station to the access point. Since each station can have its own specific value + it is a property of the stations declared inside the WiFi zone. + |br| By default, ``wifi_distance=10``. + +Here is an example of a zone with non-default ``mcs`` and ``nss`` values. + +.. code-block:: xml + + + + + + ... + + +Here is an example of setting the ``wifi_distance`` of a given station. + +.. code-block:: xml + + + + + +Constant-time model +******************* + +This model is one of the few SimGrid network models that is not based on the LMM solver. In this +model, all communication take a constant time (one second by default). It provides the lowest level of realism, but is +faster and much simpler to understand. This model may prove interesting though if you plan to study abstract +distributed algorithms such as leader election or causal broadcast. + +.. _models_ns3: ns-3 as a SimGrid model *********************** -You can use the well-known `ns-3 packet-level network simulator -`_ as a SimGrid model, for example to investigate the -validity of your simulation. Just install ns-3 and recompile SimGrid +The **ns-3 based model** is the most accurate network model in SimGrid. It relies on the well-known `ns-3 packet-level network +simulator `_ to compute full timing information related to network transfers. This model is much slower +than the LMM-based models. This is because ns-3 simulates the movement of every network packet involved in every communication, +while the LMM-based models only recompute the respective instantaneous speeds of the currently ongoing communications when a +communication starts or stops. In other terms, both SimGrid and ns-3 are fast and highly optimized, but while SimGrid only +depends on application-level events (starting and stoping of communications), ns-3 depends on network-level events (sending a +packet). + +You need to install ns-3 and recompile SimGrid accordingly to use this model. + +The SimGrid/ns-3 binding only contains features that are common to both systems. Not all ns-3 models are available from SimGrid +(only the TCP and WiFi ones are), while not all SimGrid platform files can be used in conjunction with ns-3 (routes must be of +length 1). Note also that the platform built in ns-3 from the SimGrid description is very basic. Finally, communicating from a +host to itself is forbidden in ns-3, so every such communication is simulated to take zero time. + +By default, the ns-3 model in SimGrid is not idempotent, unless you patch your version of ns-3 with [this +patch](https://gitlab.com/nsnam/ns-3-dev/-/merge_requests/1338). It is perfectly OK to have a non-idempotent model in SimGrid as +long as you only have only one such model, and as long as you don't use utterly advanced things in SimGrid. If you do want to +have an idempotent ns-3, apply the previously mentioned patch, and recompile SimGrid. It should detect the patch and react accordingly. -The SimGrid/ns-3 binding only contains features that are common to both systems. -Not all ns-3 models are available from SimGrid (only the TCP and WiFi ones are), -while not all SimGrid platform files can be used in conjunction ns-3 (routes -must be of length 1). Also, the platform built in ns-3 from the SimGrid -description is very basic. Finally, communicating from a host to -itself is forbidden in ns-3, so every such communication completes -immediately upon startup. - - Compiling the ns-3/SimGrid binding ================================== @@ -95,7 +362,7 @@ Installing ns-3 SimGrid requires ns-3 version 3.26 or higher, and you probably want the most recent version of both SimGrid and ns-3. While the Debian package of SimGrid -don't have the ns-3 bindings activated, you can still use the packaged version +does not have the ns-3 bindings activated, you can still use the packaged version of ns-3 by grabbing the ``libns3-dev ns3`` packages. Alternatively, you can install ns-3 from scratch (see the `ns-3 documentation `_). @@ -110,15 +377,15 @@ your disk. $ cmake . -Denable_ns3=ON -DNS3_HINT=/opt/ns3 # or change the path if needed -By the end of the configuration, cmake reports whether ns-3 was found, +cmake will report whether ns-3 was found, and this information is also available in ``include/simgrid/config.h`` If your local copy defines the variable ``SIMGRID_HAVE_NS3`` to 1, then ns-3 was correctly detected. Otherwise, explore ``CMakeFiles/CMakeOutput.log`` and ``CMakeFiles/CMakeError.log`` to diagnose the problem. -Test that ns-3 was successfully integrated with the following (from your SimGrid +Test that ns-3 was successfully integrated with the following command (executed from your SimGrid build directory). It will run all SimGrid tests that are related to the ns-3 -integration. If no test is run at all, you probably forgot to enable ns-3 in cmake. +integration. If no test is run at all, then ns-3 is disabled in cmake. .. code-block:: console @@ -132,8 +399,8 @@ If you use a version of ns-3 that is not known to SimGrid yet, edit comments on top of this file. Conversely, if something goes wrong with an old version of either SimGrid or ns-3, try upgrading everything. -Note that there is a known bug with version 3.31 of ns3, when it's built with -MPI support, like it is with the package libns3-dev in Debian 11 « Bullseye ». +Note that there is a known bug with the version 3.31 of ns3 when it is built with +MPI support, like it is with the libns3-dev package in Debian 11 « Bullseye ». A simple workaround is to edit the file ``/usr/include/ns3.31/ns3/point-to-point-helper.h`` to remove the ``#ifdef NS3_MPI`` include guard. This can be achieved with the following command (as root): @@ -150,7 +417,7 @@ Using ns-3 from SimGrid Platform files compatibility ---------------------------- -Any route longer than one will be ignored when using ns-3. They are +Any route with more than one hop will be ignored when using ns-3. They are harmless, but you still need to connect your hosts using one-hop routes. The best solution is to add routers to split your route. Here is an example of an invalid platform: @@ -174,7 +441,7 @@ example of an invalid platform:
-This can be reformulated as follows to make it usable with the ns-3 binding. +This platform file can be reformulated as follows to make it usable with the ns-3 binding. There is no direct connection from alice to bob, but that's OK because ns-3 automatically routes from point to point (using ``ns3::Ipv4GlobalRoutingHelper::PopulateRoutingTables``). @@ -223,105 +490,9 @@ the ns-3 node from any given host with the .. doxygenfunction:: simgrid::get_ns3node_from_sghost - -WiFi platforms -^^^^^^^^^^^^^^ - -In SimGrid, WiFi networks are modeled with WiFi zones, where a zone contains -the access point of the WiFi network and the hosts connected to it (called -station in the WiFi world). Links inside WiFi zones are modeled as regular -links with a specific attribute, and these links are then added to routes -between hosts. The main difference When using ns-3 WiFi networks is that -the network performance is not given by the link bandwidth and latency but -by the access point WiFi characteristics, and the distance between the access -point and the hosts. - -So, to declare a new WiFi network, simply declare a zone with the ``WIFI`` -routing. - -.. code-block:: xml - - - -Inside this zone you must declare which host or router will be the access point -of the WiFi network. - -.. code-block:: xml - - - -Afterward simply declare the hosts and routers inside the WiFi network. Remember -that one must have the same name as declared in the property "access point". - -.. code-block:: xml - - - - - -Finally, close the WiFi zone. - -.. code-block:: xml - - - -The WiFi zone may be connected to another zone using a traditional link and -a zoneRoute. Note that the connection between two zones is always wired. - -.. code-block:: xml - - - - - - - -WiFi network performance -"""""""""""""""""""""""" - -The performance of a wifi network is controlled by 3 property that can be added -to hosts connected to the wifi zone: - - * ``mcs`` (`Modulation and Coding Scheme `_) - Roughly speaking, it defines the speed at which the access point is - exchanging data with all stations. It depends on its model and configuration, - and the possible values are listed for example on Wikipedia. - |br| By default, ``mcs=3``. - It is a property of the WiFi zone. - * ``nss`` (Number of Spatial Streams, or `number of antennas `_) - defines the amount of simultaneous data streams that the AP can sustain. - Not all value of MCS and NSS are valid nor compatible (cf. `802.11n standard `_). - |br| By default, ``nss=1``. - It is a property of the WiFi zone. - * ``wifi_distance`` is the distance from the station to the access point. Each - station can have a specific value. - |br| By default, ``wifi_distance=10``. - It is a property of stations of the WiFi network. - -Here is an example of a zone changing ``mcs`` and ``nss`` values. - -.. code-block:: xml - - - - - - ... - - -Here is an example of a host changing ``wifi_distance`` value. - -.. code-block:: xml - - - - - -Random Number Generator ------------------------ - -It is possible to define a fixed or random seed to the ns3 random number -generator using the config tag. +Random seed +----------- +It is possible to define a fixed or random seed for ns-3's random number generator using the config tag. .. code-block:: xml @@ -334,37 +505,67 @@ generator using the config tag. ...
-The first property defines that this platform will be used with the ns3 model. -The second property defines the seed that will be used. Defined to ``time`` -it will use a random seed, defined to a number it will use this number as -the seed. +The first property defines that this platform will be used with the ns-3 model. +The second property defines the seed that will be used. If defined to ``time``, as done above, +it will use a random seed. Limitations ------------ +=========== -A ns-3 platform is automatically created from the provided SimGrid +A ns-3 platform is automatically created based on the provided SimGrid platform. However, there are some known caveats: * The default values (e.g., TCP parameters) are the ns-3 default values. * ns-3 networks are routed using the shortest path algorithm, using ``ns3::Ipv4GlobalRoutingHelper::PopulateRoutingTables``. - * End hosts cannot have more than one interface card. So, your SimGrid hosts + * End hosts cannot have more than one network interface card. So, your SimGrid hosts should be connected to the platform through only one link. Otherwise, your SimGrid host will be considered as a router (FIXME: is it still true?). Our goal is to keep the ns-3 plugin of SimGrid as easy (and hopefully readable) -as possible. If the current state does not fit your needs, you should modify -this plugin, and/or create your own plugin from the existing one. If you come up +as possible. If the current state of development does not fit your needs, you can modify +this plugin and/or create your own plugin based on the current one. If you come up with interesting improvements, please contribute them back. Troubleshooting ---------------- +=============== If your simulation hangs in a communication, this is probably because one host is sending data that is not routable in your platform. Make sure that you only use routes of length 1, and that any host is connected to the platform. Arguably, SimGrid could detect this situation and report it, but unfortunately, -this is still to be done. - +this still has to be done. + +FMI-based models +**************** + +`FMI `_ is a standard to exchange models between simulators. If you want to plug such a model +into SimGrid, you need the `SimGrid-FMI external plugin `_. +There is a specific `documentation `_ available for the plugin. +This was used to accurately study a *Smart grid* through co-simulation: `PandaPower `_ was +used to simulate the power grid, `ns-3 `_ was used to simulate the communication network while SimGrid was +used to simulate the IT infrastructure. Please also refer to the `relevant publication `_ +for more details. + +.. _models_other: + +Other kind of models +******************** + +Models are key components of SimGrid, as they should be for any simulation framework, and beyond the above performance models +SimGrid employs other models: + +The **routing models** constitute advanced elements of the platform description. This description naturally entails +:ref:`components` that are very related to the performance models. For instance, determining the execution +time of a task obviously depends on the characteristics of the machine that executes this task. Furthermore, networking +zones can be interconnected to compose larger platforms `in a scalable way `_. Each +of these zones can be given a specific :ref:`routing model` that efficiently computes the list of +links forming a network path between two given hosts. + +The model checker uses an abstraction of the performance simulations. Mc SimGrid explores every causally possible +execution paths of the application, completely abstracting the performance away. The simulated time is not even +computed in this mode! The abstraction involved in this process also models the mutual impacts among actions, to not +re-explore histories that only differ by the order of independent and unrelated actions. As with the rest of the model +checker, these models are unfortunately still to be documented properly. .. |br| raw:: html diff --git a/docs/source/Platform_cpp.rst b/docs/source/Platform_cpp.rst index 75abec5785..e0aad1210a 100644 --- a/docs/source/Platform_cpp.rst +++ b/docs/source/Platform_cpp.rst @@ -155,7 +155,7 @@ Note that the leaves and loopback links are defined through callbacks, as follow /* create each leaf in the Fat-Tree, return a pair composed of: */ static std::pair - create_hostzone(const sg4::NetZone* zone, const std::vector& /*coord*/, int id) + create_hostzone(const sg4::NetZone* zone, const std::vector& /*coord*/, unsigned long id) { /* creating zone */ std::string hostname = "host" + std::to_string(id); diff --git a/docs/source/Platform_routing.rst b/docs/source/Platform_routing.rst index f3cb3d544d..fe5a7c424d 100644 --- a/docs/source/Platform_routing.rst +++ b/docs/source/Platform_routing.rst @@ -57,11 +57,11 @@ Shortest path ============= SimGrid can compute automatically the paths between all pair of hosts in a zone. You just need to provide the one-hop routes to connect all hosts. -Several algorithms are provided: +Several algorithms are provided: - ``routing=Floyd``: use the number of hops to build shortest path. It is calculated only once at the beginning of the simulation. - - ``routing=Dijksta``: shortest-path calculated considering the path's latency. As the latency of links can change + - ``routing=Dijkstra``: shortest-path calculated considering the path's latency. As the latency of links can change during simulation, it is recomputed each time a route is necessary. - ``routing=DijkstraCache``: Just like the regular Dijkstra, but with a cache of previously computed paths for performance. @@ -110,11 +110,12 @@ Vivaldi ======= This routing model is particularly well adapted to Peer-to-Peer and Clouds platforms: each component is connected to the -cloud through a private link of which the upload and download rate may be asymmetric. +cloud through a private link whose upload and download rates may be asymmetric. -The network core (between the private links) is assumed to be over-sized so only the latency is taken into account. -Instead of a matrix of latencies that would become too large when the amount of peers grows, Vivaldi netzones give a -coordinate to each peer and compute the latency between host A=(xA,yA,zA) and host B=(xB,yB,zB) as follows: +The network core (between the private links) is assumed to be over-provisioned so that only the latency has to be +taken into account. Instead of a matrix of latencies that would become too large when the amount of peers grows, +Vivaldi netzones give a coordinate to each peer and compute the latency between host A=(xA,yA,zA) and host B=(xB,yB,zB) +as follows: latency = sqrt( (xA-xB)² + (yA-yB)² ) + zA + zB @@ -134,7 +135,7 @@ coordinate-based platforms from the OptorSim project into SimGrid platform files Such Network Coordinate systems were shown to provide rather good latency estimations in a compact way. Other systems, such as `Phoenix network coordinates `_ were shown superior to the Vivaldi system and could be also implemented in SimGrid. - + Here is a small platform example: .. code-block:: XML @@ -153,14 +154,13 @@ Here is a small platform example: Wi-Fi ===== -TODO +Please see :ref:`models_wifi`. ns-3 ==== -When using :ref:`model_ns3`, SimGrid does not uses its own platform or routing models. Your platform must be limited to one -zone only, and any routing model will be ignored. Since ns-3 uses a shortest path algorithm on its side, all routes must be -of length 1. +When using :ref:`models_ns3`, SimGrid configures the ns-3 simulator according to the configured platform. +Since ns-3 uses a shortest path algorithm on its side, all routes must be of length 1. .. _pf_routes: @@ -174,7 +174,7 @@ Defining a route between two separate zones with :ref:`pf_tag_zoneroute` takes m ``gw_src`` (source gateway) and ``gw_dst`` (destination gateway) along with the list of links. Afterward, the path from ``src_host`` in zone ``src`` to ``dst_host`` in zone ``dst`` is composed of 3 segments. First, move within zone ``src`` from ``src_host`` to the specified gateway ``gw_src``. Then, traverse all links specified by the zoneRoute (purportedly within -the common ancestor) and finally, move within zone ``dst`` from ``gw_dst`` to ``dst_host``. +the common ancestor) and finally, move within zone ``dst`` from ``gw_dst`` to ``dst_host``. SimGrid enforces that each gateway is within its zone, either directly or in a sub-zone to ensure that the algorithm described in the next section actually works. @@ -208,7 +208,7 @@ only gives an overview of the algorithm used. You should refer to the source cod .. code-block:: XML - + @@ -225,8 +225,8 @@ only gives an overview of the algorithm used. You should refer to the source cod Here, we need the route from *gw1* and *host2*. The common ancestor is *AS5*, and the relative ancestors are *AS5-4* and *AS5-3*. This route is defined as follows (routes are symmetrical by default). .. code-block:: XML - - + + @@ -242,12 +242,14 @@ only gives an overview of the algorithm used. You should refer to the source cod -In the end, our communication from *Host1@AS2* to *Host2@AS5-4* follows this path: ``{Link1, Link3, Link2}`` +In the end, our communication from *Host1@AS2* to *Host2@AS5-4* follows this path: ``{Link1, Link3, Link2}`` It is possbile to use :ref:`pf_tag_bypassZoneRoute` to provide a path between two zones that are not necessarily sibilings. If such routes exist, SimGrid will try to match each of the ancestor zones of the source with each of the ancestor zone of the destination, looking for such a bypass to use intead of the common ancestor. +.. _pf_loopback: + Loopback links ************** @@ -267,7 +269,7 @@ will then use the provided link(s) as a loopback for this host instead of the gl Some zones such as :ref:`pf_tag_cluster` provide ways to describe the characteristics of -the loopback nodes inside the zone. +the loopback nodes inside the zone. .. |br| raw:: html diff --git a/docs/source/Plugins.rst b/docs/source/Plugins.rst index 0594693ee8..aab0fe0968 100644 --- a/docs/source/Plugins.rst +++ b/docs/source/Plugins.rst @@ -23,6 +23,9 @@ documents some of the plugins distributed with SimGrid: - :ref:`Host Energy `: models the energy dissipation of the compute units. - :ref:`Link Energy `: models the energy dissipation of the network. - :ref:`WiFi Energy `: models the energy dissipation of wifi links. + - :ref:`Battery `: models batteries that get discharged by the energy consumption of a given host. + - :ref:`Solar Panel `: models solar panels which energy production depends on the solar irradiance. + - :ref:`Chiller `: models chillers which dissipate heat by consuming energy. You can activate these plugins with the :ref:`--cfg=plugin ` command line option, for example with ``--cfg=plugin:host_energy``. You can get the full @@ -67,50 +70,106 @@ kind of objects, please let us now. Fire that signal, invoking all callbacks. -Partial list of existing signals in s4u: +.. _s4u_API_signals: -- :cpp:func:`Actor::on_creation ` +Existing signals +================ + +- In actors: + :cpp:func:`Actor::on_creation ` :cpp:func:`Actor::on_suspend ` + :cpp:func:`Actor::on_this_suspend ` :cpp:func:`Actor::on_resume ` + :cpp:func:`Actor::on_this_resume ` :cpp:func:`Actor::on_sleep ` + :cpp:func:`Actor::on_this_sleep ` :cpp:func:`Actor::on_wake_up ` + :cpp:func:`Actor::on_this_wake_up ` :cpp:func:`Actor::on_host_change ` + :cpp:func:`Actor::on_this_host_change ` :cpp:func:`Actor::on_termination ` + :cpp:func:`Actor::on_this_termination ` :cpp:func:`Actor::on_destruction ` -- :cpp:func:`Comm::on_send ` - :cpp:func:`Comm::on_recv ` - :cpp:func:`Comm::on_completion ` -- :cpp:func:`CommImpl::on_start ` - :cpp:func:`CommImpl::on_completion ` -- :cpp:func:`Disk::on_creation ` - :cpp:func:`Disk::on_destruction ` - :cpp:func:`Disk::on_state_change ` -- :cpp:func:`Engine::on_platform_creation ` +- In the engine: + :cpp:func:`Engine::on_platform_creation ` :cpp:func:`Engine::on_platform_created ` :cpp:func:`Engine::on_time_advance ` :cpp:func:`Engine::on_simulation_end ` :cpp:func:`Engine::on_deadlock ` -- :cpp:func:`Exec::on_start ` - :cpp:func:`Exec::on_completion ` -- :cpp:func:`Host::on_creation ` - :cpp:func:`Host::on_destruction ` - :cpp:func:`Host::on_state_change ` - :cpp:func:`Host::on_speed_change ` -- :cpp:func:`Io::on_start ` - :cpp:func:`Io::on_completion ` -- :cpp:func:`Link::on_creation ` - :cpp:func:`Link::on_destruction ` - :cpp:func:`Link::on_state_change ` - :cpp:func:`Link::on_speed_change ` - :cpp:func:`Link::on_communication_state_change ` -- :cpp:func:`NetZone::on_creation ` - :cpp:func:`NetZone::on_seal ` -- :cpp:func:`VirtualMachine::on_start ` - :cpp:func:`VirtualMachine::on_started ` - :cpp:func:`VirtualMachine::on_suspend ` - :cpp:func:`VirtualMachine::on_resume ` - :cpp:func:`VirtualMachine::on_migration_start ` - :cpp:func:`VirtualMachine::on_migration_end ` + +- In resources: + + - :cpp:func:`Disk::on_creation ` + :cpp:func:`Disk::on_destruction ` + :cpp:func:`Disk::on_this_destruction ` + :cpp:func:`Disk::on_onoff ` + :cpp:func:`Disk::on_this_onoff ` + - :cpp:func:`Host::on_creation ` + :cpp:func:`Host::on_destruction ` + :cpp:func:`Host::on_this_destruction ` + :cpp:func:`Host::on_onoff ` + :cpp:func:`Host::on_this_onoff ` + :cpp:func:`Host::on_speed_change ` + :cpp:func:`Host::on_this_speed_change ` + :cpp:func:`Host::on_exec_state_change ` + - :cpp:func:`Link::on_creation ` + :cpp:func:`Link::on_destruction ` + :cpp:func:`Link::on_this_destruction ` + :cpp:func:`Link::on_onoff ` + :cpp:func:`Link::on_this_onoff ` + :cpp:func:`Link::on_bandwidth_change ` + :cpp:func:`Link::on_this_bandwidth_change ` + :cpp:func:`Link::on_communication_state_change ` + + - :cpp:func:`NetZone::on_creation ` + :cpp:func:`NetZone::on_seal ` + - :cpp:func:`VirtualMachine::on_start ` + :cpp:func:`VirtualMachine::on_this_start ` + :cpp:func:`VirtualMachine::on_started ` + :cpp:func:`VirtualMachine::on_this_started ` + :cpp:func:`VirtualMachine::on_suspend ` + :cpp:func:`VirtualMachine::on_this_suspend ` + :cpp:func:`VirtualMachine::on_resume ` + :cpp:func:`VirtualMachine::on_this_resume ` + :cpp:func:`VirtualMachine::on_migration_start ` + :cpp:func:`VirtualMachine::on_this_migration_start ` + :cpp:func:`VirtualMachine::on_migration_end ` + :cpp:func:`VirtualMachine::on_this_migration_end ` + +- In activities: + + - :cpp:func:`Comm::on_send ` + :cpp:func:`Comm::on_recv ` + - :cpp:func:`Comm::on_start ` + :cpp:func:`Comm::on_this_start ` + :cpp:func:`Comm::on_completion ` + :cpp:func:`Comm::on_this_completion ` + :cpp:func:`Comm::on_suspended ` + :cpp:func:`Comm::on_this_suspended ` + :cpp:func:`Comm::on_resume ` + :cpp:func:`Comm::on_this_resumed ` + :cpp:func:`Comm::on_veto ` + :cpp:func:`Comm::on_this_veto ` + - :cpp:func:`Exec::on_start ` + :cpp:func:`Exec::on_this_start ` + :cpp:func:`Exec::on_completion ` + :cpp:func:`Exec::on_this_completion ` + :cpp:func:`Exec::on_suspended ` + :cpp:func:`Exec::on_this_suspended ` + :cpp:func:`Exec::on_resume ` + :cpp:func:`Exec::on_this_resume ` + :cpp:func:`Exec::on_veto ` + :cpp:func:`Exec::on_this_veto ` + - :cpp:func:`Io::on_start ` + :cpp:func:`Io::on_this_start ` + :cpp:func:`Io::on_completion ` + :cpp:func:`Io::on_this_completion ` + :cpp:func:`Io::on_suspended ` + :cpp:func:`Io::on_this_suspended ` + :cpp:func:`Io::on_resume ` + :cpp:func:`Io::on_this_resumed ` + :cpp:func:`Io::on_veto ` + :cpp:func:`Io::on_this_veto ` Existing Plugins **************** @@ -150,8 +209,6 @@ Host Load .. doxygengroup:: plugin_host_load - - .. _plugin_filesystem: File System @@ -159,5 +216,25 @@ File System .. doxygengroup:: plugin_filesystem +.. _plugin_battery: + +Battery +======= + +.. doxygengroup:: plugin_battery + +.. _plugin_solar_panel: + +Solar Panel +=========== + +.. doxygengroup:: plugin_solar_panel + +.. _plugin_chiller: + +Chiller +======= + +.. doxygengroup:: plugin_chiller .. LocalWords: SimGrid diff --git a/docs/source/Release_Notes.rst b/docs/source/Release_Notes.rst index 6dfa36e369..8e06554e97 100644 --- a/docs/source/Release_Notes.rst +++ b/docs/source/Release_Notes.rst @@ -19,7 +19,7 @@ The Half Release, a.k.a. the Zealous Easter Trim: * Introducing v4 of the XML platform format (many long-due cleanups) * MSG examples fully reorganized (in C and Java) - * The S4U interface is rising, toward SimGrid 4:|br| All host manipulations now done in S4U, + * The S4U interface is rising, toward SimGrid 4:|br| All host manipulations now done in S4U, SimDag was mostly rewritten on top of S4U but MSG & SimDag interfaces mostly unchanged. Version 3.14 (Dec 25. 2016) @@ -183,7 +183,7 @@ interfaces and converting them to snake_case() is one release goal of v3.20. But Once the S4U interface stabilizes, we will provide C bindings on top of it, along with Java and Python ones. Maybe in 3.21 or 3.22. All this is not contradictory with the fact that MSG as a whole is deprecated, because this deprecation only means that new projects -should go for S4U instead of MSG to benefit of the future. Despite this deprecation, old MSG projects should still be usable with no +should go for S4U instead of MSG to benefit of the future. Despite this deprecation, old MSG projects should still be usable with no change, if we manage to. This is a matter of scientific reproducibility to us. Version 3.20 (June 25 2018) @@ -314,7 +314,7 @@ This is the "Palindrome Day" release (today is 02 02 2020). The plan is to completely remove MSG by 2020Q4 or 2021Q1. * SimDAG++: Automatic dependencies on S4U activities (experimental). |br| - This implements some features of SimDAG within S4U, but not all of them: you cannot block an activity until it's scheduled on a resource + This implements some features of SimDAG within S4U, but not all of them: you cannot block an activity until it's scheduled on a resource and there is no heterogeneous wait_any() that would mix Exec/Comm/Io activities. See ``examples/s4u/{io,exec,comm}-dependent`` for what's already there. Since last fall, we continued to push toward the future SimGrid4 release. This requires to remove MSG and SimDAG once all users have @@ -461,8 +461,8 @@ new feature are: of years. * The removal of SimDag led us to also remove the export to Jedule files that was tightly coupled to SimDag. The instrumentation of DAG simulation is still possible through the regular instrumentation API based on the Paje format. - -On the bindings front, we dropped the Lua bindings to create new platforms, as the C++ and Python interfaces are much better to that extend. + +On the bindings front, we dropped the Lua bindings to create new platforms, as the C++ and Python interfaces are much better to that extend. Also, the algorithm tutorial can now be taken in Python, for those of you allergic to C++. Finally, on the SMPI front, we introduced a :ref:`new documentation section ` on calibrating the SMPI models from your @@ -484,8 +484,8 @@ with another one `_), the This was efficient and nice in C, but it prevented us from using C++ features such as opaque ``std::function`` data types. As such, it hindered the ongoing SimDAG++ code reorganization toward SimGrid4, where all activity classes should be homogeneously written in modern C++. -This release introduces a new design, where the simcalls are given object-oriented ``Observers`` that can serialize the relevant information over the wire. -This information is used on the checker side to build ``Transition`` objects that the application simcalls. The checker code is now much simpler, as the +This release introduces a new design, where the simcalls are given object-oriented ``Observers`` that can serialize the relevant information over the wire. +This information is used on the checker side to build ``Transition`` objects that the application simcalls. The checker code is now much simpler, as the formal logic is not spoiled with system-level tricks to retrieve the needed information. This cleaned design allowed us to finally implement the support for mutexes, semaphores and barriers in the model-checker (condition variables are still @@ -494,9 +494,9 @@ Simix, a central element of the SimGrid 3 design, was also finally removed: the old, non-free ISP test suite by the one from the `MPI Bug Initiative `_ (not all tests are activated yet). This will eventually help improving the robustness of Mc SimGrid. -These changes unlock the future of Mc SimGrid. For the next releases, we plan to implement another exploration algorithm based on event unfoldings (using -`The Anh Pham's thesis `_), the exploration of scenarios where the actors get killed and/or where -communications timeout, and the addition of a `wrapper to pthreads `, opening the path to the verification classical +These changes unlock the future of Mc SimGrid. For the next releases, we plan to implement another exploration algorithm based on event unfoldings (using +`The Anh Pham's thesis `_), the exploration of scenarios where the actors get killed and/or where +communications timeout, and the addition of a `wrapper to pthreads `_, opening the path to the verification classical multithreaded applications. @@ -528,6 +528,229 @@ since it does not mix bytes and flops and has a homogeneous consumption over a s This release also introduces steadily progress **on the bindings front**, introducing in particular the Mutex, Barrier and Semaphore to your python scripts. +Version 3.32 (October 3. 2022) +------------------------------ + +The Wiedervereinigung release. Germany was reunited 32 years ago. + +This release introduces tons of bugs fixes overall, and many small usability improvements contributed by the community. + +**On the bindings front**, we further completed the Python bindings: the whole C++ API of Comms is now accessible (and exemplified) in Python, while a +few missing functions have been added to Engine and Mailboxes. It is also possible to manipulate ptasks from Python. + +The Python platform generation has also been improved. In particular, user's errors should now raise an exception instead of killing the interpreter. +Various small improvements have been done to the graphicator tool so that you can now use jupyter to generate your platforms semi-interactively. + +**On the model checking front**, we did many refactoring operations behind the scene (the deprecated ``mc::api`` namespace was for example emptied and removed), +but there are almost no user-level changes. The internal work is twofold. + +First, we'd like to make optional all the complexity that liveness properties require to explore the application state (dwarf, libunwind, mmalloc, +etc) and instead only rely on fork to explore all the executions when liveness is not used. This would allow us to run the verified application under valgrind to +ease its debugging. Some progress was made towards that goal, but we are still rather far from this goal. + +Second, we'd like to simplify the protocol between the model-checker and the application, to make it more robust and hopefully simplify the +model-checker code. After release v3.31, the model-checker can properly observe the simcall of a given actor through the protocol instead of reading +the application memory directly, but retrieving the list of actors still requires to read the remote memory, which in turn requires the aforementioned tricks on state +introspection that we are trying to remove. This goal is much harder to achieve than it may sound in the current code base, but we +note steady improvements in that direction. + +In addition to these refactoring, this version introduces ``sthread``, a tool to intercept pthread operations at run time. The goal is to use it +together with the model-checker, but it's not working yet: we get a segfault during the initialization phase, and we failed to debug it so far. If +only we could use valgrind on the verified application, this would probably be much easier. + +But we feel that it's probably better to not delay this release any further, as this tangled web will probably take time to get solved. So ``sthread`` +is included in the source even if it's not usable in MC mode yet. + +**On the interface front**, small API fixes and improvements have been done in S4U (in particular about virtual machines), while the support for MPI +IO has been improved in SMPI. We also hope that ``sthread`` will help simulating OpenMP applications at some point, but it's not usable for that either. +Hopefully in the next release. + +Finally, this release mostly entails maintenance work **on the model front**: a bug was fixed when using ptasks on multicore hosts, and the legacy +stochastic generator of external load has been reintroduced. + +Version 3.33 (never released) +----------------------------- + +This version was overdue for more than 6 months, so it was skipped to not hinder our process of deprecating old code. + +Version 3.34 (June 26. 2023) +---------------------------- + +**On the maintenance front,** we removed the ancient MSG interface which end-of-life was scheduled for 2020, the Java bindings +that was MSG-only, support for native builds on Windows (WSL is now required) and support for 32 bits platforms. Keeping SimGrid +alive while adding new features require to remove old, unused stuff. The very rare users impacted by these removals are urged to +move to the new API and systems. + +We also conducted many internal refactorings to remove any occurrence of "surf" and "simix". SimGrid v3.12 used a layered design +where simix was providing synchronizations to actors, on top of surf which was computing the models. These features are now +provided in modules, not layers. Surf became the kernel::{lmm, resource, routing, timer, xml} modules while simix became +the kernel::{activity, actor, context} modules. + +**On the model front,** we realized an idea that has been on the back of our minds for quite some time. The question +was: could we use something in the line of the ptask model, that mixes computations and network transfers in a single +fluid activity, to simulate a *fluid I/O stream activity* that would consume both disk and network resources? This +remained an open question for years, mainly because the implementation of the ptask does not rely on the LMM solver as +the other models do. The *fair bottleneck* solver is convenient, but with less solid theoretical bases and the +development of its replacement (the *bmf solver*) is still ongoing. However, this combination of I/Os and +communications seemed easier as these activities share the same unit (bytes). + +After a few tentatives, we opted for a simple, slightly imperfect, yet convenient way to implement such I/O streams at the +kernel level. It doesn't require a new model, just that the default HostModels implements a new function which creates a +classical NetworkAction, but add some I/O-related constraints to it. A couple little hacks here and there, and done! A single +activity mixing I/Os and communications can be created whose progress is limited by the resource (Disk or Link) of least +bandwidth value. As a result, a new :cpp:func:`Io::streamto()` function has been added to send data between arbitrary disks or +hosts. The user can specify a ``src_disk`` on a ``src_host`` and a ``dst_disk`` on a ``dst_host`` to stream data of a +given ``size``. Note that disks are optional, allowing users to simulate some kind of "disk-to-memory" or "memory-to-disk" I/O +streams. It's highly inspired by the existing :cpp:func:`Comm::sendto` that can be used to send data between arbitrary hosts. + +We also modified the Wi-Fi model so that the total capacity of a link depends on the amount of flows on that link, accordingly to +the result of some ns-3 experiments. This model can be more accurate for congestioned Wi-Fi links, but its calibration is more +demanding, as shown in the `example +`_ and in the `research +paper `_. + +We also worked on the usability of our models, by actually writing the long overdue documentation of our TCP models and by renaming +some options for clarity (old names are still accepted as aliases). A new function ``s4u::Engine::flatify_platform()`` dumps an +XML representation that is inefficient (all zones are flatified) but easier to read (routes are explicitly defined). You should +not use the output as a regular input file, but it will prove useful to double-check the your platform. + +**On the interface front**, some functions were deprecated and will be removed in 4 versions, while some old deprecated functions +were removed in this version, as usual. + +Expressing your application as a DAG or a workflow is even more integrated than before. We added a new tutorial on simulating +DAGs and a DAG loader for workflows using the `wfcommons formalism `_. Starting an activity is now +properly delayed until after all its dependencies are fulfilled. We also added a notion of :ref:`Task `, a sort +of activity that can be fired several time. It's very useful to represent complex workflows. We added a ``on_this`` variant of +:ref:`every signal `, to react to the signals emitted by one object instance only. This is sometimes easier than +reacting to every signals of a class, and then filtering on the object you want. Activity signals (veto, suspend, resume, +completion) are now specialized by activity class. That is, callbacks registered in Exec::on_suspend_cb will not be fired for +Comms nor Ios + +Three new useful plugins were added: The :ref:`battery plugin` can be used to create batteries that get discharged +by the energy consumption of a given host, the :ref:`solar panel plugin ` can be used to create +solar panels which energy production depends on the solar irradiance and the :ref:`chiller plugin ` can be used to +create chillers and compensate the heat generated by hosts. These plugins could probably be better integrated +in the framework, but our goal is to include in SimGrid the building blocks upon which everybody would agree, while the model +elements that are more arguable are provided as plugins, in the hope that the users will carefully assess the plugins and adapt +them to their specific needs before usage. Here for example, there is several models of batteries (the one provided does not +take the aging into account), and would not be adapted to every studies. + +It is now easy to mix S4U actors and SMPI applications, or even to start more than one MPI application in a given simulation +with the :ref:`SMPI_app_instance_start() ` function. + +**On the model checking front**, this release brings a huge load of good improvements. First, we finished the long refactoring +so that the model-checker only reads the memory of the application for state equality (used for liveness checking) and for +:ref:`stateful checking `. Instead, the network protocol is used to retrieve the information and the +application is simply forked to explore new execution branches. The code is now easier to read and to understand. Even better, +the verification of safety properties is now enabled by default on every platforms since it does not depend on advanced OS +mechanisms anymore. You can even run the verified application in valgrind in that case. On the other hand, liveness checking +still needs to be enabled at compile time if you need it. Tbh, this part of the framework is not very well maintained nowadays. +We should introduce more testing of the liveness verification at some point to fix this situation. + +Back on to safety verification, we fixed a bug in the DPOR reduction which resulted in some failures to be missed by the +exploration, but this somewhat hinders the reduction quality (as we don't miss branches anymore). Some scenarios which could be +exhaustively explored earlier (with our buggy algorithm) are now too large for our (correct) exploration algorithm. But that's +not a problem because we implemented several mechanism to improve the performance of the verification. First, we implemented +source sets in DPOR, to blacklist transitions that are redundant with previously explored ones. Then, we implemented several new +DPOR variants. SDPOR and ODPOR are very efficient algorithms described in the paper "Source Sets: A Foundation for Optimal +Dynamic Partial Order Reduction" by Abdulla et al in 2017. We also have an experimental implementation of UPDOR, described in +the paper "Unfolding-based Partial Order Reduction" by Rodriguez et al in 2015, but it's not completely functional yet. We hope +to finish it for the next release. And finally, we implemented a guiding mechanism trying to converge faster toward the bugs in +the reduced state space. We have some naive heuristics, and we hope to provide better ones in the next release. + +We also extended the sthread module, which allows to intercept simple code that use pthread mutex and semaphores to simulate and +verify it. You do not even need to recompile your code, as it uses LD_PRELOAD to intercept on the target functions. This module +is still rather young, but it could probably be useful already, e.g. to verify the code written by students in a class on UNIX +IPC and synchronization. Check `the examples `_. In addition, +sthread can now also check concurrent accesses to a given collection, loosely inspired from `this paper +`_. +This feature is not very usable yet, as you have to manually annotate your code, but we hope to improve it in the future. + +Version 3.35 (November 23. 2023) +-------------------------------- + +**On the performance front**, we did some profiling and optimisation for this release. We saved some memory in simulation +mixing MPI applications and S4U actors, and we greatly improved the performance of simulation exchanging many messages. We even +introduced a new abstraction called MessageQueue and associated Mess simulated object to represent control messages in a very +efficient way. When using MessageQueue and Mess instead of Mailboxes and Comms, information is automagically transported over +thin air between producer and consumer in no simulated time. The implementation is much simpler, yielding much better +performance. Indeed, this abstraction solves a scalability issue observed in the WRENCH framework, which is heavily based on +control messages. + + +**On the interface front**, we introduced a new abstraction called ActivitySets. It makes it easy to interact with a bag of +mixed activities, waiting for the next occurring one, or for the completion of the whole set. This feature already existed in +SimGrid, but was implemented in a crude way with vectors of activities and static functions. It is also much easier than earlier +to mix several kinds of activities in activity sets. + +We introduced a new plugin called JBOD (just a bunch of disks), that proves useful to represent a sort of hosts gathering many +disks. We also revamped the battery, photovoltaic and chiller plugins introduced in previous release to make it even easier to +study green computing scenarios. On a similar topic, we eased the expression of vertical scaling with the :ref:`Task +`, the repeatable activities introduced in the previous release that can be used to represent microservices +applications. + +We not only added new abstractions and plugins, but also polished the existing interfaces. For example, the declaration of +multi-zoned platforms was greatly simplified by adding methods with fewer parameters to cover the common cases, leaving the +complete methods for the more advanced use cases (see the ChangeLog for details). Another difficulty in the earlier interface +was related to :ref:`Mailbox::get_async()` which used to require the user to store the payload somewhere on her side. Instead, +it is now possible to retrieve the payload from the communication object once it's over with :ref:`Comm::get_payload()`. + +Finally on the SMPI front, we introduced :ref:`SMPI_app_instance_join()` to wait for the completion of a started MPI instance. +This enables further mixture of MPI codes and controlled by S4U applications and plugins. We are currently considering +implementing some MPI4 calls, but nothing happened so far. + +**On the model-checking front**, the first big news is that we completely removed the liveness checker from the code base. This +is unfortunate, but the truth is that this code was very fragile and not really tested. + +For the context, liveness checking is the part of model checking that can determine whether the studied system always terminates +(absence of infinite loops, called non-progression loops in this context), or whether the system can reach a desirable state in +a finite time (for example, when you press the button, you want the elevator to come eventually). This relies on the ability to +detect loops in the execution, most often through the detection that this system state was already explored earlier. SimGrid +relied on tricks and heuristics to detect such state equality by leveraging debug information meant for gdb or valgrind. It +kinda worked, but was very fragile because neither this information nor the compilation process are meant for state equality +evaluation. Not zeroing the memory induces many crufty bits, for example in the padding bytes of the data structures or on the +stack. This can be solved by only comparing the relevant bits (as instructed by the debug information), but this process was +rather slow. Detecting equality in the heap was even more hackish, as we usually don't have any debug information about the +memory blocks retrieved from malloc(). This prevents any introspection into these blocks, which is problematic because the order +of malloc calls will create states that are syntactically different (the blocks are not in the same location in memory) but +semantically equivalent (the data meaning rarely depends on the block location itself). The heuristics we used here were so +crude that I don't want to detail them here. + +If liveness checking were to be re-implemented nowadays, I would go for a compiler-aided approach. I would maybe use a compiler +plugin to save the type of malloced blocks as in `Compiler-aided type tracking for correctness checking of MPI applications +`_ and zero the stack on +call returns to ease introspection. We could even rely on a complete introspection mechanism such as `MetaCPP +`_ or similar. We had a great piece of code to checkpoint millions of states in a +memory-efficient way. It was able to detect the common memory pages between states, and only save the modified ones. I guess +that this would need to be exhumed from the git when reimplementing liveness checking in SimGrid. But I doubt that we will +happen anytime soon, as we concentrate our scarce manpower on other parts. In particular, safety checking is about searching for +failed assertions by inspecting each state. A counter example to a safety property is simply a state where the assertion failed +/ the property is violated. A counter example to a liveness property is an infinite execution path that violates the property. +In some sense, safety checking is much easier than liveness checking, but it's already very powerful to exhaustively test an +application. + +In this release, we made several interesting progress on the safety side of model checking. First, we ironed out many bugs in +the ODPOR exploration algorithm (and dependency and reversible race theorems on which it relies). ODPOR should now be usable, +and it's much faster than our previous DPOR reduction. We also extended sthread a bit, by adding many tests from the McMini tool +and by implementing pthread barriers and conditionals. It seems to work rather well with C codes using pthreads and with C++ +codes using the standard library. You can even use sthread on a process running in valgrind or gdb. + +Unfortunately, conditionals cannot be verified so far by the model checker, because our implementation of condition variables is +still synchronous. Our reduction algorithms are optimized because we know that all transitions of our computation model are +persistent: once a transition gets enabled, it remains so until it's actually fired. This enables to build upon previous +computations, while everything must be recomputed in each state when previously enabled transitions can get disabled by an +external event. Unfortunately, this requires that every activity is written in an asynchronous way. You first declare your +intent to lock that mutex in an asynchronous manner, and then wait for the ongoing_acquisition object. Once a given acquisition +is granted, it will always remain so even if another actor creates another acquisition on the same mutex. This is the equivalent +of asynchronous communications that are common in MPI, but for mutex locks, barriers and semaphores. The thing that is missing +to verify pthread_cond in sthread is that I didn't manage to write an asynchronous version of the condition variables. We have an +almost working code lying around, but it fails for timed waits on condition variables. This will probably be part of the next +release. + +Version 3.36 (TBD) +------------------ + + .. |br| raw:: html
diff --git a/docs/source/Start_your_own_project.rst b/docs/source/Start_your_own_project.rst index cb70ef0c0b..bb06f098db 100644 --- a/docs/source/Start_your_own_project.rst +++ b/docs/source/Start_your_own_project.rst @@ -1,4 +1,4 @@ -.. +.. _setup_your_own: Start your Own Project ====================== @@ -24,15 +24,16 @@ to the template itself. Building your project with CMake -------------------------------- -Here is a `CMakeLists.txt` that you can use as a starting point for -your project. It builds two simulators from a given set of source files. +Here is a `CMakeLists.txt` that you can use as a starting point for your S4U +project (see below for MPI projects). It builds two simulators from a given set +of source files. .. code-block:: cmake - cmake_minimum_required(VERSION 2.8.8) + cmake_minimum_required(VERSION 2.8.12) project(MyFirstSimulator) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") find_package(SimGrid REQUIRED) @@ -57,14 +58,33 @@ manually but your project will produce relevant error messages when trying to compile on a machine where SimGrid is not installed. Please also refer to the file header for more information. -MPI projects should include ``find_package (MPI)`` in CMakeLists.txt. Then, the -variables ``MPI_C_COMPILER``, ``MPI_CXX_COMPILER``, and ``MPI_Fortran_COMPILER`` should -point to the full path of smpicc, smpicxx, and smpiff respectively. Example: +MPI projects should NOT search for MPI as usual in cmake, but instead use the ``smpi_c_target()`` macro +to declare that a given target is meant to be executed in ``smpirun`` (which path is set in ``${SMPIRUN}``). +This macro should work for C and C++ programs. Here is a small example: -.. code-block:: console +.. code-block:: cmake + + # Search FindSimgrid in my sources + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}") + find_package(SimGrid) + + # Declare an executable, and specify that it's meant to run within smpirun + add_executable(roundtrip roundtrip.c) + smpi_c_target(roundtrip) + + # Declare a test running our executable in ${SMPIRUN} + enable_testing() + add_test(NAME RoundTrip + COMMAND ${SMPIRUN} -platform ${CMAKE_SOURCE_DIR}/../cluster_backbone.xml -np 2 ./roundtrip) + +To compile Fortran code with cmake, you must override the ``MPI_Fortran_COMPILER`` variable as follows, but it will probably +break some configuration checks, so you should export ``SMPI_PRETEND_CC=1`` during the configuration (not during the compilation +nor the execution). - $ cmake -DMPI_C_COMPILER=/opt/simgrid/bin/smpicc -DMPI_CXX_COMPILER=/opt/simgrid/bin/smpicxx -DMPI_Fortran_COMPILER=/opt/simgrid/bin/smpiff . +.. code-block:: console + $ SMPI_PRETEND_CC=1 cmake -DMPI_C_COMPILER=/opt/simgrid/bin/smpicc -DMPI_CXX_COMPILER=/opt/simgrid/bin/smpicxx -DMPI_Fortran_COMPILER=/opt/simgrid/bin/smpiff . + $ make Building your project with Makefile ----------------------------------- @@ -121,33 +141,12 @@ Develop in C++ with Eclipse If you wish to develop your plugin or modify SimGrid using Eclipse. You have to run cmake and import it as a Makefile project. -Next, you have to activate C++14 in your build settings, add -std=c++14 +Next, you have to activate C++17 in your build settings, add -std=c++17 in the CDT GCC Built-in compiler settings. .. image:: /img/eclipseScreenShot.png :align: center - -Building the Java examples in Eclipse -------------------------------------- - -If you want to build our Java examples in Eclipse, get the whole -source code and open the archive on your disk. In Eclipse, select -the menu "File / Import", and then in the wizard "General / Existing -Project into Workspace". On the next page, select the directory -"examples/deprecated/java" that you can find in the SimGrid source tree as a root -directory and finish the creation. - -The file ``simgrid.jar`` must be in the root directory of the SimGrid -tree. That's where it is built by default, but if you don't want to -compile it yourself, just grab that file from the SimGrid website and -copy it in here. - -Please note that once you better understand SimGrid, you should not -modify the examples directly but instead create your own project in -eclipse. This will make it easier to upgrade to another version of -SimGrid. - .. _install_yours_troubleshooting: Troubleshooting your Project Setup @@ -178,7 +177,6 @@ Many undefined references .. code-block:: console masterworker.c:209: undefined reference to `sg_version_check' - masterworker.c:209: undefined reference to `MSG_init_nocheck' (and many other undefined references) This happens when the linker tries to use the wrong library. Use diff --git a/docs/source/Tutorial_Algorithms.rst b/docs/source/Tutorial_Algorithms.rst index 8adaa60fd0..e7675e8d0d 100644 --- a/docs/source/Tutorial_Algorithms.rst +++ b/docs/source/Tutorial_Algorithms.rst @@ -62,7 +62,7 @@ fully-functioning example of SimGrid simulation: the Master/Workers application. We will detail each part of the code and the necessary configuration to make it work. After this tour, several exercises are proposed to let you discover some of the SimGrid features, hands -on the keyboard. This practical session will be given in C++ or Python, +on the keyboard. This practical session will be given in C++ or Python, which you are supposed to know beforehand. @@ -77,7 +77,7 @@ is in charge of distributing some computational tasks to a set of .. image:: /tuto_s4u/img/intro.svg :align: center -The provided code dispatches these tasks in `round-robin scheduling `_, +The provided code dispatches these tasks in `round-robin scheduling `_, i.e. in circular order: tasks are dispatched to each worker one after the other, until all tasks are dispatched. You will improve this scheme later in this tutorial. @@ -184,7 +184,7 @@ And this is it. In only a few lines, we defined the algorithm of our master/work .. group-tab:: Python - That being said, an algorithm alone is not enough to define a simulation: + That being said, an algorithm alone is not enough to define a simulation: you need a main block to setup the simulation and its components as follows. This code creates a SimGrid simulation engine (on line 4), registers the actor functions to the engine (on lines 7 and 8), loads the simulated platform @@ -364,7 +364,7 @@ was obtained with the Triva software. Using Docker ............ -The easiest way to take the tutorial is to use the dedicated Docker image. +The easiest way to take the tutorial is to use the dedicated Docker image. Once you `installed Docker itself `_, simply do the following: .. code-block:: console @@ -459,7 +459,7 @@ Using your Computer Natively .. group-tab:: Python To take the tutorial on your machine, you first need to :ref:`install - a recent version of SimGrid ` and ``pajeng`` to visualize the + a recent version of SimGrid ` and ``pajeng`` to visualize the traces. You may want to install `Vite `_ to get a first glance at the traces. On Debian and Ubuntu for example, you can get them as follows: @@ -467,7 +467,7 @@ Using your Computer Natively $ sudo apt install simgrid pajeng vite - An initial version of the source code is provided on framagit. + An initial version of the source code is provided on framagit. If SimGrid is correctly installed, you should be able to clone the `repository `_ and execute it as follows: @@ -483,7 +483,7 @@ Using your Computer Natively .. warning:: - If you use the stable version of Debian 11, Ubuntu 21.04 or Ubuntu 21.10, then you need the right version of this tutorial + If you use the stable version of Debian 11, Ubuntu 21.04 or Ubuntu 21.10, then you need the right version of this tutorial (add ``--branch simgrid-v3.25`` as below). These distributions only contain SimGrid v3.25 while the latest version of this tutorial needs at least SimGrid v3.27. @@ -518,7 +518,7 @@ Discovering the Provided Code $ make master-workers $ ./master-workers small_platform.xml master-workers_d.xml - If you get an error message complaining that ``simgrid::s4u::Mailbox::get()`` does not exist, + If you get an error message complaining that ``simgrid::s4u::Mailbox::get()`` does not exist, then your version of SimGrid is too old for the version of the tutorial that you got. Check again previous section. .. group-tab:: Python @@ -529,24 +529,9 @@ Discovering the Provided Code $ python master-workers.py small_platform.xml master-workers_d.xml - If you get an error stating that the simgrid module does not exist, you need to get a newer version of SimGrid. + If you get an error stating that the simgrid module does not exist, you need to get a newer version of SimGrid. You may want to take the tutorial from the docker to get the newest version. -For a more "fancy" output, you can use simgrid-colorizer. - -.. code-block:: console - - # Run C++ code - $ ./master-workers small_platform.xml master-workers_d.xml 2>&1 | simgrid-colorizer - - # Run Python code - $ python master-workers.py small_platform.xml master-workers_d.xml 2>&1 | simgrid-colorizer - -If you installed SimGrid to a non-standard path, you may have to -specify the full path to simgrid-colorizer on the above line, such as -``/opt/simgrid/bin/simgrid-colorizer``. If you did not install it at all, -you can find it in /bin/colorize. - For a classical Gantt-Chart visualization, you can use `Vite `_ if you have it installed, as follows. But do not spend too much time installing Vite, because there @@ -565,11 +550,6 @@ is a better way to visualize SimGrid traces (see below). .. image:: /tuto_s4u/img/vite-screenshot.png :align: center -.. note:: - - If you use an older version of SimGrid (before v3.26), you should use - ``--cfg=tracing/msg/process:yes`` instead of ``--cfg=tracing/actor:yes``. - If you want the full power to visualize SimGrid traces, you need to use R. As a start, you can download this `starter script `_ @@ -596,7 +576,7 @@ Lab 1: Simpler deployments .. rst-class:: compact-list - **Learning goals:** + **Learning goals:** * Get your hands on the code and change the communication pattern * Discover the Mailbox mechanism @@ -636,8 +616,8 @@ information is only written once. It thus follows the `DRY .. code-block:: cpp for (int i = 0; i < tasks_count; i++) { - std::string worker_rank = std::to_string(i % workers_count); - std::string mailbox_name = std::string("worker-") + worker_rank; + std::string worker_rank = std::to_string(i % workers_count); + std::string mailbox_name = "worker-" + worker_rank; simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); mailbox->put(...); @@ -655,7 +635,7 @@ information is only written once. It thus follows the `DRY .. code-block:: cpp - for i in range(tasks_count): + for i in range(tasks_count): mailbox = Mailbox.by_name(str(i % worker_count)) mailbox.put(...) @@ -671,7 +651,7 @@ timing. ``put()`` and ``get()`` are matched regardless of their initiators' location and then the real communication occurs between the involved parties. -Please refer to the full `Mailboxes' documentation `_ +Please refer to the full `Mailboxes' documentation `_ for more details. @@ -680,7 +660,7 @@ Lab 2: Using the Whole Platform .. rst-class:: compact-list - **Learning goals:** + **Learning goals:** * Interact with the platform (get the list of all hosts) * Create actors directly from your program instead of the deployment file @@ -728,7 +708,7 @@ Creating the workers from the master .. group-tab:: Python For that, the master needs to retrieve the list of hosts declared in - the platform with :py:func:`simgrid.Engine.get_all_hosts`. Since this method is not static, + the platform with :py:func:`simgrid.Engine.get_all_hosts`. Since this method is not static, you may want to call it on the Engine instance, as in ``Engine.instance().get_all_hosts()``. Then, the master should start the worker actors with :py:func:`simgrid.Actor.create`. @@ -798,7 +778,7 @@ Lab 3: Fixed Experiment Duration .. rst-class:: compact-list - **Learning goals:** + **Learning goals:** * Forcefully kill actors, and stop the simulation at a given point of time * Control the logging verbosity @@ -812,7 +792,7 @@ instead of beforehand. Of course, usual time functions like ``gettimeofday`` will give you the time on your real machine, which is pretty useless in the simulation. Instead, retrieve the time in the simulated world with -:cpp:func:`simgrid::s4u::Engine::get_clock` (C++) or +:cpp:func:`simgrid::s4u::Engine::get_clock` (C++) or :py:func:`simgrid.Engine.get_clock()`) (Python). You can still stop your workers with a specific task as previously, @@ -829,7 +809,7 @@ Controlling the message verbosity ................................. Not all messages are equally informative, so you probably want to -change some of the *info* messages (C: :c:macro:`XBT_INFO`; Python: :py:func:`simgrid.this_actor.info`) +change some of the *info* messages (C: :c:macro:`XBT_INFO`; Python: :py:func:`simgrid.this_actor.info`) into *debug* messages`(C: :c:macro:`XBT_DEBUG`; Python: :py:func:`simgrid.this_actor.debug`) so that they are hidden by default. For example, you may want to use an *info* message once every 100 tasks and *debug* when sending all the other tasks. Or @@ -845,7 +825,7 @@ Lab 4: What-if analysis .. rst-class:: compact-list - **Learning goals:** + **Learning goals:** * Change the platform characteristics during the simulation. * Explore other communication patterns. @@ -854,10 +834,10 @@ Computational speed ................... Attach a profile to your hosts, so that their computational speed automatically vary over time, modeling an external load on these machines. -This can be done with :cpp:func:`simgrid::s4u::Host::set_speed_profile` (C++) or :py:func:`simgrid.Host.set_speed_profile` (Python). +This can be done with :cpp:func:`simgrid::s4u::Host::set_speed_profile` (C++) or :py:func:`simgrid.Host.set_speed_profile` (Python). Make it so that one of the hosts get really really slow, and observe how your whole application performance decreases. -This is because one slow host slows down the whole process. Instead of a round-robin dispatch push, +This is because one slow host slows down the whole process. Instead of a round-robin dispatch push, you should completely reorganize your application in a First-Come First-Served manner (FCFS). Actors should pull a task whenever they are ready, so that fast actors can overpass slow ones in the queue. @@ -866,7 +846,7 @@ or the master directly pushes the tasks to a centralized mailbox from which the to what would happen with communications based on BSD sockets while the second is closer to message queues. You could also decide to model your socket application in the second manner if you want to neglect these details and keep your simulator simple. It's your decision. -Changing the communication schema can be a bit hairy, but once it works, you will see that such as simple FCFS schema allows one to greatly +Changing the communication schema can be a bit hairy, but once it works, you will see that such as simple FCFS schema allows one to greatly increase the amount of tasks handled over time here. Things may be different with another platform file. Communication speed @@ -884,22 +864,22 @@ Modify the bandwidth of a given link with :cpp:func:`simgrid::s4u::Link::set_ban You can even have the bandwidth automatically vary over time with :cpp:func:`simgrid::s4u::Link::set_bandwidth_profile` (C++) or :py:func:`simgrid.Link.set_bandwidth_profile` (python). Once implemented, you will notice that slow communications may still result in situations -where one worker only works at a given point of time. To overcome that, your master needs -to send data to several workers in parallel, using +where one worker only works at a given point of time. To overcome that, your master needs +to send data to several workers in parallel, using :cpp:func:`simgrid::s4u::Mailbox::put_async` (C++) or :py:func:`simgrid.Mailbox.put_async` (Python) to start several communications in parallel, and -:cpp:func:`simgrid::s4u::Comm::wait_any` (C++) or and :py:func:`simgrid.Comm.wait_any` (Python) -to react to the completion of one of these communications. Actually, since this code somewhat tricky -to write, it's provided as :ref:`an example ` in the distribution (search for -``wait_any`` in that page). +:cpp:func:`simgrid::s4u::Comm::wait_any` (C++) or and :py:func:`simgrid.Comm.wait_any` (Python) +to react to the completion of one of these communications. Actually, since this code somewhat tricky +to write, it's provided as :ref:`an example ` in the distribution (search for +``wait_any`` in that page). Dealing with failures ..................... -Turn a given link off with :cpp:func:`simgrid::s4u::Link::turn_off` (C++) or :py:func:`simgrid.Link.turn_off` (python). -You can even implement churn where a link automatically turn off and on again over time with :cpp:func:`simgrid::s4u::Link::set_state_profile` (C++) or :py:func:`simgrid.Link.set_state_profile` (python). +Turn a given link off with :cpp:func:`simgrid::s4u::Link::turn_off` (C++) or :py:func:`simgrid.Link.turn_off` (python). +You can even implement churn where a link automatically turn off and on again over time with :cpp:func:`simgrid::s4u::Link::set_state_profile` (C++) or :py:func:`simgrid.Link.set_state_profile` (python). -If a link fails while you try to use it, ``wait()`` will raise a ``NetworkFailureException`` that you need to catch. +If a link fails while you try to use it, ``wait()`` will raise a ``NetworkFailureException`` that you need to catch. Again, there is a nice example demoing this feature, :ref:`under platform-failures `. Lab 5: Competing Applications @@ -907,7 +887,7 @@ Lab 5: Competing Applications .. rst-class:: compact-list - **Learning goals:** + **Learning goals:** * Advanced vizualization through tracing categories @@ -925,7 +905,7 @@ will categorize the tasks. Instead of starting the execution in one function call only with ``this_actor::execute(cost)``, you need to -create the execution activity, set its tracing category, start it +create the execution activity, set its tracing category, start it and wait for its completion, as follows. .. tabs:: @@ -1002,12 +982,6 @@ After this Tutorial This tutorial is now terminated. You could keep reading the online documentation and tutorials, or you could head up to the :ref:`example section ` to read some code. -.. todo:: - - Things to improve in the future: - - - Propose equivalent exercises and skeleton in Java once we fix the Java binding. - .. |br| raw:: html
diff --git a/docs/source/Tutorial_DAG.rst b/docs/source/Tutorial_DAG.rst new file mode 100644 index 0000000000..4bddc09040 --- /dev/null +++ b/docs/source/Tutorial_DAG.rst @@ -0,0 +1,410 @@ +.. _simdag: + +Simulating DAG +============== + +This tutorial presents the basics to understand how DAG are represented in SimGrid and how to simulate their workflow. + +Definition of a DAG +------------------- + +Directed Acyclic Graph: + +.. math:: + + \mathcal{G} = (\mathcal{V},\mathcal{E}) + +Set of vertices representing :ref:`Activities `: + +.. math:: + + \mathcal{V} = {v_i | i = 1, ..., V} + +Set of edges representing precedence constraints between :ref:`Activities `: + +.. math:: + + \mathcal{E} = {e_i,j | (i,j) \in {1, ..., V} x {1, ..., V}} + +.. image:: /img/dag.svg + :align: center + +Representing Vertices/Activities +................................ + +There is two types of :ref:`Activities ` that can represent Vertices: :ref:`Exec ` and :ref:`Comm `. +Thoses activities must be initiated and configured to properly describe your worflow. + +An Exec represents the execution of an amount of flop on a :ref:`Host ` of your platform. + +.. code-block:: cpp + + ExecPtr exec = Exec::init(); + exec->set_flops_amount(int); + exec->set_host(Host*); + exec->start(); + +A Comm represents a data transfer between two :ref:`Hosts ` of your platform. + +.. code-block:: cpp + + CommPtr comm = Comm::sendto_init(); + comm->set_source(Host*); + comm->set_destination(Host*); + comm->start(); + +Representing Edges/Dependencies +............................... + +An activity will not start until all of its dependencies have been completed. +Activities may have any number of successors. +Dependencies between Activities are created using :cpp:func:`simgrid::s4u::Activity::add_successor`. + +.. code-block:: cpp + + exec->add_successor(comm); + +The Activity ``comm`` will not start until ``exec`` has been completed. + +Lab 1: Basics +--------------- + +The goal of this lab is to describe the following DAG: + +.. image:: /img/dag1.svg + :align: center + +In this DAG we want ``c1`` to compute 1e9 flops, ``c2`` to compute 5e9 flops and ``c3`` to compute 2e9 flops. +There is also a data transfer of 5e8 bytes between ``c1`` and ``c3``. + +First of all, include the SimGrid library and define the log category. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 6-8 + +Inside the ``main`` function create an instance of :ref:`Engine ` and load the platform. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 12-13 + +Retrieve pointers to some hosts. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 15-16 + +Initiate the activities. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 18-21 + +Give names to thoses activities. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 23-26 + +Set the amount of work for each activity. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 28-31 + +Define the dependencies between the activities. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 33-35 + +Set the location of each Exec activity and source and destination for the Comm activity. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 37-41 + +Start the executions of Activities without dependencies. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 43-44 + +Add a callback to monitor the activities. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 46-49 + +Finally, run the simulation. + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.cpp + :language: cpp + :lines: 51 + +The execution of this code should give you the following output: + +.. literalinclude:: ../../examples/cpp/dag-tuto/s4u-dag-tuto.tesh + :language: none + :lines: 4- + +Lab 2: Import a DAG from a file +------------------------------- + +In this lab we present how to import a DAG into you SimGrid simulation, either using a DOT file, a JSON file, or a DAX file. + +The files presented in this lab describe the following DAG: + +.. image:: /img/dag2.svg + :align: center + +From a DOT file +............... + +A DOT file describes a workflow in accordance with the graphviz format. + +The following DOT file describes the workflow presented at the beginning of this lab: + +.. literalinclude:: ../../examples/cpp/dag-from-dot-simple/dag.dot + :language: dot + +It can be imported as a vector of Activities into SimGrid using :cpp:func:`simgrid::s4u::create_DAG_from_DOT`. Then, you have to assign hosts to your Activities. + +.. literalinclude:: ../../examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.cpp + :language: cpp + +The execution of this code should give you the following output: + +.. literalinclude:: ../../examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.tesh + :language: none + :lines: 4- + +From a JSON file +................ + +A JSON file describes a workflow in accordance with the `wfformat `_ . + +The following JSON file describes the workflow presented at the beginning of this lab: + +.. literalinclude:: ../../examples/cpp/dag-from-json-simple/dag.json + :language: json + +It can be imported as a vector of Activities into SimGrid using :cpp:func:`simgrid::s4u::create_DAG_from_json`. + +.. literalinclude:: ../../examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.cpp + :language: cpp + +The execution of this code should give you the following output: + +.. literalinclude:: ../../examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.tesh + :language: none + :lines: 4- + +From a DAX file [deprecated] +............................ + +A DAX file describes a workflow in accordance with the `Pegasus `_ format. + +The following DAX file describes the workflow presented at the beginning of this lab: + +.. literalinclude:: ../../examples/cpp/dag-from-dax-simple/dag.xml + :language: xml + +It can be imported as a vector of Activities into SimGrid using :cpp:func:`simgrid::s4u::create_DAG_from_DAX`. + +.. literalinclude:: ../../examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple.cpp + :language: cpp + +Lab 3: Scheduling with the Min-Min algorithm +-------------------------------------------- + +In this lab we present how to schedule activities imported from a DAX file using the +`Min-Min algorithm `_. + +The source code for this lab can be found `here `_. + +For code readability we first create the `sg4` namespace. + +.. code-block:: cpp + + namespace sg4 = simgrid::s4u; + +The core mechanism of the algorithm lies in three functions. +They respectively serve the purpose of finding tasks to schedule, +finding the best host to execute them and properly scheduling them. + +Find Tasks to Schedule +...................... + +The role of this function is to retrieve tasks that are ready to be scheduled, i.e, that have their dependencies solved. + +.. literalinclude:: ../../examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp + :language: cpp + :lines: 15-38 + +Find the Best Placement +....................... + +Once we have a task ready to be scheduled, we need to find the best placement for it. +This is done by evaluating the earliest finish time among all hosts. +It depends on the duration of the data transfers of the parents of this task to this host. + +.. literalinclude:: ../../examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp + :language: cpp + :lines: 40-91 + +Schedule a Task +............... + +When the best host has been found, the task is scheduled on it: + +* it sets the host of the task to schedule +* it stores the finish time of this task on the host +* it sets the destination of parents communication +* it sets the source of any child communication. + +.. literalinclude:: ../../examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp + :language: cpp + :lines: 93-113 + +Mixing it all Together +...................... + +Now that we have the key components of the algorithm let's merge them inside the main function. + +.. code-block:: cpp + + int main(int argc, char** argv) + { + ... + +First, we initialize the SimGrid Engine. + +.. code-block:: cpp + + sg4::Engine e(&argc, argv); + +The Min-Min algorithm schedules unscheduled tasks. +To keep track of them we make use of the method :cpp:func:`simgrid::s4u::Engine::track_vetoed_activities`. + +.. code-block:: cpp + + std::set vetoed; + e.track_vetoed_activities(&vetoed); + +We add the following callback that will be triggered at the end of execution activities. +This callback stores the finish time of the execution, +to use it as a start time for any subsequent communications. + +.. code-block:: cpp + + sg4::Activity::on_completion_cb([](sg4::Activity const& activity) { + // when an Exec completes, we need to set the potential start time of all its ouput comms + const auto* exec = dynamic_cast(&activity); + if (exec == nullptr) // Only Execs are concerned here + return; + for (const auto& succ : exec->get_successors()) { + auto* comm = dynamic_cast(succ.get()); + if (comm != nullptr) { + auto* finish_time = new double(exec->get_finish_time()); + // We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential start + // time + comm->set_data(finish_time); + } + } + }); + +We load the platform and force sequential execution on hosts. + +.. code-block:: cpp + + e.load_platform(argv[1]); + + /* Mark all hosts as sequential, as it ought to be in such a scheduling example. + * + * It means that the hosts can only compute one thing at a given time. If an execution already takes place on a given + * host, any subsequently started execution will be queued until after the first execution terminates */ + for (auto const& host : e.get_all_hosts()) { + host->set_concurrency_limit(1); + host->set_data(new double(0.0)); + } + +The tasks are imported from a DAX file. + +.. code-block:: cpp + + /* load the DAX file */ + auto dax = sg4::create_DAG_from_DAX(argv[2]); + +We look for the best host for the root task and schedule it. +We then advance the simulation to unlock next schedulable tasks. + +.. code-block:: cpp + + /* Schedule the root first */ + double finish_time; + auto* root = static_cast(dax.front().get()); + auto host = get_best_host(root, &finish_time); + schedule_on(root, host); + e.run(); + +Then, we get to the major loop of the algorithm. +This loop goes on until all tasks have been scheduled and executed. +It starts by finding ready tasks using `get_ready_tasks`. +It iteratively looks for the task that will finish first among ready tasks using `get_best_host`, and place it using `schedule_on`. +When no more tasks can be placed, we advance the simulation. + +.. code-block:: cpp + + while (not vetoed.empty()) { + XBT_DEBUG("Start new scheduling round"); + /* Get the set of ready tasks */ + auto ready_tasks = get_ready_tasks(dax); + vetoed.clear(); + + if (ready_tasks.empty()) { + /* there is no ready exec, let advance the simulation */ + e.run(); + continue; + } + /* For each ready exec: + * get the host that minimizes the completion time. + * select the exec that has the minimum completion time on its best host. + */ + double min_finish_time = std::numeric_limits::max(); + sg4::Exec* selected_task = nullptr; + sg4::Host* selected_host = nullptr; + + for (auto exec : ready_tasks) { + XBT_DEBUG("%s is ready", exec->get_cname()); + double finish_time; + host = get_best_host(exec, &finish_time); + if (finish_time < min_finish_time) { + min_finish_time = finish_time; + selected_task = exec; + selected_host = host; + } + } + + XBT_INFO("Schedule %s on %s", selected_task->get_cname(), selected_host->get_cname()); + schedule_on(selected_task, selected_host, min_finish_time); + + ready_tasks.clear(); + e.run(); + } + +Finally, we clean up the memory. + +.. code-block:: cpp + + /* Cleanup memory */ + for (auto const& h : e.get_all_hosts()) + delete h->get_data(); + + + + + + + diff --git a/docs/source/Tutorial_MPI_Applications.rst b/docs/source/Tutorial_MPI_Applications.rst index e06fb9cada..b486608b97 100644 --- a/docs/source/Tutorial_MPI_Applications.rst +++ b/docs/source/Tutorial_MPI_Applications.rst @@ -653,7 +653,7 @@ and use specific memory for the important parts. It can be freed afterward with SMPI_SHARED_FREE. If allocations are performed with malloc or calloc, SMPI (from version 3.25) provides the option -``--cfg=smpi/auto-shared-malloc-shared:n`` which will replace all allocations above size n bytes by +``--cfg=smpi/auto-shared-malloc-thresh:n`` which will replace all allocations above size n bytes by shared allocations. The value has to be carefully selected to avoid smaller control arrays, containing data necessary for the completion of the run. Try to run the (non modified) DT example again, with values going from 10 to 100,000 to show that diff --git a/docs/source/Tutorial_Model-checking.rst b/docs/source/Tutorial_Model-checking.rst index 0a5f1ca3ee..4e01642d53 100644 --- a/docs/source/Tutorial_Model-checking.rst +++ b/docs/source/Tutorial_Model-checking.rst @@ -4,7 +4,7 @@ Formal Verification and Model-checking ====================================== SimGrid can not only predict the performance of your application, but also assess its correctness through formal methods. Mc SimGrid is -a full-featured model-checker that is embedded in the SimGrid framework. It can be used to formally verify safety and liveness +a full-featured model-checker that is embedded in the SimGrid framework. It can be used to formally verify safety properties on codes running on top of SimGrid, be it :ref:`simple algorithms ` or :ref:`full MPI applications `. @@ -31,18 +31,39 @@ barrier, etc). Since it does not explicitly observe memory accesses, Mc SimGrid multithreaded programs. It can however be used to detect misuses of the synchronization functions, such as the ones resulting in deadlocks. -Mc SimGrid can be used to verify classical `safety and liveness properties `_, but +Mc SimGrid can be used to verify classical `safety properties `_, but also `communication determinism `_, a property that allows more efficient solutions toward fault-tolerance. It can alleviate the state space explosion problem through `Dynamic Partial Ordering Reduction (DPOR) `_ and `state equality `_. Note that Mc SimGrid is currently less mature than other parts of the framework, but it improves every month. Please report any question and issue so that we can further improve it. +Limits +^^^^^^ + +The main limit of Model Checking lies in the huge amount of scenarios to explore. SimGrid tries to explore only non-redundant +scenarios thanks to classical reduction techniques (such as DPOR and stateful exploration) but the exploration may well never +finish if you don't carefully adapt your application to this mode. + +A classical trap is that the Model Checker can only verify whether your application fits the properties provided, which is +useless if you have a bug in your property. Remember also that one way for your application to never violate a given assertion +is to not start at all, because of a stupid bug. + +Another limit of this mode is that it does not use the performance models of the simulation mode. Time becomes discrete: You can +say for example that the application took 42 steps to run, but there is no way to know how much time it took or the number of +watts that were dissipated. + +Finally, the model checker only explores the interleavings of computations and communications. Other factors such as thread +execution interleaving are not considered by the SimGrid model checker. + +The model checker may well miss existing issues, as it computes the possible outcomes *from a given initial situation*. There is +no way to prove the correctness of your application in full generality with this tool. + Getting Mc SimGrid ------------------ It is included in the SimGrid source code, but it is not compiled in by default as it induces a small performance overhead to the -simulations. It is also not activated in the Debian package, nor in the Java or Python binary distributions. If you just plan to +simulations. It is also not activated in the Debian package, nor in the Python binary distributions. If you just plan to experiment with Mc SimGrid, the easiest is to get the corresponding docker image. On the long term, you probably want to install it on your machine: it works out of the box on Linux, Windows (with WSL2) and FreeBSD. Simply request it from cmake (``cmake -Denable_model-checking .``) and then compile SimGrid :ref:`as usual `. Unfortunately, Mc SimGrid does not work natively @@ -86,7 +107,7 @@ if you prefer (see below for details on using the MPI version). .. toggle-header:: :header: Code of ``ndet-receive-s4u.cpp``: click here to open - + You can also `view it online `_ .. literalinclude:: tuto_mc/ndet-receive-s4u.cpp @@ -287,9 +308,6 @@ If you want to run such analysis on your own code, out of the provided docker, t - SimGrid should naturally :ref:`be compiled ` with model-checking support. This requires a full set of dependencies (documented on the :ref:`relevant page `) and should not be activated by default as there is a small performance penalty for codes using a SimGrid with MC enabled (even if you don't activate the model-checking at run time). -- You should pass some specific flags to the linker when compiling your application: ``-Wl,-znorelro -Wl,-znoseparate-code`` In the - docker, the provided CMakeLists.txt provides them for you when compiling the provided code. ``smpicc`` and friends also add this - parameter automatically. - Also install ``libboost-stacktrace-dev`` to display nice backtraces from the application side (the one from the model-checking side is available in any case, but it contains less details). - Mc SimGrid uses the ``ptrace`` system call to spy on the verified application. Some versions of Docker forbid the use of this call by @@ -301,11 +319,12 @@ Going further ------------- This tutorial is not complete yet, as there is nothing on reduction -techniques nor on liveness properties. For now, the best source of +techniques. For now, the best source of information on these topics is `this old tutorial `_ and `that old presentation -`_. +`_. But be warned that these source of +information are very old: the liveness verification was removed in v3.35, even if these docs still mention it. .. |br| raw:: html diff --git a/docs/source/XML_reference.rst b/docs/source/XML_reference.rst index 1060796fd8..dad879d7bb 100644 --- a/docs/source/XML_reference.rst +++ b/docs/source/XML_reference.rst @@ -26,6 +26,7 @@ Here is the complete list of all existing tags in the DTD: :ref:`pf_tag_bypassRoute`: tweeking the routing (advanced tag). |br| :ref:`pf_tag_bypassZoneRoute`: tweeking the routing (expert-only tag). |br| :ref:`pf_tag_cabinet`: building clusters manually from the XML (deprecated, please use the C++ API). |br| +:ref:`pf_tag_cluster`: building a cluster (aka, a full zone in one tag only). |br| :ref:`pf_tag_config`: pass simulation parameters from the XML file. |br| :ref:`pf_tag_disk`: storage resource. |br| :ref:`pf_tag_host`: computing resource. |br| @@ -131,10 +132,10 @@ name of the flag and ``value`` is what it has to be set to. - + - + @@ -192,13 +193,13 @@ We provide an example model of file system as a plugin, (sparsely) documented in A host is the computing resource on which an actor can run. See :cpp:class:`simgrid::s4u::Host`. **Parent tags:** :ref:`pf_tag_zone` (only leaf zones, i.e., zones containing neither inner zones nor clusters) |br| -**Children tags:** :ref:`pf_tag_mount`, :ref:`pf_tag_prop`, :ref:`pf_tag_disk` |br| +**Children tags:** :ref:`pf_tag_prop`, :ref:`pf_tag_disk` |br| **Attributes:** :``id``: Host name. Must be unique over the whole platform. :``speed``: Computational power (per core, in flop/s). - If you use DVFS, provide a comma-separated list of values for each pstate (see :ref:`howto_dvfs`). + If you use DVFS, provide a comma-separated list of values for each pstate (see :ref:`API_s4u_Host_dvfs`). :``core``: Amount of cores (default: 1). See :ref:`howto_multicore`. :``availability_file``: @@ -246,7 +247,7 @@ A host is the computing resource on which an actor can run. See :cpp:class:`simg :``coordinates``: Vivaldi coordinates (meaningful for Vivaldi zones only). See :ref:`pf_tag_peer`. :``pstate``: Initial pstate (default: 0, the first one). - See :ref:`howto_dvfs`. + See :ref:`API_s4u_Host_dvfs`. ------------------------------------------------------------------------------- @@ -399,7 +400,7 @@ and a download link. :``id``: Name of the host. Must be unique on the whole platform. :``speed``: Computational power (in flop/s). - If you use DVFS, provide a comma-separated list of values for each pstate (see :ref:`howto_dvfs`). + If you use DVFS, provide a comma-separated list of values for each pstate (see :ref:`API_s4u_Host_dvfs`). :``bw_in``: Bandwidth of the private downstream link, along with its unit. See :ref:`pf_tag_link`. :``bw_out``: Bandwidth of the private upstream link, along with its @@ -456,12 +457,12 @@ the plugins. From your code, you can interact with these properties using the following functions: -- Actor: :cpp:func:`simgrid::s4u::Actor::get_property` or :cpp:func:`MSG_process_get_property_value` +- Actor: :cpp:func:`simgrid::s4u::Actor::get_property` - Cluster: this is a zone, see below. - Disk: :cpp:func:`simgrid::s4u::Disk::get_property` -- Host: :cpp:func:`simgrid::s4u::Host::get_property` or :cpp:func:`MSG_host_get_property_value` +- Host: :cpp:func:`simgrid::s4u::Host::get_property` - Link: :cpp:func:`simgrid::s4u::Link::get_property` -- Zone: :cpp:func:`simgrid::s4u::NetZone::get_property` of :cpp:func:`MSG_zone_get_property_value` +- Zone: :cpp:func:`simgrid::s4u::NetZone::get_property` **Parent tags:** :ref:`pf_tag_actor`, :ref:`pf_tag_config`, :ref:`pf_tag_cluster`, :ref:`pf_tag_host`, :ref:`pf_tag_link`, :ref:`pf_tag_disk`,:ref:`pf_tag_zone` |br| @@ -554,7 +555,7 @@ More detail can be found in the following sections :ref:`pf_routes` and :ref:`pf :``gw_src``: Netpoint (within src zone) from which this route starts. Must be an existing host/router. :``gw_dst``: Netpoint (within dst zone) to which this route leads. Must be an existing host/router. :``symmetrical``: Whether this route is symmetrical, ie, whether we are defining the route ``dst -> src`` at the same - time. Valid values: ``yes``, ``no``, ``YES``, ``NO``. + time. Valid values: ``yes``, ``no``, ``YES``, ``NO``. ------------------------------------------------------------------------------- @@ -605,7 +606,7 @@ to experts. :``gw_src``: Netpoint (within src zone) from which this route starts. Must be an existing host/router. :``gw_dst``: Netpoint (within dst zone) to which this route leads. Must be an existing host/router. :``symmetrical``: Whether this route is symmetrical, ie, whether we are defining the route ``dst -> src`` at the same - time. Valid values: ``yes``, ``no``, ``YES``, ``NO``. + time. Valid values: ``yes``, ``no``, ``YES``, ``NO``. ------------------------------------------------------------------------------- @@ -680,5 +681,5 @@ Specify the up and down private links of a given host, which must be in a Cluste .. |br| raw:: html - +
diff --git a/docs/source/_ext/javasphinx/.gitignore b/docs/source/_ext/javasphinx/.gitignore deleted file mode 100644 index 03ecc2b774..0000000000 --- a/docs/source/_ext/javasphinx/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.pyc -dist/ -*.egg-info/ -.vscode -.DS_Store \ No newline at end of file diff --git a/docs/source/_ext/javasphinx/LICENSE b/docs/source/_ext/javasphinx/LICENSE deleted file mode 100644 index d645695673..0000000000 --- a/docs/source/_ext/javasphinx/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/docs/source/_ext/javasphinx/MANIFEST.in b/docs/source/_ext/javasphinx/MANIFEST.in deleted file mode 100644 index 9561fb1061..0000000000 --- a/docs/source/_ext/javasphinx/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -include README.rst diff --git a/docs/source/_ext/javasphinx/README.md b/docs/source/_ext/javasphinx/README.md deleted file mode 100644 index a523ad213b..0000000000 --- a/docs/source/_ext/javasphinx/README.md +++ /dev/null @@ -1,12 +0,0 @@ - -# javasphinx - -[![Documentation Status](https://readthedocs.org/projects/bronto-javasphinx/badge/?version=latest)](http://bronto-javasphinx.readthedocs.io/en/latest/?badge=latest) - -**This project is no longer maintained and should be used for historical purposes only.** - -javasphinx is an extension to the Sphinx documentation system which adds support for documenting Java projects. It includes a Java domain for writing documentation manually and a javasphinx-apidoc utility which will automatically generate API documentation from existing Javadoc markup. - -javasphinx is available in the Python Package Index (PyPi) under the name _javasphinx_ and can be installed using tools such as `pip` or `easy_install`. - -Documentation for javasphinx is available at http://bronto-javasphinx.readthedocs.io diff --git a/docs/source/_ext/javasphinx/doc/conf.py b/docs/source/_ext/javasphinx/doc/conf.py deleted file mode 100644 index de52125b06..0000000000 --- a/docs/source/_ext/javasphinx/doc/conf.py +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright 2012-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -project = 'javasphinx' -version = '0.9.15' -release = version - -extensions = ['javasphinx'] - -master_doc = 'index' -copyright = u'2012-2017, Bronto Software Inc. and contributors' -primary_domain = 'rst' diff --git a/docs/source/_ext/javasphinx/doc/index.rst b/docs/source/_ext/javasphinx/doc/index.rst deleted file mode 100644 index 8780a23eaf..0000000000 --- a/docs/source/_ext/javasphinx/doc/index.rst +++ /dev/null @@ -1,219 +0,0 @@ - -####################### -javasphinx User's Guide -####################### - -Welcome to the javasphinx user's guide. - -Introduction -============ - -javasphinx is a Sphinx_ extension that provides a Sphinx domain_ for documenting -Java projects and a ``javasphinx-apidoc`` command line tool for automatically -generating API documentation from existing Java source code and Javadoc -documentation. - -.. _Sphinx: http://sphinx-doc.org -.. _domain: http://sphinx-doc.org/domains.html - -Installing -========== - -javasphinx is available in the Python Package Index (PyPi) and can be installed -using tools such as ``pip`` or ``easy_install``, - -.. code-block:: sh - - $ pip install javasphinx - -or, - -.. code-block:: sh - - $ easy_install -U javasphinx - -Configuration -============= - -To enable javasphinx for your existing Sphinx configuration add ``'javasphinx'`` -to the list of extensions in your conf.py file. javasphinx can be configured to -cross link to external sources of documentation using the ``javadoc_url_map`` -option, - -.. code-block:: python - - javadoc_url_map = { - 'com.netflix.curator' : ('http://netflix.github.com/curator/doc', 'javadoc'), - 'org.springframework' : ('http://static.springsource.org/spring/docs/3.1.x/javadoc-api/', 'javadoc'), - 'org.springframework.data.redis' : ('http://static.springsource.org/spring-data/data-redis/docs/current/api/', 'javadoc') - } - -Each key in the map should be a Java package. Each value is a tuple of the form -``(base_url, doc_type)`` where ``base_url`` is the base URL of the documentation -source, and ``doc_type`` is one of, - -``javadoc`` - For documentation generated by the Javadoc tool *before* version 8. - -``javadoc8`` - For documentation generated by the Javadoc tool after version 8. This is - required due to changes in how method anchors are generated (see JDK-8144118_). - -``sphinx`` - For external documentation generated by javasphinx. - -When comparing referenced types to the list of available packages the longest -match will be used. Entries for ``java``, ``javax``, ``org.xml``, and -``org.w3c`` packages pointing to http://docs.oracle.com/javase/8/docs/api are -included automatically and do not need to be defined explicitly. - -.. _JDK-8144118: https://bugs.openjdk.java.net/browse/JDK-8144118 - -Java domain -=========== - -Directives ----------- - -The Java domain uses the name **java** and provides the following directives, - -.. rst:directive:: .. java:type:: type-signature - - Describe a Java type. The signature can represent either a class, interface, - enum or annotation declaration. - - Use the ``param`` field to document type parameters. - - Example, - - .. code-block:: rst - - .. java:type:: public interface List extends Collection, Iterable - - An ordered collection (also known as a *sequence*) - - :param E: type of item stored by the list - - produces, - - .. java:type:: public interface List extends Collection, Iterable - - An ordered collection (also known as a *sequence*) - - :param E: type of item stored by the list - -.. rst:directive:: .. java:field:: field-signature - - Describe a Java field. - -.. rst:directive:: .. java:method:: method-signature - - Describe a Java method. - - Use the ``param`` field to document parameters. - - Use the ``throws`` field to document exceptions thrown by the method. - - Use the ``return`` field to document the return type - -.. rst:directive:: .. java:constructor:: constructor-signature - - Describe a Java constructor. - - Use the ``param`` field to document parameters. - - Use the ``throws`` field to document exceptions thrown by the constructor. - -.. rst:directive:: .. java:package:: package - - Provide package-level documentation and also sets the active package for the - type, method, field, constructors, and references that follow. - - Use the ``:noindex:`` option if the directive is only being used to specify - the active package. Only one directive for a given package should exclude - ``:noindex:``. - -.. rst:directive:: .. java:import:: package type - - Declare the given type as being provided by the given package. This - information helps javasphinx create cross references for types in type, - method, and field declarations. It also allows explicit cross references - (using the ``java:ref`` role) to exclude the package qualification. - -The method, construct, field, and type directives all accept the following -standard options, - -.. describe:: package - - Specify the package the declaration is within. Can be used instead of, or to - override, a ``java:package`` directive. - -.. describe:: outertype - - Specify the class/interface the documented object is contained within. This - option should be provided for any constructor, method, or field directive - that isn't nested within a corresponding type directive. - -Roles ------ - -The following roles are provided, - -.. rst:role:: java:ref - - This role can be used to create a cross reference to any object type within - the Java domain. Aliases for this role include ``java:meth``, ``java:type``, - ``java:field``, ``java:package``, and ``java:construct``. - - An explicit title can be provided by using the standard ``title `` - syntax. - -.. rst:role:: java:extdoc - - This role can be used to explicitly link to an externally documented - type. The reference must be fully qualified and supports an explicit title - using the ``title `` syntax. - - The ``java:ref`` role will also create external references as a fall-back if - it can't find a matching local declaration so using this role is not strictly - necessary. - -javasphinx-apidoc -================= - -The ``javasphinx-apidoc`` tool is the counterpoint to the ``sphinx-apidoc`` tool -within the Java domain. It can be used to generate reST source from existing -Java source code which has been marked up with Javadoc-style comments. The -generated reST is then processed alongside hand-written documentation by Sphinx. - -At minimum a source and destination directory must be provided. The input -directory will be scanned for .java files and documentation will be generated -for all non-private types and members. A separate output file will be generated -for each type (including inner classes). Each file is put within a directory -corresponding to its package (with periods replaced by directory separators) and -with the basename of the file deriving from the type name. Inner types are -placed in files with a basename using a hyphen to separate inner and outer -types, e.g. ``OuterType-InnerType.rst``. - -By default ``javasphinx-apidoc`` will not override existing files. Two options -can change this behavior, - -.. option:: -f, --force - - All existing output files will be rewritten. If a cache directory is - specified it will be rebuilt. - -.. option:: -u, --update - - Updated source files will have their corresponding output files - updated. Unchanged files will be left alone. Most projects will want to use - this option. - -For larger projects it is recommended to use a cache directory. This can speed -up subsequent runs by an order of magnitude or more. Specify a directory to -store cached output using the :option:`-c` option, - -.. option:: -c, --cache-dir - - Specify a directory to cache intermediate documentation representations. This - directory will be created if it does not already exist. diff --git a/docs/source/_ext/javasphinx/javasphinx/__init__.py b/docs/source/_ext/javasphinx/javasphinx/__init__.py deleted file mode 100644 index c6b9cb9bf0..0000000000 --- a/docs/source/_ext/javasphinx/javasphinx/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright 2012-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from .domain import JavaDomain -from .extdoc import javadoc_role - -def setup(app): - app.add_domain(JavaDomain) - - app.add_config_value('javadoc_url_map', dict(), '') - app.add_role('java:extdoc', javadoc_role) diff --git a/docs/source/_ext/javasphinx/javasphinx/apidoc.py b/docs/source/_ext/javasphinx/javasphinx/apidoc.py deleted file mode 100755 index c4eca15591..0000000000 --- a/docs/source/_ext/javasphinx/javasphinx/apidoc.py +++ /dev/null @@ -1,351 +0,0 @@ -# -# Copyright 2012-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from __future__ import print_function, unicode_literals - -try: - import cPickle as pickle -except ImportError: - import pickle - -import hashlib -import logging -import sys -import os -import os.path - -from optparse import OptionParser - -import javalang - -import javasphinx.compiler as compiler -import javasphinx.util as util - -def encode_output(s): - if isinstance(s, str): - return s - return s.encode('utf-8') - -def find_source_files(input_path, excludes): - """ Get a list of filenames for all Java source files within the given - directory. - - """ - - java_files = [] - - input_path = os.path.normpath(os.path.abspath(input_path)) - - for dirpath, dirnames, filenames in os.walk(input_path): - if is_excluded(dirpath, excludes): - del dirnames[:] - continue - - for filename in filenames: - if filename.endswith(".java"): - java_files.append(os.path.join(dirpath, filename)) - - return java_files - -def write_toc(packages, opts): - doc = util.Document() - doc.add_heading(opts.toc_title, '=') - - toc = util.Directive('toctree') - toc.add_option('maxdepth', '2') - doc.add_object(toc) - - for package in sorted(packages.keys()): - toc.add_content("%s/package-index\n" % package.replace('.', '/')) - - filename = 'packages.' + opts.suffix - fullpath = os.path.join(opts.destdir, filename) - - if os.path.exists(fullpath) and not (opts.force or opts.update): - sys.stderr.write(fullpath + ' already exists. Use -f to overwrite.\n') - sys.exit(1) - - f = open(fullpath, 'w') - f.write(encode_output(doc.build())) - f.close() - -def write_documents(packages, documents, sources, opts): - package_contents = dict() - - # Write individual documents - for fullname, (package, name, document) in documents.items(): - if is_package_info_doc(name): - continue - - package_path = package.replace('.', os.sep) - filebasename = name.replace('.', '-') - filename = filebasename + '.' + opts.suffix - dirpath = os.path.join(opts.destdir, package_path) - fullpath = os.path.join(dirpath, filename) - - if not os.path.exists(dirpath): - os.makedirs(dirpath) - elif os.path.exists(fullpath) and not (opts.force or opts.update): - sys.stderr.write(fullpath + ' already exists. Use -f to overwrite.\n') - sys.exit(1) - - # Add to package indexes - package_contents.setdefault(package, list()).append(filebasename) - - if opts.update and os.path.exists(fullpath): - # If the destination file is newer than the source file than skip - # writing it out - source_mod_time = os.stat(sources[fullname]).st_mtime - dest_mod_time = os.stat(fullpath).st_mtime - - if source_mod_time < dest_mod_time: - continue - - f = open(fullpath, 'w') - f.write(encode_output(document)) - f.close() - - # Write package-index for each package - for package, classes in package_contents.items(): - doc = util.Document() - doc.add_heading(package, '=') - - #Adds the package documentation (if any) - if packages[package] != '': - documentation = packages[package] - doc.add_line("\n%s" % documentation) - - doc.add_object(util.Directive('java:package', package)) - - toc = util.Directive('toctree') - toc.add_option('maxdepth', '1') - - classes.sort() - for filebasename in classes: - toc.add_content(filebasename + '\n') - doc.add_object(toc) - - package_path = package.replace('.', os.sep) - filename = 'package-index.' + opts.suffix - dirpath = os.path.join(opts.destdir, package_path) - fullpath = os.path.join(dirpath, filename) - - if not os.path.exists(dirpath): - os.makedirs(dirpath) - elif os.path.exists(fullpath) and not (opts.force or opts.update): - sys.stderr.write(fullpath + ' already exists. Use -f to overwrite.\n') - sys.exit(1) - - f = open(fullpath, 'w') - f.write(encode_output(doc.build())) - f.close() - -def get_newer(a, b): - if not os.path.exists(a): - return b - - if not os.path.exists(b): - return a - - a_mtime = int(os.stat(a).st_mtime) - b_mtime = int(os.stat(b).st_mtime) - - if a_mtime < b_mtime: - return b - - return a - -def format_syntax_error(e): - rest = "" - if e.at.position: - value = e.at.value - pos = e.at.position - rest = ' at %s line %d, character %d' % (value, pos[0], pos[1]) - return e.description + rest - -def generate_from_source_file(doc_compiler, source_file, cache_dir): - if cache_dir: - fingerprint = hashlib.md5(source_file.encode()).hexdigest() - cache_file = os.path.join(cache_dir, 'parsed-' + fingerprint + '.p') - - if get_newer(source_file, cache_file) == cache_file: - return pickle.load(open(cache_file, 'rb')) - else: - cache_file = None - - f = open(source_file) - source = f.read() - f.close() - - try: - ast = javalang.parse.parse(source) - except javalang.parser.JavaSyntaxError as e: - util.error('Syntax error in %s: %s', source_file, format_syntax_error(e)) - except Exception: - util.unexpected('Unexpected exception while parsing %s', source_file) - - documents = {} - try: - if source_file.endswith("package-info.java"): - if ast.package is not None: - documentation = doc_compiler.compile_docblock(ast.package) - documents[ast.package.name] = (ast.package.name, 'package-info', documentation) - else: - documents = doc_compiler.compile(ast) - except Exception: - util.unexpected('Unexpected exception while compiling %s', source_file) - - if cache_file: - dump_file = open(cache_file, 'wb') - pickle.dump(documents, dump_file) - dump_file.close() - - return documents - -def generate_documents(source_files, cache_dir, verbose, member_headers, parser): - documents = {} - sources = {} - doc_compiler = compiler.JavadocRestCompiler(None, member_headers, parser) - - for source_file in source_files: - if verbose: - print('Processing', source_file) - - this_file_documents = generate_from_source_file(doc_compiler, source_file, cache_dir) - for fullname in this_file_documents: - sources[fullname] = source_file - - documents.update(this_file_documents) - - #Existing packages dict, where each key is a package name - #and each value is the package documentation (if any) - packages = {} - - #Gets the name of the package where the document was declared - #and adds it to the packages dict with no documentation. - #Package documentation, if any, will be collected from package-info.java files. - for package, name, _ in documents.values(): - packages[package] = "" - - #Gets packages documentation from package-info.java documents (if any). - for package, name, content in documents.values(): - if is_package_info_doc(name): - packages[package] = content - - return packages, documents, sources - -def normalize_excludes(rootpath, excludes): - f_excludes = [] - for exclude in excludes: - if not os.path.isabs(exclude) and not exclude.startswith(rootpath): - exclude = os.path.join(rootpath, exclude) - f_excludes.append(os.path.normpath(exclude) + os.path.sep) - return f_excludes - -def is_excluded(root, excludes): - sep = os.path.sep - if not root.endswith(sep): - root += sep - for exclude in excludes: - if root.startswith(exclude): - return True - return False - -def is_package_info_doc(document_name): - ''' Checks if the name of a document represents a package-info.java file. ''' - return document_name == 'package-info' - - -def main(argv=sys.argv): - logging.basicConfig(level=logging.WARN) - - parser = OptionParser( - usage="""\ -usage: %prog [options] -o [exclude_paths, ...] - -Look recursively in for Java sources files and create reST files -for all non-private classes, organized by package under . A package -index (package-index.) will be created for each package, and a top level -table of contents will be generated named packages.. - -Paths matching any of the given exclude_paths (interpreted as regular -expressions) will be skipped. - -Note: By default this script will not overwrite already created files.""") - - parser.add_option('-o', '--output-dir', action='store', dest='destdir', - help='Directory to place all output', default='') - parser.add_option('-f', '--force', action='store_true', dest='force', - help='Overwrite all files') - parser.add_option('-c', '--cache-dir', action='store', dest='cache_dir', - help='Directory to stored cachable output') - parser.add_option('-u', '--update', action='store_true', dest='update', - help='Overwrite new and changed files', default=False) - parser.add_option('-T', '--no-toc', action='store_true', dest='notoc', - help='Don\'t create a table of contents file') - parser.add_option('-t', '--title', dest='toc_title', default='Javadoc', - help='Title to use on table of contents') - parser.add_option('--no-member-headers', action='store_false', default=True, dest='member_headers', - help='Don\'t generate headers for class members') - parser.add_option('-s', '--suffix', action='store', dest='suffix', - help='file suffix (default: rst)', default='rst') - parser.add_option('-I', '--include', action='append', dest='includes', - help='Additional input paths to scan', default=[]) - parser.add_option('-p', '--parser', dest='parser_lib', default='lxml', - help='Beautiful Soup---html parser library option.') - parser.add_option('-v', '--verbose', action='store_true', dest='verbose', - help='verbose output') - - (opts, args) = parser.parse_args(argv[1:]) - - if not args: - parser.error('A source path is required.') - - rootpath, excludes = args[0], args[1:] - - input_paths = opts.includes - input_paths.append(rootpath) - - if not opts.destdir: - parser.error('An output directory is required.') - - if opts.suffix.startswith('.'): - opts.suffix = opts.suffix[1:] - - for input_path in input_paths: - if not os.path.isdir(input_path): - sys.stderr.write('%s is not a directory.\n' % (input_path,)) - sys.exit(1) - - if not os.path.isdir(opts.destdir): - os.makedirs(opts.destdir) - - if opts.cache_dir and not os.path.isdir(opts.cache_dir): - os.makedirs(opts.cache_dir) - - excludes = normalize_excludes(rootpath, excludes) - source_files = [] - - for input_path in input_paths: - source_files.extend(find_source_files(input_path, excludes)) - - packages, documents, sources = generate_documents(source_files, opts.cache_dir, opts.verbose, - opts.member_headers, opts.parser_lib) - - write_documents(packages, documents, sources, opts) - - if not opts.notoc: - write_toc(packages, opts) diff --git a/docs/source/_ext/javasphinx/javasphinx/compiler.py b/docs/source/_ext/javasphinx/javasphinx/compiler.py deleted file mode 100644 index e4fe6238bf..0000000000 --- a/docs/source/_ext/javasphinx/javasphinx/compiler.py +++ /dev/null @@ -1,345 +0,0 @@ -# -# Copyright 2012-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import javalang - -import javasphinx.formatter as formatter -import javasphinx.util as util -import javasphinx.htmlrst as htmlrst - -class JavadocRestCompiler(object): - """ Javadoc to ReST compiler. Builds ReST documentation from a Java syntax - tree. """ - - def __init__(self, filter=None, member_headers=True, parser='lxml'): - if filter: - self.filter = filter - else: - self.filter = self.__default_filter - - self.converter = htmlrst.Converter(parser) - - self.member_headers = member_headers - - def __default_filter(self, node): - """Excludes private members and those tagged "@hide" / "@exclude" in their - docblocks. - - """ - - if not isinstance(node, javalang.tree.Declaration): - return False - - if 'private' in node.modifiers: - return False - - if isinstance(node, javalang.tree.Documented) and node.documentation: - doc = javalang.javadoc.parse(node.documentation) - if 'hide' in doc.tags or 'exclude' in doc.tags: - return False - - return True - - def __html_to_rst(self, s): - return self.converter.convert(s) - - def __output_doc(self, documented): - if not isinstance(documented, javalang.tree.Documented): - raise ValueError('node not documented') - - output = util.Document() - - if not documented.documentation: - return output - - doc = javalang.javadoc.parse(documented.documentation) - - if doc.description: - output.add(self.__html_to_rst(doc.description)) - output.clear() - - if doc.authors: - output.add_line(':author: %s' % (self.__html_to_rst(', '.join(doc.authors)),)) - - for name, value in doc.params: - output.add_line(':param %s: %s' % (name, self.__html_to_rst(value))) - - for exception in doc.throws: - description = doc.throws[exception] - output.add_line(':throws %s: %s' % (exception, self.__html_to_rst(description))) - - if doc.return_doc: - output.add_line(':return: %s' % (self.__html_to_rst(doc.return_doc),)) - - if doc.tags.get('see'): - output.clear() - - see_also = ', '.join(self.__output_see(see) for see in doc.tags['see']) - output.add_line('**See also:** %s' % (see_also,)) - - return output - - def __output_see(self, see): - """ Convert the argument to a @see tag to rest """ - - if see.startswith('... - return self.__html_to_rst(see) - if '"' in see: - # Plain text - return see - - # Type reference (default) - return ':java:ref:`%s`' % (see.replace('#', '.').replace(' ', ''),) - - def compile_type(self, declaration): - signature = util.StringBuilder() - formatter.output_declaration(declaration, signature) - - doc = self.__output_doc(declaration) - - directive = util.Directive('java:type', signature.build()) - directive.add_content(doc) - - return directive - - def compile_enum_constant(self, enum, constant): - signature = util.StringBuilder() - - for annotation in constant.annotations: - formatter.output_annotation(annotation, signature) - - # All enum constants are public, static, and final - signature.append('public static final ') - signature.append(enum) - signature.append(' ') - signature.append(constant.name) - - doc = self.__output_doc(constant) - - directive = util.Directive('java:field', signature.build()) - directive.add_content(doc) - - return directive - - def compile_field(self, field): - signature = util.StringBuilder() - - for annotation in field.annotations: - formatter.output_annotation(annotation, signature) - - formatter.output_modifiers(field.modifiers, signature) - signature.append(' ') - - formatter.output_type(field.type, signature) - signature.append(' ') - signature.append(field.declarators[0].name) - - doc = self.__output_doc(field) - - directive = util.Directive('java:field', signature.build()) - directive.add_content(doc) - - return directive - - def compile_constructor(self, constructor): - signature = util.StringBuilder() - - for annotation in constructor.annotations: - formatter.output_annotation(annotation, signature) - - formatter.output_modifiers(constructor.modifiers, signature) - signature.append(' ') - - if constructor.type_parameters: - formatter.output_type_params(constructor.type_parameters, signature) - signature.append(' ') - - signature.append(constructor.name) - - signature.append('(') - formatter.output_list(formatter.output_formal_param, constructor.parameters, signature, ', ') - signature.append(')') - - if constructor.throws: - signature.append(' throws ') - formatter.output_list(formatter.output_exception, constructor.throws, signature, ', ') - - doc = self.__output_doc(constructor) - - directive = util.Directive('java:constructor', signature.build()) - directive.add_content(doc) - - return directive - - def compile_method(self, method): - signature = util.StringBuilder() - - for annotation in method.annotations: - formatter.output_annotation(annotation, signature) - - formatter.output_modifiers(method.modifiers, signature) - signature.append(' ') - - if method.type_parameters: - formatter.output_type_params(method.type_parameters, signature) - signature.append(' ') - - formatter.output_type(method.return_type, signature) - signature.append(' ') - - signature.append(method.name) - - signature.append('(') - formatter.output_list(formatter.output_formal_param, method.parameters, signature, ', ') - signature.append(')') - - if method.throws: - signature.append(' throws ') - formatter.output_list(formatter.output_exception, method.throws, signature, ', ') - - doc = self.__output_doc(method) - - directive = util.Directive('java:method', signature.build()) - directive.add_content(doc) - - return directive - - def compile_type_document(self, imports_block, package, name, declaration): - """ Compile a complete document, documenting a type and its members """ - - outer_type = name.rpartition('.')[0] - - document = util.Document() - document.add(imports_block) - document.add_heading(name, '=') - - method_summary = util.StringBuilder() - document.add_object(method_summary) - - package_dir = util.Directive('java:package', package) - package_dir.add_option('noindex') - document.add_object(package_dir) - - # Add type-level documentation - type_dir = self.compile_type(declaration) - if outer_type: - type_dir.add_option('outertype', outer_type) - document.add_object(type_dir) - - if isinstance(declaration, javalang.tree.EnumDeclaration): - enum_constants = list(declaration.body.constants) - enum_constants.sort(key=lambda c: c.name) - - document.add_heading('Enum Constants') - for enum_constant in enum_constants: - if self.member_headers: - document.add_heading(enum_constant.name, '^') - c = self.compile_enum_constant(name, enum_constant) - c.add_option('outertype', name) - document.add_object(c) - - fields = list(filter(self.filter, declaration.fields)) - if fields: - document.add_heading('Fields', '-') - fields.sort(key=lambda f: f.declarators[0].name) - for field in fields: - if self.member_headers: - document.add_heading(field.declarators[0].name, '^') - f = self.compile_field(field) - f.add_option('outertype', name) - document.add_object(f) - - constructors = list(filter(self.filter, declaration.constructors)) - if constructors: - document.add_heading('Constructors', '-') - constructors.sort(key=lambda c: c.name) - for constructor in constructors: - if self.member_headers: - document.add_heading(constructor.name, '^') - c = self.compile_constructor(constructor) - c.add_option('outertype', name) - document.add_object(c) - - methods = list(filter(self.filter, declaration.methods)) - if methods: - document.add_heading('Methods', '-') - methods.sort(key=lambda m: m.name) - for method in methods: - if self.member_headers: - document.add_heading(method.name, '^') - m = self.compile_method(method) - m.add_option('outertype', name) - document.add_object(m) - - return document - - def compile(self, ast): - """ Compile autodocs for the given Java syntax tree. Documents will be - returned documenting each separate type. """ - - documents = {} - - imports = util.StringBuilder() - for imp in ast.imports: - if imp.static or imp.wildcard: - continue - - package_parts = [] - cls_parts = [] - - for part in imp.path.split('.'): - if cls_parts or part[0].isupper(): - cls_parts.append(part) - else: - package_parts.append(part) - - - # If the import's final part wasn't capitalized, - # append it to the class parts anyway so sphinx doesn't complain. - if cls_parts == []: - cls_parts.append(package_parts.pop()) - - package = '.'.join(package_parts) - cls = '.'.join(cls_parts) - - imports.append(util.Directive('java:import', package + ' ' + cls).build()) - import_block = imports.build() - - if not ast.package: - raise ValueError('File must have package declaration') - - package = ast.package.name - type_declarations = [] - for path, node in ast.filter(javalang.tree.TypeDeclaration): - if not self.filter(node): - continue - - classes = [n.name for n in path if isinstance(n, javalang.tree.TypeDeclaration)] - classes.append(node.name) - - name = '.'.join(classes) - type_declarations.append((package, name, node)) - - for package, name, declaration in type_declarations: - full_name = package + '.' + name - document = self.compile_type_document(import_block, package, name, declaration) - documents[full_name] = (package, name, document.build()) - return documents - - def compile_docblock(self, documented): - ''' Compiles a single, standalone docblock. ''' - return self.__output_doc(documented).build() diff --git a/docs/source/_ext/javasphinx/javasphinx/domain.py b/docs/source/_ext/javasphinx/javasphinx/domain.py deleted file mode 100644 index 3784d8a87b..0000000000 --- a/docs/source/_ext/javasphinx/javasphinx/domain.py +++ /dev/null @@ -1,591 +0,0 @@ -# -# Copyright 2012-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import re -import string - -from docutils import nodes -from docutils.parsers.rst import Directive, directives - -from sphinx import addnodes, version_info -from sphinx.roles import XRefRole -from sphinx.locale import _ -from sphinx.domains import Domain, ObjType -from sphinx.directives import ObjectDescription -from sphinx.util.nodes import make_refnode -from sphinx.util.docfields import Field, TypedField, GroupedField - -import javalang - -import javasphinx.extdoc as extdoc -import javasphinx.formatter as formatter -import javasphinx.util as util - -# Classes in java.lang. These are available without an import. -java_dot_lang = set([ - 'AbstractMethodError', 'Appendable', 'ArithmeticException', - 'ArrayIndexOutOfBoundsException', 'ArrayStoreException', 'AssertionError', - 'AutoCloseable', 'Boolean', 'BootstrapMethodError', 'Byte', 'Character', - 'CharSequence', 'Class', 'ClassCastException', 'ClassCircularityError', - 'ClassFormatError', 'ClassLoader', 'ClassNotFoundException', 'ClassValue', - 'Cloneable', 'CloneNotSupportedException', 'Comparable', 'Compiler', - 'Deprecated', 'Double', 'Enum', 'EnumConstantNotPresentException', 'Error', - 'Exception', 'ExceptionInInitializerError', 'Float', 'IllegalAccessError', - 'IllegalAccessException', 'IllegalArgumentException', - 'IllegalMonitorStateException', 'IllegalStateException', - 'IllegalThreadStateException', 'IncompatibleClassChangeError', - 'IndexOutOfBoundsException', 'InheritableThreadLocal', 'InstantiationError', - 'InstantiationException', 'Integer', 'InternalError', 'InterruptedException', - 'Iterable', 'LinkageError', 'Long', 'Math', 'NegativeArraySizeException', - 'NoClassDefFoundError', 'NoSuchFieldError', 'NoSuchFieldException', - 'NoSuchMethodError', 'NoSuchMethodException', 'NullPointerException', 'Number', - 'NumberFormatException', 'Object', 'OutOfMemoryError', 'Override', 'Package', - 'Process', 'ProcessBuilder', 'Readable', 'ReflectiveOperationException', - 'Runnable', 'Runtime', 'RuntimeException', 'RuntimePermission', 'SafeVarargs', - 'SecurityException', 'SecurityManager', 'Short', 'StackOverflowError', - 'StackTraceElement', 'StrictMath', 'String', 'StringBuffer', 'StringBuilder', - 'StringIndexOutOfBoundsException', 'SuppressWarnings', 'System', 'Thread', - 'ThreadDeath', 'ThreadGroup', 'ThreadLocal', 'Throwable', - 'TypeNotPresentException', 'UnknownError', 'UnsatisfiedLinkError', - 'UnsupportedClassVersionError', 'UnsupportedOperationException', 'VerifyError', - 'VirtualMachineError', 'Void']) - -class JavaObject(ObjectDescription): - option_spec = { - 'noindex': directives.flag, - 'package': directives.unchanged, - 'outertype': directives.unchanged - } - - def _build_ref_node(self, target): - ref = addnodes.pending_xref('', refdomain='java', reftype='type', reftarget=target, modname=None, classname=None) - ref['java:outertype'] = self.get_type() - - package = self.env.temp_data.get('java:imports', dict()).get(target, None) - - if not package and target in java_dot_lang: - package = 'java.lang' - - if package: - ref['java:imported'] = True - ref['java:package'] = package - else: - ref['java:imported'] = False - ref['java:package'] = self.get_package() - - return ref - - def _build_type_node(self, typ): - if isinstance(typ, javalang.tree.ReferenceType): - if typ.dimensions: - dim = '[]' * len(typ.dimensions) - else: - dim = '' - - target = typ.name - parts = [] - - while typ: - ref_node = self._build_ref_node(target) - ref_node += nodes.Text(typ.name, typ.name) - parts.append(ref_node) - - if typ.arguments: - parts.append(nodes.Text('<', '<')) - - first = True - for type_arg in typ.arguments: - if first: - first = False - else: - parts.append(nodes.Text(', ', ', ')) - - if type_arg.pattern_type == '?': - parts.append(nodes.Text('?', '?')) - else: - if type_arg.pattern_type: - s = '? %s ' % (type_arg.pattern_type,) - parts.append(nodes.Text(s, s)) - parts.extend(self._build_type_node(type_arg.type)) - - parts.append(nodes.Text('>', '>')) - - typ = typ.sub_type - - if typ: - target = target + '.' + typ.name - parts.append(nodes.Text('.', '.')) - elif dim: - parts.append(nodes.Text(dim, dim)) - - return parts - - type_repr = formatter.output_type(typ).build() - return [nodes.Text(type_repr, type_repr)] - - def _build_type_node_list(self, types): - parts = self._build_type_node(types[0]) - for typ in types[1:]: - parts.append(nodes.Text(', ', ', ')) - parts.extend(self._build_type_node(typ)) - return parts - - def handle_signature(self, sig, signode): - handle_name = 'handle_%s_signature' % (self.objtype,) - handle = getattr(self, handle_name, None) - - if handle: - return handle(sig, signode) - raise NotImplementedError - - def get_index_text(self, package, typ, name): - raise NotImplementedError - - def get_package(self): - return self.options.get('package', self.env.temp_data.get('java:package')) - - def get_type(self): - return self.options.get('outertype', '.'.join(self.env.temp_data.get('java:outertype', []))) - - def add_target_and_index(self, name, sig, signode): - package = self.get_package() - typ = self.get_type() - - fullname = '.'.join(filter(None, (package, typ, name))) - basename = fullname.partition('(')[0] - - # note target - if fullname not in self.state.document.ids: - signode['names'].append(fullname) - signode['ids'].append(fullname) - signode['first'] = (not self.names) - self.state.document.note_explicit_target(signode) - - objects = self.env.domaindata['java']['objects'] - if fullname in objects: - self.state_machine.reporter.warning( - 'duplicate object description of %s, ' % fullname + - 'other instance in ' + self.env.doc2path(objects[fullname][0]) + - ', use :noindex: for one of them', - line=self.lineno) - - objects[fullname] = (self.env.docname, self.objtype, basename) - - indextext = self.get_index_text(package, typ, name) - if indextext: - self.indexnode['entries'].append(_create_indexnode(indextext, fullname)) - - def before_content(self): - self.set_type = False - - if self.objtype == 'type' and self.names: - self.set_type = True - self.env.temp_data.setdefault('java:outertype', list()).append(self.names[0]) - - def after_content(self): - if self.set_type: - self.env.temp_data['java:outertype'].pop() - -class JavaMethod(JavaObject): - doc_field_types = [ - TypedField('parameter', label=_('Parameters'), - names=('param', 'parameter', 'arg', 'argument'), - typerolename='type', typenames=('type',)), - Field('returnvalue', label=_('Returns'), has_arg=False, - names=('returns', 'return')), - GroupedField('throws', names=('throws',), label=_('Throws'), rolename='type') - ] - - def handle_method_signature(self, sig, signode): - try: - member = javalang.parse.parse_member_signature(sig) - except javalang.parser.JavaSyntaxError: - raise self.error("syntax error in method signature") - - if not isinstance(member, javalang.tree.MethodDeclaration): - raise self.error("expected method declaration") - - mods = formatter.output_modifiers(member.modifiers).build() - signode += nodes.Text(mods + ' ', mods + ' ') - - if member.type_parameters: - type_params = formatter.output_type_params(member.type_parameters).build() - signode += nodes.Text(type_params, type_params) - signode += nodes.Text(' ', ' ') - - rnode = addnodes.desc_type('', '') - rnode += self._build_type_node(member.return_type) - - signode += rnode - signode += nodes.Text(' ', ' ') - signode += addnodes.desc_name(member.name, member.name) - - paramlist = addnodes.desc_parameterlist() - for parameter in member.parameters: - param = addnodes.desc_parameter('', '', noemph=True) - param += self._build_type_node(parameter.type) - - if parameter.varargs: - param += nodes.Text('...', '') - - param += nodes.emphasis(' ' + parameter.name, ' ' + parameter.name) - paramlist += param - signode += paramlist - - param_reprs = [formatter.output_type(param.type, with_generics=False).build() for param in member.parameters] - return member.name + '(' + ', '.join(param_reprs) + ')' - - def get_index_text(self, package, typ, name): - return _('%s (Java method)' % (name,)) - -class JavaConstructor(JavaObject): - doc_field_types = [ - TypedField('parameter', label=_('Parameters'), - names=('param', 'parameter', 'arg', 'argument'), - typerolename='type', typenames=('type',)), - GroupedField('throws', names=('throws',), label=_('Throws')) - ] - - def handle_constructor_signature(self, sig, signode): - try: - member = javalang.parse.parse_constructor_signature(sig) - except javalang.parser.JavaSyntaxError: - raise self.error("syntax error in constructor signature") - - if not isinstance(member, javalang.tree.ConstructorDeclaration): - raise self.error("expected constructor declaration") - - mods = formatter.output_modifiers(member.modifiers).build() - signode += nodes.Text(mods + ' ', mods + ' ') - - signode += addnodes.desc_name(member.name, member.name) - - paramlist = addnodes.desc_parameterlist() - for parameter in member.parameters: - param = addnodes.desc_parameter('', '', noemph=True) - param += self._build_type_node(parameter.type) - - if parameter.varargs: - param += nodes.Text('...', '') - - param += nodes.emphasis(' ' + parameter.name, ' ' + parameter.name) - paramlist += param - signode += paramlist - - param_reprs = [formatter.output_type(param.type, with_generics=False).build() for param in member.parameters] - return '%s(%s)' % (member.name, ', '.join(param_reprs)) - - def get_index_text(self, package, typ, name): - return _('%s (Java constructor)' % (name,)) - -class JavaType(JavaObject): - doc_field_types = [ - GroupedField('parameter', names=('param',), label=_('Parameters')) - ] - - declaration_type = None - - def handle_type_signature(self, sig, signode): - try: - member = javalang.parse.parse_type_signature(sig) - except javalang.parser.JavaSyntaxError: - raise self.error("syntax error in field signature") - - if isinstance(member, javalang.tree.ClassDeclaration): - self.declaration_type = 'class' - elif isinstance(member, javalang.tree.InterfaceDeclaration): - self.declaration_type = 'interface' - elif isinstance(member, javalang.tree.EnumDeclaration): - self.declaration_type = 'enum' - elif isinstance(member, javalang.tree.AnnotationDeclaration): - self.declaration_type = 'annotation' - else: - raise self.error("expected type declaration") - - mods = formatter.output_modifiers(member.modifiers).build() - signode += nodes.Text(mods + ' ', mods + ' ') - - if self.declaration_type == 'class': - signode += nodes.Text('class ', 'class ') - elif self.declaration_type == 'interface': - signode += nodes.Text('interface ', 'interface ') - elif self.declaration_type == 'enum': - signode += nodes.Text('enum ', 'enum ') - elif self.declaration_type == 'annotation': - signode += nodes.Text('@interface ', '@interface ') - - signode += addnodes.desc_name(member.name, member.name) - - if self.declaration_type in ('class', 'interface') and member.type_parameters: - type_params = formatter.output_type_params(member.type_parameters).build() - signode += nodes.Text(type_params, type_params) - - if self.declaration_type == 'class': - if member.extends: - extends = ' extends ' - signode += nodes.Text(extends, extends) - signode += self._build_type_node(member.extends) - if member.implements: - implements = ' implements ' - signode += nodes.Text(implements, implements) - signode += self._build_type_node_list(member.implements) - elif self.declaration_type == 'interface': - if member.extends: - extends = ' extends ' - signode += nodes.Text(extends, extends) - signode += self._build_type_node_list(member.extends) - elif self.declaration_type == 'enum': - if member.implements: - implements = ' implements ' - signode += nodes.Text(implements, implements) - signode += self._build_type_node_list(member.implements) - - return member.name - - def get_index_text(self, package, typ, name): - return _('%s (Java %s)' % (name, self.declaration_type)) - -class JavaField(JavaObject): - def handle_field_signature(self, sig, signode): - try: - member = javalang.parse.parse_member_signature(sig) - except javalang.parser.JavaSyntaxError: - raise self.error("syntax error in field signature") - - if not isinstance(member, javalang.tree.FieldDeclaration): - raise self.error("expected field declaration") - - mods = formatter.output_modifiers(member.modifiers).build() - signode += nodes.Text(mods + ' ', mods + ' ') - - tnode = addnodes.desc_type('', '') - tnode += self._build_type_node(member.type) - - signode += tnode - signode += nodes.Text(' ', ' ') - - if len(member.declarators) > 1: - self.error('only one field may be documented at a time') - - declarator = member.declarators[0] - signode += addnodes.desc_name(declarator.name, declarator.name) - - dim = '[]' * len(declarator.dimensions) - signode += nodes.Text(dim) - - if declarator.initializer and isinstance(declarator.initializer, javalang.tree.Literal): - signode += nodes.Text(' = ' + declarator.initializer.value) - - return declarator.name - - def get_index_text(self, package, typ, name): - return _('%s (Java field)' % (name,)) - -class JavaPackage(Directive): - """ - Directive to mark description of a new package. - """ - - has_content = False - required_arguments = 1 - optional_arguments = 0 - final_argument_whitespace = False - option_spec = { - 'noindex': directives.flag, - } - - def run(self): - env = self.state.document.settings.env - package = self.arguments[0].strip() - noindex = 'noindex' in self.options - env.temp_data['java:package'] = package - env.domaindata['java']['objects'][package] = (env.docname, 'package', package) - ret = [] - - if not noindex: - targetnode = nodes.target('', '', ids=['package-' + package], ismod=True) - self.state.document.note_explicit_target(targetnode) - - # the platform and synopsis aren't printed; in fact, they are only - # used in the modindex currently - ret.append(targetnode) - - indextext = _('%s (package)') % (package,) - inode = addnodes.index(entries=[_create_indexnode(indextext, 'package-' + package)]) - ret.append(inode) - - return ret - -class JavaImport(Directive): - """ - This directive is just to tell Sphinx the source of a referenced type. - """ - - has_content = False - required_arguments = 2 - optional_arguments = 0 - final_argument_whitespace = False - option_spec = {} - - def run(self): - env = self.state.document.settings.env - package, typename = self.arguments - - env.temp_data.setdefault('java:imports', dict())[typename] = package - return [] - -class JavaXRefRole(XRefRole): - def process_link(self, env, refnode, has_explicit_title, title, target): - refnode['java:outertype'] = '.'.join(env.temp_data.get('java:outertype', list())) - - target = target.lstrip('~') - - # Strip a method component from the target - basetype = target - if '(' in basetype: - basetype = basetype.partition('(')[0] - if '.' in basetype: - basetype = basetype.rpartition('.')[0] - - package = env.temp_data.get('java:imports', dict()).get(basetype, None) - - if package: - refnode['java:imported'] = True - refnode['java:package'] = package - else: - refnode['java:imported'] = False - refnode['java:package'] = env.temp_data.get('java:package') - - if not has_explicit_title: - # if the first character is a tilde, don't display the module/class - # parts of the contents - if title[0:1] == '~': - title = title.partition('(')[0] - title = title[1:] - dot = title.rfind('.') - if dot != -1: - title = title[dot+1:] - - return title, target - -class JavaDomain(Domain): - """Java language domain.""" - name = 'java' - label = 'Java' - - object_types = { - 'package': ObjType(_('package'), 'package', 'ref'), - 'type': ObjType(_('type'), 'type', 'ref'), - 'field': ObjType(_('field'), 'field', 'ref'), - 'constructor': ObjType(_('constructor'), 'construct', 'ref'), - 'method': ObjType(_('method'), 'meth', 'ref') - } - - directives = { - 'package': JavaPackage, - 'type': JavaType, - 'field': JavaField, - 'constructor': JavaConstructor, - 'method': JavaMethod, - 'import': JavaImport - } - - roles = { - 'package': JavaXRefRole(), - 'type': JavaXRefRole(), - 'field': JavaXRefRole(), - 'construct': JavaXRefRole(), - 'meth': JavaXRefRole(), - 'ref': JavaXRefRole(), - } - - initial_data = { - 'objects': {}, # fullname -> docname, objtype, basename - } - - def clear_doc(self, docname): - objects = dict(self.data['objects']) - - for fullname, (fn, _, _) in objects.items(): - if fn == docname: - del self.data['objects'][fullname] - - def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): - objects = self.data['objects'] - package = node.get('java:package') - imported = node.get('java:imported') - type_context = node.get('java:outertype') - - # Partial function to make building the response easier - make_ref = lambda fullname: make_refnode(builder, fromdocname, objects[fullname][0], fullname, contnode, fullname) - - # Check for fully qualified references - if target in objects: - return make_ref(target) - - # Try with package name prefixed - if package: - fullname = package + '.' + target - if fullname in objects: - return make_ref(fullname) - - # Try with package and type prefixed - if package and type_context: - fullname = package + '.' + type_context + '.' + target - if fullname in objects: - return make_ref(fullname) - - # Try to find a matching suffix - suffix = '.' + target - basename_match = None - basename_suffix = suffix.partition('(')[0] - - for fullname, (_, _, basename) in objects.items(): - if fullname.endswith(suffix): - return make_ref(fullname) - if basename.endswith(basename_suffix): - basename_match = fullname - - if basename_match: - return make_ref(basename_match) - - # Try creating an external documentation reference - ref = extdoc.get_javadoc_ref(self.env, target, target) - - if not ref and target in java_dot_lang: - fulltarget = 'java.lang.' + target - ref = extdoc.get_javadoc_ref(self.env, fulltarget, fulltarget) - - # If the target was imported try with the package prefixed - if not ref and imported: - fulltarget = package + '.' + target - ref = extdoc.get_javadoc_ref(self.env, fulltarget, fulltarget) - - if ref: - ref.append(contnode) - return ref - return None - - def get_objects(self): - for refname, (docname, typ, _) in self.data['objects'].items(): - yield (refname, refname, typ, docname, refname, 1) - - -def _create_indexnode(indextext, fullname): - # See https://github.com/sphinx-doc/sphinx/issues/2673 - if version_info < (1, 4): - return ('single', indextext, fullname, '') - return ('single', indextext, fullname, '', None) diff --git a/docs/source/_ext/javasphinx/javasphinx/extdoc.py b/docs/source/_ext/javasphinx/javasphinx/extdoc.py deleted file mode 100644 index 1586bc21c0..0000000000 --- a/docs/source/_ext/javasphinx/javasphinx/extdoc.py +++ /dev/null @@ -1,124 +0,0 @@ -# -# Copyright 2012-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import re - -from docutils import nodes, utils -from sphinx.util.nodes import split_explicit_title - -def get_javadoc_ref(app, rawtext, text): - javadoc_url_map = app.config.javadoc_url_map - - # Add default Java SE sources - if not javadoc_url_map.get("java"): - javadoc_url_map["java"] = ("http://docs.oracle.com/javase/8/docs/api", 'javadoc8') - if not javadoc_url_map.get("javax"): - javadoc_url_map["javax"] = ("http://docs.oracle.com/javase/8/docs/api", 'javadoc8') - if not javadoc_url_map.get("org.xml"): - javadoc_url_map["org.xml"] = ("http://docs.oracle.com/javase/8/docs/api", 'javadoc8') - if not javadoc_url_map.get("org.w3c"): - javadoc_url_map["org.w3c"] = ("http://docs.oracle.com/javase/8/docs/api", 'javadoc8') - - source = None - package = '' - method = None - - if '(' in text: - # If the javadoc contains a line like this: - # {@link #sort(List)} - # there is no package so the text.rindex will fail - try: - split_point = text.rindex('.', 0, text.index('(')) - method = text[split_point + 1:] - text = text[:split_point] - except ValueError: - pass - - for pkg, (baseurl, ext_type) in javadoc_url_map.items(): - if text.startswith(pkg + '.') and len(pkg) > len(package): - source = baseurl, ext_type - package = pkg - - if not source: - return None - - baseurl, ext_type = source - - package_parts = [] - cls_parts = [] - - for part in text.split('.'): - if cls_parts or part[0].isupper(): - cls_parts.append(part) - else: - package_parts.append(part) - - package = '.'.join(package_parts) - cls = '.'.join(cls_parts) - - if not baseurl.endswith('/'): - baseurl = baseurl + '/' - - if ext_type == 'javadoc': - if not cls: - cls = 'package-summary' - source = baseurl + package.replace('.', '/') + '/' + cls + '.html' - if method: - source = source + '#' + method - elif ext_type == 'javadoc8': - if not cls: - cls = 'package-summary' - source = baseurl + package.replace('.', '/') + '/' + cls + '.html' - if method: - source = source + '#' + re.sub(r'[()]', '-', method) - elif ext_type == 'sphinx': - if not cls: - cls = 'package-index' - source = baseurl + package.replace('.', '/') + '/' + cls.replace('.', '-') + '.html' - if method: - source = source + '#' + package + '.' + cls + '.' + method - else: - raise ValueError('invalid target specifier ' + ext_type) - - title = '.'.join(filter(None, (package, cls, method))) - node = nodes.reference(rawtext, '') - node['refuri'] = source - node['reftitle'] = title - - return node - -def javadoc_role(name, rawtext, text, lineno, inliner, options={}, content=[]): - """ Role for linking to external Javadoc """ - - has_explicit_title, title, target = split_explicit_title(text) - title = utils.unescape(title) - target = utils.unescape(target) - - if not has_explicit_title: - target = target.lstrip('~') - - if title[0] == '~': - title = title[1:].rpartition('.')[2] - - app = inliner.document.settings.env.app - ref = get_javadoc_ref(app, rawtext, target) - - if not ref: - raise ValueError("no Javadoc source found for %s in javadoc_url_map" % (target,)) - - ref.append(nodes.Text(title, title)) - - return [ref], [] diff --git a/docs/source/_ext/javasphinx/javasphinx/formatter.py b/docs/source/_ext/javasphinx/javasphinx/formatter.py deleted file mode 100644 index ce6f6f5e24..0000000000 --- a/docs/source/_ext/javasphinx/javasphinx/formatter.py +++ /dev/null @@ -1,163 +0,0 @@ -# -# Copyright 2012-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -""" -Convert Java syntax tree nodes to string representations. - -""" - -import javalang - -from .util import StringBuilder - -# The order for displaying modifiers -__modifiers_order = ('public', 'protected', 'private', 'static', 'abstract', 'final', - 'native', 'synchronized', 'transient', 'volatile', 'strictfp') - -def formatter(f): - def _f(node, output=None, **kwargs): - if output is None: - output = StringBuilder() - - f(node, output, **kwargs) - return output - return _f - -def output_list(f, items, output=None, sep=', '): - if items: - f(items[0], output) - for item in items[1:]: - output.append(sep) - f(item, output) - -@formatter -def output_annotation(annotation, output): - output.append('@') - output.append(annotation.name) - output.append(' ') - -@formatter -def output_type(typ, output, with_generics=True): - if not typ: - output.append('void') - return - - if typ.dimensions: - dim = '[]' * len(typ.dimensions) - else: - dim = '' - - if isinstance(typ, javalang.tree.BasicType): - output.append(typ.name) - else: - while typ: - output.append(typ.name) - - if with_generics: - output_type_args(typ.arguments, output) - - typ = typ.sub_type - - if typ: - output.append('.') - output.append(dim) - -@formatter -def output_exception(exception, output): - output.append(exception) - -@formatter -def output_type_arg(type_arg, output): - if type_arg.pattern_type == '?': - output.append('?') - else: - if type_arg.pattern_type: - output.append('? ') - output.append(type_arg.pattern_type) - output.append(' ') - - output_type(type_arg.type, output) - -@formatter -def output_type_args(type_args, output): - if type_args: - output.append('<') - output_list(output_type_arg, type_args, output, ', ') - output.append('>') - -@formatter -def output_type_param(type_param, output): - output.append(type_param.name) - - if type_param.extends: - output.append(' extends ') - output_list(output_type, type_param.extends, output, ' & ') - -@formatter -def output_type_params(type_params, output): - if type_params: - output.append('<') - output_list(output_type_param, type_params, output, ', ') - output.append('>') - -@formatter -def output_declaration(declaration, output): - for annotation in declaration.annotations: - output_annotation(annotation, output) - - output_modifiers(declaration.modifiers, output) - output.append(' ') - - if isinstance(declaration, javalang.tree.ClassDeclaration): - output.append('class ') - elif isinstance(declaration, javalang.tree.EnumDeclaration): - output.append('enum ') - elif isinstance(declaration, javalang.tree.InterfaceDeclaration): - output.append('interface ') - elif isinstance(declaration, javalang.tree.AnnotationDeclaration): - output.append('@interface ') - - output.append(declaration.name) - - if isinstance(declaration, (javalang.tree.ClassDeclaration, javalang.tree.InterfaceDeclaration)): - output_type_params(declaration.type_parameters, output) - - if isinstance(declaration, javalang.tree.ClassDeclaration) and declaration.extends: - output.append(' extends ') - output_type(declaration.extends, output) - - if isinstance(declaration, javalang.tree.InterfaceDeclaration) and declaration.extends: - output.append(' extends ') - output_list(output_type, declaration.extends, output, ', ') - - if isinstance(declaration, (javalang.tree.ClassDeclaration, javalang.tree.EnumDeclaration)) and declaration.implements: - output.append(' implements ') - output_list(output_type, declaration.implements, output, ', ') - -@formatter -def output_formal_param(param, output): - output_type(param.type, output) - - if param.varargs: - output.append('...') - - output.append(' ') - output.append(param.name) - -@formatter -def output_modifiers(modifiers, output): - ordered_modifiers = [mod for mod in __modifiers_order if mod in modifiers] - output_list(lambda mod, output: output.append(mod), ordered_modifiers, output, ' ') diff --git a/docs/source/_ext/javasphinx/javasphinx/htmlrst.py b/docs/source/_ext/javasphinx/javasphinx/htmlrst.py deleted file mode 100644 index 687a034448..0000000000 --- a/docs/source/_ext/javasphinx/javasphinx/htmlrst.py +++ /dev/null @@ -1,414 +0,0 @@ -# -# Copyright 2013-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from __future__ import unicode_literals -from builtins import str - -import collections -import re - -from xml.sax.saxutils import escape as html_escape -from bs4 import BeautifulSoup - -Cell = collections.namedtuple('Cell', ['type', 'rowspan', 'colspan', 'contents']) - -class Converter(object): - def __init__(self, parser): - self._unknown_tags = set() - self._clear = '\n\n..\n\n' - - # Regular expressions - self._preprocess_anchors = re.compile(r'') - self._post_process_empty_lines = re.compile(r'^\s+$', re.MULTILINE) - self._post_process_compress_lines = re.compile(r'\n{3,}') - self._whitespace_with_newline = re.compile(r'[\s\n]+') - self._whitespace = re.compile(r'\s+') - self._html_tag = re.compile(r'<.*?>') - - self._preprocess_entity = re.compile(r'&(nbsp|lt|gt|amp)([^;]|[\n])') - self._parser = parser - - # -------------------------------------------------------------------------- - # ---- reST Utility Methods ---- - - def _unicode(self, s): - if isinstance(s, unicode): - return s - return unicode(s, 'utf8') - - def _separate(self, s): - return u'\n\n' + s + u'\n\n' - - def _escape_inline(self, s): - return '\\ ' + s + '\\ ' - - def _inline(self, tag, s): - # Seems fishy if our inline markup spans lines. We will instead just return - # the string as is - if '\n' in s: - return s - - s = s.strip() - - if not s: - return s - - return self._escape_inline(tag + s.strip() + tag) - - def _role(self, role, s, label=None): - if label: - return self._escape_inline(':%s:`%s <%s>`' % (role, label, s)) - return self._escape_inline(':%s:`%s`' % (role, s)) - - def _directive(self, directive, body=None): - header = '\n\n.. %s::\n\n' % (directive,) - - if body: - return header + self._left_justify(body, 3) + '\n\n' - return header + '\n' - - def _hyperlink(self, target, label): - return self._escape_inline('`%s <%s>`_' % (label, target)) - - def _listing(self, marker, items): - items = [self._left_justify(item, len(marker) + 1) for item in items] - items = [marker + item[len(marker):] for item in items] - return self._separate('..') + self._separate('\n'.join(items)) - - def _left_justify(self, s, indent=0): - lines = [l.rstrip() for l in s.split('\n')] - indents = [len(l) - len(l.lstrip()) for l in lines if l] - - if not indents: - return s - - shift = indent - min(indents) - - if shift < 0: - return '\n'.join(l[-shift:] for l in lines) - - prefix = ' ' * shift - return '\n'.join(prefix + l for l in lines) - - def _compress_whitespace(self, s, replace=' ', newlines=True): - if newlines: - return self._whitespace_with_newline.sub(replace, s) - return self._whitespace.sub(replace, s) - - # -------------------------------------------------------------------------- - # ---- DOM Tree Processing ---- - - def _process_table_cells(self, table): - """ Compile all the table cells. - - Returns a list of rows. The rows may have different lengths because of - column spans. - - """ - - rows = [] - - for i, tr in enumerate(table.find_all('tr')): - row = [] - - for c in tr.contents: - cell_type = getattr(c, 'name', None) - - if cell_type not in ('td', 'th'): - continue - - rowspan = int(c.attrs.get('rowspan', 1)) - colspan = int(c.attrs.get('colspan', 1)) - contents = self._process_children(c).strip() - - if cell_type == 'th' and i > 0: - contents = self._inline('**', contents) - - row.append(Cell(cell_type, rowspan, colspan, contents)) - - rows.append(row) - - return rows - - def _process_table(self, node): - rows = self._process_table_cells(node) - - if not rows: - return '' - - table_num_columns = max(sum(c.colspan for c in row) for row in rows) - - normalized = [] - - for row in rows: - row_num_columns = sum(c.colspan for c in row) - - if row_num_columns < table_num_columns: - cell_type = row[-1].type if row else 'td' - row.append(Cell(cell_type, 1, table_num_columns - row_num_columns, '')) - - col_widths = [0] * table_num_columns - row_heights = [0] * len(rows) - - for i, row in enumerate(rows): - j = 0 - for cell in row: - current_w = sum(col_widths[j:j + cell.colspan]) - required_w = max(len(l) for l in cell.contents.split('\n')) - - if required_w > current_w: - additional = required_w - current_w - col_widths[j] += additional - (cell.colspan - 1) * (additional // cell.colspan) - for jj in range(j + 1, j + cell.colspan): - col_widths[jj] += (additional // cell.colspan) - - current_h = row_heights[i] - required_h = len(cell.contents.split('\n')) - - if required_h > current_h: - row_heights[i] = required_h - - j += cell.colspan - - row_sep = '+' + '+'.join('-' * (l + 2) for l in col_widths) + '+' - header_sep = '+' + '+'.join('=' * (l + 2) for l in col_widths) + '+' - lines = [row_sep] - - for i, row in enumerate(rows): - for y in range(0, row_heights[i]): - line = [] - j = 0 - for c in row: - w = sum(n + 3 for n in col_widths[j:j+c.colspan]) - 2 - h = row_heights[i] - - line.append('| ') - cell_lines = c.contents.split('\n') - content = cell_lines[y] if y < len(cell_lines) else '' - line.append(content.ljust(w)) - - j += c.colspan - - line.append('|') - lines.append(''.join(line)) - - if i == 0 and all(c.type == 'th' for c in row): - lines.append(header_sep) - else: - lines.append(row_sep) - - return self._separate('\n'.join(lines)) - - def _process_children(self, node): - parts = [] - is_newline = False - - for c in node.contents: - part = self._process(c) - - if is_newline: - part = part.lstrip() - - if part: - parts.append(part) - is_newline = part.endswith('\n') - - return ''.join(parts) - - def _process_text(self, node): - return ''.join(node.strings) - - def _process(self, node): - if isinstance(node, str): - return self._compress_whitespace(node) - - simple_tags = { - 'b' : lambda s: self._inline('**', s), - 'strong' : lambda s: self._inline('**', s), - 'i' : lambda s: self._inline('*', s), - 'em' : lambda s: self._inline('*', s), - 'tt' : lambda s: self._inline('``', s), - 'code' : lambda s: self._inline('``', s), - 'h1' : lambda s: self._inline('**', s), - 'h2' : lambda s: self._inline('**', s), - 'h3' : lambda s: self._inline('**', s), - 'h4' : lambda s: self._inline('**', s), - 'h5' : lambda s: self._inline('**', s), - 'h6' : lambda s: self._inline('**', s), - 'sub' : lambda s: self._role('sub', s), - 'sup' : lambda s: self._role('sup', s), - 'hr' : lambda s: self._separate('') # Transitions not allowed - } - - if node.name in simple_tags: - return simple_tags[node.name](self._process_text(node)) - - if node.name == 'p': - return self._separate(self._process_children(node).strip()) - - if node.name == 'pre': - return self._directive('parsed-literal', self._process_text(node)) - - if node.name == 'a': - if 'name' in node.attrs: - return self._separate('.. _' + node['name'] + ':') - if 'href' in node.attrs: - target = node['href'] - label = self._compress_whitespace(self._process_text(node).strip('\n')) - - if target.startswith('#'): - return self._role('ref', target[1:], label) - if target.startswith('@'): - return self._role('java:ref', target[1:], label) - return self._hyperlink(target, label) - - if node.name == 'ul': - items = [self._process(n) for n in node.find_all('li', recursive=False)] - return self._listing('*', items) - - if node.name == 'ol': - items = [self._process(n) for n in node.find_all('li', recursive=False)] - return self._listing('#.', items) - - if node.name == 'li': - s = self._process_children(node) - s = s.strip() - - # If it's multiline clear the end to correcly support nested lists - if '\n' in s: - s = s + '\n\n' - - return s - - if node.name == 'table': - return self._process_table(node) - - self._unknown_tags.add(node.name) - - return self._process_children(node) - - # -------------------------------------------------------------------------- - # ---- HTML Preprocessing ---- - - def _preprocess_inline_javadoc_replace(self, tag, f, s): - parts = [] - - start = '{@' + tag - start_length = len(start) - - i = s.find(start) - j = 0 - - while i != -1: - parts.append(s[j:i]) - - # Find a closing bracket such that the brackets are balanced between - # them. This is necessary since code examples containing { and } are - # commonly wrapped in {@code ...} tags - - try: - j = s.find('}', i + start_length) + 1 - while s.count('{', i, j) != s.count('}', i, j): - j = s.index('}', j) + 1 - except ValueError: - raise ValueError('Unbalanced {} brackets in ' + tag + ' tag') - - parts.append(f(s[i + start_length:j - 1].strip())) - i = s.find(start, j) - - parts.append(s[j:]) - - return ''.join(parts) - - def _preprocess_replace_javadoc_link(self, s): - s = self._compress_whitespace(s) - - target = None - label = '' - - if ' ' not in s: - target = s - else: - i = s.find(' ') - - while s.count('(', 0, i) != s.count(')', 0, i): - i = s.find(' ', i + 1) - - if i == -1: - i = len(s) - break - - target = s[:i] - label = s[i:] - - if target[0] == '#': - target = target[1:] - - target = target.replace('#', '.').replace(' ', '').strip() - - # Strip HTML tags from the target - target = self._html_tag.sub('', target) - - label = label.strip() - - return '%s' % (target, label) - - def _preprocess_close_anchor_tags(self, s): - # Add closing tags to all anchors so they are better handled by the parser - return self._preprocess_anchors.sub(r'', s) - - def _preprocess_fix_entities(self, s): - return self._preprocess_entity.sub(r'&\1;\2', s) - - def _preprocess(self, s_html): - to_tag = lambda t: lambda m: '<%s>%s' % (t, html_escape(m), t) - s_html = self._preprocess_inline_javadoc_replace('code', to_tag('code'), s_html) - s_html = self._preprocess_inline_javadoc_replace('literal', to_tag('span'), s_html) - s_html = self._preprocess_inline_javadoc_replace('docRoot', lambda m: '', s_html) - s_html = self._preprocess_inline_javadoc_replace('linkplain', self._preprocess_replace_javadoc_link, s_html) - s_html = self._preprocess_inline_javadoc_replace('link', self._preprocess_replace_javadoc_link, s_html) - - # Make sure all anchor tags are closed - s_html = self._preprocess_close_anchor_tags(s_html) - - # Fix up some entitities without closing ; - s_html = self._preprocess_fix_entities(s_html) - - return s_html - - # -------------------------------------------------------------------------- - # ---- Conversion entry point ---- - - def convert(self, s_html): - if not isinstance(s_html, str): - s_html = str(s_html, 'utf8') - - s_html = self._preprocess(s_html) - - if not s_html.strip(): - return '' - - soup = BeautifulSoup(s_html, self._parser) - top = soup.html.body - - result = self._process_children(top) - - # Post processing - result = self._post_process_empty_lines.sub('', result) - result = self._post_process_compress_lines.sub('\n\n', result) - result = result.strip() - - return result diff --git a/docs/source/_ext/javasphinx/javasphinx/util.py b/docs/source/_ext/javasphinx/javasphinx/util.py deleted file mode 100644 index 8e5f2a8c8e..0000000000 --- a/docs/source/_ext/javasphinx/javasphinx/util.py +++ /dev/null @@ -1,119 +0,0 @@ -# -# Copyright 2012-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from __future__ import unicode_literals -from builtins import str - -import logging -import re -import sys - -class StringBuilder(list): - def build(self): - return str(self) - - def __str__(self): - return ''.join(self) - -class Directive(object): - - def __init__(self, typ, argument=''): - self.type = typ - self.argument = argument - - self.options = [] - self.content = [] - - def add_option(self, name, value=''): - self.options.append((name, value)) - - def add_content(self, o): - assert o is not None - self.content.append(o) - - def build(self): - doc = Document() - doc.add_line('.. %s:: %s' % (self.type, self.argument)) - - for name, value in self.options: - doc.add_line(' :%s: %s\n' % (name, value)) - - content = Document() - - for obj in self.content: - content.add_object(obj) - - doc.clear() - for line in content.build().splitlines(): - doc.add_line(' ' + line) - doc.clear() - - return doc.build() - -class Document(object): - remove_trailing_whitespace_re = re.compile('[ \t]+$', re.MULTILINE) - collapse_empty_lines_re = re.compile('\n' + '{3,}', re.DOTALL) - - def __init__(self): - self.content = [] - - def add_object(self, o): - assert o is not None - - self.content.append(o) - - def add(self, s): - self.add_object(s) - - def add_line(self, s): - self.add(s) - self.add('\n') - - def add_heading(self, s, t='-'): - self.add_line(s) - self.add_line(t * len(s)) - - def clear(self): - self.add('\n\n') - - def build(self): - output = StringBuilder() - - for obj in self.content: - if isinstance(obj, Directive): - output.append('\n\n') - output.append(obj.build()) - output.append('\n\n') - elif isinstance(obj, Document): - output.append(obj.build()) - else: - output.append(str(obj)) - - output.append('\n\n') - - output = str(output) - output = self.remove_trailing_whitespace_re.sub('', output) - output = self.collapse_empty_lines_re.sub('\n\n', output) - - return output - -def error(s, *args, **kwargs): - logging.error(s, *args, **kwargs) - sys.exit(1) - -def unexpected(s, *args, **kwargs): - logging.exception(s, *args, **kwargs) - sys.exit(1) diff --git a/docs/source/_ext/javasphinx/setup.py b/docs/source/_ext/javasphinx/setup.py deleted file mode 100644 index 3e4f362cfa..0000000000 --- a/docs/source/_ext/javasphinx/setup.py +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright 2012-2015 Bronto Software, Inc. and contributors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from setuptools import setup - -setup( - name = "javasphinx", - packages = ["javasphinx"], - version = "0.9.15", - author = "Chris Thunes", - author_email = "cthunes@brewtab.com", - url = "http://github.com/bronto/javasphinx", - description = "Sphinx extension for documenting Java projects", - license = "Apache 2.0", - classifiers = [ - "Programming Language :: Python", - "Development Status :: 4 - Beta", - "Operating System :: OS Independent", - "License :: OSI Approved :: Apache Software License", - "Intended Audience :: Developers", - "Topic :: Software Development :: Libraries" - ], - install_requires=[ - "javalang>=0.10.1", - "lxml", - "beautifulsoup4", - "future", - "docutils", - "sphinx" - ], - entry_points={ - 'console_scripts': [ - 'javasphinx-apidoc = javasphinx.apidoc:main' - ] - }, - long_description = """\ -========== -javasphinx -========== - -javasphinx is an extension to the Sphinx documentation system which adds support -for documenting Java projects. It includes a Java domain for writing -documentation manually and a javasphinx-apidoc utility which will automatically -generate API documentation from existing Javadoc markup. -""" -) diff --git a/docs/source/_templates/breadcrumbs.html b/docs/source/_templates/breadcrumbs.html index 0ce11e7e27..a92391c7a3 100644 --- a/docs/source/_templates/breadcrumbs.html +++ b/docs/source/_templates/breadcrumbs.html @@ -5,9 +5,6 @@ {% block breadcrumbs_aside %}
  • {% if hasdoc(pagename) and pagename != "search" and pagename != "genindex" %} - {# TODO: How to rule out all java pages? - # (not re.match(pagename, "java/org/simgrid")) - # fails because re is not imported #} {{ _('Edit on FramaGit') }} {% endif %} diff --git a/docs/source/app_msg.rst b/docs/source/app_msg.rst deleted file mode 100644 index d3dc33e474..0000000000 --- a/docs/source/app_msg.rst +++ /dev/null @@ -1,377 +0,0 @@ -.. _MSG_doc: - -The MSG Interface (legacy interface) -#################################### - -.. warning:: - - MSG used to be the main API of SimGrid 3, but we are currently in - the process of releasing SimGrid 4. So MSG is frozen and will - probably never evolve. If you are starting a new project, you - should consider S4U instead. Note that the support for MSG will not - be removed from SimGrid before 2020Q4 or 2021Q1. - - This interface is disabled by default. Pass -Denable_msg=ON to - cmake if you still need it. - -MSG is a simple API to write algorithms organized with Concurrent -Sequential Processes (CSP) that interact by exchanging messages. It -constitutes a convenient simplification of the reality of distributed -systems. It can be used to build rather realistic simulations, but -remains simple to use: most unpleasant technical elements can be -abstracted away rather easily. - -C API reference -*************** - -Main MSG Functions -================== - -The basic workflow is the following: - - - Initialize the library with :c:macro:`MSG_init` - - Create a platform (usually by parsing a file with :cpp:func:`MSG_create_environment`) - - Register the functions that your processes are supposed to run with - :cpp:func:`MSG_function_register` (and maybe :cpp:func:`MSG_function_register_default`) - - Launch your processes from a deployment file with :cpp:func:`MSG_launch_application` - - Run the simulation with :cpp:func:`MSG_main` - -.. doxygenenum:: msg_error_t - -.. doxygenfunction:: MSG_config -.. doxygenfunction:: MSG_create_environment -.. doxygenfunction:: MSG_function_register -.. doxygenfunction:: MSG_function_register_default -.. doxygenfunction:: MSG_get_clock -.. doxygenfunction:: MSG_get_sent_msg -.. doxygendefine:: MSG_init -.. doxygenfunction:: MSG_launch_application -.. doxygenfunction:: MSG_main - -Process Management -================== - -This describes the process structure :cpp:type:`msg_process_t` and the functions for managing it. - -.. doxygentypedef:: msg_process_t -.. doxygenfunction:: MSG_process_attach -.. doxygenfunction:: MSG_process_auto_restart_set -.. doxygenfunction:: MSG_process_create -.. doxygenfunction:: MSG_process_create_with_arguments -.. doxygenfunction:: MSG_process_create_with_environment -.. doxygenfunction:: MSG_process_daemonize -.. doxygenfunction:: MSG_process_detach -.. doxygenfunction:: MSG_process_from_PID -.. doxygenfunction:: MSG_process_get_data -.. doxygenfunction:: MSG_process_get_host -.. doxygenfunction:: MSG_process_get_name -.. doxygenfunction:: MSG_process_get_PID -.. doxygenfunction:: MSG_process_get_PPID -.. doxygenfunction:: MSG_process_get_properties -.. doxygenfunction:: MSG_process_get_property_value -.. doxygenfunction:: MSG_process_is_suspended -.. doxygenfunction:: MSG_process_join -.. doxygenfunction:: MSG_process_kill -.. doxygenfunction:: MSG_process_killall -.. doxygenfunction:: MSG_process_migrate -.. doxygenfunction:: MSG_process_on_exit -.. doxygenfunction:: MSG_process_ref -.. doxygenfunction:: MSG_process_restart -.. doxygenfunction:: MSG_process_resume -.. doxygenfunction:: MSG_process_self -.. doxygenfunction:: MSG_process_self_name -.. doxygenfunction:: MSG_process_self_PID -.. doxygenfunction:: MSG_process_self_PPID -.. doxygenfunction:: MSG_process_set_data -.. doxygenfunction:: MSG_process_set_data_cleanup -.. doxygenfunction:: MSG_process_set_kill_time -.. doxygenfunction:: MSG_process_sleep -.. doxygenfunction:: MSG_process_suspend -.. doxygenfunction:: MSG_process_unref -.. doxygenfunction:: MSG_process_yield - -Host Management -=============== - -.. doxygentypedef:: msg_host_t -.. doxygenfunction:: MSG_host_by_name -.. doxygenfunction:: MSG_get_host_by_name -.. doxygenfunction:: MSG_get_host_number -.. doxygenfunction:: MSG_host_get_core_number -.. doxygenfunction:: MSG_host_get_data -.. doxygenfunction:: MSG_host_get_name -.. doxygenfunction:: MSG_host_get_nb_pstates -.. doxygenfunction:: MSG_host_get_load -.. doxygenfunction:: MSG_host_get_power_peak_at -.. doxygenfunction:: MSG_host_get_process_list -.. doxygenfunction:: MSG_host_get_properties -.. doxygenfunction:: MSG_host_get_property_value -.. doxygenfunction:: MSG_host_get_pstate -.. doxygenfunction:: MSG_host_get_speed -.. doxygenfunction:: MSG_host_is_on -.. doxygenfunction:: MSG_host_off -.. doxygenfunction:: MSG_host_on -.. doxygenfunction:: MSG_host_self -.. doxygenfunction:: MSG_host_set_data -.. doxygenfunction:: MSG_host_set_property_value -.. doxygenfunction:: MSG_host_set_pstate - -Task Management -=============== - -Task structure of MSG :cpp:type:`msg_task_t` and associated functions. - -.. doxygentypedef:: msg_task_t -.. doxygentypedef:: const_msg_task_t -.. doxygendefine:: MSG_TASK_UNINITIALIZED - -.. doxygenfunction:: MSG_parallel_task_create -.. doxygenfunction:: MSG_parallel_task_execute -.. doxygenfunction:: MSG_parallel_task_execute_with_timeout -.. doxygenfunction:: MSG_task_cancel -.. doxygenfunction:: MSG_task_create -.. doxygenfunction:: MSG_task_destroy -.. doxygenfunction:: MSG_task_dsend -.. doxygenfunction:: MSG_task_dsend_bounded -.. doxygenfunction:: MSG_task_execute -.. doxygenfunction:: MSG_task_get_bytes_amount -.. doxygenfunction:: MSG_task_get_category -.. doxygenfunction:: MSG_task_get_data -.. doxygenfunction:: MSG_task_get_flops_amount -.. doxygenfunction:: MSG_task_get_name -.. doxygenfunction:: MSG_task_get_remaining_communication -.. doxygenfunction:: MSG_task_get_remaining_work_ratio -.. doxygenfunction:: MSG_task_get_sender -.. doxygenfunction:: MSG_task_get_source -.. doxygenfunction:: MSG_task_irecv -.. doxygenfunction:: MSG_task_irecv_bounded -.. doxygenfunction:: MSG_task_isend -.. doxygenfunction:: MSG_task_isend_bounded -.. doxygenfunction:: MSG_task_listen -.. doxygenfunction:: MSG_task_listen_from -.. doxygenfunction:: MSG_task_receive -.. doxygenfunction:: MSG_task_receive_bounded -.. doxygenfunction:: MSG_task_receive_with_timeout -.. doxygenfunction:: MSG_task_receive_with_timeout_bounded -.. doxygendefine:: MSG_task_recv -.. doxygendefine:: MSG_task_recv_bounded -.. doxygenfunction:: MSG_task_send -.. doxygenfunction:: MSG_task_send_bounded -.. doxygenfunction:: MSG_task_send_with_timeout -.. doxygenfunction:: MSG_task_send_with_timeout_bounded -.. doxygenfunction:: MSG_task_set_bound -.. doxygenfunction:: MSG_task_set_bytes_amount -.. doxygenfunction:: MSG_task_set_category -.. doxygenfunction:: MSG_task_set_data -.. doxygenfunction:: MSG_task_set_flops_amount -.. doxygenfunction:: MSG_task_set_name -.. doxygenfunction:: MSG_task_set_priority - - -Mailbox Management -================== - -.. doxygenfunction:: MSG_mailbox_set_async - -Communications -============== - -.. doxygentypedef:: msg_comm_t -.. doxygentypedef:: const_msg_comm_t -.. doxygenfunction:: MSG_comm_destroy -.. doxygenfunction:: MSG_comm_get_status -.. doxygenfunction:: MSG_comm_get_task -.. doxygenfunction:: MSG_comm_test -.. doxygenfunction:: MSG_comm_testany -.. doxygenfunction:: MSG_comm_wait -.. doxygenfunction:: MSG_comm_waitall -.. doxygenfunction:: MSG_comm_waitany - -Explicit Synchronization -======================== - -Explicit synchronization mechanisms: semaphores (:cpp:type:`msg_sem_t`) and friends. - -In some situations, these things are very helpful to synchronize processes without message exchanges. - -Barriers --------- - -.. doxygentypedef:: msg_bar_t -.. doxygenfunction:: MSG_barrier_destroy -.. doxygenfunction:: MSG_barrier_init -.. doxygenfunction:: MSG_barrier_wait - -Semaphores ----------- - -.. doxygentypedef:: msg_sem_t -.. doxygenfunction:: MSG_sem_acquire -.. doxygenfunction:: MSG_sem_acquire_timeout -.. doxygenfunction:: MSG_sem_destroy -.. doxygenfunction:: MSG_sem_get_capacity -.. doxygenfunction:: MSG_sem_init -.. doxygenfunction:: MSG_sem_release -.. doxygenfunction:: MSG_sem_would_block - -Virtual Machines -================ - -This interface mimics IaaS clouds. -With it, you can create virtual machines to put your processes -into, and interact directly with the VMs to manage groups of -processes. - -.. doxygentypedef:: msg_vm_t -.. doxygenfunction:: MSG_vm_create_core -.. doxygenfunction:: MSG_vm_create_multicore -.. doxygenfunction:: MSG_vm_destroy -.. doxygenfunction:: MSG_vm_get_name -.. doxygenfunction:: MSG_vm_get_pm -.. doxygenfunction:: MSG_vm_get_ramsize -.. doxygenfunction:: MSG_vm_is_created -.. doxygenfunction:: MSG_vm_is_running -.. doxygenfunction:: MSG_vm_is_suspended -.. doxygenfunction:: MSG_vm_resume -.. doxygenfunction:: MSG_vm_set_bound -.. doxygenfunction:: MSG_vm_set_ramsize -.. doxygenfunction:: MSG_vm_shutdown -.. doxygenfunction:: MSG_vm_start -.. doxygenfunction:: MSG_vm_suspend - -NetZone Management -================== -Network Zone (:cpp:type:`msg_netzone_t`) and associated functions. - -.. doxygentypedef:: msg_netzone_t -.. doxygenfunction:: MSG_zone_get_by_name -.. doxygenfunction:: MSG_zone_get_hosts -.. doxygenfunction:: MSG_zone_get_name -.. doxygenfunction:: MSG_zone_get_property_value -.. doxygenfunction:: MSG_zone_get_root -.. doxygenfunction:: MSG_zone_get_sons -.. doxygenfunction:: MSG_zone_set_property_value - -.. _Java_doc: - -Java bindings -************* - -This section describes jMSG, the Java API to Simgrid. This API mimics -:ref:`MSG `, which is a simple yet somehow realistic interface. -The full reference documentation is provided at the end of this page. - -Most of the documentation of the :ref:`MSG API ` in C applies -directly to the Java bindings (any divergence is seen as a bug that we -should fix). MSG structures are mapped to Java objects as expected, -and the MSG functions are methods in these objects. - -Installing the Java bindings -============================ - -The easiest is to use a :ref:`precompiled jarfile `, -but some people may prefer to :ref:`compile it from the sources `. - - -Using the Java bindings -======================= - -In most cases, you can use the SimGrid bindings as if it was a Java -library: - -.. code-block:: console - - $ javac -classpath .:path/to/simgrid.jar your/java/Code.java - $ java -classpath .:path/to/simgrid.jar your.java.Code the/parameter/to/your/code - -For example: - -.. code-block:: console - - $ cd examples/deprecated/java - $ java -classpath ../../simgrid.jar:. .:../../simgrid.jar app.pingpong.Main ../platforms/platform.xml - -Any SimGrid simulation (java or not) is usually constituted of several -kind of actors or processes (classes extending @c Msg.Process) that -are deployed over the hosts of the virtual platform. So, your code -should declare these actors, plus a Main class in charge of deploying -your actors on the platform. Please refer to the examples for details. - -Troubleshooting -=============== - -Actually, these bindings are not only implemented in Java. They do use -the C implementation of SimGrid. This should be transparent as this -library is directly included in the ``simgrid.jar`` file but things can -still go wrong is several ways. - -Error: library simgrid not found --------------------------------- - -This means that the JVM fails to load the native library. If you use a -precompiled jarfile, please report this bug. - -If you built it yourself, you can try to use an installed version of -the library instead of the one included in the jar. For that, add the -path to the native library into the ``LD_LIBRARY_PATH`` variable (or in -the ``DYLD_LIBRARY_PATH`` on macOS). - -pthread_create failed ---------------------- - -You reached the amount of threads that can be run on your system. Try -increasing the thread limits of your operating system. - -Other errors ------------- - -When using jMSG, your program can crash for 3 main reasons: - -- Your Java part is not good: you'll have a good old java exception thrown, - and hence you should be able to correct it by yourself. -- Our java part is not good: you'll also have a java exception thrown, but - we have real doubts this can happen, since the java part is only a JNI - binding. The other option is that it crashed because you used incorrectly - the MSG API, so this means also you should have an MSGException. It means - you should read carefully MSG samples and/or documentation. -- Something has crashed in the C part. Okay, here comes the tricky - thing. It happens mainly for 2 reasons: - - - When something goes wrong in your simulation, sometimes the C part stops - because you used SimGrid incorrectly, and JNI bindings are not fond of that. - It means that you'll have something that looks ugly, but you should be able - to identify what's going wrong in your code by carefully reading the whole - error message - - It may happen that the problem comes directly from SimGrid: in this case, - the error should be uglier. In that case, you may submit a bug directly to - SimGrid. - -API Reference -============= - -Package org.simgrid.msg ------------------------ - -.. java:package:: org.simgrid.msg - -.. toctree:: - :maxdepth: 1 - - Class org.simgrid.msg.As - Class org.simgrid.msg.Comm - Class org.simgrid.msg.Host - Class org.simgrid.msg.HostFailureException - Class org.simgrid.msg.HostNotFoundException - Class org.simgrid.msg.JniException - Class org.simgrid.msg.Msg - Class org.simgrid.msg.MsgException - Class org.simgrid.msg.Mutex - Class org.simgrid.msg.Process - Class org.simgrid.msg.ProcessKilledError - Class org.simgrid.msg.ProcessNotFoundException - Class org.simgrid.msg.Semaphore - Class org.simgrid.msg.Task - Class org.simgrid.msg.TaskCancelledException - Class org.simgrid.msg.TimeoutException - Class org.simgrid.msg.TransferFailureException - Class org.simgrid.msg.VM diff --git a/docs/source/app_s4u.rst b/docs/source/app_s4u.rst index 014a1e96ed..ff648e0f6f 100644 --- a/docs/source/app_s4u.rst +++ b/docs/source/app_s4u.rst @@ -20,15 +20,12 @@ with the full power of C++. This is the preferred interface to describe abstract algorithms in the domains of Cloud, P2P, HPC, IoT, and similar settings. -Since v3.20 (June 2018), S4U is the way to go for long-term -projects. It is feature complete, but may still evolve slightly in -future releases. It can already be used to do everything that can be -done in SimGrid, but you may have to adapt your code in future -releases. When this happens, compiling your code will produce -deprecation warnings for 4 releases (one year) before the removal of -the old symbols. -If you want an API that will never ever evolve in the future, you -should use the :ref:`deprecated MSG API ` instead. +Since v3.33 (Spring 2023), S4U is the main interface of SimGrid for algorithms. +It is feature complete, but may still evolve slightly in future releases. +When this happens, compiling your code will produce deprecation warnings for 4 +releases (one year) before the removal of the old symbols. + +.. _S4U_main_concepts: Main Concepts ************* @@ -85,6 +82,7 @@ provides many helper functions to simplify the code of actors. - :ref:`class Comm `: Communication activity, started on Mailboxes and consuming links. - :ref:`class Exec `: Computation activity, started on Host and consuming CPU resources. - :ref:`class Io `: I/O activity, started on and consuming disks. + - :ref:`class ActivtySet `: Bag of activities, to wait for any of the set, or all of them. - **Synchronization Objects**: Classical IPC that actors can use @@ -99,6 +97,9 @@ provides many helper functions to simplify the code of actors. .. |API_s4u_Activities| replace:: **Activities** .. _API_s4u_Activities: #api-s4u-activity +.. |API_s4u_Tasks| replace:: **Tasks** +.. _API_s4u_Tasks: #api-s4u-task + .. |API_s4u_Hosts| replace:: **Hosts** .. _API_s4u_Hosts: #api-s4u-host @@ -165,38 +166,55 @@ Every kind of activity can be asynchronous. :cpp:func:`s4u::Disk::write_async() `; and :ref:`s4u::ExecPtr ` are created with :cpp:func:`s4u::Host::exec_async() `. -In the future, it will become possible to have asynchronous IPC such as asynchronous mutex lock requests. - -The following example shows how to have several concurrent -communications ongoing. First, you have to declare a vector in which -we will store the ongoing communications. It is also useful to have a -vector of mailboxes. - -.. literalinclude:: ../../examples/cpp/comm-waitall/s4u-comm-waitall.cpp - :language: c++ - :start-after: init-begin - :end-before: init-end - :dedent: 2 - -Then, you start all the communications that should occur concurrently with -:cpp:func:`s4u::Mailbox::put_async() `. -Finally, the actor waits for the completion of all of them at once -with :cpp:func:`s4u::Comm::wait_all() `. - -.. literalinclude:: ../../examples/cpp/comm-waitall/s4u-comm-waitall.cpp - :language: c++ - :start-after: put-begin - :end-before: put-end - :dedent: 2 +In the future, it will become possible to have asynchronous IPC such as asynchronous mutex lock requests (it is already possible +internally, but the interface is not exposed in S4U yet). + +If you want for the completion of any activity in a given set, to react to the earlier occuring completion, then you need an +:ref:`activity set `. Please refer to the :ref:`relevant examples ` for more information. ===================== -Activities Life cycle +Activities Life Cycle ===================== Sometimes, you want to change the setting of an activity before it even starts. .. todo:: write this section +===================== +Repeatable Activities +===================== + +In order to simulate the execution of Dataflow applications, we introduced the +concept of |API_s4u_Tasks|, that can be seen as repeatable activities. A Dataflow +is defined as a graph of |API_s4u_Tasks|, where each |API_s4u_Tasks| has a set of +successors and predecessors. When a |API_s4u_Tasks| ends it sends a token to each +of its successors. Each |API_s4u_Tasks| has to receive a token from each of its +predecessor to start. Tokens can carry any user-defined data. + +|API_s4u_Tasks| are composed of several instances: a dispatcher, a collector, and +instance_0 to instance_n. The dispatcher rely on a load balancing function to select +the next instance to fire. Once this instance finishes it fires the collector. + +Each instance of an |API_s4u_ExecTask| can be placed on a different host. +|API_s4u_Comm| activities are automatically created when an instance triggers +another instance on a different host. Each instance has its own parallelism degree +to scale horizontally on several cores. + +To initiate the execution of a Dataflow, it is possible to some make +|API_s4u_Tasks| fire one or more activities without waiting for any token with the +:cpp:func:`s4u::Task::enqueue_firings() ` +function. + +The parameters of Tasks can be redefined at runtime by attaching +callbacks to the +:cpp:func:`s4u::Task::on_this_start ` +and +:cpp:func:`s4u::Task::on_this_completion ` +signals. The former is triggered by instances others than the dispatcher and the collector, +and the latter is triggered by the collector. + + + .. _s4u_mailbox: Mailboxes @@ -244,8 +262,8 @@ on the data you want to get from the mailbox. To model such settings in SimGrid, you'd have one mailbox per potential topic, and subscribe to each topic individually with a :cpp:func:`get_async() ` on each mailbox. -Then, use :cpp:func:`Comm::wait_any() ` -to get the first message on any of the mailboxes you are subscribed to. +Then, use an :ref:`class ActivtySet ` to get the first +message on any of the mailboxes you are subscribed to. The mailboxes are not located on the network, and you can access them without any latency. The network delays are only related to the @@ -370,10 +388,6 @@ pointers (yet?). This means that it is currently impossible to destroy a mailbox or a link. You can still destroy a host (but probably shouldn't), using :cpp:func:`simgrid::s4u::Host::destroy`. -.. THE EXAMPLES - -.. include:: ../../examples/README.rst - API Reference ************* @@ -399,7 +413,7 @@ Simulation objects .. group-tab:: Python - + .. autoclass:: simgrid.Actor Basic management @@ -457,6 +471,8 @@ See also :ref:`the relevant example `. .. group-tab:: C + .. doxygentypedef:: xbt_main_func_t + .. doxygenfunction:: sg_actor_create(const char *name, sg_host_t host, xbt_main_func_t code, int argc, char *const *argv) .. doxygenfunction:: sg_actor_init(const char *name, sg_host_t host) .. doxygenfunction:: sg_actor_start(sg_actor_t actor, xbt_main_func_t code, int argc, char *const *argv) @@ -619,12 +635,19 @@ Signals .. doxygenfunction:: simgrid::s4u::Actor::on_creation_cb .. doxygenfunction:: simgrid::s4u::Actor::on_suspend_cb + .. doxygenfunction:: simgrid::s4u::Actor::on_this_suspend_cb .. doxygenfunction:: simgrid::s4u::Actor::on_host_change_cb + .. doxygenfunction:: simgrid::s4u::Actor::on_this_host_change_cb .. doxygenfunction:: simgrid::s4u::Actor::on_resume_cb + .. doxygenfunction:: simgrid::s4u::Actor::on_this_resume_cb .. doxygenfunction:: simgrid::s4u::Actor::on_sleep_cb + .. doxygenfunction:: simgrid::s4u::Actor::on_this_sleep_cb .. doxygenfunction:: simgrid::s4u::Actor::on_wake_up_cb + .. doxygenfunction:: simgrid::s4u::Actor::on_this_wake_up_cb .. doxygenfunction:: simgrid::s4u::Actor::on_termination_cb + .. doxygenfunction:: simgrid::s4u::Actor::on_this_termination_cb .. doxygenfunction:: simgrid::s4u::Actor::on_destruction_cb + .. doxygenfunction:: simgrid::s4u::Actor::on_this_destruction_cb .. _API_s4u_this_actor: @@ -793,7 +816,7 @@ Exiting .. doxygenclass:: simgrid::s4u::Engine .. group-tab:: Python - + .. autoclass:: simgrid.Engine Engin initialization @@ -805,7 +828,6 @@ Engin initialization .. doxygenfunction:: simgrid::s4u::Engine::Engine(int *argc, char **argv) .. doxygenfunction:: simgrid::s4u::Engine::is_initialized() - .. doxygenfunction:: simgrid::s4u::Engine::shutdown() .. doxygenfunction:: simgrid::s4u::Engine::get_instance() .. group-tab:: Python @@ -832,6 +854,7 @@ Simulation setup .. doxygenfunction:: simgrid::s4u::Engine::load_deployment .. doxygenfunction:: simgrid::s4u::Engine::load_platform + .. doxygenfunction:: simgrid::s4u::Engine::flatify_platform .. doxygenfunction:: simgrid::s4u::Engine::register_actor(const std::string &name) .. doxygenfunction:: simgrid::s4u::Engine::register_actor(const std::string &name, F code) .. doxygenfunction:: simgrid::s4u::Engine::register_default(const std::function< void(int, char **)> &code) @@ -979,7 +1002,7 @@ Signals .. doxygenclass:: simgrid::s4u::Mailbox .. group-tab:: Python - + .. autoclass:: simgrid.Mailbox Please also refer to the :ref:`full doc on s4u::Mailbox `. @@ -1126,7 +1149,7 @@ Resources .. doxygenclass:: simgrid::s4u::Disk .. group-tab:: Python - + .. autoclass:: simgrid.Disk .. group-tab:: C @@ -1177,11 +1200,17 @@ Querying info .. doxygenfunction:: simgrid::s4u::Disk::set_property(const std::string &, const std::string &value) .. doxygenfunction:: simgrid::s4u::Disk::set_sharing_policy + .. doxygenenum:: simgrid::s4u::Disk::Operation + .. doxygenenum:: simgrid::s4u::Disk::SharingPolicy + .. group-tab:: Python .. autoattribute:: simgrid.Disk.name .. automethod:: simgrid.Disk.set_sharing_policy + .. autoclass:: simgrid.Disk.Operation + .. autoclass:: simgrid.Disk.SharingPolicy + I/O operations -------------- @@ -1211,7 +1240,9 @@ Signals .. doxygenfunction:: simgrid::s4u::Disk::on_creation_cb .. doxygenfunction:: simgrid::s4u::Disk::on_destruction_cb - .. doxygenfunction:: simgrid::s4u::Disk::on_state_change_cb + .. doxygenfunction:: simgrid::s4u::Disk::on_this_destruction_cb + .. doxygenfunction:: simgrid::s4u::Disk::on_onoff_cb + .. doxygenfunction:: simgrid::s4u::Disk::on_this_onoff_cb .. _API_s4u_Host: @@ -1227,7 +1258,7 @@ Signals .. doxygenclass:: simgrid::s4u::Host .. group-tab:: Python - + .. autoclass:: simgrid.Host Basic management @@ -1398,9 +1429,13 @@ On/Off .. doxygenfunction:: sg_host_turn_off(sg_host_t host) .. doxygenfunction:: sg_host_turn_on(sg_host_t host) +.. _API_s4u_Host_dvfs: + DVFS ---- +See also the :ref:`relevant examples `. + .. tabs:: .. group-tab:: C++ @@ -1471,7 +1506,7 @@ using :cpp:func:`Comm::sendto() `. .. autoattribute:: simgrid.Host.netpoint .. automethod:: simgrid.Host.create_disk - + .. automethod:: simgrid.Host.route_to .. group-tab:: C @@ -1490,8 +1525,12 @@ Signals .. doxygenfunction:: simgrid::s4u::Host::on_creation_cb .. doxygenfunction:: simgrid::s4u::Host::on_destruction_cb + .. doxygenfunction:: simgrid::s4u::Host::on_this_destruction_cb .. doxygenfunction:: simgrid::s4u::Host::on_speed_change_cb - .. doxygenfunction:: simgrid::s4u::Host::on_state_change_cb + .. doxygenfunction:: simgrid::s4u::Host::on_this_speed_change_cb + .. doxygenfunction:: simgrid::s4u::Host::on_onoff_cb + .. doxygenfunction:: simgrid::s4u::Host::on_this_onoff_cb + .. doxygenfunction:: simgrid::s4u::Host::on_exec_state_change_cb .. _API_s4u_Link: @@ -1509,7 +1548,7 @@ Signals .. group-tab:: Python - + .. autoclass:: simgrid.Link Basic management @@ -1544,9 +1583,7 @@ Basic management #include .. doxygentypedef:: sg_link_t - .. cpp:type:: const s4u_Link* const_sg_link_t - - Pointer to a constant link object. + .. doxygentypedef:: const_sg_link_t Retrieving links ---------------- @@ -1580,51 +1617,70 @@ Querying info .. group-tab:: C++ - .. doxygenfunction:: simgrid::s4u::Link::get_bandwidth() const .. doxygenfunction:: simgrid::s4u::Link::get_cname() const - .. doxygenfunction:: simgrid::s4u::Link::get_latency() const .. doxygenfunction:: simgrid::s4u::Link::get_name() const - .. doxygenfunction:: simgrid::s4u::Link::get_sharing_policy() const - .. doxygenfunction:: simgrid::s4u::Link::get_usage() const + .. doxygenfunction:: simgrid::s4u::Link::get_load() const .. doxygenfunction:: simgrid::s4u::Link::is_used() const .. group-tab:: Python - .. autoattribute:: simgrid.Link.bandwidth - .. autoattribute:: simgrid.Link.latency + .. autoattribute:: simgrid.Link.name .. group-tab:: C - .. doxygenfunction:: sg_link_get_bandwidth(const_sg_link_t link) - .. doxygenfunction:: sg_link_get_latency(const_sg_link_t link) .. doxygenfunction:: sg_link_get_name(const_sg_link_t link) .. doxygenfunction:: sg_link_is_shared(const_sg_link_t link) -Modifying characteristics -------------------------- +Performance +----------- .. tabs:: .. group-tab:: C++ + .. doxygenfunction:: simgrid::s4u::Link::get_bandwidth() const + .. doxygenfunction:: simgrid::s4u::Link::get_latency() const .. doxygenfunction:: simgrid::s4u::Link::set_bandwidth(double value) .. doxygenfunction:: simgrid::s4u::Link::set_latency(double value) .. doxygenfunction:: simgrid::s4u::Link::set_latency(const std::string& value) - .. doxygenfunction:: simgrid::s4u::Link::set_concurrency_limit(int limit) - .. doxygenfunction:: simgrid::s4u::Link::set_sharing_policy .. group-tab:: Python + .. autoattribute:: simgrid.Link.bandwidth + .. autoattribute:: simgrid.Link.latency .. automethod:: simgrid.Link.set_bandwidth .. automethod:: simgrid.Link.set_latency - .. automethod:: simgrid.Link.set_concurrency_limit - .. automethod:: simgrid.Link.set_sharing_policy .. group-tab:: C + .. doxygenfunction:: sg_link_get_bandwidth(const_sg_link_t link) + .. doxygenfunction:: sg_link_get_latency(const_sg_link_t link) .. doxygenfunction:: sg_link_set_bandwidth(sg_link_t link, double value) .. doxygenfunction:: sg_link_set_latency(sg_link_t link, double value) +Model policy +------------ + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenenum:: simgrid::s4u::Link::SharingPolicy + + .. doxygenfunction:: simgrid::s4u::Link::get_sharing_policy() const + .. doxygenfunction:: simgrid::s4u::Link::set_sharing_policy + + .. doxygenfunction:: simgrid::s4u::Link::get_concurrency_limit() const + .. doxygenfunction:: simgrid::s4u::Link::set_concurrency_limit(int limit) + + .. group-tab:: Python + + .. automethod:: simgrid.Link.set_concurrency_limit + .. automethod:: simgrid.Link.set_sharing_policy + + .. group-tab:: C + + User data and properties ------------------------ @@ -1701,10 +1757,13 @@ Signals .. group-tab:: C++ .. doxygenfunction:: simgrid::s4u::Link::on_bandwidth_change_cb + .. doxygenfunction:: simgrid::s4u::Link::on_this_bandwidth_change_cb .. doxygenfunction:: simgrid::s4u::Link::on_communication_state_change_cb .. doxygenfunction:: simgrid::s4u::Link::on_creation_cb .. doxygenfunction:: simgrid::s4u::Link::on_destruction_cb - .. doxygenfunction:: simgrid::s4u::Link::on_state_change_cb + .. doxygenfunction:: simgrid::s4u::Link::on_this_destruction_cb + .. doxygenfunction:: simgrid::s4u::Link::on_onoff_cb + .. doxygenfunction:: simgrid::s4u::Link::on_this_onoff_cb .. _API_s4u_NetZone: @@ -1719,7 +1778,7 @@ Signals .. doxygenclass:: simgrid::s4u::NetZone .. group-tab:: Python - + .. autoclass:: simgrid.NetZone Basic management @@ -1783,7 +1842,7 @@ Querying info .. doxygenfunction:: simgrid::s4u::NetZone::get_cname() const .. doxygenfunction:: simgrid::s4u::NetZone::get_name() const - .. doxygenfunction:: simgrid::s4u::NetZone::get_netpoint() + .. doxygenfunction:: simgrid::s4u::NetZone::get_netpoint .. group-tab:: Python @@ -1836,8 +1895,10 @@ Routing data .. group-tab:: C++ .. doxygenfunction:: simgrid::s4u::NetZone::add_component(kernel::routing::NetPoint *elm) - .. doxygenfunction:: simgrid::s4u::NetZone::add_route - .. doxygenfunction:: simgrid::s4u::NetZone::add_bypass_route + .. doxygenfunction:: simgrid::s4u::NetZone::add_route(const Host *src, const Host *dst, const std::vector< LinkInRoute > &link_list, bool symmetrical=true) + .. doxygenfunction:: simgrid::s4u::NetZone::add_route(const Host *src, const Host *dst, const std::vector< const Link * > &links) + .. doxygenfunction:: simgrid::s4u::NetZone::add_route(const NetZone *src, const NetZone *dst, const std::vector< LinkInRoute > &link_list, bool symmetrical=true) + .. doxygenfunction:: simgrid::s4u::NetZone::add_route(const NetZone *src, const NetZone *dst, const std::vector< const Link * > &links) .. doxygenfunction:: simgrid::s4u::NetZone::get_children() const .. doxygenfunction:: simgrid::s4u::NetZone::get_parent() const .. doxygenfunction:: simgrid::s4u::NetZone::set_parent(const NetZone* parent) @@ -1905,6 +1966,10 @@ Hosts .. doxygenfunction:: simgrid::s4u::NetZone::create_host(const std::string& name, double speed) .. doxygenfunction:: simgrid::s4u::NetZone::create_host(const std::string& name, const std::vector& speed_per_pstate) .. doxygenfunction:: simgrid::s4u::NetZone::create_host(const std::string& name, const std::string& speed) + .. doxygenfunction:: simgrid::s4u::NetZone::create_host(const std::string &name, const std::string &speed) + .. doxygenfunction:: simgrid::s4u::NetZone::create_host(const std::string &name, const std::vector< double > &speed_per_pstate) + .. doxygenfunction:: simgrid::s4u::NetZone::create_host(const std::string &name, const std::vector< std::string > &speed_per_pstate) + .. doxygenfunction:: simgrid::s4u::NetZone::create_host(const std::string &name, double speed) .. group-tab:: Python @@ -1917,12 +1982,12 @@ Links .. group-tab:: C++ - .. doxygenfunction:: simgrid::s4u::NetZone::create_link(const std::string& name, const std::vector& bandwidths) - .. doxygenfunction:: simgrid::s4u::NetZone::create_link(const std::string& name, double bandwidth) - .. doxygenfunction:: simgrid::s4u::NetZone::create_link(const std::string& name, const std::vector& bandwidthds) - .. doxygenfunction:: simgrid::s4u::NetZone::create_link(const std::string& name, const std::string& bandwidth) - .. doxygenfunction:: simgrid::s4u::NetZone::create_split_duplex_link(const std::string& name, const std::string& bandwidth) - .. doxygenfunction:: simgrid::s4u::NetZone::create_split_duplex_link(const std::string& name, double bandwidth) + .. doxygenfunction:: simgrid::s4u::NetZone::create_link(const std::string &name, const std::vector< double > &bandwidths) + .. doxygenfunction:: simgrid::s4u::NetZone::create_link(const std::string &name, double bandwidth) + .. doxygenfunction:: simgrid::s4u::NetZone::create_link(const std::string &name, const std::vector< std::string > &bandwidths) + .. doxygenfunction:: simgrid::s4u::NetZone::create_link(const std::string &name, const std::string &bandwidth) + .. doxygenfunction:: simgrid::s4u::NetZone::create_split_duplex_link(const std::string &name, const std::string &bandwidth) + .. doxygenfunction:: simgrid::s4u::NetZone::create_split_duplex_link(const std::string &name, double bandwidth) .. group-tab:: Python @@ -2047,13 +2112,21 @@ Signals .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_creation_cb .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_destruction_cb + .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_destruction_cb .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_migration_end_cb + .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_migration_end_cb .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_migration_start_cb + .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_migration_start_cb .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_resume_cb + .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_resume_cb .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_shutdown_cb + .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_shutdown_cb .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_start_cb + .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_start_cb .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_started_cb + .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_started_cb .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_suspend_cb + .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_suspend_cb .. _API_s4u_Activity: @@ -2086,6 +2159,11 @@ Basic management .. doxygentypedef:: ActivityPtr + .. group-tab:: C + + .. doxygentypedef:: sg_activity_t + .. doxygentypedef:: const_sg_activity_t + Querying info ------------- @@ -2093,8 +2171,8 @@ Querying info .. group-tab:: C++ - .. doxygenfunction:: simgrid::s4u::Activity::get_cname - .. doxygenfunction:: simgrid::s4u::Activity::get_name + .. doxygenfunction:: simgrid::s4u::Activity::get_cname() const + .. doxygenfunction:: simgrid::s4u::Activity::get_name() const .. doxygenfunction:: simgrid::s4u::Activity::get_remaining() const .. doxygenfunction:: simgrid::s4u::Activity::get_state() const .. doxygenfunction:: simgrid::s4u::Activity::set_remaining(double remains) @@ -2114,7 +2192,6 @@ Activities life cycle .. doxygenfunction:: simgrid::s4u::Activity::wait .. doxygenfunction:: simgrid::s4u::Activity::wait_for .. doxygenfunction:: simgrid::s4u::Activity::wait_until(double time_limit) - .. doxygenfunction:: simgrid::s4u::Activity::vetoable_start() Suspending and resuming an activity ----------------------------------- @@ -2127,17 +2204,6 @@ Suspending and resuming an activity .. doxygenfunction:: simgrid::s4u::Activity::resume .. doxygenfunction:: simgrid::s4u::Activity::is_suspended -Signals -------- - -.. tabs:: - - .. group-tab:: C++ - - .. doxygenfunction:: simgrid::s4u::Activity::on_completion_cb - .. doxygenfunction:: simgrid::s4u::Activity::on_suspended_cb - .. doxygenfunction:: simgrid::s4u::Activity::on_resumed_cb - .. _API_s4u_Comm: ============= @@ -2151,7 +2217,7 @@ Signals .. doxygenclass:: simgrid::s4u::Comm .. group-tab:: Python - + .. autoclass:: simgrid.Comm Basic management @@ -2211,11 +2277,12 @@ Querying info .. automethod:: simgrid.Comm.set_payload_size .. automethod:: simgrid.Comm.set_rate -Life cycle ----------- +Direct host-to-host communication +--------------------------------- Most communications are created using :ref:`s4u_mailbox`, but you can -also start direct communications as shown below. +also start direct communications as shown below. See also the +:ref:`relevant examples `. .. tabs:: @@ -2226,42 +2293,56 @@ also start direct communications as shown below. .. doxygenfunction:: simgrid::s4u::Comm::sendto_init(Host *from, Host *to) .. doxygenfunction:: simgrid::s4u::Comm::sendto_async + .. group-tab:: Python + + .. automethod:: simgrid.Comm.sendto + .. automethod:: simgrid.Comm.sendto_init + .. automethod:: simgrid.Comm.sendto_async + +Life cycle +---------- + +.. tabs:: + + .. group-tab:: C++ + .. doxygenfunction:: simgrid::s4u::Comm::cancel .. doxygenfunction:: simgrid::s4u::Comm::start .. doxygenfunction:: simgrid::s4u::Comm::test - .. doxygenfunction:: simgrid::s4u::Comm::test_any(const std::vector< CommPtr >& comms) .. doxygenfunction:: simgrid::s4u::Comm::wait - .. doxygenfunction:: simgrid::s4u::Comm::wait_all(const std::vector< CommPtr >& comms) - .. doxygenfunction:: simgrid::s4u::Comm::wait_all_for(const std::vector< CommPtr >& comms, double timeout) - .. doxygenfunction:: simgrid::s4u::Comm::wait_any(const std::vector< CommPtr >& comms) - .. doxygenfunction:: simgrid::s4u::Comm::wait_any_for(const std::vector< CommPtr >& comms, double timeout) .. doxygenfunction:: simgrid::s4u::Comm::wait_for .. doxygenfunction:: simgrid::s4u::Comm::wait_until .. group-tab:: Python - .. automethod:: simgrid.Comm.sendto - .. automethod:: simgrid.Comm.sendto_init - .. automethod:: simgrid.Comm.sendto_async - .. automethod:: simgrid.Comm.cancel .. automethod:: simgrid.Comm.start .. automethod:: simgrid.Comm.test - .. automethod:: simgrid.Comm.test_any .. automethod:: simgrid.Comm.wait .. automethod:: simgrid.Comm.wait_for - .. automethod:: simgrid.Comm.wait_all - .. automethod:: simgrid.Comm.wait_all_for - .. automethod:: simgrid.Comm.wait_any - .. automethod:: simgrid.Comm.wait_any_for .. automethod:: simgrid.Comm.wait_until .. group-tab:: C .. doxygenfunction:: sg_comm_test .. doxygenfunction:: sg_comm_wait - .. doxygenfunction:: sg_comm_wait_all - .. doxygenfunction:: sg_comm_wait_any + +Suspending and resuming a communication +--------------------------------------- + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenfunction:: simgrid::s4u::Comm::suspend + .. doxygenfunction:: simgrid::s4u::Comm::resume + .. doxygenfunction:: simgrid::s4u::Comm::is_suspended + + .. group-tab:: Python + + .. automethod:: simgrid.Comm.suspend + .. automethod:: simgrid.Comm.resume + .. autoattribute:: simgrid.Comm.is_suspended Signals ------- @@ -2270,10 +2351,22 @@ Signals .. group-tab:: C++ - .. doxygenfunction:: simgrid::s4u::Comm::on_start_cb .. doxygenfunction:: simgrid::s4u::Comm::on_completion_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_start_cb .. doxygenfunction:: simgrid::s4u::Comm::on_recv_cb .. doxygenfunction:: simgrid::s4u::Comm::on_send_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_suspended_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_suspend_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_resume_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_resumed_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_veto_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_this_completion_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_this_recv_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_this_resume_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_this_send_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_this_start_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_this_suspended_cb + .. doxygenfunction:: simgrid::s4u::Comm::on_this_veto_cb .. _API_s4u_Exec: @@ -2288,9 +2381,14 @@ Signals .. doxygenclass:: simgrid::s4u::Exec .. group-tab:: Python - + .. autoclass:: simgrid.Exec + .. group-tab:: C + + .. doxygentypedef:: sg_exec_t + .. doxygentypedef:: const_sg_exec_t + Basic management ---------------- @@ -2316,9 +2414,6 @@ Basic management #include - .. doxygentypedef:: sg_exec_t - .. doxygentypedef:: const_sg_exec_t - Querying info ------------- @@ -2363,9 +2458,6 @@ Life cycle .. doxygenfunction:: simgrid::s4u::Exec::start .. doxygenfunction:: simgrid::s4u::Exec::test .. doxygenfunction:: simgrid::s4u::Exec::wait - .. doxygenfunction:: simgrid::s4u::Exec::wait_any(const std::vector< ExecPtr >& execs) - .. doxygenfunction:: simgrid::s4u::Exec::wait_any_for(const std::vector< ExecPtr >& execs, double timeout) - .. doxygenfunction:: simgrid::s4u::Exec::wait_for .. group-tab:: Python @@ -2380,9 +2472,23 @@ Life cycle .. doxygenfunction:: sg_exec_cancel(sg_exec_t exec); .. doxygenfunction:: sg_exec_test(sg_exec_t exec); .. doxygenfunction:: sg_exec_wait(sg_exec_t exec); - .. doxygenfunction:: sg_exec_wait_for(sg_exec_t exec, double timeout); - .. doxygenfunction:: sg_exec_wait_any_for(sg_exec_t* execs, size_t count, double timeout); - .. doxygenfunction:: sg_exec_wait_any(sg_exec_t* execs, size_t count); + +Suspending and resuming an execution +------------------------------------ + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenfunction:: simgrid::s4u::Exec::suspend + .. doxygenfunction:: simgrid::s4u::Exec::resume + .. doxygenfunction:: simgrid::s4u::Exec::is_suspended + + .. group-tab:: Python + + .. automethod:: simgrid.Exec.suspend + .. automethod:: simgrid.Exec.resume + .. autoattribute:: simgrid.Exec.is_suspended Signals ------- @@ -2392,7 +2498,14 @@ Signals .. group-tab:: C++ .. doxygenfunction:: simgrid::s4u::Exec::on_start_cb + .. doxygenfunction:: simgrid::s4u::Exec::on_this_start_cb .. doxygenfunction:: simgrid::s4u::Exec::on_completion_cb + .. doxygenfunction:: simgrid::s4u::Exec::on_this_completion_cb + + .. doxygenfunction:: simgrid::s4u::Exec::on_suspended_cb + .. doxygenfunction:: simgrid::s4u::Exec::on_resumed_cb + .. doxygenfunction:: simgrid::s4u::Exec::on_veto_cb + .. doxygenfunction:: simgrid::s4u::Exec::on_this_veto_cb .. _API_s4u_Io: @@ -2407,7 +2520,7 @@ Signals .. doxygenclass:: simgrid::s4u::Io .. group-tab:: Python - + .. autoclass:: simgrid.Io Basic management @@ -2444,16 +2557,11 @@ Life cycle .. doxygenfunction:: simgrid::s4u::Io::start .. doxygenfunction:: simgrid::s4u::Io::test .. doxygenfunction:: simgrid::s4u::Io::wait - .. doxygenfunction:: simgrid::s4u::Io::wait_for - .. doxygenfunction:: simgrid::s4u::Io::wait_any(const std::vector &ios) - .. doxygenfunction:: simgrid::s4u::Io::wait_any_for(const std::vector &ios, double timeout) .. group-tab:: Python .. automethod:: simgrid.Io.test .. automethod:: simgrid.Io.wait - .. automethod:: simgrid.Io.wait_any_for - .. automethod:: simgrid.Io.wait_any Signals ------- @@ -2463,7 +2571,336 @@ Signals .. group-tab:: C++ .. doxygenfunction:: simgrid::s4u::Io::on_start_cb + .. doxygenfunction:: simgrid::s4u::Io::on_this_start_cb .. doxygenfunction:: simgrid::s4u::Io::on_completion_cb + .. doxygenfunction:: simgrid::s4u::Io::on_this_completion_cb + + .. doxygenfunction:: simgrid::s4u::Io::on_suspended_cb + .. doxygenfunction:: simgrid::s4u::Io::on_resumed_cb + .. doxygenfunction:: simgrid::s4u::Io::on_veto_cb + .. doxygenfunction:: simgrid::s4u::Io::on_this_veto_cb + +.. _API_s4u_ActivitySet: + +==================== +⁣  class ActivitySet +==================== + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenclass:: simgrid::s4u::ActivitySet + + .. group-tab:: Python + + .. autoclass:: simgrid.ActivitySet + + .. group-tab:: C + + .. doxygentypedef:: sg_activity_set_t + .. doxygentypedef:: const_sg_activity_set_t + +Basic management +---------------- + +.. tabs:: + + .. group-tab:: C++ + + .. code-block:: C++ + + #include + + .. doxygentypedef:: ActivitySetPtr + + .. group-tab:: Python + + .. code:: Python + + from simgrid import ActivitySet + + .. group-tab:: C + + .. code-block:: C + + #include + + .. doxygenfunction:: sg_activity_set_init + .. doxygenfunction:: sg_activity_set_delete + +Managing activities +------------------- + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenfunction:: simgrid::s4u::ActivitySet::push + .. doxygenfunction:: simgrid::s4u::ActivitySet::erase + .. doxygenfunction:: simgrid::s4u::ActivitySet::empty + .. doxygenfunction:: simgrid::s4u::ActivitySet::size + + .. group-tab:: Python + + .. automethod:: simgrid.ActivitySet.push() + .. automethod:: simgrid.ActivitySet.erase() + .. automethod:: simgrid.ActivitySet.empty() + .. automethod:: simgrid.ActivitySet.size() + + .. group-tab:: c + + .. doxygenfunction:: sg_activity_set_push + .. doxygenfunction:: sg_activity_set_erase + .. doxygenfunction:: sg_activity_set_empty + .. doxygenfunction:: sg_activity_set_size + +Interacting with the set +------------------------ + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenfunction:: simgrid::s4u::ActivitySet::test_any + .. doxygenfunction:: simgrid::s4u::ActivitySet::wait_all + .. doxygenfunction:: simgrid::s4u::ActivitySet::wait_all_for + .. doxygenfunction:: simgrid::s4u::ActivitySet::wait_any + .. doxygenfunction:: simgrid::s4u::ActivitySet::wait_any_for + + .. group-tab:: Python + + .. automethod:: simgrid.ActivitySet.test_any() + .. automethod:: simgrid.ActivitySet.wait_all() + .. automethod:: simgrid.ActivitySet.wait_all_for() + .. automethod:: simgrid.ActivitySet.wait_any() + .. automethod:: simgrid.ActivitySet.wait_any_for() + + .. group-tab:: c + + .. doxygenfunction:: sg_activity_set_test_any + .. doxygenfunction:: sg_activity_set_wait_all + .. doxygenfunction:: sg_activity_set_wait_all_for + .. doxygenfunction:: sg_activity_set_wait_any + .. doxygenfunction:: sg_activity_set_wait_any_for + .. doxygenfunction:: sg_activity_unref + +Dealing with failed activities +------------------------------ + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenfunction:: simgrid::s4u::ActivitySet::get_failed_activity() + .. doxygenfunction:: simgrid::s4u::ActivitySet::has_failed_activities() + +.. _API_s4u_Tasks: + +========== +Tasks +========== + +============== +class Task +============== + +.. doxygenclass:: simgrid::s4u::Task + +**Known subclasses:** +:ref:`Communication Tasks `, +:ref:`Executions Tasks `, +:ref:`I/O Tasks `. +See also the :ref:`section on activities ` above. + +Basic management +---------------- + +.. tabs:: + + .. group-tab:: C++ + + .. code-block:: C++ + + #include + + .. doxygentypedef:: TaskPtr + +Querying info +------------- + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenfunction:: simgrid::s4u::Task::get_cname() const + .. doxygenfunction:: simgrid::s4u::Task::get_name() const + .. doxygenfunction:: simgrid::s4u::Task::get_count(std::string instance) const + .. doxygenfunction:: simgrid::s4u::Task::get_amount(std::string instance) const + .. doxygenfunction:: simgrid::s4u::Task::get_queued_firings(std::string instance) const + .. doxygenfunction:: simgrid::s4u::Task::get_running_count(std::string instance) const + .. doxygenfunction:: simgrid::s4u::Task::get_parallelism_degree(std::string instance) const + .. doxygenfunction:: simgrid::s4u::Task::set_name(std::string name) + +Life cycle +---------- + +.. tabs:: + + .. group-tab:: C++ + .. doxygenfunction:: simgrid::s4u::Task::enqueue_firings(int n) + .. doxygenfunction:: simgrid::s4u::Task::set_amount(double amount, std::string instance) + .. doxygenfunction:: simgrid::s4u::Task::set_parallelism_degree(int n, std::string instance) + +Managing Dependencies +--------------------- + +.. tabs:: + + .. group-tab:: C++ + .. doxygenfunction:: simgrid::s4u::Task::add_successor(TaskPtr t) + .. doxygenfunction:: simgrid::s4u::Task::remove_successor(TaskPtr t) + .. doxygenfunction:: simgrid::s4u::Task::remove_all_successors() + .. doxygenfunction:: simgrid::s4u::Task::get_successors() const + +Managing Tokens +--------------- + +.. doxygenclass:: simgrid::s4u::Token + +.. tabs:: + + .. group-tab:: C++ + .. doxygenfunction:: simgrid::s4u::Task::get_token_from(TaskPtr t) const + .. doxygenfunction:: simgrid::s4u::Task::get_tokens_from(TaskPtr t) const + .. doxygenfunction:: simgrid::s4u::Task::deque_token_from(TaskPtr t) + .. doxygenfunction:: simgrid::s4u::Task::set_token(std::shared_ptr token) + +Signals +------- + +.. tabs:: + + .. group-tab:: C++ + .. doxygenfunction:: simgrid::s4u::Task::on_start_cb + .. doxygenfunction:: simgrid::s4u::Task::on_this_start_cb + .. doxygenfunction:: simgrid::s4u::Task::on_completion_cb + .. doxygenfunction:: simgrid::s4u::Task::on_this_completion_cb + +.. _API_s4u_CommTask: + +================= +⁣  class CommTask +================= +.. tabs:: + + .. group-tab:: C++ + + .. doxygenclass:: simgrid::s4u::CommTask + +Basic management +---------------- + +.. tabs:: + + .. group-tab:: C++ + + .. code-block:: C++ + + #include + + .. doxygentypedef:: CommTaskPtr + +Querying info +------------- + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenfunction:: simgrid::s4u::CommTask::get_source() const + .. doxygenfunction:: simgrid::s4u::CommTask::get_destination() const + .. doxygenfunction:: simgrid::s4u::CommTask::get_bytes() const + .. doxygenfunction:: simgrid::s4u::CommTask::set_source(Host* source); + .. doxygenfunction:: simgrid::s4u::CommTask::set_destination(Host* destination); + .. doxygenfunction:: simgrid::s4u::CommTask::set_bytes(double bytes) + + +.. _API_s4u_ExecTask: + +================= +⁣  class ExecTask +================= +.. tabs:: + + .. group-tab:: C++ + + .. doxygenclass:: simgrid::s4u::ExecTask + +Basic management +---------------- + +.. tabs:: + + .. group-tab:: C++ + + .. code-block:: C++ + + #include + + .. doxygentypedef:: ExecTaskPtr + +Querying info +------------- + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenfunction:: simgrid::s4u::ExecTask::get_host(std::string instance) const + .. doxygenfunction:: simgrid::s4u::ExecTask::get_flops(std::string instance) const + .. doxygenfunction:: simgrid::s4u::ExecTask::set_host(Host* host, std::string instance); + .. doxygenfunction:: simgrid::s4u::ExecTask::set_flops(double flops, std::string instance); + .. doxygenfunction:: simgrid::s4u::ExecTask::add_instances(int n); + .. doxygenfunction:: simgrid::s4u::ExecTask::remove_instances(int n); + +.. _API_s4u_IoTask: + +================ +⁣  class IoTask +================ +.. tabs:: + + .. group-tab:: C++ + + .. doxygenclass:: simgrid::s4u::IoTask + +Basic management +---------------- + +.. tabs:: + + .. group-tab:: C++ + + .. code-block:: C++ + + #include + + .. doxygentypedef:: IoTaskPtr + +Querying info +------------- + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenfunction:: simgrid::s4u::IoTask::get_disk() const + .. doxygenfunction:: simgrid::s4u::IoTask::get_bytes() const + .. doxygenfunction:: simgrid::s4u::IoTask::get_op_type() const + .. doxygenfunction:: simgrid::s4u::IoTask::set_disk(Disk* disk); + .. doxygenfunction:: simgrid::s4u::IoTask::set_bytes(double bytes); + .. doxygenfunction:: simgrid::s4u::IoTask::set_op_type(Io::OpType type); .. _API_s4u_Synchronizations: @@ -2500,7 +2937,7 @@ Basic management .. doxygentypedef:: MutexPtr - .. doxygenfunction:: simgrid::s4u::Mutex::create() + .. doxygenfunction:: simgrid::s4u::Mutex::create .. group-tab:: Python @@ -2582,6 +3019,7 @@ Locking .. doxygenfunction:: simgrid::s4u::Barrier::create(unsigned int expected_actors) .. doxygenfunction:: simgrid::s4u::Barrier::wait() + .. doxygenfunction:: simgrid::s4u::Barrier::to_string() .. group-tab:: Python @@ -2754,6 +3192,55 @@ Locking .. doxygenfunction:: sg_sem_release(sg_sem_t sem) .. doxygenfunction:: sg_sem_would_block(const_sg_sem_t sem) +=============== +Error reporting +=============== + +.. tabs:: + + .. group-tab:: C++ + + .. doxygenclass:: simgrid::Exception + + The following exceptions denote a problem in the simulated platform, and it is often useful to catch them. + + .. doxygenclass:: simgrid::CancelException + .. doxygenclass:: simgrid::HostFailureException + .. doxygenclass:: simgrid::NetworkFailureException + .. doxygenclass:: simgrid::StorageFailureException + .. doxygenclass:: simgrid::TimeoutException + .. doxygenclass:: simgrid::VmFailureException + + The following errors denote a problem in the SimGrid tool itself. Most of the time, you should let these + exception go, so that the simulation stops. But you may want to catch them, for example when you launch + SimGrid from a python notebook and want to handle the problem accordingly. + + .. doxygenclass:: simgrid::AssertionError + .. doxygenclass:: simgrid::ParseError + .. doxygenclass:: simgrid::TracingError + + .. group-tab:: Python + + The following exceptions denote a problem in the simulated platform, and it is often useful to catch them. + + .. autoclass:: simgrid.CancelException + .. autoclass:: simgrid.HostFailureException + .. autoclass:: simgrid.NetworkFailureException + .. autoclass:: simgrid.StorageFailureException + .. autoclass:: simgrid.TimeoutException + .. autoclass:: simgrid.VmFailureException + + The following errors denote a problem in the SimGrid tool itself. Most of the time, you should let these + exception go, so that the simulation stops. But you may want to catch them, for example when you launch + SimGrid from a python notebook and want to handle the problem accordingly. + + .. autoclass:: simgrid.AssertionError + + .. group-tab:: C + + .. doxygenenum:: sg_error_t + + .. |hr| raw:: html
    diff --git a/docs/source/app_smpi.rst b/docs/source/app_smpi.rst index 24f8bf73ae..84bb4fc09d 100644 --- a/docs/source/app_smpi.rst +++ b/docs/source/app_smpi.rst @@ -42,11 +42,121 @@ For **further scalability**, you may modify your code to speed up your studies or save memory space. Maximal **simulation accuracy** requires some specific care from you. +------------------------- +What can run within SMPI? +------------------------- + +You can run unmodified MPI applications (both C/C++ and Fortran) within +SMPI, provided that you only use MPI calls that we implemented. Global +variables should be handled correctly on Linux systems. + +.................... +MPI coverage of SMPI +.................... + +SMPI support a large faction of the MPI interface: we pass many of the MPICH coverage tests, and many of the existing +:ref:`proxy apps ` run almost unmodified on top of SMPI. But our support is still incomplete, with I/O +primitives the being one of the major missing feature. + +The full list of functions that remain to be implemented is documented in the file `include/smpi/smpi.h +`_ in your version of SimGrid, between two lines +containing the ``FIXME`` marker. If you miss a feature, please get in touch with us: we can guide you through the SimGrid +code to help you implementing it, and we'd be glad to integrate your contribution to the main project. + +.. _SMPI_what_globals: + +................................. +Privatization of global variables +................................. + +Concerning the globals, the problem comes from the fact that usually, +MPI processes run as real UNIX processes while they are all folded +into threads of a unique system process in SMPI. Global variables are +usually private to each MPI process while they become shared between +the processes in SMPI. The problem and some potential solutions are +discussed in this article: `Automatic Handling of Global Variables for +Multi-threaded MPI Programs +` (note that +this article does not deal with SMPI but with a competing solution +called AMPI that suffers of the same issue). This point used to be +problematic in SimGrid, but the problem should now be handled +automatically on Linux. + +Older versions of SimGrid came with a script that automatically +privatized the globals through static analysis of the source code. But +our implementation was not robust enough to be used in production, so +it was removed at some point. Currently, SMPI comes with two +privatization mechanisms that you can :ref:`select at runtime +`. The dlopen approach is used by +default as it is much faster and still very robust. The mmap approach +is an older approach that proves to be slower. + +With the **mmap approach**, SMPI duplicates and dynamically switch the +``.data`` and ``.bss`` segments of the ELF process when switching the +MPI ranks. This allows each ranks to have its own copy of the global +variables. No copy actually occurs as this mechanism uses ``mmap()`` +for efficiency. This mechanism is considered to be very robust on all +systems supporting ``mmap()`` (Linux and most BSDs). Its performance +is questionable since each context switch between MPI ranks induces +several syscalls to change the ``mmap`` that redirects the ``.data`` +and ``.bss`` segments to the copies of the new rank. The code will +also be copied several times in memory, inducing a slight increase of +memory occupation. + +Another limitation is that SMPI only accounts for global variables +defined in the executable. If the processes use external global +variables from dynamic libraries, they won't be switched +correctly. The easiest way to solve this is to statically link against +the library with these globals. This way, each MPI rank will get its +own copy of these libraries. Of course you should never statically +link against the SimGrid library itself. + +With the **dlopen approach**, SMPI loads several copies of the same +executable in memory as if it were a library, so that the global +variables get naturally duplicated. It first requires the executable +to be compiled as a relocatable binary, which is less common for +programs than for libraries. But most distributions are now compiled +this way for security reason as it allows one to randomize the address +space layout. It should thus be safe to compile most (any?) program +this way. The second trick is that the dynamic linker refuses to link +the exact same file several times, be it a library or a relocatable +executable. It makes perfectly sense in the general case, but we need +to circumvent this rule of thumb in our case. To that extend, the +binary is copied in a temporary file before being re-linked against. +``dlmopen()`` cannot be used as it only allows 256 contexts, and as it +would also duplicate SimGrid itself. + +This approach greatly speeds up the context switching, down to about +40 CPU cycles with our raw contexts, instead of requesting several +syscalls with the ``mmap()`` approach. Another advantage is that it +permits one to run the SMPI contexts in parallel, which is obviously not +possible with the ``mmap()`` approach. It was tricky to implement, but +we are not aware of any flaws, so smpirun activates it by default. + +In the future, it may be possible to further reduce the memory and +disk consumption. It seems that we could `punch holes +`_ in the files before dl-loading +them to remove the code and constants, and mmap these area onto a +unique copy. If done correctly, this would reduce the disk- and +memory- usage to the bare minimum, and would also reduce the pressure +on the CPU instruction cache. See the `relevant bug +`_ on github for +implementation leads.\n + +Also, currently, only the binary is copied and dlopen-ed for each MPI +rank. We could probably extend this to external dependencies, but for +now, any external dependencies must be statically linked into your +application. As usual, SimGrid itself shall never be statically linked +in your app. You don't want to give a copy of SimGrid to each MPI rank: +that's ways too much for them to deal with. + +.. todo: speak of smpi/privatize-libs here + .. _SMPI_online: ------------------ -Using SMPI online ------------------ +--------------------------- +Online SMPI: live execution +--------------------------- In this mode, your application is actually executed. Every computation occurs for real while every communication is simulated. In addition, @@ -106,7 +216,7 @@ tracing during the simulation. You can get the full list by running Finally, you can pass :ref:`any valid SimGrid parameter ` to your program. In particular, you can pass ``--cfg=network/model:ns-3`` to -switch to use :ref:`model_ns3`. These parameters should be placed after +switch to use :ref:`models_ns3`. These parameters should be placed after the name of your binary on the command line. ............................... @@ -203,9 +313,11 @@ means that the selected algorithm will be used .. Warning:: Some collective may require specific conditions to be executed correctly (for instance having a communicator with a power of two number of nodes only), which are currently not enforced by - Simgrid. Some crashes can be expected while trying these algorithms + SimGrid. Some crashes can be expected while trying these algorithms with unusual sizes/parameters +To retrieve the full list of implemented algorithms in your version of SimGrid, simply use ``smpirun --help-coll``. + MPI_Alltoall ^^^^^^^^^^^^ @@ -453,7 +565,7 @@ Adding an algorithm ^^^^^^^^^^^^^^^^^^^ To add a new algorithm, one should check in the src/smpi/colls folder -how other algorithms are coded. Using plain MPI code inside Simgrid +how other algorithms are coded. Using plain MPI code inside SimGrid can't be done, so algorithms have to be changed to use smpi version of the calls instead (MPI_Send will become smpi_mpi_send). Some functions may have different signatures than their MPI counterpart, please check @@ -471,7 +583,7 @@ Example: adding a "pair" version of the Alltoall collective. - To register the new version of the algorithm, simply add a line to the corresponding macro in src/smpi/colls/cools.h ( add a "COLL_APPLY(action, COLL_ALLTOALL_SIG, pair)" to the COLL_ALLTOALLS macro ). The algorithm should now be compiled and be selected when using --cfg=smpi/alltoall:pair at runtime. - - To add a test for the algorithm inside Simgrid's test suite, juste add the new algorithm name in the ALLTOALL_COLL list found inside teshsuite/smpi/CMakeLists.txt . When running ctest, a test for the new algorithm should be generated and executed. If it does not pass, please check your code or contact us. + - To add a test for the algorithm inside SimGrid's test suite, juste add the new algorithm name in the ALLTOALL_COLL list found inside teshsuite/smpi/CMakeLists.txt . When running ctest, a test for the new algorithm should be generated and executed. If it does not pass, please check your code or contact us. - Please submit your patch for inclusion in SMPI, for example through a pull request on GitHub or directly per email. @@ -498,119 +610,38 @@ Alltoall on 16 Nodes with the Ring Algorithm. Alltoall on 16 Nodes with the Pairwise Algorithm. -------------------------- -What can run within SMPI? -------------------------- +.. _SMPI_mix_s4u: -You can run unmodified MPI applications (both C/C++ and Fortran) within -SMPI, provided that you only use MPI calls that we implemented. Global -variables should be handled correctly on Linux systems. - -.................... -MPI coverage of SMPI -.................... - -SMPI support a large faction of the MPI interface: we pass many of the MPICH coverage tests, and many of the existing -:ref:`proxy apps ` run almost unmodified on top of SMPI. But our support is still incomplete, with I/O -primitives the being one of the major missing feature. - -The full list of functions that remain to be implemented is documented in the file `include/smpi/smpi.h -`_ in your version of SimGrid, between two lines -containing the ``FIXME`` marker. If you miss a feature, please get in touch with us: we can guide you through the SimGrid -code to help you implementing it, and we'd be glad to integrate your contribution to the main project. - -.. _SMPI_what_globals: - -................................. -Privatization of global variables -................................. - -Concerning the globals, the problem comes from the fact that usually, -MPI processes run as real UNIX processes while they are all folded -into threads of a unique system process in SMPI. Global variables are -usually private to each MPI process while they become shared between -the processes in SMPI. The problem and some potential solutions are -discussed in this article: `Automatic Handling of Global Variables for -Multi-threaded MPI Programs -` (note that -this article does not deal with SMPI but with a competing solution -called AMPI that suffers of the same issue). This point used to be -problematic in SimGrid, but the problem should now be handled -automatically on Linux. +............................. +Mixing S4U and MPI simulation +............................. -Older versions of SimGrid came with a script that automatically -privatized the globals through static analysis of the source code. But -our implementation was not robust enough to be used in production, so -it was removed at some point. Currently, SMPI comes with two -privatization mechanisms that you can :ref:`select at runtime -`. The dlopen approach is used by -default as it is much faster and still very robust. The mmap approach -is an older approach that proves to be slower. +Mixing both interfaces is very easy. This can be useful to easily implement a service in S4U that is provided by your +infrastructure in some way, and test how your MPI application interacts with this service. Or you can use it to start more than +one MPI application in your simulation, and study their interactions. For that, you just need to use +:cpp:ref:`SMPI_app_instance_register` in a regular S4U program, as shown in the example below. Compile it as usual (with gcc or +g++, **not** smpicc) and execute it directly (**not** with smpirun). -With the **mmap approach**, SMPI duplicates and dynamically switch the -``.data`` and ``.bss`` segments of the ELF process when switching the -MPI ranks. This allows each ranks to have its own copy of the global -variables. No copy actually occurs as this mechanism uses ``mmap()`` -for efficiency. This mechanism is considered to be very robust on all -systems supporting ``mmap()`` (Linux and most BSDs). Its performance -is questionable since each context switch between MPI ranks induces -several syscalls to change the ``mmap`` that redirects the ``.data`` -and ``.bss`` segments to the copies of the new rank. The code will -also be copied several times in memory, inducing a slight increase of -memory occupation. +.. doxygenfunction:: SMPI_app_instance_start -Another limitation is that SMPI only accounts for global variables -defined in the executable. If the processes use external global -variables from dynamic libraries, they won't be switched -correctly. The easiest way to solve this is to statically link against -the library with these globals. This way, each MPI rank will get its -own copy of these libraries. Of course you should never statically -link against the SimGrid library itself. +.. tabs:: -With the **dlopen approach**, SMPI loads several copies of the same -executable in memory as if it were a library, so that the global -variables get naturally duplicated. It first requires the executable -to be compiled as a relocatable binary, which is less common for -programs than for libraries. But most distributions are now compiled -this way for security reason as it allows one to randomize the address -space layout. It should thus be safe to compile most (any?) program -this way. The second trick is that the dynamic linker refuses to link -the exact same file several times, be it a library or a relocatable -executable. It makes perfectly sense in the general case, but we need -to circumvent this rule of thumb in our case. To that extend, the -binary is copied in a temporary file before being re-linked against. -``dlmopen()`` cannot be used as it only allows 256 contextes, and as it -would also duplicate simgrid itself. + .. group-tab:: Example -This approach greatly speeds up the context switching, down to about -40 CPU cycles with our raw contextes, instead of requesting several -syscalls with the ``mmap()`` approach. Another advantage is that it -permits one to run the SMPI contexts in parallel, which is obviously not -possible with the ``mmap()`` approach. It was tricky to implement, but -we are not aware of any flaws, so smpirun activates it by default. + Here is a simple example of use, which starts the function ``alltoall_mpi`` as a MPI instance on 4 hosts, along several + S4U actors doing a master/workers. -In the future, it may be possible to further reduce the memory and -disk consumption. It seems that we could `punch holes -`_ in the files before dl-loading -them to remove the code and constants, and mmap these area onto a -unique copy. If done correctly, this would reduce the disk- and -memory- usage to the bare minimum, and would also reduce the pressure -on the CPU instruction cache. See the `relevant bug -`_ on github for -implementation leads.\n + .. showfile:: examples/smpi/smpi_s4u_masterworker/masterworker_mailbox_smpi.cpp + :language: cpp -Also, currently, only the binary is copied and dlopen-ed for each MPI -rank. We could probably extend this to external dependencies, but for -now, any external dependencies must be statically linked into your -application. As usual, simgrid itself shall never be statically linked -in your app. You don't want to give a copy of SimGrid to each MPI rank: -that's ways too much for them to deal with. + .. group-tab:: Deployment file -.. todo: speak of smpi/privatize-libs here + .. showfile:: examples/smpi/smpi_s4u_masterworker/deployment_masterworker_mailbox_smpi.xml + :language: xml ----------------------------------------------- +.............................................. Adapting your MPI code for further scalability ----------------------------------------------- +.............................................. As detailed in the `reference article `_, you may want to adapt your code @@ -619,9 +650,8 @@ hinder the result quality (or even prevent the app to run) if used wrongly. We assume that if you want to simulate an HPC application, you know what you are doing. Don't prove us wrong! -.............................. Reducing your memory footprint -.............................. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you get short on memory (the whole app is executed on a single node when simulated), you should have a look at the SMPI_SHARED_MALLOC and @@ -649,9 +679,8 @@ This feature is demoed by the example file .. _SMPI_use_faster: -......................... Toward Faster Simulations -......................... +^^^^^^^^^^^^^^^^^^^^^^^^^ If your application is too slow, try using SMPI_SAMPLE_LOCAL, SMPI_SAMPLE_GLOBAL and friends to indicate which computation loops can @@ -671,9 +700,8 @@ what is necessary to group calls of a given size together. This feature is demoed by the example file `examples/smpi/NAS/ep.c `_ -............................. Ensuring Accurate Simulations -............................. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Out of the box, SimGrid may give you fairly accurate results, but there is a plenty of factors that could go wrong and make your results @@ -715,9 +743,9 @@ modeling distributed systems. .. _SMPI_proxy_apps: ----------------------- +...................... Examples of SMPI Usage ----------------------- +...................... A small amount of examples can be found directly in the SimGrid archive, under `examples/smpi `_. @@ -745,6 +773,50 @@ next generation of runtimes and hardware. `This project from different sources, along with the patches needed (if any) to run them on top of SMPI. +.. _SMPI_offline: + +-------------------------- +Offline SMPI: Trace Replay +-------------------------- + +Although SMPI is often used for :ref:`online simulation +`, where the application is executed for real, you can +also go for offline simulation through trace replay. + +SimGrid uses time-independent traces, in which each actor is given a +script of the actions to do sequentially. These trace files can +actually be captured with the online version of SMPI, as follows: + +.. code-block:: console + + $ smpirun -trace-ti --cfg=tracing/filename:LU.A.32 -np 32 -platform ../cluster_backbone.xml bin/lu.A.32 + +The produced trace is composed of a file ``LU.A.32`` and a folder +``LU.A.32_files``. The file names don't match with the MPI ranks, but +that's expected. + +To replay this with SMPI, you need to first compile the provided +``smpi_replay.cpp`` file, that comes from +`simgrid/examples/smpi/replay +`_. + +.. code-block:: console + + $ smpicxx ../replay.cpp -O3 -o ../smpi_replay + +Afterward, you can replay your trace in SMPI as follows: + +.. code-block:: console + + $ smpirun -np 32 -platform ../cluster_torus.xml -ext smpi_replay ../smpi_replay LU.A.32 + +All the outputs are gone, as the application is not really simulated +here. Its trace is simply replayed. But if you visualize the live +simulation and the replay, you will see that the behavior is +unchanged. The simulation does not run much faster on this very +example, but this becomes very interesting when your application +is computationally hungry. + ------------------------- Troubleshooting with SMPI ------------------------- @@ -806,52 +878,6 @@ only if you declare ``_GNU_SOURCE`` before including SMPI, then you need to ensure that you pass the right configuration defines as advised above. - - -.. _SMPI_offline: - ------------------------------ -Trace Replay and Offline SMPI ------------------------------ - -Although SMPI is often used for :ref:`online simulation -`, where the application is executed for real, you can -also go for offline simulation through trace replay. - -SimGrid uses time-independent traces, in which each actor is given a -script of the actions to do sequentially. These trace files can -actually be captured with the online version of SMPI, as follows: - -.. code-block:: console - - $ smpirun -trace-ti --cfg=tracing/filename:LU.A.32 -np 32 -platform ../cluster_backbone.xml bin/lu.A.32 - -The produced trace is composed of a file ``LU.A.32`` and a folder -``LU.A.32_files``. The file names don't match with the MPI ranks, but -that's expected. - -To replay this with SMPI, you need to first compile the provided -``smpi_replay.cpp`` file, that comes from -`simgrid/examples/smpi/replay -`_. - -.. code-block:: console - - $ smpicxx ../replay.cpp -O3 -o ../smpi_replay - -Afterward, you can replay your trace in SMPI as follows: - -.. code-block:: console - - $ smpirun -np 32 -platform ../cluster_torus.xml -ext smpi_replay ../smpi_replay LU.A.32 - -All the outputs are gone, as the application is not really simulated -here. Its trace is simply replayed. But if you visualize the live -simulation and the replay, you will see that the behavior is -unchanged. The simulation does not run much faster on this very -example, but this becomes very interesting when your application -is computationally hungry. - .. |br| raw:: html
    diff --git a/docs/source/application.rst b/docs/source/application.rst index 2cd7745754..499465af93 100644 --- a/docs/source/application.rst +++ b/docs/source/application.rst @@ -31,14 +31,7 @@ to mix several interfaces in the same simulation. MPI profilers). You can reuse this mechanism for any kind of trace that you want to replay, for example to study how a P2P DHT overlay reacts to a given workload. - - Simulating algorithms with the legacy interface: :ref:`MSG for distributed - algorithms ` (in :ref:`C ` or :ref:`Java - `). SimGrid was founded in 1998, and many interfaces were proposed - along the way. MSG (introduced around 2002) is still present in SimGrid. It - does not evolve anymore, but given its popularity, it will not be removed - until at least 2020. That being said, our goal is to make S4U so useful that - this legacy API becomes useless and obsolete. - - We are currently working on the ability to modify any existing + - A prototypal tool is intended to allow the modification of any existing application so that it can run on top of SimGrid. This project, called `Remote-SimGrid `_, is somewhat @@ -56,6 +49,3 @@ applications, but our long term goal would be to allow for the execution of any legacy application, with absolutely no modification. We call it SimOS, even if it will not become usable before several years of additional work. - -.. The old documentation of the obsolete MSG replay module was removed in -.. https://github.com/simgrid/simgrid/commit/e05361c201fb95d2b7605e59001cd0a49a489739 diff --git a/docs/source/conf.py b/docs/source/conf.py index 03d7271983..96b64bf36f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -26,17 +26,15 @@ read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' if read_the_docs_build: subprocess.call('pwd', shell=True) # should be in docs/source subprocess.call('doxygen', shell=True) - subprocess.call('javasphinx-apidoc --force -o java/ ../../src/bindings/java/org/simgrid/msg', shell=True) - subprocess.call('rm java/packages.rst', shell=True) # -- Project information ----------------------------------------------------- project = u'SimGrid' -copyright = u'2002-2022, The SimGrid Team' +copyright = u'2002-2023, The SimGrid Team' author = u'The SimGrid Team' # The short X.Y version -version = u'3.31.1' +version = u'3.35.1' # -- General configuration --------------------------------------------------- @@ -51,11 +49,11 @@ extensions = [ 'sphinx.ext.todo', 'breathe', 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', 'sphinx.ext.autosummary', + 'sphinx.ext.intersphinx', + 'sphinx.ext.mathjax', 'sphinx_tabs.tabs', 'sphinx_copybutton', - 'javasphinx', 'showfile', ] @@ -120,8 +118,6 @@ nitpick_ignore = [ ('cpp:identifier', 's4u_Semaphore'), ('cpp:identifier', 's4u_VM'), ('cpp:identifier', 's4u_VirtualMachine'), - ('cpp:identifier', 'sg_msg_Comm'), - ('cpp:identifier', 'sg_msg_Task'), ('cpp:identifier', 'simgrid'), ('cpp:identifier', 'simgrid::s4u'), ('cpp:identifier', 'simgrid::s4u::Activity_T'), @@ -129,7 +125,6 @@ nitpick_ignore = [ ('cpp:identifier', 'simgrid::s4u::Activity_T'), ('cpp:identifier', 'simgrid::s4u::this_actor'), ('cpp:identifier', 'simgrid::xbt'), - ('cpp:identifier', 'simgrid::xbt::string'), ('cpp:identifier', 'size_t'), ('cpp:identifier', 'ssize_t'), ('cpp:identifier', 'this_actor'), @@ -161,7 +156,6 @@ nitpick_ignore = [ ('cpp:identifier', 'xbt::signal'), ('cpp:identifier', 'xbt::signal'), ('cpp:identifier', 'xbt::signal'), - ('cpp:identifier', 'xbt::string'), ] # For cross-ref generation @@ -182,7 +176,7 @@ master_doc = 'index' # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. diff --git a/docs/source/img/battery_degradation.svg b/docs/source/img/battery_degradation.svg new file mode 100644 index 0000000000..432fa43288 --- /dev/null +++ b/docs/source/img/battery_degradation.svg @@ -0,0 +1,1986 @@ + + + + + + + + 2023-07-13T14:07:53.987014 + image/svg+xml + + + Matplotlib v3.7.1, https://matplotlib.org/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/img/dag.svg b/docs/source/img/dag.svg new file mode 100644 index 0000000000..58a2e07bdf --- /dev/null +++ b/docs/source/img/dag.svg @@ -0,0 +1,955 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12345678910111213141516171819202122232524 + + + + + + + + + diff --git a/docs/source/img/dag1.svg b/docs/source/img/dag1.svg new file mode 100644 index 0000000000..7a6835f5d5 --- /dev/null +++ b/docs/source/img/dag1.svg @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + t1c1c2c3 + + + + + + + + + diff --git a/docs/source/img/dag2.svg b/docs/source/img/dag2.svg new file mode 100644 index 0000000000..76111394ba --- /dev/null +++ b/docs/source/img/dag2.svg @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + t1c1c2c3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/img/design-scheduling-parallel.svg b/docs/source/img/design-scheduling-parallel.svg new file mode 100644 index 0000000000..4947e120fa --- /dev/null +++ b/docs/source/img/design-scheduling-parallel.svg @@ -0,0 +1,1231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Maestro + + +   + + Worker 1 + many + actors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Worker 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Figure: Actual execution a parallel simulation. + + + diff --git a/docs/source/img/design-scheduling-simulatedtime.svg b/docs/source/img/design-scheduling-simulatedtime.svg new file mode 100644 index 0000000000..6be34b054d --- /dev/null +++ b/docs/source/img/design-scheduling-simulatedtime.svg @@ -0,0 +1,1417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Simulation setup (kernel mode) + + + Model solving (kernel mode) + + + Context switching + + + + User code (isolated) + + + + + + + + + + + Maestro + + + + + +   + + Actor 2 + + + + + + + + Actor 3 + + + + + + + + Actor 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + request+body+answer + One simcall= + + Scheduling round: run actors, declare their activities, solve models + update timestamp + + + + + + + + + + + + + Figure: Logical view of a SimGrid simulation. + + diff --git a/docs/source/img/design-scheduling-wallclock.svg b/docs/source/img/design-scheduling-wallclock.svg new file mode 100644 index 0000000000..51a6f4490f --- /dev/null +++ b/docs/source/img/design-scheduling-wallclock.svg @@ -0,0 +1,1014 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + Actor 2 + + + + + + Actor 3 + Actor 3 + + + + + + + + + + + Actor 1 + Actor 2 + Actor 1 + + + + + + + + + + + + + + + + + + + + + + + + + Maestro + Maestro + Maestro + + + + + + + + + + + + + + + + + + + + + + Figure: Actual execution of each parts (sequential simulation). + + + diff --git a/docs/source/img/graphical-toc.svg b/docs/source/img/graphical-toc.svg index f710aa1db3..aeaf4908c7 100644 --- a/docs/source/img/graphical-toc.svg +++ b/docs/source/img/graphical-toc.svg @@ -2,21 +2,21 @@ + inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)" + sodipodi:docname="graphical-toc.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + guidetolerance="10" + inkscape:showpageshadow="0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1"> ExperimentalExperimentalSetup Profiles SimulationSimulation Model CheckingModel Checking Property + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';stroke-width:0.264583px">Property Reduction + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.46806px;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';stroke-width:0.264583px">Reduction ▸ Safety + style="font-size:4.23333px;stroke-width:0.264583px">▸ Safety ▸ Liveness + style="font-size:4.23333px;stroke-width:0.264583px">▸ Liveness ▸ Patterns + style="font-size:4.23333px;stroke-width:0.264583px">▸ Patterns Exhaustive testExhaustive test ▸ DPOR + style="font-size:4.23333px;stroke-width:0.264583px">▸ DPOR @@ -2601,10 +2601,10 @@ id="text1032-0-1" y="130.17258" x="150.47285" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;line-height:4.4979167px;font-family:'Amiri Quran Colored';-inkscape-font-specification:'Amiri Quran Colored';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93889px;line-height:4.49792px;font-family:'Amiri Quran Colored';-inkscape-font-specification:'Amiri Quran Colored';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" xml:space="preserve">▸ State @@ -2612,10 +2612,10 @@ id="text1032-0-1-8" y="134.97" x="154.33516" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93888903px;line-height:4.4979167px;font-family:'Amiri Quran Colored';-inkscape-font-specification:'Amiri Quran Colored';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93889px;line-height:4.49792px;font-family:'Amiri Quran Colored';-inkscape-font-specification:'Amiri Quran Colored';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" xml:space="preserve">Equality @@ -5346,36 +5346,30 @@ - x - + id="tspan12224">x - ← - + id="tspan12228">← - 2 - + id="tspan12232">2 @@ -5469,9 +5463,9 @@ id="text15126" y="135.22546" x="255.25545" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:6.61458302px;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-align:start;letter-spacing:-0.01322917px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222px;line-height:6.61458px;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-align:start;letter-spacing:-0.0132292px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" xml:space="preserve"> - y - + style="stroke-width:0.352778">y - ← - + style="stroke-width:0.352778">← - 1 - + style="stroke-width:0.352778">1 - send(1) - + id="tspan12232-3">send(1) - send(2) - + id="tspan12232-3-7">send(2) + inkscape:label="text1028-1-4-1-1" /> - - + id="tspan32726" /> - - + style="font-variant:normal;font-weight:normal;font-size:23.9992px;font-family:Helvetica;-inkscape-font-specification:Helvetica;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="text34358" /> Plugins + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.46806px;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';stroke-width:0.264583px">Plugins Your code ▸ Signals + style="font-size:4.23333px;stroke-width:0.264583px">▸ Signals ▸ Extensions + style="font-size:4.23333px;stroke-width:0.264583px">▸ Extensions deep inside - + + style="display:inline;opacity:0.93999999;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.35277778;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:label="ModelsBox" + transform="translate(-1.3229068,-6.6145851)" /> operations - + Counter exampleCounter example - $./my_simulator|MSG_visualization/colorize.pl - $./my_simulator[0.000] - [0.000][Tremblay:master]Got3workersand6taskstoprocess - [Tremblay:master]Got3workersand6taskstoprocess[0.000] - [0.000][Tremblay:master]Sending’Task_0’to’Jupiter’ - [Tremblay:master]Sending’Task_0’to’Jupiter’[0.148] - [0.148][Tremblay:master]Sending’Task_1’to’Fafard’ - [Tremblay:master]Sending’Task_1’to’Fafard’[0.148] - [0.148][Jupiter:worker]Processing’Task_0’ - [Jupiter:worker]Processing’Task_0’[0.347] - [0.347][Tremblay:master]Sending’Task_2’to’Ginette’ - [Tremblay:master]Sending’Task_2’to’Ginette’[0.347] - [0.347][Fafard:worker]Processing’Task_1’ - [Fafard:worker]Processing’Task_1’[0.476] - [0.476][Tremblay:master]Sending’Task_3’to’Jupiter’ - [Tremblay:master]Sending’Task_3’to’Jupiter’[0.476] - [0.476][Ginette:worker]Processing’Task_2’ - [Ginette:worker]Processing’Task_2’[0.803] - [0.803][Jupiter:worker]’Task_0’done - [Jupiter:worker]’Task_0’done[0.951] - [0.951][Tremblay:master]Sending’Task_4’to’Fafard’ - [Tremblay:master]Sending’Task_4’to’Fafard’[0.951] - [0.951][Jupiter:worker]Processing’Task_3’ - [Jupiter:worker]Processing’Task_3’[1.003] - [1.003][Fafard:worker]’Task_1’done - [Fafard:worker]’Task_1’done[1.202] - [1.202][Tremblay:master]Sending’Task_5’to’Ginette’ - [Tremblay:master]Sending’Task_5’to’Ginette’[1.202] - [1.202][Fafard:worker]Processing’Task_4’ - [Fafard:worker]Processing’Task_4’[1.507] - [1.507][Ginette:worker]’Task_2’done - [Ginette:worker]’Task_2’done[1.606] - [1.606][Jupiter:worker]’Task_3’done - [Jupiter:worker]’Task_3’done[1.635] - [1.635][Tremblay:master]Alltasksdispatched.Let’sstopworkers. - [Tremblay:master]Alltasksdispatched.Let’sstopworkers.[1.635] - [1.635][Ginette:worker]Processing’Task_5’ - [Ginette:worker]Processing’Task_5’[1.637] - [1.637][Jupiter:worker]I’mdone.Seeyou! - [Jupiter:worker]I’mdone.Seeyou![1.857] - [1.857][Fafard:worker]’Task_4’done - [Fafard:worker]’Task_4’done[1.859] - [1.859][Fafard:worker]I’mdone.Seeyou! - [Fafard:worker]I’mdone.Seeyou![2.666] - [2.666][Ginette:worker]’Task_5’done - [Ginette:worker]’Task_5’done[2.668] - [2.668][Tremblay:master]Goodbyenow! - [Tremblay:master]Goodbyenow![2.668] - [2.668][Ginette:worker]I’mdone.Seeyou! - [Ginette:worker]I’mdone.Seeyou![2.668][]Simulationtime2.66766 - + style="stroke-width:0.0891421">[2.668][]Simulationtime2.66766 Textual logsTextual logs R visualizations @@ -6159,7 +6084,7 @@ inkscape:label="CalibrBox" /> AutomaticAutomaticCalibration Config UserUserManual Routing + style="font-size:4.93889px;stroke-width:0.264583px">Routing paths + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.58611px;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';stroke-width:0.264583px">paths Abstract ActorsAbstract Actors Offline TracesOffline Traces Real MPI CodeReal MPI Code Examples + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93889px;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';stroke-width:0.264583px">Examples Reference + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93889px;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';stroke-width:0.264583px">Reference diff --git a/docs/source/img/lmm-overview.svg b/docs/source/img/lmm-overview.svg new file mode 100644 index 0000000000..b8f6bff5e0 --- /dev/null +++ b/docs/source/img/lmm-overview.svg @@ -0,0 +1,3407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 37243524524553053050664 + +++... + ⩽ + C + A + ⩽ + C + B + ⩽ + C + E + ⩽ + C + C + ⩽ + C + D + + ... + ... + ... + Activities + Actions + Constraints + work + remaining + variable + (for hostA) + (for linkB) + (for linkC) + (for linkD) + (for linkE) + Actors + Userinterface + Simulation kernel + Linear MaxMin solver + ϱ + a + A1 + 1 + ϱ + 1 + ϱ + a + B2 + 2 + ϱ + a + C2 + 2 + ϱ + a + C3 + 3 + ϱ + a + E3 + 3 + ϱ + a + D2 + 2 + ϱ + a + An + n + ϱ + 2 + ϱ + 3 + ϱ + n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 2 + 3 + n + + Simulation + + + Host + Host A + + + + + + Host + Link C + Link D + Link B + Link E + Host + + + + + + exec 1 + + + + exec n + + + comm 3 + + + + + + + + + + + + + comm 2 + + + + diff --git a/docs/source/img/plugin-energy.svg b/docs/source/img/plugin-energy.svg new file mode 100644 index 0000000000..9f18e1f5b7 --- /dev/null +++ b/docs/source/img/plugin-energy.svg @@ -0,0 +1,493 @@ + + + + + + + + + + 100 + 120 + 140 + 160 + 180 + 200 + 10 + 0 + 0 + 1 + 2 + 3 + 4 + #cores + Consumption (W) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wattage_off + + wattage_idle + + + + + + diff --git a/docs/source/index.rst b/docs/source/index.rst index 050033fd45..38445ad0c3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -5,9 +5,9 @@ The Modern Age of Computer Systems Simulation ============================================= -SimGrid is a framework to simulate distributed computer systems. It can be used -to either :ref:`assess abstract algorithms ` or to -:ref:`debug and profile real MPI applications `. +SimGrid is a framework to simulate distributed computer systems. It can be used to either :ref:`assess the performance of +abstract algorithms `, to :ref:`debug and profile real MPI applications `. To some extend, it can +also be used to :ref:`formally assess the correctness of simple algorithms and applications `. SimGrid is routinely used in studies on (data-)Grids, IaaS Clouds (:ref:`API `, :ref:`examples `), @@ -22,13 +22,13 @@ The simulation models are **fast** (`🖹 `__) **highly scalable** (`🖹 `__) while **theoretically sound and experimentally assessed** (`🖹 `__). Most of the time, SimGrid is used to predict the performance (time and energy) of a -given IT infrastructure, and it includes a prototype model checker to formally +given IT infrastructure, and it includes a prototypical model checker to formally assess these systems. Technically speaking, SimGrid is a library. It is neither a graphical interface nor a command-line simulator running user scripts. The interaction with SimGrid is done by writing programs with the exposed -functions to build your own simulator. This can be done in C/C++, Python or Java, +functions to build your own simulator. This can be done in C/C++ or Python, on Linux, Mac OSX or Windows (using the WSL). SimGrid is a Free Software distributed under the LGPL-2.1-only license. You are @@ -59,6 +59,7 @@ of every page. Bugs in the code should be reported Simulating distributed algorithms Simulating MPI applications Model-checking algorithms + Simulating DAG .. toctree:: :hidden: @@ -72,18 +73,18 @@ of every page. Bugs in the code should be reported    Release Notes Describing your application    The S4U interface +    S4U examples    The SMPI interface -    The MSG interface    The XBT toolbox Describing the simulated platform    Network topology examples    Advanced routing    XML reference    C++ platforms - The SimGrid models -    SimGrid plugins + The SimGrid models    Modeling hints -    Calibrating the models +    Calibrating the models +    SimGrid plugins Running an experiment    Configuring SimGrid    Deploying your application @@ -95,6 +96,7 @@ of every page. Bugs in the code should be reported :caption: SimGrid's Internals: Design goals + Contributor's documentation .. Cheat Sheet on the sublevels .. diff --git a/docs/source/tuto_disk/CMakeLists.txt b/docs/source/tuto_disk/CMakeLists.txt index 4cb7b1be0e..ea673f3965 100644 --- a/docs/source/tuto_disk/CMakeLists.txt +++ b/docs/source/tuto_disk/CMakeLists.txt @@ -1,7 +1,7 @@ -cmake_minimum_required(VERSION 2.8.8) +cmake_minimum_required(VERSION 2.8.12) project(tuto_disk) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/" "../../../") find_package(SimGrid REQUIRED) diff --git a/docs/source/tuto_disk/Dockerfile b/docs/source/tuto_disk/Dockerfile index dbf2671e06..582d016b98 100644 --- a/docs/source/tuto_disk/Dockerfile +++ b/docs/source/tuto_disk/Dockerfile @@ -20,7 +20,7 @@ RUN printf '%s\n' \ r-cran-plyr \ r-cran-jsonlite \ r-cran-gridextra \ -# simgrid dependencies +# SimGrid dependencies g++ \ gcc \ git \ @@ -41,7 +41,7 @@ RUN printf '%s\n' \ RUN mkdir /source && cd /source && \ git clone https://github.com/msnoigrs/ox-rst.git ox-rst.git -# compile install simgrid +# compile install SimGrid RUN cd /source && git clone --depth=1 https://framagit.org/simgrid/simgrid.git simgrid.git && \ cd simgrid.git && \ cmake -DCMAKE_INSTALL_PREFIX=/usr/ -Denable_documentation=OFF -Denable_smpi=ON -Denable_compile_optimizations=ON . && \ diff --git a/docs/source/tuto_disk/analysis.irst b/docs/source/tuto_disk/analysis.irst index 2f564afcbc..912d7bcdcb 100644 --- a/docs/source/tuto_disk/analysis.irst +++ b/docs/source/tuto_disk/analysis.irst @@ -32,8 +32,8 @@ in IO operations (Fig. 5 to 7). data for your context. - SimGrid has been in active development since the paper release in - 2015, thus the MSG and XML description used in the paper may have - evolved and may not be available anymore. + 2015, thus the XML description used in the paper may have evolved + while MSG was superseeded by S4U since then. Running this tutorial --------------------- diff --git a/docs/source/tuto_disk/analysis.org b/docs/source/tuto_disk/analysis.org index ee082ba512..01ed87cacb 100644 --- a/docs/source/tuto_disk/analysis.org +++ b/docs/source/tuto_disk/analysis.org @@ -30,8 +30,8 @@ - You must run similar experiments on your hardware to get realistic data for your context. - SimGrid has been in active development since the paper release in - 2015, thus the MSG and XML description used in the paper may have - evolved and may not be available anymore. + 2015, thus the XML description used in the paper may have evolved + while MSG was superseeded by S4U since then. *** Running this tutorial diff --git a/docs/source/tuto_disk/tuto_disk.cpp b/docs/source/tuto_disk/tuto_disk.cpp index a945024975..0f487ff4a6 100644 --- a/docs/source/tuto_disk/tuto_disk.cpp +++ b/docs/source/tuto_disk/tuto_disk.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -35,7 +35,7 @@ static void estimate_bw(const sg4::Disk* disk, int n, int n_flows, bool read) act->wait(); double elapsed_time = sg4::Engine::get_clock() - cur_time; - printf("%s,%s,%d,%d,%d,%lf\n", disk->get_cname(), read ? "read" : "write", n, n_flows, size, elapsed_time); + printf("%s,%s,%d,%d,%llu,%lf\n", disk->get_cname(), read ? "read" : "write", n, n_flows, size, elapsed_time); } static void host() @@ -60,7 +60,7 @@ class DiskNoise { std::mt19937& gen_; public: - DiskNoise(double capacity, std::mt19937& gen, const std::vector& b, const std::vector h) + DiskNoise(double capacity, std::mt19937& gen, const std::vector& b, const std::vector& h) : bw_(capacity), breaks_(b), heights_(h), gen_(gen) { } diff --git a/docs/source/tuto_mc/ndet-receive-mpi.c b/docs/source/tuto_mc/ndet-receive-mpi.c new file mode 100644 index 0000000000..4123ab9809 --- /dev/null +++ b/docs/source/tuto_mc/ndet-receive-mpi.c @@ -0,0 +1,54 @@ +/* Copyright (c) 2010-2021. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/******************** Non-deterministic message ordering *********************/ +/* Server assumes a fixed order in the reception of messages from its clients */ +/* which is incorrect because the message ordering is non-deterministic */ +/******************************************************************************/ + +#include + +int main(int argc, char **argv) +{ + int size; + int rank; + MPI_Status status; + + /* Initialize MPI */ + int err = MPI_Init(&argc, &argv); + if (err != MPI_SUCCESS) { + printf("MPI initialization failed!\n"); + exit(1); + } + + MPI_Comm_size(MPI_COMM_WORLD, &size); /* Get nr of tasks */ + MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Get id of this process */ + if (size != 4) { + printf("run this program with exactly 4 processes (-np 4)\n"); + MPI_Finalize(); + exit(0); + } + + if (rank == 0) { + int recv_buffer; + for (int i = 0; i < size - 1; i++) { + MPI_Recv(&recv_buffer, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + printf("Message received from %d\n", recv_buffer); + } + + if (recv_buffer != 3) { + printf("The last received message is not 3 but %d!\n", recv_buffer); + fflush(stdout); + abort(); + } + }else{ + MPI_Send(&rank, 1, MPI_INT, 0, 42, MPI_COMM_WORLD); + printf("Sent %d to rank 0\n", rank); + } + + MPI_Finalize(); + + return 0; +} diff --git a/docs/source/tuto_mc/ndet-receive-s4u.cpp b/docs/source/tuto_mc/ndet-receive-s4u.cpp new file mode 100644 index 0000000000..cf1aba3923 --- /dev/null +++ b/docs/source/tuto_mc/ndet-receive-s4u.cpp @@ -0,0 +1,56 @@ +/* Copyright (c) 2010-2021. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/******************** Non-deterministic message ordering *********************/ +/* Server assumes a fixed order in the reception of messages from its clients */ +/* which is incorrect because the message ordering is non-deterministic */ +/******************************************************************************/ + +#include +namespace sg4 = simgrid::s4u; + +constexpr int N = 3; + +XBT_LOG_NEW_DEFAULT_CATEGORY(example, "this example"); + +static void server() +{ + auto* mb = sg4::Mailbox::by_name("mymailbox"); + int value_got = -1; + for (int count = 0; count < N; count++) { + int *received = mb->get(); + value_got = *received; + delete received; + } + xbt_assert(value_got == 3); + + XBT_INFO("OK"); +} + +static void client(int id) +{ + auto* payload = new int(id); + XBT_INFO("Sending %d", id); + sg4::Mailbox::by_name("mymailbox")->put(payload, 10000); + XBT_INFO("Sent!"); +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + + std::string platform_file = "small_platform.xml"; + if (argc > 1) + platform_file = argv[1]; + e.load_platform(platform_file); + + sg4::Actor::create("server", sg4::Host::by_name("Tremblay"), server); + sg4::Actor::create("client", sg4::Host::by_name("Jupiter"), client, 1); + sg4::Actor::create("client", sg4::Host::by_name("Bourassa"), client, 2); + sg4::Actor::create("client", sg4::Host::by_name("Ginette"), client, 3); + + e.run(); + return 0; +} diff --git a/docs/source/tuto_network_calibration/CMakeLists.txt b/docs/source/tuto_network_calibration/CMakeLists.txt index ebcd24d441..d8a7314cc7 100644 --- a/docs/source/tuto_network_calibration/CMakeLists.txt +++ b/docs/source/tuto_network_calibration/CMakeLists.txt @@ -1,7 +1,7 @@ -cmake_minimum_required(VERSION 2.8.8) +cmake_minimum_required(VERSION 2.8.12) project(tuto_network) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/" "../../../") find_package(SimGrid REQUIRED) diff --git a/docs/source/tuto_network_calibration/Dockerfile b/docs/source/tuto_network_calibration/Dockerfile index 3bf0cb68f5..105aa7df81 100644 --- a/docs/source/tuto_network_calibration/Dockerfile +++ b/docs/source/tuto_network_calibration/Dockerfile @@ -15,7 +15,7 @@ RUN printf '%s\n' \ r-cran-dplyr \ r-cran-irkernel \ r-cran-quantreg \ -# simgrid dependencies +# SimGrid dependencies g++ \ gcc \ git \ @@ -63,7 +63,7 @@ RUN pip install --no-cache-dir --upgrade pip && \ papermill==2.3.3 \ ipywidgets==7.6.5 -# simgrid +# SimGrid RUN mkdir -p /source && cd /source && git clone --depth=1 https://framagit.org/simgrid/simgrid.git simgrid.git && \ cd simgrid.git && \ cmake -DCMAKE_INSTALL_PREFIX=/usr/ -Denable_documentation=OFF -Denable_smpi=ON -Denable_compile_optimizations=ON . && \ diff --git a/docs/source/tuto_network_calibration/Utils.cpp b/docs/source/tuto_network_calibration/Utils.cpp index 69ffef5c0f..708d40e158 100644 --- a/docs/source/tuto_network_calibration/Utils.cpp +++ b/docs/source/tuto_network_calibration/Utils.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/docs/source/tuto_network_calibration/Utils.hpp b/docs/source/tuto_network_calibration/Utils.hpp index a5c3d06ceb..8544f3ec89 100644 --- a/docs/source/tuto_network_calibration/Utils.hpp +++ b/docs/source/tuto_network_calibration/Utils.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/docs/source/tuto_network_calibration/dahu_platform_ckmeans.cpp b/docs/source/tuto_network_calibration/dahu_platform_ckmeans.cpp index d47c52154d..2ac5db27d3 100644 --- a/docs/source/tuto_network_calibration/dahu_platform_ckmeans.cpp +++ b/docs/source/tuto_network_calibration/dahu_platform_ckmeans.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,7 +8,6 @@ #include #include #include -#include #include #include namespace sg4 = simgrid::s4u; @@ -19,13 +18,13 @@ class NormalMixture : public Sampler { std::mt19937& gen_; public: - NormalMixture(std::mt19937& gen) : gen_(gen) {} + explicit NormalMixture(std::mt19937& gen) : gen_(gen) {} void append(double mean, double stddev, double prob) { mixture_.push_back(std::normal_distribution(mean, stddev)); prob_.push_back(prob); } - double sample() + double sample() override { std::discrete_distribution<> d(prob_.begin(), prob_.end()); int index = d(gen_); @@ -40,7 +39,7 @@ public: * * @param latency_base The base latency for this calibration (user-defined) * @param seg Segmentation (user-defined) - * @param size Message size (simgrid) + * @param size Message size (SimGrid) */ static double latency_factor_cb(double latency_base, const SegmentedRegression& seg, double size, const sg4::Host* /*src*/, const sg4::Host* /*dst*/, @@ -58,7 +57,7 @@ static double latency_factor_cb(double latency_base, const SegmentedRegression& * * @param bw_base The base bandwidth for this calibration (user-defined) * @param seg Segmentation (user-defined) - * @param size Message size (simgrid) + * @param size Message size (SimGrid) */ static double bw_factor_cb(double bw_base, const SegmentedRegression& seg, double size, const sg4::Host* /*src*/, const sg4::Host* /*dst*/, const std::vector& /*links*/, @@ -88,7 +87,7 @@ static SegmentedRegression read_json_file(const std::string& jsonFile, std::mt19 double max = it.second.get_child("max_x").get_value(); coefs[max] = it.second.get_child("coefficient").get_value(); auto& mixture = mixtures[max]; - if (!mixture) + if (not mixture) mixture = std::make_shared(gen); mixture->append(it.second.get_child("mean").get_value(), it.second.get_child("sd").get_value(), it.second.get_child("prob").get_value()); @@ -119,14 +118,14 @@ void load_platform(const sg4::Engine& e) static std::mt19937 gen(42); // remove it from stack, since we need it after this this load_platform function is over /* setting network factors callbacks */ - simgrid::kernel::resource::NetworkModelIntf* model = e.get_netzone_root()->get_network_model(); + auto* zone = e.get_netzone_root(); SegmentedRegression seg = read_json_file("pingpong_ckmeans.json", gen, false); - model->set_lat_factor_cb(std::bind(&latency_factor_cb, lat_base, seg, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + zone->set_latency_factor_cb(std::bind(&latency_factor_cb, lat_base, seg, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); - model->set_bw_factor_cb(std::bind(&bw_factor_cb, bw_base, seg, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + zone->set_bandwidth_factor_cb(std::bind(&bw_factor_cb, bw_base, seg, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); seg = read_json_file("send_ckmeans.json", gen); smpi_register_op_cost_callback(SmpiOperation::SEND, std::bind(&smpi_cost_cb, seg, std::placeholders::_1, @@ -138,4 +137,4 @@ void load_platform(const sg4::Engine& e) seg = read_json_file("recv_ckmeans.json", gen); smpi_register_op_cost_callback(SmpiOperation::RECV, std::bind(&smpi_cost_cb, seg, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); -} \ No newline at end of file +} diff --git a/docs/source/tuto_network_calibration/dahu_platform_dhist.cpp b/docs/source/tuto_network_calibration/dahu_platform_dhist.cpp index 38f7e75c9f..d48288bf69 100644 --- a/docs/source/tuto_network_calibration/dahu_platform_dhist.cpp +++ b/docs/source/tuto_network_calibration/dahu_platform_dhist.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,7 +8,6 @@ #include #include #include -#include #include #include namespace sg4 = simgrid::s4u; @@ -20,15 +19,15 @@ class DhistSampler : public Sampler { std::mt19937& gen_; public: - DhistSampler(bool log, std::mt19937& gen, const std::vector& b, const std::vector h) - : log_(log_), breaks_(b), heights_(h), gen_(gen) + DhistSampler(bool log, std::mt19937& gen, const std::vector& b, const std::vector& h) + : log_(log), breaks_(b), heights_(h), gen_(gen) { } - double sample() + double sample() override { std::piecewise_constant_distribution d(breaks_.begin(), breaks_.end(), heights_.begin()); auto value = d(gen_); - if (log) + if (log_) value = std::exp(value); return value; } @@ -39,7 +38,7 @@ public: * * @param latency_base The base latency for this calibration (user-defined) * @param seg Segmentation (user-defined) - * @param size Message size (simgrid) + * @param size Message size (SimGrid) */ static double latency_factor_cb(double latency_base, const SegmentedRegression& seg, double size, const sg4::Host* /*src*/, const sg4::Host* /*dst*/, @@ -57,7 +56,7 @@ static double latency_factor_cb(double latency_base, const SegmentedRegression& * * @param bw_base The base bandwidth for this calibration (user-defined) * @param seg Segmentation (user-defined) - * @param size Message size (simgrid) + * @param size Message size (SimGrid) */ static double bw_factor_cb(double bw_base, const SegmentedRegression& seg, double size, const sg4::Host* /*src*/, const sg4::Host* /*dst*/, const std::vector& /*links*/, @@ -125,13 +124,13 @@ void load_platform(const sg4::Engine& e) static std::mt19937 gen(42); // remove it from stack, since we need it after this this load_platform function is over /* setting network factors callbacks */ - simgrid::kernel::resource::NetworkModelIntf* model = e.get_netzone_root()->get_network_model(); - SegmentedRegression seg = read_json_file("pingpong_dhist.json", gen, false); - model->set_lat_factor_cb(std::bind(&latency_factor_cb, lat_base, seg, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + auto* zone = e.get_netzone_root(); + SegmentedRegression seg = read_json_file("pingpong_dhist.json", gen, false); + zone->set_latency_factor_cb(std::bind(&latency_factor_cb, lat_base, seg, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); - model->set_bw_factor_cb(std::bind(&bw_factor_cb, bw_base, seg, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + zone->set_bandwidth_factor_cb(std::bind(&bw_factor_cb, bw_base, seg, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); seg = read_json_file("send_dhist.json", gen); smpi_register_op_cost_callback(SmpiOperation::SEND, std::bind(&smpi_cost_cb, seg, std::placeholders::_1, @@ -143,4 +142,4 @@ void load_platform(const sg4::Engine& e) seg = read_json_file("recv_dhist.json", gen); smpi_register_op_cost_callback(SmpiOperation::RECV, std::bind(&smpi_cost_cb, seg, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); -} \ No newline at end of file +} diff --git a/docs/source/tuto_network_calibration/network_calibration_tutorial.ipynb b/docs/source/tuto_network_calibration/network_calibration_tutorial.ipynb index bac5f7507d..7b77c0edbe 100644 --- a/docs/source/tuto_network_calibration/network_calibration_tutorial.ipynb +++ b/docs/source/tuto_network_calibration/network_calibration_tutorial.ipynb @@ -6733,7 +6733,7 @@ "import json\n", "\n", "def plot_compare(df):\n", - " \"\"\" Auxiliary function to compare simgrid and reality \"\"\"\n", + " \"\"\" Auxiliary function to compare SimGrid and reality \"\"\"\n", " func = list(df['op'].unique())\n", " assert len(func) == 1\n", " func = func[0]\n", @@ -10154,7 +10154,7 @@ "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/privatization' to '1'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/np' to '2'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/hostfile' to '/tmp/host.txt'\n", - "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'\n", + "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'precision/timing' to '1e-9'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/simulate-computation' to '0'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/display-timing' to 'yes'\n", @@ -10246,7 +10246,7 @@ "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/privatization' to '1'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/np' to '2'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/hostfile' to '/tmp/host.txt'\n", - "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9'\n", + "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'precision/timing' to '1e-9'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/simulate-computation' to '0'\n", "[0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/display-timing' to 'yes'\n", @@ -10656,7 +10656,7 @@ } ], "source": [ - "# simgrid has fewer executions than real life, keep the same amount of samples for better visualization\n", + "# SimGrid has fewer executions than real life, keep the same amount of samples for better visualization\n", "N = df_smpi_send.groupby(\"msg_size\").size().iloc[0]\n", "\n", "tmp = pandas.concat([df_send.groupby(\"msg_size\").sample(N), df_smpi_send, df_isend.groupby(\"msg_size\").sample(N), df_smpi_isend, df_recv.groupby(\"msg_size\").sample(N), df_smpi_recv, df_pingpong.groupby(\"msg_size\").sample(N), df_smpi_pingpong])\n", @@ -10948,7 +10948,7 @@ } ], "source": [ - "# simgrid has fewer executions than real life, keep the same amount of samples for better visualization\n", + "# SimGrid has fewer executions than real life, keep the same amount of samples for better visualization\n", "N = df_smpi_send.groupby(\"msg_size\").size().iloc[0]\n", "\n", "tmp = pandas.concat([df_send.groupby(\"msg_size\").sample(N), df_smpi_send, df_isend.groupby(\"msg_size\").sample(N), df_smpi_isend, df_recv.groupby(\"msg_size\").sample(N), df_smpi_recv, df_pingpong.groupby(\"msg_size\").sample(N), df_smpi_pingpong])\n", diff --git a/docs/source/tuto_network_calibration/network_calibration_tutorial.rst b/docs/source/tuto_network_calibration/network_calibration_tutorial.rst index 566b78f357..7a3d02de8d 100644 --- a/docs/source/tuto_network_calibration/network_calibration_tutorial.rst +++ b/docs/source/tuto_network_calibration/network_calibration_tutorial.rst @@ -6,18 +6,20 @@ the performance of MPI operations in a Grid’5000 cluster. However, the same approach can be performed to calibrate any other environment. This tutorial is the result of the effort from many people along the years. -Specially, it is based on Tom Cornebize’s Phd thesis -(https://tel.archives-ouvertes.fr/tel-03328956). +Specially, it is based on Tom Cornebize’s Phd thesis (https://tel.archives-ouvertes.fr/tel-03328956). You can execute the notebook `network_calibration_tutorial.ipynb `_) by yourself using the docker image available at: `Dockerfile `_. For that, run the -following commands in the tutorial folder inside simgrid's code source (``docs/source/tuto_network_calibration``): +following commands in the tutorial folder inside SimGrid's code source (``docs/source/tuto_network_calibration``): .. code-block:: docker build -t tuto_network . docker run -p 8888:8888 tuto_network +Please also refer to https://framagit.org/simgrid/platform-calibration/ for more complete information. + + 0. Introduction =============== @@ -644,7 +646,7 @@ The execution is similar for both modes. The only change is the platform library [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/privatization' to '1' [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/np' to '2' [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/hostfile' to '/tmp/host.txt' - [0.000000] [xbt_cfg/INFO] Configuration change: Set 'surf/precision' to '1e-9' + [0.000000] [xbt_cfg/INFO] Configuration change: Set 'precision/work-amount' to '1e-9' [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI' [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/simulate-computation' to '0' [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/display-timing' to 'yes' diff --git a/docs/source/tuto_s4u/draw_gantt.R b/docs/source/tuto_s4u/draw_gantt.R index ecc2cc4526..e412cd494a 100644 --- a/docs/source/tuto_s4u/draw_gantt.R +++ b/docs/source/tuto_s4u/draw_gantt.R @@ -6,7 +6,7 @@ library(pajengr) # Load and relabel the data df = pajeng_read(args[1]) df$state %>% - # rename some columns to use simgrid terminology + # rename some columns to use SimGrid terminology rename(Actor = Container, State = Value) %>% # do the plot diff --git a/docs/source/tuto_s4u/master-workers-lab1.cpp b/docs/source/tuto_s4u/master-workers-lab1.cpp index 7b6fbb67cb..5f9808538a 100644 --- a/docs/source/tuto_s4u/master-workers-lab1.cpp +++ b/docs/source/tuto_s4u/master-workers-lab1.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -29,9 +29,9 @@ static void master(std::vector args) for (int i = 0; i < tasks_count; i++) { /* For each task to be executed: */ /* - Select a worker in a round-robin way */ - std::string worker_rank = std::to_string(i % workers_count); - std::string mailbox_name = std::string("worker-") + worker_rank; - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + std::string worker_rank = std::to_string(i % workers_count); + std::string mailbox_name = "worker-" + worker_rank; + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); /* - Send the computation cost to that worker */ XBT_INFO("Sending task %d of %ld to mailbox '%s'", i, tasks_count, mailbox->get_cname()); @@ -41,8 +41,8 @@ static void master(std::vector args) XBT_INFO("All tasks have been dispatched. Request all workers to stop."); for (int i = 0; i < workers_count; i++) { /* The workers stop when receiving a negative compute_cost */ - std::string mailbox_name = std::string("worker-") + std::to_string(i); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + std::string mailbox_name = "worker-" + std::to_string(i); + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); mailbox->put(new double(-1.0), 0); } @@ -53,8 +53,8 @@ static void worker(std::vector args) xbt_assert(args.size() == 2, "The worker expects a single argument"); long id = std::stol(args[1]); - const std::string mailbox_name = std::string("worker-") + std::to_string(id); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + const std::string mailbox_name = "worker-" + std::to_string(id); + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); double compute_cost; do { diff --git a/docs/source/tuto_s4u/master-workers-lab1.py b/docs/source/tuto_s4u/master-workers-lab1.py index 26216a67ff..60229123d8 100644 --- a/docs/source/tuto_s4u/master-workers-lab1.py +++ b/docs/source/tuto_s4u/master-workers-lab1.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/docs/source/tuto_s4u/master-workers-lab2.cpp b/docs/source/tuto_s4u/master-workers-lab2.cpp index 231a705eca..7f8b3943ee 100644 --- a/docs/source/tuto_s4u/master-workers-lab2.cpp +++ b/docs/source/tuto_s4u/master-workers-lab2.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -18,8 +18,8 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_masterworker, "Messages specific for this e static void worker() { - const std::string mailbox_name = std::string("worker-") + std::to_string(simgrid::s4u::this_actor::get_pid()); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + const std::string mailbox_name = "worker-" + std::to_string(simgrid::s4u::this_actor::get_pid()); + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); double compute_cost; do { @@ -45,7 +45,7 @@ static void master(std::vector args) std::vector actors; for (auto* host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) { - simgrid::s4u::ActorPtr act = simgrid::s4u::Actor::create(std::string("Worker-") + host->get_name(), host, worker); + simgrid::s4u::ActorPtr act = simgrid::s4u::Actor::create("Worker-" + host->get_name(), host, worker); actors.push_back(act); } @@ -53,9 +53,9 @@ static void master(std::vector args) for (int i = 0; i < tasks_count; i++) { /* For each task to be executed: */ /* - Select a worker in a round-robin way */ - aid_t worker_pid = actors.at(i % actors.size())->get_pid(); - std::string mailbox_name = std::string("worker-") + std::to_string(worker_pid); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + aid_t worker_pid = actors.at(i % actors.size())->get_pid(); + std::string mailbox_name = "worker-" + std::to_string(worker_pid); + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); /* - Send the computation cost to that worker */ XBT_INFO("Sending task %d of %ld to mailbox '%s'", i, tasks_count, mailbox->get_cname()); @@ -65,8 +65,8 @@ static void master(std::vector args) XBT_INFO("All tasks have been dispatched. Request all workers to stop."); for (unsigned long i = 0; i < actors.size(); i++) { /* The workers stop when receiving a negative compute_cost */ - std::string mailbox_name = std::string("worker-") + std::to_string(actors.at(i)->get_pid()); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + std::string mailbox_name = "worker-" + std::to_string(actors.at(i)->get_pid()); + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); mailbox->put(new double(-1.0), 0); } diff --git a/docs/source/tuto_s4u/master-workers-lab2.py b/docs/source/tuto_s4u/master-workers-lab2.py index 09b7b20dbb..c0a5d18f2d 100644 --- a/docs/source/tuto_s4u/master-workers-lab2.py +++ b/docs/source/tuto_s4u/master-workers-lab2.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/docs/source/tuto_s4u/master-workers-lab3.cpp b/docs/source/tuto_s4u/master-workers-lab3.cpp index 2f10f58f0f..653546ef26 100644 --- a/docs/source/tuto_s4u/master-workers-lab3.cpp +++ b/docs/source/tuto_s4u/master-workers-lab3.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -18,8 +18,8 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_masterworker, "Messages specific for this e static void worker() { - const std::string mailbox_name = std::string("worker-") + std::to_string(simgrid::s4u::this_actor::get_pid()); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + const std::string mailbox_name = "worker-" + std::to_string(simgrid::s4u::this_actor::get_pid()); + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); while (true) { // Master forcefully kills the workers by the end of the simulation double* msg = mailbox->get(); @@ -45,16 +45,16 @@ static void master(std::vector args) XBT_INFO("Asked to run for %.1f seconds", simulation_duration); for (auto* host : e->get_all_hosts()) { - simgrid::s4u::ActorPtr act = simgrid::s4u::Actor::create(std::string("Worker-") + host->get_name(), host, worker); + simgrid::s4u::ActorPtr act = simgrid::s4u::Actor::create("Worker-" + host->get_name(), host, worker); actors.push_back(act); } int task_id = 0; while (simgrid::s4u::Engine::get_clock() < simulation_duration) { /* For each task: */ /* - Select a worker in a round-robin way */ - aid_t worker_pid = actors.at(task_id % actors.size())->get_pid(); - std::string mailbox_name = std::string("worker-") + std::to_string(worker_pid); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + aid_t worker_pid = actors.at(task_id % actors.size())->get_pid(); + std::string mailbox_name = "worker-" + std::to_string(worker_pid); + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); /* - Send the computation cost to that worker */ if (task_id % 100 == 0) diff --git a/docs/source/tuto_s4u/master-workers-lab4.cpp b/docs/source/tuto_s4u/master-workers-lab4.cpp index 3cc8ff2657..74195e05a6 100644 --- a/docs/source/tuto_s4u/master-workers-lab4.cpp +++ b/docs/source/tuto_s4u/master-workers-lab4.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -18,8 +18,8 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_masterworker, "Messages specific for this e static void worker(std::string category) { - const std::string mailbox_name = std::string("worker-") + std::to_string(simgrid::s4u::this_actor::get_pid()); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + const std::string mailbox_name = "worker-" + std::to_string(simgrid::s4u::this_actor::get_pid()); + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); while (true) { // Master forcefully kills the workers by the end of the simulation double* msg = mailbox->get(); @@ -45,22 +45,21 @@ static void master(std::vector args) std::vector actors; simgrid::s4u::Engine* e = simgrid::s4u::Engine::get_instance(); - std::string my_name = std::string("master-") + std::to_string(simgrid::s4u::this_actor::get_pid()); + std::string my_name = "master-" + std::to_string(simgrid::s4u::this_actor::get_pid()); XBT_INFO("Asked to run for %.1f seconds", simulation_duration); for (auto* host : e->get_all_hosts()) { - simgrid::s4u::ActorPtr act = - simgrid::s4u::Actor::create(std::string("Worker-") + host->get_name(), host, worker, my_name); + simgrid::s4u::ActorPtr act = simgrid::s4u::Actor::create("Worker-" + host->get_name(), host, worker, my_name); actors.push_back(act); } int task_id = 0; while (simgrid::s4u::Engine::get_clock() < simulation_duration) { /* For each task: */ /* - Select a worker in a round-robin way */ - aid_t worker_pid = actors.at(task_id % actors.size())->get_pid(); - std::string mailbox_name = std::string("worker-") + std::to_string(worker_pid); - simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); + aid_t worker_pid = actors.at(task_id % actors.size())->get_pid(); + std::string mailbox_name = "worker-" + std::to_string(worker_pid); + simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name); /* - Send the computation cost to that worker */ XBT_DEBUG("Sending task %d to mailbox '%s'", task_id, mailbox->get_cname()); diff --git a/docs/source/tuto_smpi/gemm_mpi.cpp b/docs/source/tuto_smpi/gemm_mpi.cpp index c9966ac944..ab9920b6c8 100644 --- a/docs/source/tuto_smpi/gemm_mpi.cpp +++ b/docs/source/tuto_smpi/gemm_mpi.cpp @@ -1,10 +1,10 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "stdio.h" -#include "mpi.h" +#include +#include const int size = 3000; @@ -27,7 +27,7 @@ int main(int argc, char* argv[]) { int rank, nproc; int istart, iend; - double start, end; + // double start, end; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nproc); diff --git a/docs/source/tuto_smpi/roundtrip.c b/docs/source/tuto_smpi/roundtrip.c index eb0cacc2bf..fa6711f3c1 100644 --- a/docs/source/tuto_smpi/roundtrip.c +++ b/docs/source/tuto_smpi/roundtrip.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/README.rst b/examples/README.rst index 9fe8b5f8cc..9b22d37a1c 100644 --- a/examples/README.rst +++ b/examples/README.rst @@ -1,12 +1,12 @@ -.. S4U (Simgrid for you) is the modern interface of SimGrid, which new project should use. +.. S4U (SimGrid for you) is the modern interface of SimGrid, which new project should use. .. .. This file follows the ReStructured syntax to be included in the .. documentation, but it should remain readable directly. .. _s4u_examples: -Examples -******** +S4U Examples +############ SimGrid comes with an extensive set of examples, documented on this page. Most of them only demonstrate one single feature, with some @@ -25,17 +25,17 @@ to simulate. .. _s4u_ex_actors: -=========================== +*************************** Actors: the Active Entities -=========================== +*************************** Starting and Stopping Actors ----------------------------- +============================ .. _s4u_ex_actors_create: Creating actors -^^^^^^^^^^^^^^^ +--------------- Most actors are started from the deployment XML file because this is a :ref:`better scientific habit `, but you can @@ -71,7 +71,7 @@ also create them directly from your code. The following file is used in both C++ and Python. Reacting to actors' end -^^^^^^^^^^^^^^^^^^^^^^^ +----------------------- You can attach callbacks to the end of actors. There are several ways of doing so, depending on whether you want to attach your callback to a given actor and on how you define the end of a @@ -95,7 +95,7 @@ actors. :cpp:func:`sg_actor_on_exit()`. Killing actors -^^^^^^^^^^^^^^ +-------------- Actors can forcefully stop other actors. @@ -116,7 +116,7 @@ Actors can forcefully stop other actors. See also :cpp:func:`sg_actor_kill`, :cpp:func:`sg_actor_kill_all`, :cpp:func:`sg_actor_exit`, :cpp:func:`sg_actor_on_exit`. Actors' life cycle from XML_reference -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------------------- You can specify a start time and a kill time in the deployment file. @@ -139,7 +139,7 @@ You can specify a start time and a kill time in the deployment file. This file is not really interesting: the important matter is in the XML file. Daemon actors -^^^^^^^^^^^^^ +------------- Some actors may be intended to simulate daemons that run in the background. This example shows how to transform a regular @@ -160,7 +160,7 @@ actor into a daemon that will be automatically killed once the simulation is ove See also :cpp:func:`sg_actor_daemonize` and :cpp:func:`sg_actor_is_daemon`. Specifying the stack size -^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------- The stack size can be specified by default on the command line, globally by changing the configuration with :cpp:func:`simgrid::s4u::Engine::set_config`, @@ -173,14 +173,14 @@ or for a specific actor using :cpp:func:`simgrid::s4u::Actor::set_stacksize` bef .. example-tab:: examples/c/actor-stacksize/actor-stacksize.c Inter-Actors Interactions -------------------------- +========================= See also the examples on :ref:`inter-actors communications ` and the ones on :ref:`classical synchronization objects `. Suspending/resuming Actors -^^^^^^^^^^^^^^^^^^^^^^^^^^ +-------------------------- Actors can be suspended and resumed during their executions. @@ -204,7 +204,7 @@ Actors can be suspended and resumed during their executions. :cpp:func:`sg_actor_is_suspended()`. Migrating Actors -^^^^^^^^^^^^^^^^ +---------------- Actors can move or be moved from a host to another very easily. It amounts to setting them on a new host. @@ -223,7 +223,7 @@ Actors can move or be moved from a host to another very easily. It amounts to se See also :cpp:func:`sg_actor_set_host()`. Waiting for the termination of an actor (joining on it) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------------------------------------- You can block the current actor until the end of another actor. @@ -242,7 +242,7 @@ You can block the current actor until the end of another actor. See also :cpp:func:`sg_actor_join`. Yielding to other actors -^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------ The ```yield()``` function interrupts the execution of the current actor, leaving a chance to the other actors that are ready to run @@ -263,7 +263,7 @@ at this timestamp. See also :cpp:func:`sg_actor_yield()`. Traces Replay as a Workload ---------------------------- +=========================== This section details how to run trace-driven simulations. It is very handy when you want to test an algorithm or protocol that only reacts @@ -282,7 +282,7 @@ with, but the second is more efficient on very large traces. Check also the tesh files in the example directories for details. Communication replay -^^^^^^^^^^^^^^^^^^^^ +-------------------- Presents a set of event handlers reproducing classical communication primitives (asynchronous send/receive at the moment). @@ -291,7 +291,7 @@ Presents a set of event handlers reproducing classical communication primitives .. example-tab:: examples/cpp/replay-comm/s4u-replay-comm.cpp I/O replay -^^^^^^^^^^ +---------- Presents a set of event handlers reproducing classical I/O primitives (open, read, close). @@ -299,17 +299,17 @@ Presents a set of event handlers reproducing classical I/O primitives (open, rea .. example-tab:: examples/cpp/replay-io/s4u-replay-io.cpp -========================== +************************** Activities: what Actors do -========================== +************************** .. _s4u_ex_communication: Communications on the Network ------------------------------ +============================= Basic communications -^^^^^^^^^^^^^^^^^^^^ +-------------------- This simple example just sends one message back and forth. The tesh file laying in the directory shows how to start the simulator binary, highlighting how to pass options to @@ -323,11 +323,10 @@ the simulators (as detailed in Section :ref:`options`). .. example-tab:: examples/c/comm-pingpong/comm-pingpong.c - Basic asynchronous communications -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +--------------------------------- -Illustrates how to have non-blocking communications, that are communications running in the background leaving the process +Illustrates how to have non-blocking communications, that are communications running in the background leaving the process free to do something else during their completion. .. tabs:: @@ -345,8 +344,10 @@ free to do something else during their completion. See also :cpp:func:`sg_mailbox_put_async()` and :cpp:func:`sg_comm_wait()`. Waiting for communications with timeouts -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +---------------------------------------- +There is two ways of declaring timeouts in SimGrid. ``waituntil`` let you specify the deadline until when you want to wait, while +``waitfor`` expects the maximal wait duration. This example is very similar to the previous one, simply adding how to declare timeouts when waiting on asynchronous communication. .. tabs:: @@ -355,12 +356,31 @@ This example is very similar to the previous one, simply adding how to declare t See also :cpp:func:`simgrid::s4u::Activity::wait_until()` and :cpp:func:`simgrid::s4u::Comm::wait_for()`. - .. example-tab:: examples/python/comm-waitfor/comm-waitfor.py + .. example-tab:: examples/python/comm-waituntil/comm-waituntil.py + + See also :py:func:`simgrid.Comm.wait_until()` + +.. _s4u_ex_mailbox_ready: + +Checking for incoming communications +------------------------------------ + +This example uses ``Mailbox.ready()`` to check for completed communications. When this function returns true, then at least a message +is arrived, so you know that ``Mailbox.get()`` will complete immediately. This is thus another way toward asynchronous communications. + +.. tabs:: + + .. example-tab:: examples/cpp/comm-ready/s4u-comm-ready.cpp + + See also :cpp:func:`simgrid::s4u::Mailbox::ready()`. + + .. example-tab:: examples/python/comm-ready/comm-ready.py + + See also :py:func:`simgrid.Mailbox.ready()` - See also :py:func:`simgrid.Comm.wait_for()` and :py:func:`simgrid.Comm.wait_any_for()` Suspending communications -^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------- The ``suspend()`` and ``resume()`` functions block the progression of a given communication for a while and then unblock it. ``is_suspended()`` returns whether that activity is currently blocked or not. @@ -375,69 +395,51 @@ The ``suspend()`` and ``resume()`` functions block the progression of a given co .. example-tab:: examples/python/comm-suspend/comm-suspend.py - See also :py:func:`simgrid.Comm::suspend()` and + See also :py:func:`simgrid.Comm.suspend()` and :py:func:`simgrid.Comm.resume()`. -Waiting for all communications in a set -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The ``wait_all()`` function is useful when you want to block until all activities in a given set have been completed. - -.. tabs:: - - .. example-tab:: examples/cpp/comm-waitall/s4u-comm-waitall.cpp - - See also :cpp:func:`simgrid::s4u::Comm::wait_all()`. +.. _s4u_ex_comm_failure: - .. example-tab:: examples/python/comm-waitall/comm-waitall.py - - See also :py:func:`simgrid.Comm.wait_all()`. - - .. example-tab:: examples/c/comm-waitall/comm-waitall.c - - See also :cpp:func:`sg_comm_wait_all()`. +Dealing with network failures +----------------------------- -Waiting for the first completed communication in a set -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The ``wait_any()`` blocks until one activity of the set completes, no matter which terminates first. +This examples shows how to survive to network exceptions that occurs when a link is turned off, or when the actor with whom +you communicate fails because its host is turned off. In this case, any blocking operation such as ``put``, ``get`` or +``wait`` will raise an exception that you can catch and react to. See also :ref:`howto_churn`, +:ref:`this example ` on how to attach a state profile to hosts and +:ref:`that example ` on how to react to host failures. .. tabs:: - .. example-tab:: examples/cpp/comm-waitany/s4u-comm-waitany.cpp - - See also :cpp:func:`simgrid::s4u::Comm::wait_any()`. - - .. example-tab:: examples/python/comm-waitany/comm-waitany.py - - See also :py:func:`simgrid.Comm.wait_any()`. + .. example-tab:: examples/cpp/comm-failure/s4u-comm-failure.cpp - .. example-tab:: examples/c/comm-waitany/comm-waitany.c + .. example-tab:: examples/python/comm-failure/comm-failure.py - See also :cpp:func:`sg_comm_wait_any`. +.. _s4u_ex_comm_host2host: -Testing whether at least one communication completed -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Direct host-to-host communication +--------------------------------- -The ``test_any()`` returns whether at least one activity of the set has completed, or -1. +This example demonstrates the direct communication mechanism, that allows to send data from one host to another without +relying on the mailbox mechanism. .. tabs:: - .. example-tab:: examples/cpp/comm-testany/s4u-comm-testany.cpp + .. example-tab:: examples/cpp/comm-host2host/s4u-comm-host2host.cpp - See also :cpp:func:`simgrid::s4u::Comm::test_any()`. + See also :cpp:func:`simgrid::s4u::Comm::sendto_init()` and :cpp:func:`simgrid::s4u::Comm::sendto_async()`. - .. example-tab:: examples/python/comm-testany/comm-testany.py + .. example-tab:: examples/python/comm-host2host/comm-host2host.py - See also :py:func:`simgrid.Comm.test_any()`. + See also :py:func:`simgrid.Comm.sendto_init()` and :py:func:`simgrid.Comm.sendto_async()`. .. _s4u_ex_execution: Executions on the CPU ---------------------- +===================== Basic execution -^^^^^^^^^^^^^^^ +--------------- The computations done in your program are not reported to the simulated world unless you explicitly request the simulator to pause @@ -462,7 +464,7 @@ get more resources. and :cpp:func:`void sg_actor_execute_with_priority(double, double)`. Asynchronous execution -^^^^^^^^^^^^^^^^^^^^^^ +---------------------- You can start asynchronous executions, just like you would fire background threads. @@ -499,9 +501,10 @@ You can start asynchronous executions, just like you would fire background threa :cpp:func:`sg_exec_cancel()`, Remote execution -^^^^^^^^^^^^^^^^ +---------------- You can start executions on remote hosts, or even change the host on which they occur during their execution. +This is naturally not very realistic, but it's something handy to have. .. tabs:: @@ -520,7 +523,7 @@ You can start executions on remote hosts, or even change the host on which they .. _s4u_ex_ptasks: Parallel executions -^^^^^^^^^^^^^^^^^^^ +------------------- These objects are convenient abstractions of parallel computational kernels that span over several machines, such as a @@ -540,8 +543,40 @@ This allows simulating malleable tasks. See also :cpp:func:`simgrid::s4u::this_actor::parallel_execute()`. + .. example-tab:: examples/python/exec-ptask/exec-ptask.py + + See also :ref:`simgrid.this_actor.parallel_execute()` + +Ptasks play well with the host energy plugin, as shown in this example. +There is not much new compared to the above ptask example or the +:ref:`examples about energy `. It just works. + +.. tabs:: + + .. example-tab:: examples/cpp/energy-exec-ptask/s4u-energy-exec-ptask.cpp + + .. example-tab:: examples/c/energy-exec-ptask/energy-exec-ptask.c + +.. _s4u_ex_exec_failure: + +Dealing with host failures +-------------------------- + +This examples shows how to survive to host failure exceptions that occur when an host is turned off. The actors do not get notified when the host +on which they run is turned off: they are just terminated in this case, and their ``on_exit()`` callback gets executed. For remote executions on +failing hosts however, any blocking operation such as ``exec`` or ``wait`` will raise an exception that you can catch and react to. See also +:ref:`howto_churn`, +:ref:`this example ` on how to attach a state profile to hosts, and +:ref:`that example ` on how to react to network failures. + +.. tabs:: + + .. example-tab:: examples/cpp/exec-failure/s4u-exec-failure.cpp + +.. _s4u_ex_dvfs: + DVFS and pstates -^^^^^^^^^^^^^^^^ +---------------- This example shows how to define a set of pstates in the XML. The current pstate of a host can then be accessed and changed from the program. @@ -562,17 +597,21 @@ of a host can then be accessed and changed from the program. .. example-tab:: examples/platforms/energy_platform.xml + The important parts are in the :ref:`pf_tag_host` tag. The ``pstate`` attribute is the initial pstate while the ``speed`` attribute must + be a comma-separated list of values: the speed at each pstate. This platform file also describes the ``wattage_per_state`` and + ``wattage_off`` properties, that are used by the :ref:`plugin_host_energy` plugin. + .. _s4u_ex_disk_io: I/O on Disks and Files ----------------------- +====================== SimGrid provides two levels of abstraction to interact with the simulated disks. At the simplest level, you simply create read and write actions on the disk resources. Access to raw disk devices -^^^^^^^^^^^^^^^^^^^^^^^^^^ +-------------------------- This example illustrates how to simply read and write data on a simulated disk resource. @@ -586,8 +625,17 @@ This example illustrates how to simply read and write data on a simulated disk r This shows how to declare disks in XML. +Asynchronous raw accesses +------------------------- + +As most other activities, raw IO accesses can be used asynchronously, as illustrated in this example. + +.. tabs:: + + .. example-tab:: examples/cpp/io-async/s4u-io-async.cpp + Filesystem plugin -^^^^^^^^^^^^^^^^^ +----------------- The FileSystem plugin provides a more detailed view, with the classical operations over files: open, move, unlink, and of course, @@ -602,6 +650,8 @@ result in short reads and short writes, as in reality. .. example-tab:: examples/cpp/io-file-system/s4u-io-file-system.cpp + .. example-tab:: examples/c/io-file-system/io-file-system.c + - **Remote I/O:** I/O operations on files can also be done remotely, i.e. when the accessed disk is not mounted on the caller's host. @@ -612,13 +662,213 @@ result in short reads and short writes, as in reality. .. example-tab:: examples/c/io-file-remote/io-file-remote.c +.. _s4u_ex_activityset: + +Bags of activities +================== + +Sometimes, you want to block on a set of activities, getting unblocked when any activity of the set unblocks, or waiting for the +completion of all activities in the set. This is where the ActivitySet become useful. + +Waiting for all activities in a set +----------------------------------- + +The ``wait_all()`` function is useful when you want to block until all activities in a given set have been completed. + +.. tabs:: + + .. example-tab:: examples/cpp/activityset-waitall/s4u-activityset-waitall.cpp + + See also :cpp:func:`simgrid::s4u::ActivitySet::wait_all()`. + + .. example-tab:: examples/python/activityset-waitall/activityset-waitall.py + + See also :py:func:`simgrid.ActivitySet.wait_all()`. + + .. example-tab:: examples/c/activityset-waitall/activityset-waitall.c + + See also :cpp:func:`sg_activity_set_wait_all()`. + +Waiting for all activities in a set (with timeout) +-------------------------------------------------- + +The ``wait_all_for()`` function is very similar to ``wait_all()`` but allows to specify a timeout. + +.. tabs:: + + .. example-tab:: examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.cpp + + See also :cpp:func:`simgrid::s4u::ActivitySet::wait_all_for()`. + + .. example-tab:: examples/python/activityset-waitallfor/activityset-waitallfor.py + + See also :py:func:`simgrid.ActivitySet.wait_all_for()`. + + .. example-tab:: examples/c/activityset-waitallfor/activityset-waitallfor.c + + See also :cpp:func:`sg_activity_set_wait_all_for()`. + +Waiting for the first completed activity in a set +------------------------------------------------- + +The ``wait_any()`` blocks until one activity of the set completes, no matter which terminates first. + +.. tabs:: + + .. example-tab:: examples/cpp/activityset-waitany/s4u-activityset-waitany.cpp + + See also :cpp:func:`simgrid::s4u::ActivitySet::wait_any()`. + + .. example-tab:: examples/python/activityset-waitany/activityset-waitany.py + + See also :py:func:`simgrid.ActivitySet.wait_any()`. + + .. example-tab:: examples/c/activityset-waitany/activityset-waitany.c + + See also :cpp:func:`sg_activity_set_wait_any`. + +Testing whether at least one activity completed +----------------------------------------------- + +The ``test_any()`` returns whether at least one activity of the set has completed. + +.. tabs:: + + .. example-tab:: examples/cpp/activityset-testany/s4u-activityset-testany.cpp + + See also :cpp:func:`simgrid::s4u::ActivitySet::test_any()`. + + .. example-tab:: examples/python/activityset-testany/activityset-testany.py + + See also :py:func:`simgrid.ActivitySet.test_any()`. + + .. example-tab:: examples/c/activityset-testany/activityset-testany.c + + See also :cpp:func:`sg_activity_set_test_any`. + +.. _s4u_ex_dag: + +Dependencies between activities +=============================== + +SimGrid makes it easy to express dependencies between activities, where a given activity cannot start until the completion of +all its predecessors. You can even have simulation not involving any actors, where the main thread (called maestro) creates and +schedules activities itself. + +Simple dependencies +------------------- + +When you declare dependencies between two activities, the dependent will not actually start until all its dependencies complete, +as shown in the following examples. The first one declare dependencies between executions while the second one declare +dependencies between communications. You could declare such dependencies between arbitrary activities. + +.. tabs:: + + .. example-tab:: examples/cpp/exec-dependent/s4u-exec-dependent.cpp + +.. tabs:: + + .. example-tab:: examples/cpp/comm-dependent/s4u-comm-dependent.cpp + +Assigning activities +-------------------- + +To actually start, an activity needs to be assigned to a given resource. This examples illustrates how an execution that is not +assigned will not actually start until being assigned. In some sense, activities' assignment can be seen as a specific +dependency that can withdraw their execution. + +.. tabs:: + + .. example-tab:: examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp + +Simple DAG of activities +------------------------ + +This example shows how to create activities from the maestro directly without relying on an actor, organize the dependencies of +activities as a DAG (direct acyclic graph), and start them. Each activity will start as soon as its dependencies are fulfilled. + +.. tabs:: + + .. example-tab:: examples/cpp/dag-simple/s4u-dag-simple.cpp + +DAG with communication +---------------------- + +This is a little example showing how add communication activities to your DAG, representing inter-task data exchanges. + +.. tabs:: + + .. example-tab:: examples/cpp/dag-comm/s4u-dag-comm.cpp + +DAG with I/O +------------ + +This is a little example showing how add I/O activities to your DAG, representing disk buffers. + +.. tabs:: + + .. example-tab:: examples/cpp/dag-io/s4u-dag-io.cpp + +Scheduling activities +--------------------- + +This example illustrates a simple scheduling algorithm, where the activities are placed on the "most adapted" host. Of course, there is many way +to determine which host is the better fit for a given activity, and this example just uses a simple algorithm. + +.. tabs:: + + .. example-tab:: examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp + +Loading DAGs from file +---------------------- + +There is currently two file formats that you can load directly in SimGrid, but writing another loader for your beloved format should not be difficult. + +.. tabs:: + + .. example-tab:: examples/cpp/dag-from-dax/s4u-dag-from-dax.cpp + + .. group-tab:: input + + .. showfile:: examples/cpp/dag-from-dax/smalldax.xml + :language: xml + +.. tabs:: + + .. example-tab:: examples/cpp/dag-from-dot/s4u-dag-from-dot.cpp + + .. group-tab:: input + + .. showfile:: examples/cpp/dag-from-dot/dag.dot + :language: xml + +Simulating a time slice +----------------------- + +When you declare activities, :cpp:func:`simgrid::s4u::Engine::run()` runs up to the point of time where an activity completes. +Sometimes, you want to give a maximal duration to simulate up to a given date at most, for example to inject a new activity at that time. +This example shows how to do it. + +.. tabs:: + + .. example-tab:: examples/cpp/engine-run-partial/s4u-engine-run-partial.cpp + +DAG and failures +---------------- + +This example shows how to deal with host or network failures while scheduling DAGs of activities. + +.. tabs:: + + .. example-tab:: examples/cpp/dag-failure/s4u-dag-failure.cpp + .. _s4u_ex_IPC: Classical synchronization objects ---------------------------------- +================================= Barrier -^^^^^^^ +------- Shows how to use :cpp:type:`simgrid::s4u::Barrier` synchronization objects. @@ -629,7 +879,7 @@ Shows how to use :cpp:type:`simgrid::s4u::Barrier` synchronization objects. .. example-tab:: examples/python/synchro-barrier/synchro-barrier.py Condition variable: basic usage -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------------- Shows how to use :cpp:type:`simgrid::s4u::ConditionVariable` synchronization objects. @@ -638,7 +888,7 @@ Shows how to use :cpp:type:`simgrid::s4u::ConditionVariable` synchronization obj .. example-tab:: examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp Condition variable: timeouts -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +---------------------------- Shows how to specify timeouts when blocking on condition variables. @@ -647,7 +897,7 @@ Shows how to specify timeouts when blocking on condition variables. .. example-tab:: examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.cpp Mutex -^^^^^ +----- Shows how to use :cpp:type:`simgrid::s4u::Mutex` synchronization objects. @@ -658,7 +908,7 @@ Shows how to use :cpp:type:`simgrid::s4u::Mutex` synchronization objects. .. example-tab:: examples/python/synchro-mutex/synchro-mutex.py Semaphore -^^^^^^^^^ +--------- Shows how to use :cpp:type:`simgrid::s4u::Semaphore` synchronization objects. @@ -666,14 +916,16 @@ Shows how to use :cpp:type:`simgrid::s4u::Semaphore` synchronization objects. .. example-tab:: examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp + .. example-tab:: examples/python/synchro-semaphore/synchro-semaphore.py + .. example-tab:: examples/c/synchro-semaphore/synchro-semaphore.c -============================= +***************************** Interacting with the Platform -============================= +***************************** User-defined properties ------------------------ +======================= You can attach arbitrary information to most platform elements from the XML file, and then interact with these values from your program. Note that the changes are not written permanently on disk, in the XML file nor anywhere else. They only last until the end of @@ -702,10 +954,10 @@ your simulation. :language: xml Element filtering ------------------ +================= Retrieving the netzones matching given criteria -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +----------------------------------------------- Shows how to filter the cluster netzones. @@ -714,7 +966,7 @@ Shows how to filter the cluster netzones. .. example-tab:: examples/cpp/routing-get-clusters/s4u-routing-get-clusters.cpp Retrieving the list of hosts matching given criteria -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +---------------------------------------------------- Shows how to filter the actors that match given criteria. @@ -723,13 +975,17 @@ Shows how to filter the actors that match given criteria. .. example-tab:: examples/cpp/engine-filtering/s4u-engine-filtering.cpp Profiles --------- +======== + +.. _s4u_ex_platform_state_profile: Specifying state profiles -^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------- Shows how to specify when the resources must be turned off and on again, and how to react to such -failures in your code. See also :ref:`howto_churn`. +failures in your code. See also :ref:`howto_churn`, +:ref:`this example ` on how to react to communication failures, and +:ref:`that example ` on how to react to host failures. .. tabs:: @@ -737,6 +993,8 @@ failures in your code. See also :ref:`howto_churn`. .. example-tab:: examples/c/platform-failures/platform-failures.c + .. example-tab:: examples/python/platform-failures/platform-failures.py + .. group-tab:: XML .. showfile:: examples/platforms/small_platform_failures.xml @@ -747,7 +1005,7 @@ failures in your code. See also :ref:`howto_churn`. .. showfile:: examples/platforms/profiles/fafard_state.profile Specifying speed profiles -^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------- Shows how to specify an external load to resources, variating their peak speed over time. @@ -768,15 +1026,39 @@ Shows how to specify an external load to resources, variating their peak speed o .. showfile:: examples/platforms/profiles/link1_latency.profile -================= +Modifying the platform +====================== + +Serializing communications +-------------------------- + +This example shows how to limit the amount of communications going through a given link. +It is very similar to the other asynchronous communication examples, but messages get serialized by the platform. +Without this call to ``Link::set_concurrency_limit(2)``, all messages would be received at the exact same timestamp since +they are initiated at the same instant and are of the same size. But with this extra configuration to the link, at most 2 +messages can travel through the link at the same time. + +.. tabs:: + + .. example-tab:: examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.cpp + + See also :cpp:func:`simgrid::s4u::Link::set_concurrency_limit()`. + + .. example-tab:: examples/python/platform-comm-serialize/platform-comm-serialize.py + + See also :py:func:`simgrid.Link.set_concurrency_limit()`. + +.. _s4u_ex_energy: + +***************** Energy Simulation -================= +***************** Setup ------ +===== Describing the energy profiles in the platform -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +---------------------------------------------- The first platform file contains the energy profile of each link and host for a wired network, which is necessary to get energy consumption predictions. The second platform file is the equivalent for a wireless network. As usual, you should not trust our example, and you should @@ -793,10 +1075,10 @@ strive to double-check that your instantiation matches your target platform. :language: xml Usage ------ +===== CPU energy consumption -^^^^^^^^^^^^^^^^^^^^^^ +---------------------- This example shows how to retrieve the amount of energy consumed by the CPU during computations, and the impact of the pstate. @@ -807,7 +1089,7 @@ This example shows how to retrieve the amount of energy consumed by the CPU duri .. example-tab:: examples/c/energy-exec/energy-exec.c Virtual machines consumption -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +---------------------------- This example is very similar to the previous one, adding VMs to the picture. @@ -818,7 +1100,7 @@ This example is very similar to the previous one, adding VMs to the picture. .. example-tab:: examples/c/energy-vm/energy-vm.c Wired network energy consumption -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-------------------------------- This example shows how to retrieve and display the energy consumed by the wired network during communications. @@ -827,7 +1109,7 @@ This example shows how to retrieve and display the energy consumed by the wired .. example-tab:: examples/cpp/energy-link/s4u-energy-link.cpp WiFi network energy consumption -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------------- This example shows how to retrieve and display the energy consumed by the wireless network during communications. @@ -836,7 +1118,7 @@ This example shows how to retrieve and display the energy consumed by the wirele .. example-tab:: examples/cpp/energy-wifi/s4u-energy-wifi.cpp Modeling the shutdown and boot of hosts -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +--------------------------------------- Simple example of a model for the energy consumption during the host boot and shutdown periods. @@ -846,9 +1128,9 @@ Simple example of a model for the energy consumption during the host boot and sh .. example-tab:: examples/cpp/energy-boot/s4u-energy-boot.cpp -======================= +*********************** Tracing and Visualizing -======================= +*********************** Tracing can be activated by various configuration options which are illustrated in these examples. See also the :ref:`full list of options related to tracing `. @@ -859,10 +1141,10 @@ The following introduces some option sets of interest that you may want to pass A full command line to see the result in the right tool (vite/FrameSoc) should be given along with some screenshots. Platform Tracing ----------------- +================ Basic example -^^^^^^^^^^^^^ +------------- This program is a toy example just loading the platform so that you can play with the platform visualization. Recommended options: ``--cfg=tracing:yes --cfg=tracing/categorized:yes`` @@ -872,7 +1154,7 @@ This program is a toy example just loading the platform so that you can play wit .. example-tab:: examples/cpp/trace-platform/s4u-trace-platform.cpp Setting Categories -^^^^^^^^^^^^^^^^^^ +------------------ This example declares several tracing categories that are used to classify its tasks. When the program is executed, the tracing mechanism @@ -885,7 +1167,7 @@ categories. Recommended options: .. example-tab:: examples/cpp/trace-categories/s4u-trace-categories.cpp Master Workers tracing -^^^^^^^^^^^^^^^^^^^^^^ +---------------------- This is an augmented version of our basic master/worker example using several tracing features. It traces resource usage, sorted out in several @@ -899,7 +1181,7 @@ options: ``--cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes`` .. example-tab:: examples/python/app-masterworkers/app-masterworkers.py Process migration tracing -^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------- This version is enhanced so that the process migrations can be displayed as arrows in a Gantt-chart visualization. Recommended options to that @@ -910,21 +1192,21 @@ extend: ``--cfg=tracing:yes --cfg=tracing/actor:yes`` .. example-tab:: examples/cpp/trace-process-migration/s4u-trace-process-migration.cpp Tracing user variables ----------------------- +====================== You can also attach your own variables to any resource described in the platform file. The following examples illustrate this feature. They have to be run with the following options: ``--cfg=tracing:yes --cfg=tracing/platform:yes`` Attaching variables to Hosts -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +---------------------------- .. tabs:: .. example-tab:: examples/cpp/trace-host-user-variables/s4u-trace-host-user-variables.cpp Attaching variables to Links -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +---------------------------- The tricky part is that you have to know the name of the link you want to enhance with a variable. @@ -933,7 +1215,7 @@ The tricky part is that you have to know the name of the link you want to enhanc .. example-tab:: examples/cpp/trace-link-user-variables/s4u-trace-link-user-variables.cpp Attaching variables to network routes -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------------------- It is often easier to update a given variable for all links of a given network path (identified by its source and destination hosts) instead of knowing the name of each specific link. @@ -942,17 +1224,17 @@ knowing the name of each specific link. .. example-tab:: examples/cpp/trace-route-user-variables/s4u-trace-route-user-variables.cpp -======================== +************************ Larger SimGrid Exemplars -======================== +************************ This section contains application examples that are somewhat larger than the previous examples. Classical examples ------------------- +================== Token ring -^^^^^^^^^^ +---------- Shows how to implement a classical communication pattern, where a token is exchanged along a ring to reach every participant. @@ -963,9 +1245,9 @@ Shows how to implement a classical communication pattern, where a token is excha .. example-tab:: examples/c/app-token-ring/app-token-ring.c Master Workers -^^^^^^^^^^^^^^ +-------------- -Another good old example, where one Master acto$ has a bunch of tasks to dispatch to a set of several Worker actors. +Another good old example, where one Master actor has a bunch of tasks to dispatch to a set of several Worker actors. This example is used in the :ref:`SimGrid tutorial `. .. tabs:: @@ -989,11 +1271,13 @@ This example is used in the :ref:`SimGrid tutorial `. .. showfile:: examples/c/app-masterworker/app-masterworker.c :language: cpp + .. example-tab:: examples/python/app-masterworkers/app-masterworkers.py + Data diffusion --------------- +============== Bit Torrent -^^^^^^^^^^^ +----------- Classical protocol for Peer-to-Peer data diffusion. @@ -1022,7 +1306,7 @@ Classical protocol for Peer-to-Peer data diffusion. :language: cpp Chained Send -^^^^^^^^^^^^ +------------ Data broadcast over a ring of processes. @@ -1042,10 +1326,10 @@ Data broadcast over a ring of processes. :language: c Distributed Hash Tables (DHT) ------------------------------ +============================= Chord Protocol -^^^^^^^^^^^^^^ +-------------- One of the most famous DHT protocol. @@ -1060,7 +1344,7 @@ One of the most famous DHT protocol. :language: cpp Kademlia -^^^^^^^^ +-------- Another well-known DHT protocol. @@ -1098,7 +1382,7 @@ Another well-known DHT protocol. :language: cpp Pastry -^^^^^^ +------ Yet another well-known DHT protocol. @@ -1109,10 +1393,10 @@ Yet another well-known DHT protocol. .. _s4u_ex_clouds: Simulating Clouds ------------------ +================= Cloud basics -^^^^^^^^^^^^ +------------ This example starts some computations both on PMs and VMs and migrates some VMs around. @@ -1123,7 +1407,7 @@ This example starts some computations both on PMs and VMs and migrates some VMs .. example-tab:: examples/c/cloud-simple/cloud-simple.c Migrating VMs -^^^^^^^^^^^^^ +------------- This example shows how to migrate VMs between PMs. @@ -1133,12 +1417,12 @@ This example shows how to migrate VMs between PMs. .. example-tab:: examples/c/cloud-migration/cloud-migration.c -======================= +*********************** Model-Related Examples -======================= +*********************** ns-3 as a model ---------------- +=============== This simple ping-pong example demonstrates how to use the bindings to the Network Simulator. The most interesting is probably not the C++ files since @@ -1159,7 +1443,7 @@ start a simulation in these settings. :language: xml WiFi links ----------- +========== This demonstrates how to declare a wifi zone in your platform and how to use it in your simulation. For that, you should have a link @@ -1188,9 +1472,23 @@ the first level is used. .. showfile:: examples/platforms/wifi.xml :language: xml -=============== +You can also use the **ns-3 models on your wifi networks** as follows: + +.. tabs:: + + .. example-tab:: examples/cpp/network-ns3-wifi/s4u-network-ns3-wifi.cpp + + .. group-tab:: XML + + **Platform files:** + + .. showfile:: examples/platforms/wifi_ns3.xml + :language: xml + + +*************** Plugin Examples -=============== +*************** It is possible to extend SimGrid without modifying its internals by attaching code to the existing signals and by adding extra data to the @@ -1203,7 +1501,7 @@ that you are very welcome to modify the plugins to fit your needs. It should be much easier than modifying the SimGrid kernel. Monitoring the host load ------------------------- +======================== .. tabs:: @@ -1212,21 +1510,21 @@ Monitoring the host load .. example-tab:: examples/c/plugin-host-load/plugin-host-load.c Monitoring the link load ------------------------- +======================== .. tabs:: .. example-tab:: examples/cpp/plugin-link-load/s4u-plugin-link-load.cpp -======================= +*********************** Model-Checking Examples -======================= +*********************** The model-checker can be used to exhaustively search for issues in the tested application. It must be activated at compile-time, but this mode is rather experimental in SimGrid (as of v3.25). We are working on it :) Failing assert --------------- +============== In this example, two actors send some data to a central server, which asserts that the messages are always received in the same order. This is wrong, and the model-checker correctly finds a counter-example to that assertion. diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index 25cccf5ba1..3a9d3a6127 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -4,11 +4,12 @@ foreach(x actor-create actor-daemon actor-exiting actor-join actor-kill actor-lifetime actor-migrate actor-stacksize actor-suspend actor-yield + activityset-testany activityset-waitall activityset-waitallfor activityset-waitany app-masterworker app-token-ring - comm-pingpong comm-wait comm-waitall comm-waitany + comm-pingpong comm-wait cloud-capping cloud-masterworker cloud-migration cloud-simple dht-pastry - exec-async exec-basic exec-dvfs exec-remote exec-waitany + exec-async exec-basic exec-dvfs exec-remote energy-exec energy-exec-ptask energy-vm io-disk-raw io-file-remote io-file-system platform-failures platform-properties @@ -85,8 +86,6 @@ set(xml_files ${xml_files} ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/actor-cr ${CMAKE_CURRENT_SOURCE_DIR}/comm-wait/comm-wait2_d.xml ${CMAKE_CURRENT_SOURCE_DIR}/comm-wait/comm-wait3_d.xml ${CMAKE_CURRENT_SOURCE_DIR}/comm-wait/comm-wait4_d.xml - ${CMAKE_CURRENT_SOURCE_DIR}/comm-waitall/comm-waitall_d.xml - ${CMAKE_CURRENT_SOURCE_DIR}/comm-waitany/comm-waitany_d.xml ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/dht-kademlia_d.xml ${CMAKE_CURRENT_SOURCE_DIR}/dht-pastry/dht-pastry_d.xml ${CMAKE_CURRENT_SOURCE_DIR}/io-file-remote/io-file-remote_d.xml @@ -96,11 +95,12 @@ set(xml_files ${xml_files} ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/actor-cr foreach(x actor-create actor-daemon actor-exiting actor-join actor-kill actor-lifetime actor-migrate actor-stacksize actor-suspend actor-yield + activityset-testany activityset-waitall activityset-waitallfor activityset-waitany app-bittorrent app-chainsend app-masterworker app-token-ring - comm-pingpong comm-wait comm-waitall comm-waitany + comm-pingpong comm-wait cloud-capping cloud-masterworker cloud-migration cloud-simple dht-kademlia dht-pastry - exec-async exec-basic exec-dvfs exec-remote exec-waitany + exec-async exec-basic exec-dvfs exec-remote energy-exec energy-exec-ptask energy-vm io-disk-raw io-file-remote io-file-system platform-failures platform-properties diff --git a/examples/c/activityset-testany/activityset-testany.c b/examples/c/activityset-testany/activityset-testany.c new file mode 100644 index 0000000000..b0c870214a --- /dev/null +++ b/examples/c/activityset-testany/activityset-testany.c @@ -0,0 +1,77 @@ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/activity_set.h" +#include "simgrid/actor.h" +#include "simgrid/comm.h" +#include "simgrid/engine.h" +#include "simgrid/exec.h" +#include "simgrid/host.h" +#include "simgrid/mailbox.h" + +#include "xbt/log.h" +#include "xbt/sysdep.h" + +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_testany, "Messages specific for this s4u example"); + +static void bob(int argc, char* argv[]) +{ + XBT_INFO("Create my asynchronous activities"); + sg_exec_t exec = sg_actor_exec_init(5e9); + sg_exec_start(exec); + + sg_mailbox_t mbox = sg_mailbox_by_name("mbox"); + void* payload = NULL; + sg_comm_t comm = sg_mailbox_get_async(mbox, &payload); + + sg_activity_set_t pending_activities = sg_activity_set_init(); + sg_activity_set_push(pending_activities, (sg_activity_t)exec); + sg_activity_set_push(pending_activities, (sg_activity_t)comm); + + XBT_INFO("Sleep_for a while"); + sg_actor_sleep_for(1); + + XBT_INFO("Test for completed activities"); + while (!sg_activity_set_empty(pending_activities)) { + sg_activity_t completed_one = sg_activity_set_test_any(pending_activities); + if (completed_one != NULL) { + if (sg_comm_isinstance(completed_one)) + XBT_INFO("Completed a Comm"); + if (sg_exec_isinstance(completed_one)) + XBT_INFO("Completed an Exec"); + sg_activity_unref(completed_one); + } else { + XBT_INFO("Nothing matches, test again in 0.5s"); + sg_actor_sleep_for(.5); + } + } + XBT_INFO("Last activity is complete"); + free(payload); +} + +static void alice(int argc, char* argv[]) +{ + char* payload = xbt_strdup("Message"); + XBT_INFO("Send '%s'", payload); + sg_mailbox_put(sg_mailbox_by_name("mbox"), payload, 6e8); +} + +int main(int argc, char* argv[]) +{ + simgrid_init(&argc, argv); + xbt_assert(argc > 1, + "Usage: %s platform_file\n" + "\tExample: %s hosts_with_disks.xml\n", + argv[0], argv[0]); + + simgrid_load_platform(argv[1]); + + sg_actor_create("alice", sg_host_by_name("alice"), alice, 0, NULL); + sg_actor_create("bob", sg_host_by_name("bob"), bob, 0, NULL); + + simgrid_run(); + + return 0; +} diff --git a/examples/c/activityset-testany/activityset-testany.tesh b/examples/c/activityset-testany/activityset-testany.tesh new file mode 100644 index 0000000000..6293fa309c --- /dev/null +++ b/examples/c/activityset-testany/activityset-testany.tesh @@ -0,0 +1,19 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/c-activityset-testany ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%4.2r]%e[%5a]%e%m%n" +> [0.00] [alice] Send 'Message' +> [0.00] [ bob] Create my asynchronous activities +> [0.00] [ bob] Sleep_for a while +> [1.00] [ bob] Test for completed activities +> [1.00] [ bob] Nothing matches, test again in 0.5s +> [1.50] [ bob] Nothing matches, test again in 0.5s +> [2.00] [ bob] Nothing matches, test again in 0.5s +> [2.50] [ bob] Nothing matches, test again in 0.5s +> [3.00] [ bob] Nothing matches, test again in 0.5s +> [3.50] [ bob] Nothing matches, test again in 0.5s +> [4.00] [ bob] Nothing matches, test again in 0.5s +> [4.50] [ bob] Nothing matches, test again in 0.5s +> [5.00] [ bob] Completed an Exec +> [5.00] [ bob] Nothing matches, test again in 0.5s +> [5.50] [ bob] Completed a Comm +> [5.50] [ bob] Last activity is complete diff --git a/examples/c/activityset-waitall/activityset-waitall.c b/examples/c/activityset-waitall/activityset-waitall.c new file mode 100644 index 0000000000..fe9e2710b9 --- /dev/null +++ b/examples/c/activityset-waitall/activityset-waitall.c @@ -0,0 +1,65 @@ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/activity_set.h" +#include "simgrid/actor.h" +#include "simgrid/comm.h" +#include "simgrid/engine.h" +#include "simgrid/exec.h" +#include "simgrid/host.h" +#include "simgrid/mailbox.h" + +#include "xbt/log.h" +#include "xbt/sysdep.h" + +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waitall, "Messages specific for this s4u example"); + +static void bob() +{ + XBT_INFO("Create my asynchronous activities"); + sg_exec_t exec = sg_actor_exec_init(5e9); + sg_exec_start(exec); + + sg_mailbox_t mbox = sg_mailbox_by_name("mbox"); + void* payload = NULL; + sg_comm_t comm = sg_mailbox_get_async(mbox, &payload); + + sg_activity_set_t pending_activities = sg_activity_set_init(); + sg_activity_set_push(pending_activities, (sg_activity_t)exec); + sg_activity_set_push(pending_activities, (sg_activity_t)comm); + + XBT_INFO("Wait for asynchronous activities to complete, all in one shot."); + sg_activity_set_wait_all(pending_activities); + sg_activity_unref((sg_activity_t)exec); + sg_activity_unref((sg_activity_t)comm); + + XBT_INFO("All activities are completed."); + free(payload); +} + +static void alice() +{ + char* payload = xbt_strdup("Message"); + XBT_INFO("Send '%s'", payload); + sg_mailbox_put(sg_mailbox_by_name("mbox"), payload, 6e8); +} + +int main(int argc, char* argv[]) +{ + simgrid_init(&argc, argv); + xbt_assert(argc > 1, + "Usage: %s platform_file\n" + "\tExample: %s hosts_with_disks.xml\n", + argv[0], argv[0]); + + simgrid_load_platform(argv[1]); + + sg_actor_create("alice", sg_host_by_name("alice"), alice, 0, NULL); + sg_actor_create("bob", sg_host_by_name("bob"), bob, 0, NULL); + + simgrid_run(); + + return 0; +} diff --git a/examples/c/activityset-waitall/activityset-waitall.tesh b/examples/c/activityset-waitall/activityset-waitall.tesh new file mode 100644 index 0000000000..1093563f44 --- /dev/null +++ b/examples/c/activityset-waitall/activityset-waitall.tesh @@ -0,0 +1,7 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/c-activityset-waitall ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%7.6r]%e[%5a]%e%m%n" +> [0.000000] [alice] Send 'Message' +> [0.000000] [ bob] Create my asynchronous activities +> [0.000000] [ bob] Wait for asynchronous activities to complete, all in one shot. +> [5.197828] [ bob] All activities are completed. diff --git a/examples/c/activityset-waitallfor/activityset-waitallfor.c b/examples/c/activityset-waitallfor/activityset-waitallfor.c new file mode 100644 index 0000000000..5bc1ede402 --- /dev/null +++ b/examples/c/activityset-waitallfor/activityset-waitallfor.c @@ -0,0 +1,77 @@ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/activity_set.h" +#include "simgrid/actor.h" +#include "simgrid/comm.h" +#include "simgrid/engine.h" +#include "simgrid/exec.h" +#include "simgrid/host.h" +#include "simgrid/mailbox.h" + +#include "xbt/log.h" +#include "xbt/sysdep.h" + +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waitallfor, "Messages specific for this s4u example"); + +static void bob() +{ + XBT_INFO("Create my asynchronous activities"); + sg_exec_t exec = sg_actor_exec_init(5e9); + sg_exec_start(exec); + + sg_mailbox_t mbox = sg_mailbox_by_name("mbox"); + void* payload = NULL; + sg_comm_t comm = sg_mailbox_get_async(mbox, &payload); + + sg_activity_set_t pending_activities = sg_activity_set_init(); + sg_activity_set_push(pending_activities, (sg_activity_t)exec); + sg_activity_set_push(pending_activities, (sg_activity_t)comm); + + XBT_INFO("Wait for asynchronous activities to complete"); + while (!sg_activity_set_empty(pending_activities)) { + if (!sg_activity_set_wait_all_for(pending_activities, 1)) { + XBT_INFO("Not all activities are terminated yet."); + } + + sg_activity_t completed_one = sg_activity_set_test_any(pending_activities); + while (completed_one != NULL) { + if (sg_comm_isinstance(completed_one)) + XBT_INFO("Completed a Comm"); + if (sg_exec_isinstance(completed_one)) + XBT_INFO("Completed an Exec"); + sg_activity_unref(completed_one); + completed_one = sg_activity_set_test_any(pending_activities); + } + } + + XBT_INFO("Last activity is complete"); + free(payload); +} + +static void alice() +{ + char* payload = xbt_strdup("Message"); + XBT_INFO("Send '%s'", payload); + sg_mailbox_put(sg_mailbox_by_name("mbox"), payload, 6e8); +} + +int main(int argc, char* argv[]) +{ + simgrid_init(&argc, argv); + xbt_assert(argc > 1, + "Usage: %s platform_file\n" + "\tExample: %s hosts_with_disks.xml\n", + argv[0], argv[0]); + + simgrid_load_platform(argv[1]); + + sg_actor_create("alice", sg_host_by_name("alice"), alice, 0, NULL); + sg_actor_create("bob", sg_host_by_name("bob"), bob, 0, NULL); + + simgrid_run(); + + return 0; +} diff --git a/examples/c/activityset-waitallfor/activityset-waitallfor.tesh b/examples/c/activityset-waitallfor/activityset-waitallfor.tesh new file mode 100644 index 0000000000..26a73c5d36 --- /dev/null +++ b/examples/c/activityset-waitallfor/activityset-waitallfor.tesh @@ -0,0 +1,14 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/c-activityset-waitallfor ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%7.6r]%e[%5a]%e%m%n" +> [0.000000] [alice] Send 'Message' +> [0.000000] [ bob] Create my asynchronous activities +> [0.000000] [ bob] Wait for asynchronous activities to complete +> [1.000000] [ bob] Not all activities are terminated yet. +> [2.000000] [ bob] Not all activities are terminated yet. +> [3.000000] [ bob] Not all activities are terminated yet. +> [4.000000] [ bob] Not all activities are terminated yet. +> [5.000000] [ bob] Not all activities are terminated yet. +> [5.000000] [ bob] Completed an Exec +> [5.197828] [ bob] Completed a Comm +> [5.197828] [ bob] Last activity is complete diff --git a/examples/c/activityset-waitany/activityset-waitany.c b/examples/c/activityset-waitany/activityset-waitany.c new file mode 100644 index 0000000000..3bf9b25b79 --- /dev/null +++ b/examples/c/activityset-waitany/activityset-waitany.c @@ -0,0 +1,72 @@ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/activity_set.h" +#include "simgrid/actor.h" +#include "simgrid/comm.h" +#include "simgrid/engine.h" +#include "simgrid/exec.h" +#include "simgrid/host.h" +#include "simgrid/mailbox.h" + +#include "xbt/log.h" +#include "xbt/sysdep.h" + +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waittany, "Messages specific for this s4u example"); + +static void bob() +{ + XBT_INFO("Create my asynchronous activities"); + sg_exec_t exec = sg_actor_exec_init(5e9); + sg_exec_start(exec); + + sg_mailbox_t mbox = sg_mailbox_by_name("mbox"); + void* payload = NULL; + sg_comm_t comm = sg_mailbox_get_async(mbox, &payload); + + sg_activity_set_t pending_activities = sg_activity_set_init(); + sg_activity_set_push(pending_activities, (sg_activity_t)exec); + sg_activity_set_push(pending_activities, (sg_activity_t)comm); + + XBT_INFO("Wait for asynchronous activities to complete"); + while (!sg_activity_set_empty(pending_activities)) { + + sg_activity_t completed_one = sg_activity_set_wait_any(pending_activities); + if (sg_comm_isinstance(completed_one)) + XBT_INFO("Completed a Comm"); + else if (sg_exec_isinstance(completed_one)) + XBT_INFO("Completed an Exec"); + else + xbt_die("This activity set is supposed to only contain Comm or Exec"); + sg_activity_unref(completed_one); + } + XBT_INFO("Last activity is complete"); + free(payload); +} + +static void alice() +{ + char* payload = xbt_strdup("Message"); + XBT_INFO("Send '%s'", payload); + sg_mailbox_put(sg_mailbox_by_name("mbox"), payload, 6e8); +} + +int main(int argc, char* argv[]) +{ + simgrid_init(&argc, argv); + xbt_assert(argc > 1, + "Usage: %s platform_file\n" + "\tExample: %s hosts_with_disks.xml\n", + argv[0], argv[0]); + + simgrid_load_platform(argv[1]); + + sg_actor_create("alice", sg_host_by_name("alice"), alice, 0, NULL); + sg_actor_create("bob", sg_host_by_name("bob"), bob, 0, NULL); + + simgrid_run(); + + return 0; +} diff --git a/examples/c/activityset-waitany/activityset-waitany.tesh b/examples/c/activityset-waitany/activityset-waitany.tesh new file mode 100644 index 0000000000..dac02a8716 --- /dev/null +++ b/examples/c/activityset-waitany/activityset-waitany.tesh @@ -0,0 +1,9 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/c-activityset-waitany ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%7.6r]%e[%5a]%e%m%n" +> [0.000000] [alice] Send 'Message' +> [0.000000] [ bob] Create my asynchronous activities +> [0.000000] [ bob] Wait for asynchronous activities to complete +> [5.000000] [ bob] Completed an Exec +> [5.197828] [ bob] Completed a Comm +> [5.197828] [ bob] Last activity is complete diff --git a/examples/c/actor-create/actor-create.c b/examples/c/actor-create/actor-create.c index 91303c10c1..43382e8041 100644 --- a/examples/c/actor-create/actor-create.c +++ b/examples/c/actor-create/actor-create.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/actor-daemon/actor-daemon.c b/examples/c/actor-daemon/actor-daemon.c index 4b3a2df7b8..c2e30632fe 100644 --- a/examples/c/actor-daemon/actor-daemon.c +++ b/examples/c/actor-daemon/actor-daemon.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/actor-exiting/actor-exiting.c b/examples/c/actor-exiting/actor-exiting.c index 2e7a536ed4..e32bec0be5 100644 --- a/examples/c/actor-exiting/actor-exiting.c +++ b/examples/c/actor-exiting/actor-exiting.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/actor-exiting/actor-exiting.tesh b/examples/c/actor-exiting/actor-exiting.tesh index 2fb10eec44..4bc56ef830 100644 --- a/examples/c/actor-exiting/actor-exiting.tesh +++ b/examples/c/actor-exiting/actor-exiting.tesh @@ -8,6 +8,6 @@ $ ${bindir:=.}/c-actor-exiting ${platfdir}/small_platform.xml "--log=root.fmt:[% > [ 3.000000] (maestro@) Oops! Deadlock detected, some activities are still around but will never complete. This usually happens when the user code is not perfectly clean. > [ 3.000000] (maestro@) 1 actors are still running, waiting for something. > [ 3.000000] (maestro@) Legend of the following listing: "Actor (@): " -> [ 3.000000] (maestro@) Actor 3 (C@Ginette): waiting for communication activity 0xdeadbeef () in state WAITING to finish +> [ 3.000000] (maestro@) Actor 3 (C@Ginette): waiting for communication activity 0xdeadbeef () in state WAITING to finish > [ 3.000000] (C@Ginette) I was killed! > [ 3.000000] (C@Ginette) The backtrace would be displayed here if --log=no_loc would not have been passed diff --git a/examples/c/actor-join/actor-join.c b/examples/c/actor-join/actor-join.c index 97a185bc9a..b45c7ed770 100644 --- a/examples/c/actor-join/actor-join.c +++ b/examples/c/actor-join/actor-join.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/actor-kill/actor-kill.c b/examples/c/actor-kill/actor-kill.c index 8757fa0a5f..6dd0b81681 100644 --- a/examples/c/actor-kill/actor-kill.c +++ b/examples/c/actor-kill/actor-kill.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/actor-lifetime/actor-lifetime.c b/examples/c/actor-lifetime/actor-lifetime.c index f2ba1b6293..73e033f79a 100644 --- a/examples/c/actor-lifetime/actor-lifetime.c +++ b/examples/c/actor-lifetime/actor-lifetime.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/actor-migrate/actor-migrate.c b/examples/c/actor-migrate/actor-migrate.c index 16cfd3df5e..2b6b68d6f6 100644 --- a/examples/c/actor-migrate/actor-migrate.c +++ b/examples/c/actor-migrate/actor-migrate.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/actor-stacksize/actor-stacksize.c b/examples/c/actor-stacksize/actor-stacksize.c index 37d5deaae6..cb863cc035 100644 --- a/examples/c/actor-stacksize/actor-stacksize.c +++ b/examples/c/actor-stacksize/actor-stacksize.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/actor-suspend/actor-suspend.c b/examples/c/actor-suspend/actor-suspend.c index 1ee46d3802..d38034d2a1 100644 --- a/examples/c/actor-suspend/actor-suspend.c +++ b/examples/c/actor-suspend/actor-suspend.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/actor-yield/actor-yield.c b/examples/c/actor-yield/actor-yield.c index 76ab935ceb..f2a658cadb 100644 --- a/examples/c/actor-yield/actor-yield.c +++ b/examples/c/actor-yield/actor-yield.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/app-bittorrent/app-bittorrent.c b/examples/c/app-bittorrent/app-bittorrent.c index 71aa208865..fafe793971 100644 --- a/examples/c/app-bittorrent/app-bittorrent.c +++ b/examples/c/app-bittorrent/app-bittorrent.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/app-bittorrent/app-bittorrent.h b/examples/c/app-bittorrent/app-bittorrent.h index 80f39ab449..de88d3b2a6 100644 --- a/examples/c/app-bittorrent/app-bittorrent.h +++ b/examples/c/app-bittorrent/app-bittorrent.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/app-bittorrent/bittorrent-peer.c b/examples/c/app-bittorrent/bittorrent-peer.c index 2d5275c210..55e2ed213d 100644 --- a/examples/c/app-bittorrent/bittorrent-peer.c +++ b/examples/c/app-bittorrent/bittorrent-peer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -254,7 +254,7 @@ int is_interested(const_peer_t peer, const_connection_t remote_peer) /** Indicates if the remote peer has a piece not stored by the local peer nor requested by the local peer */ int is_interested_and_free(const_peer_t peer, const_connection_t remote_peer) { - for (int i = 0; i < FILE_PIECES; i++) + for (unsigned int i = 0; i < FILE_PIECES; i++) if (peer_has_not_piece(peer, i) && connection_has_piece(remote_peer, i) && peer_is_not_downloading_piece(peer, i)) return 1; return 0; @@ -263,14 +263,14 @@ int is_interested_and_free(const_peer_t peer, const_connection_t remote_peer) /** @brief Updates the list of who has a piece from a bitfield */ void update_pieces_count_from_bitfield(const_peer_t peer, unsigned int bitfield) { - for (int i = 0; i < FILE_PIECES; i++) + for (unsigned int i = 0; i < FILE_PIECES; i++) if (bitfield & (1U << i)) peer->pieces_count[i]++; } -int count_pieces(unsigned int bitfield) +unsigned int count_pieces(unsigned int bitfield) { - int count = 0; + unsigned int count = 0; unsigned int n = bitfield; while (n) { count += n & 1U; @@ -424,7 +424,7 @@ void handle_message(peer_t peer, message_t message) break; case MESSAGE_HAVE: XBT_DEBUG("\t for piece %d", message->piece); - xbt_assert((message->piece >= 0 && message->piece < FILE_PIECES), "Wrong HAVE message received"); + xbt_assert((message->piece >= 0 && (unsigned)message->piece < FILE_PIECES), "Wrong HAVE message received"); remote_peer->bitfield = remote_peer->bitfield | (1U << message->piece); peer->pieces_count[message->piece]++; // If the piece is in our pieces, we tell the peer that we are interested. @@ -437,7 +437,7 @@ void handle_message(peer_t peer, message_t message) break; case MESSAGE_REQUEST: xbt_assert(remote_peer->interested); - xbt_assert((message->piece >= 0 && message->piece < FILE_PIECES), "Wrong request received"); + xbt_assert((message->piece >= 0 && (unsigned)message->piece < FILE_PIECES), "Wrong request received"); if (remote_peer->choked_upload == 0) { XBT_DEBUG("\t for piece %d (%d,%d)", message->piece, message->block_index, message->block_index + message->block_length); @@ -453,7 +453,7 @@ void handle_message(peer_t peer, message_t message) message->block_index + message->block_length); xbt_assert(!remote_peer->choked_download); xbt_assert(remote_peer->choked_download != 1, "Can't received a piece if I'm choked !"); - xbt_assert((message->piece >= 0 && message->piece < FILE_PIECES), "Wrong piece received"); + xbt_assert((message->piece >= 0 && (unsigned)message->piece < FILE_PIECES), "Wrong piece received"); // TODO: Execute a computation. if (peer_has_not_piece(peer, message->piece)) { update_bitfield_blocks(peer, message->piece, message->block_index, message->block_length); @@ -529,7 +529,7 @@ int select_piece_to_download(const_peer_t peer, const_connection_t remote_peer) (is_interested(peer, remote_peer) != 0)) { int nb_interesting_pieces = 0; // compute the number of interesting pieces - for (int i = 0; i < FILE_PIECES; i++) { + for (unsigned int i = 0; i < FILE_PIECES; i++) { if (peer_has_not_piece(peer, i) && connection_has_piece(remote_peer, i)) { nb_interesting_pieces++; } @@ -538,7 +538,7 @@ int select_piece_to_download(const_peer_t peer, const_connection_t remote_peer) // get a random interesting piece int random_piece_index = rand() % nb_interesting_pieces; int current_index = 0; - for (int i = 0; i < FILE_PIECES; i++) { + for (unsigned int i = 0; i < FILE_PIECES; i++) { if (peer_has_not_piece(peer, i) && connection_has_piece(remote_peer, i)) { if (random_piece_index == current_index) { piece = i; @@ -554,7 +554,7 @@ int select_piece_to_download(const_peer_t peer, const_connection_t remote_peer) if (count_pieces(peer->bitfield) < 4 && (is_interested_and_free(peer, remote_peer) != 0)) { int nb_interesting_pieces = 0; // compute the number of interesting pieces - for (int i = 0; i < FILE_PIECES; i++) { + for (unsigned int i = 0; i < FILE_PIECES; i++) { if (peer_has_not_piece(peer, i) && connection_has_piece(remote_peer, i) && peer_is_not_downloading_piece(peer, i)) { nb_interesting_pieces++; @@ -564,7 +564,7 @@ int select_piece_to_download(const_peer_t peer, const_connection_t remote_peer) // get a random interesting piece int random_piece_index = rand() % nb_interesting_pieces; int current_index = 0; - for (int i = 0; i < FILE_PIECES; i++) { + for (unsigned int i = 0; i < FILE_PIECES; i++) { if (peer_has_not_piece(peer, i) && connection_has_piece(remote_peer, i) && peer_is_not_downloading_piece(peer, i)) { if (random_piece_index == current_index) { @@ -581,14 +581,14 @@ int select_piece_to_download(const_peer_t peer, const_connection_t remote_peer) int nb_min_pieces = 0; int current_index = 0; // compute the smallest number of copies of available pieces - for (int i = 0; i < FILE_PIECES; i++) { + for (unsigned int i = 0; i < FILE_PIECES; i++) { if (peer->pieces_count[i] < min && peer_has_not_piece(peer, i) && connection_has_piece(remote_peer, i) && peer_is_not_downloading_piece(peer, i)) min = peer->pieces_count[i]; } xbt_assert(min != SHRT_MAX || (is_interested_and_free(peer, remote_peer) == 0)); // compute the number of rarest pieces - for (int i = 0; i < FILE_PIECES; i++) { + for (unsigned int i = 0; i < FILE_PIECES; i++) { if (peer->pieces_count[i] == min && peer_has_not_piece(peer, i) && connection_has_piece(remote_peer, i) && peer_is_not_downloading_piece(peer, i)) nb_min_pieces++; @@ -599,7 +599,7 @@ int select_piece_to_download(const_peer_t peer, const_connection_t remote_peer) if (nb_min_pieces > 0) { random_rarest_index = rand() % nb_min_pieces; } - for (int i = 0; i < FILE_PIECES; i++) { + for (unsigned int i = 0; i < FILE_PIECES; i++) { if (peer->pieces_count[i] == min && peer_has_not_piece(peer, i) && connection_has_piece(remote_peer, i) && peer_is_not_downloading_piece(peer, i)) { if (random_rarest_index == current_index) { @@ -723,7 +723,7 @@ void update_interested_after_receive(const_peer_t peer) if (connection->am_interested != 0) { int interested = 0; // Check if the peer still has a piece we want. - for (int i = 0; i < FILE_PIECES; i++) { + for (unsigned int i = 0; i < FILE_PIECES; i++) { if (peer_has_not_piece(peer, i) && connection_has_piece(connection, i)) { interested = 1; break; @@ -739,8 +739,8 @@ void update_interested_after_receive(const_peer_t peer) void update_bitfield_blocks(peer_t peer, int index, int block_index, int block_length) { - xbt_assert((index >= 0 && index <= FILE_PIECES), "Wrong piece."); - xbt_assert((block_index >= 0 && block_index <= PIECES_BLOCKS), "Wrong block : %d.", block_index); + xbt_assert((index >= 0 && (unsigned)index <= FILE_PIECES), "Wrong piece."); + xbt_assert((block_index >= 0 && (unsigned)block_index <= PIECES_BLOCKS), "Wrong block : %d.", block_index); for (int i = block_index; i < (block_index + block_length); i++) { peer->bitfield_blocks |= (1ULL << (unsigned int)(index * PIECES_BLOCKS + i)); } @@ -749,7 +749,7 @@ void update_bitfield_blocks(peer_t peer, int index, int block_index, int block_l /** Returns if a peer has completed the download of a piece */ int piece_complete(const_peer_t peer, int index) { - for (int i = 0; i < PIECES_BLOCKS; i++) { + for (unsigned int i = 0; i < PIECES_BLOCKS; i++) { if (!(peer->bitfield_blocks & 1ULL << (index * PIECES_BLOCKS + i))) { return 0; } @@ -760,7 +760,7 @@ int piece_complete(const_peer_t peer, int index) /** Returns the first block that a peer doesn't have in a piece. If the peer has all blocks of the piece, returns -1. */ int get_first_missing_block_from(const_peer_t peer, int piece) { - for (int i = 0; i < PIECES_BLOCKS; i++) { + for (unsigned int i = 0; i < PIECES_BLOCKS; i++) { if (!(peer->bitfield_blocks & 1ULL << (piece * PIECES_BLOCKS + i))) { return i; } @@ -771,7 +771,7 @@ int get_first_missing_block_from(const_peer_t peer, int piece) /** Returns a piece that is partially downloaded and stored by the remote peer if any -1 otherwise. */ int partially_downloaded_piece(const_peer_t peer, const_connection_t remote_peer) { - for (int i = 0; i < FILE_PIECES; i++) { + for (unsigned int i = 0; i < FILE_PIECES; i++) { if (peer_has_not_piece(peer, i) && connection_has_piece(remote_peer, i) && peer_is_not_downloading_piece(peer, i) && get_first_missing_block_from(peer, i) > 0) return i; diff --git a/examples/c/app-bittorrent/bittorrent-peer.h b/examples/c/app-bittorrent/bittorrent-peer.h index 70171a6702..7757e668bc 100644 --- a/examples/c/app-bittorrent/bittorrent-peer.h +++ b/examples/c/app-bittorrent/bittorrent-peer.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -73,7 +73,7 @@ int is_interested(const_peer_t peer, const_connection_t remote_peer); int is_interested_and_free(const_peer_t peer, const_connection_t remote_peer); void update_pieces_count_from_bitfield(const_peer_t peer, unsigned int bitfield); -int count_pieces(unsigned int bitfield); +unsigned int count_pieces(unsigned int bitfield); int nb_interested_peers(const_peer_t peer); void leech(peer_t peer); diff --git a/examples/c/app-bittorrent/generate.py b/examples/c/app-bittorrent/generate.py index aaaa1f9d59..ff40e8cdf2 100755 --- a/examples/c/app-bittorrent/generate.py +++ b/examples/c/app-bittorrent/generate.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright (c) 2012-2022. The SimGrid Team. +# Copyright (c) 2012-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/app-bittorrent/tracker.c b/examples/c/app-bittorrent/tracker.c index 359f8035ae..abed9ce267 100644 --- a/examples/c/app-bittorrent/tracker.c +++ b/examples/c/app-bittorrent/tracker.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/app-bittorrent/tracker.h b/examples/c/app-bittorrent/tracker.h index 33e2508e3d..808c7aaae5 100644 --- a/examples/c/app-bittorrent/tracker.h +++ b/examples/c/app-bittorrent/tracker.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/app-chainsend/broadcaster.c b/examples/c/app-chainsend/broadcaster.c index ef82e68d2f..7133408e80 100644 --- a/examples/c/app-chainsend/broadcaster.c +++ b/examples/c/app-chainsend/broadcaster.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -36,16 +36,14 @@ static void broadcaster_build_chain(broadcaster_t bc) static void broadcaster_send_file(const_broadcaster_t bc) { - int nb_pending_sends = 0; - for (unsigned int current_piece = 0; current_piece < bc->piece_count; current_piece++) { XBT_DEBUG("Sending (send) piece %u from %s into mailbox %s", current_piece, sg_host_self_get_name(), sg_mailbox_get_name(bc->first)); char* file_piece = bprintf("piece-%u", current_piece); sg_comm_t comm = sg_mailbox_put_async(bc->first, file_piece, MESSAGE_SEND_DATA_HEADER_SIZE + PIECE_SIZE); - bc->pending_sends[nb_pending_sends++] = comm; + sg_activity_set_push(bc->pending_sends, (sg_activity_t)comm); } - sg_comm_wait_all(bc->pending_sends, nb_pending_sends); + sg_activity_set_wait_all(bc->pending_sends); } static broadcaster_t broadcaster_init(sg_mailbox_t* mailboxes, unsigned int host_count, unsigned int piece_count) @@ -56,7 +54,7 @@ static broadcaster_t broadcaster_init(sg_mailbox_t* mailboxes, unsigned int host bc->host_count = host_count; bc->piece_count = piece_count; bc->mailboxes = mailboxes; - bc->pending_sends = xbt_malloc(sizeof(sg_comm_t) * MAX_PENDING_COMMS); + bc->pending_sends = sg_activity_set_init(); broadcaster_build_chain(bc); @@ -65,7 +63,7 @@ static broadcaster_t broadcaster_init(sg_mailbox_t* mailboxes, unsigned int host static void broadcaster_destroy(broadcaster_t bc) { - xbt_free(bc->pending_sends); + sg_activity_set_delete(bc->pending_sends); xbt_free(bc->mailboxes); xbt_free(bc); } diff --git a/examples/c/app-chainsend/chainsend.c b/examples/c/app-chainsend/chainsend.c index ea85c906bf..3fcd81e0ef 100644 --- a/examples/c/app-chainsend/chainsend.c +++ b/examples/c/app-chainsend/chainsend.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/app-chainsend/chainsend.h b/examples/c/app-chainsend/chainsend.h index 9366babcae..86a86aaad7 100644 --- a/examples/c/app-chainsend/chainsend.h +++ b/examples/c/app-chainsend/chainsend.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -7,6 +7,7 @@ #ifndef CHAINSEND_H #define CHAINSEND_H +#include "simgrid/activity_set.h" #include "simgrid/actor.h" #include "simgrid/comm.h" #include "simgrid/engine.h" @@ -30,7 +31,7 @@ typedef struct s_broadcaster { unsigned int piece_count; sg_mailbox_t first; sg_mailbox_t* mailboxes; - sg_comm_t* pending_sends; + sg_activity_set_t pending_sends; } s_broadcaster_t; typedef s_broadcaster_t* broadcaster_t; @@ -54,8 +55,8 @@ typedef struct s_peer { unsigned long long received_bytes; unsigned int received_pieces; unsigned int total_pieces; - sg_comm_t* pending_recvs; - sg_comm_t* pending_sends; + sg_activity_set_t pending_recvs; + sg_activity_set_t pending_sends; } s_peer_t; typedef s_peer_t* peer_t; diff --git a/examples/c/app-chainsend/peer.c b/examples/c/app-chainsend/peer.c index 2fd052514d..f4591f8535 100644 --- a/examples/c/app-chainsend/peer.c +++ b/examples/c/app-chainsend/peer.c @@ -1,5 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,26 +21,21 @@ static void peer_join_chain(peer_t p) static void peer_forward_file(peer_t p) { void* received; - int done = 0; - size_t nb_pending_sends = 0; - size_t nb_pending_recvs = 0; + int done = 0; while (!done) { - p->pending_recvs[nb_pending_recvs] = sg_mailbox_get_async(p->me, &received); - nb_pending_recvs++; + sg_activity_set_push(p->pending_recvs, (sg_activity_t)sg_mailbox_get_async(p->me, &received)); - ssize_t idx = sg_comm_wait_any(p->pending_recvs, nb_pending_recvs); - if (idx != -1) { + sg_activity_t acti = sg_activity_set_wait_any(p->pending_recvs); + if (acti != NULL) { + sg_comm_unref((sg_comm_t)acti); XBT_DEBUG("Peer %s got a 'SEND_DATA' message", sg_mailbox_get_name(p->me)); - /* move the last pending comm where the finished one was, and decrement */ - p->pending_recvs[idx] = p->pending_recvs[--nb_pending_recvs]; if (p->next != NULL) { XBT_DEBUG("Sending %s (asynchronously) from %s to %s", (char*)received, sg_mailbox_get_name(p->me), sg_mailbox_get_name(p->next)); sg_comm_t send = sg_mailbox_put_async(p->next, received, MESSAGE_SEND_DATA_HEADER_SIZE + PIECE_SIZE); - p->pending_sends[nb_pending_sends] = send; - nb_pending_sends++; + sg_activity_set_push(p->pending_sends, (sg_activity_t)send); } else free(received); @@ -53,7 +47,7 @@ static void peer_forward_file(peer_t p) } } } - sg_comm_wait_all(p->pending_sends, nb_pending_sends); + sg_activity_set_wait_all(p->pending_sends); } static peer_t peer_init(int argc, char* argv[]) @@ -63,8 +57,8 @@ static peer_t peer_init(int argc, char* argv[]) p->next = NULL; p->received_pieces = 0; p->received_bytes = 0; - p->pending_recvs = xbt_malloc(sizeof(sg_comm_t) * MAX_PENDING_COMMS); - p->pending_sends = xbt_malloc(sizeof(sg_comm_t) * MAX_PENDING_COMMS); + p->pending_recvs = sg_activity_set_init(); + p->pending_sends = sg_activity_set_init(); p->me = sg_mailbox_by_name(sg_host_self_get_name()); @@ -73,8 +67,8 @@ static peer_t peer_init(int argc, char* argv[]) static void peer_delete(peer_t p) { - xbt_free(p->pending_recvs); - xbt_free(p->pending_sends); + sg_activity_set_delete(p->pending_recvs); + sg_activity_set_delete(p->pending_sends); xbt_free(p); } diff --git a/examples/c/app-masterworker/app-masterworker.c b/examples/c/app-masterworker/app-masterworker.c index 5dbb2238bb..7591a16955 100644 --- a/examples/c/app-masterworker/app-masterworker.c +++ b/examples/c/app-masterworker/app-masterworker.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/app-token-ring/app-token-ring.c b/examples/c/app-token-ring/app-token-ring.c index 3eef350891..9717becead 100644 --- a/examples/c/app-token-ring/app-token-ring.c +++ b/examples/c/app-token-ring/app-token-ring.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -23,29 +23,29 @@ static void relay_runner(int argc, char* argv[]) xbt_assert(argc == 0, "The relay_runner function does not accept any parameter from the XML deployment file"); const char* name = sg_actor_self_get_name(); - int rank = (int)xbt_str_parse_int(name, "Any actor of this example must have a numerical name"); + unsigned rank = (unsigned)xbt_str_parse_int(name, "Any actor of this example must have a numerical name"); sg_mailbox_t my_mailbox = sg_mailbox_by_name(name); /* The last actor sends the token back to rank 0, the others send to their right neighbor (rank+1) */ char neighbor_mailbox_name[256]; - snprintf(neighbor_mailbox_name, 255, "%d", rank + 1 == sg_host_count() ? 0 : rank + 1); + snprintf(neighbor_mailbox_name, 255, "%u", rank + 1 == sg_host_count() ? 0 : rank + 1); sg_mailbox_t neighbor_mailbox = sg_mailbox_by_name(neighbor_mailbox_name); char* res; if (rank == 0) { /* The root actor (rank 0) first sends the token then waits to receive it back */ - XBT_INFO("Host \"%d\" send 'Token' to Host \"%s\"", rank, neighbor_mailbox_name); + XBT_INFO("Host \"%u\" send 'Token' to Host \"%s\"", rank, neighbor_mailbox_name); sg_mailbox_put(neighbor_mailbox, xbt_strdup("Token"), 1000000); res = (char*)sg_mailbox_get(my_mailbox); - XBT_INFO("Host \"%d\" received \"%s\"", rank, res); + XBT_INFO("Host \"%u\" received \"%s\"", rank, res); } else { /* The others actors receive from their left neighbor (rank-1) and send to their right neighbor (rank+1) */ res = (char*)sg_mailbox_get(my_mailbox); - XBT_INFO("Host \"%d\" received \"%s\"", rank, res); - XBT_INFO("Host \"%d\" send 'Token' to Host \"%s\"", rank, neighbor_mailbox_name); + XBT_INFO("Host \"%u\" received \"%s\"", rank, res); + XBT_INFO("Host \"%u\" send 'Token' to Host \"%s\"", rank, neighbor_mailbox_name); sg_mailbox_put(neighbor_mailbox, xbt_strdup("Token"), 1000000); } free(res); diff --git a/examples/c/cloud-capping/cloud-capping.c b/examples/c/cloud-capping/cloud-capping.c index 5f5b525d2b..f5988c69a0 100644 --- a/examples/c/cloud-capping/cloud-capping.c +++ b/examples/c/cloud-capping/cloud-capping.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/cloud-masterworker/cloud-masterworker.c b/examples/c/cloud-masterworker/cloud-masterworker.c index a38f3557bd..7f3ed8f238 100644 --- a/examples/c/cloud-masterworker/cloud-masterworker.c +++ b/examples/c/cloud-masterworker/cloud-masterworker.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/cloud-migration/cloud-migration.c b/examples/c/cloud-migration/cloud-migration.c index b1c5dc2618..eb00d9b808 100644 --- a/examples/c/cloud-migration/cloud-migration.c +++ b/examples/c/cloud-migration/cloud-migration.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/cloud-simple/cloud-simple.c b/examples/c/cloud-simple/cloud-simple.c index dcd03e0782..83e38c2af5 100644 --- a/examples/c/cloud-simple/cloud-simple.c +++ b/examples/c/cloud-simple/cloud-simple.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/comm-pingpong/comm-pingpong.c b/examples/c/comm-pingpong/comm-pingpong.c index e974abe1e2..12a62d54d7 100644 --- a/examples/c/comm-pingpong/comm-pingpong.c +++ b/examples/c/comm-pingpong/comm-pingpong.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/comm-pingpong/comm-pingpong.tesh b/examples/c/comm-pingpong/comm-pingpong.tesh index b12b9edfed..2adb74f997 100644 --- a/examples/c/comm-pingpong/comm-pingpong.tesh +++ b/examples/c/comm-pingpong/comm-pingpong.tesh @@ -39,17 +39,16 @@ $ ${bindir:=.}/c-comm-pingpong ${platfdir}/small_platform.xml comm-pingpong_d.xm > [145.639041] (1:pinger@Tremblay) Pong time (bandwidth bound): 145.638 > [145.639041] (0:maestro@) Total simulation time: 145.639 -p Testing the surf network constant model +p Testing the network constant model -$ ${bindir:=.}/c-comm-pingpong ${platfdir}/small_platform_routing_none.xml comm-pingpong_d.xml "--cfg=host/model:compound cpu/model:Cas01 network/model:Constant" "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ${bindir:=.}/c-comm-pingpong ${platfdir}/small_platform_routing_none.xml comm-pingpong_d.xml "--cfg=cpu/model:Cas01 network/model:Constant" "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/model' to 'Cas01' > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'Constant' > [ 0.000000] (1:pinger@Tremblay) Ping from mailbox Mailbox 1 to mailbox Mailbox 2 > [ 0.000000] (2:ponger@Jupiter) Pong from mailbox Mailbox 2 to mailbox Mailbox 1 -> [ 13.010000] (2:ponger@Jupiter) Task received : small communication (latency bound) -> [ 13.010000] (2:ponger@Jupiter) Ping time (latency bound) 13.010000 -> [ 13.010000] (2:ponger@Jupiter) task_bw->data = 13.010 -> [ 26.020000] (1:pinger@Tremblay) Task received : large communication (bandwidth bound) -> [ 26.020000] (1:pinger@Tremblay) Pong time (bandwidth bound): 13.010 -> [ 26.020000] (0:maestro@) Total simulation time: 26.020 +> [ 1.000000] (2:ponger@Jupiter) Task received : small communication (latency bound) +> [ 1.000000] (2:ponger@Jupiter) Ping time (latency bound) 1.000000 +> [ 1.000000] (2:ponger@Jupiter) task_bw->data = 1.000 +> [ 2.000000] (1:pinger@Tremblay) Task received : large communication (bandwidth bound) +> [ 2.000000] (1:pinger@Tremblay) Pong time (bandwidth bound): 1.000 +> [ 2.000000] (0:maestro@) Total simulation time: 2.000 diff --git a/examples/c/comm-wait/comm-wait.c b/examples/c/comm-wait/comm-wait.c index ae2275fe8b..8a1eb80cc4 100644 --- a/examples/c/comm-wait/comm-wait.c +++ b/examples/c/comm-wait/comm-wait.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/comm-waitall/comm-waitall.c b/examples/c/comm-waitall/comm-waitall.c deleted file mode 100644 index ad537dcaec..0000000000 --- a/examples/c/comm-waitall/comm-waitall.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/actor.h" -#include "simgrid/comm.h" -#include "simgrid/engine.h" -#include "simgrid/host.h" -#include "simgrid/mailbox.h" - -#include "xbt/log.h" -#include "xbt/str.h" -#include "xbt/sysdep.h" - -#include /* snprintf */ - -XBT_LOG_NEW_DEFAULT_CATEGORY(comm_waitall, "Messages specific for this example"); - -static void sender(int argc, char* argv[]) -{ - xbt_assert(argc == 4, "This function expects 3 parameters from the XML deployment file"); - long messages_count = xbt_str_parse_int(argv[1], "Invalid message count"); - long message_size = xbt_str_parse_int(argv[2], "Invalid message size"); - long receivers_count = xbt_str_parse_int(argv[3], "Invalid amount of receivers"); - xbt_assert(receivers_count > 0); - - /* Array in which we store all ongoing communications */ - sg_comm_t* pending_comms = xbt_malloc(sizeof(sg_comm_t) * (messages_count + receivers_count)); - int pending_comms_count = 0; - - /* Make an array of the mailboxes to use */ - sg_mailbox_t* mboxes = xbt_malloc(sizeof(sg_mailbox_t) * receivers_count); - for (long i = 0; i < receivers_count; i++) { - char mailbox_name[80]; - snprintf(mailbox_name, 79, "receiver-%ld", i); - sg_mailbox_t mbox = sg_mailbox_by_name(mailbox_name); - mboxes[i] = mbox; - } - - /* Start dispatching all messages to receivers, in a round robin fashion */ - for (long i = 0; i < messages_count; i++) { - char msg_content[80]; - snprintf(msg_content, 79, "Message %ld", i); - sg_mailbox_t mbox = mboxes[i % receivers_count]; - XBT_INFO("Send '%s' to '%s'", msg_content, sg_mailbox_get_name(mbox)); - /* Create a communication representing the ongoing communication, and store it in pending_comms */ - pending_comms[pending_comms_count++] = sg_mailbox_put_async(mbox, xbt_strdup(msg_content), message_size); - } - - /* Start sending messages to let the workers know that they should stop */ - for (long i = 0; i < receivers_count; i++) { - XBT_INFO("Send 'finalize' to 'receiver-%ld'", i); - char* end_msg = xbt_strdup("finalize"); - sg_mailbox_t mbox = mboxes[i % receivers_count]; - pending_comms[pending_comms_count++] = sg_mailbox_put_async(mbox, end_msg, 0); - } - - XBT_INFO("Done dispatching all messages"); - - /* Now that all message exchanges were initiated, wait for their completion in one single call */ - sg_comm_wait_all(pending_comms, pending_comms_count); - - xbt_free(pending_comms); - xbt_free(mboxes); - - XBT_INFO("Goodbye now!"); -} - -static void receiver(int argc, char* argv[]) -{ - xbt_assert(argc == 2, "Expecting one parameter from the XML deployment file but got %d", argc); - int id = (int)xbt_str_parse_int(argv[1], "ID should be numerical"); - char mailbox_name[80]; - snprintf(mailbox_name, 79, "receiver-%d", id); - sg_mailbox_t mbox = sg_mailbox_by_name(mailbox_name); - XBT_INFO("Wait for my first message"); - while (1) { - char* received = (char*)sg_mailbox_get(mbox); - XBT_INFO("I got a '%s'.", received); - if (!strcmp(received, "finalize")) { // If it's a finalize message, we're done - xbt_free(received); - break; - } - xbt_free(received); - } -} - -int main(int argc, char* argv[]) -{ - simgrid_init(&argc, argv); - xbt_assert(argc > 2, - "Usage: %s platform_file deployment_file\n" - "\tExample: %s platform.xml deployment.xml\n", - argv[0], argv[0]); - - simgrid_load_platform(argv[1]); - - simgrid_register_function("sender", sender); - simgrid_register_function("receiver", receiver); - simgrid_load_deployment(argv[2]); - - simgrid_run(); - - return 0; -} diff --git a/examples/c/comm-waitall/comm-waitall.tesh b/examples/c/comm-waitall/comm-waitall.tesh deleted file mode 100644 index 1c3cfe6bea..0000000000 --- a/examples/c/comm-waitall/comm-waitall.tesh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 -$ ${bindir:=.}/c-comm-waitall ${platfdir:=.}/small_platform_fatpipe.xml ${srcdir:=.}/comm-waitall_d.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (1:sender@Tremblay) Send 'Message 0' to 'receiver-0' -> [ 0.000000] (2:receiver@Ruby) Wait for my first message -> [ 0.000000] (3:receiver@Perl) Wait for my first message -> [ 0.000000] (1:sender@Tremblay) Send 'Message 1' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 2' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 3' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 4' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Done dispatching all messages -> [ 0.004022] (2:receiver@Ruby) I got a 'Message 0'. -> [ 0.004022] (3:receiver@Perl) I got a 'Message 1'. -> [ 0.008043] (2:receiver@Ruby) I got a 'Message 2'. -> [ 0.008043] (3:receiver@Perl) I got a 'Message 3'. -> [ 0.009995] (3:receiver@Perl) I got a 'finalize'. -> [ 0.012065] (2:receiver@Ruby) I got a 'Message 4'. -> [ 0.014016] (2:receiver@Ruby) I got a 'finalize'. -> [ 0.014016] (1:sender@Tremblay) Goodbye now! diff --git a/examples/c/comm-waitall/comm-waitall_d.xml b/examples/c/comm-waitall/comm-waitall_d.xml deleted file mode 100644 index 8f9d88bf1c..0000000000 --- a/examples/c/comm-waitall/comm-waitall_d.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/examples/c/comm-waitany/comm-waitany.c b/examples/c/comm-waitany/comm-waitany.c deleted file mode 100644 index 64df359c13..0000000000 --- a/examples/c/comm-waitany/comm-waitany.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/actor.h" -#include "simgrid/comm.h" -#include "simgrid/engine.h" -#include "simgrid/forward.h" -#include "simgrid/mailbox.h" -#include "xbt/log.h" -#include "xbt/str.h" -#include "xbt/sysdep.h" - -#include /* snprintf */ - -XBT_LOG_NEW_DEFAULT_CATEGORY(comm_waitany, "Messages specific for this example"); - -static void sender(int argc, char* argv[]) -{ - xbt_assert(argc == 4, "Expecting 3 parameters from the XML deployment file but got %d", argc); - long messages_count = xbt_str_parse_int(argv[1], "Invalid message count"); - long msg_size = xbt_str_parse_int(argv[2], "Invalid message size"); - long receivers_count = xbt_str_parse_int(argv[3], "Invalid amount of receivers"); - xbt_assert(receivers_count > 0); - - /* Array in which we store all ongoing communications */ - sg_comm_t* pending_comms = xbt_malloc(sizeof(sg_comm_t) * (messages_count + receivers_count)); - int pending_comms_count = 0; - - /* Make an array of the mailboxes to use */ - sg_mailbox_t* mboxes = xbt_malloc(sizeof(sg_mailbox_t) * receivers_count); - for (long i = 0; i < receivers_count; i++) { - char mailbox_name[80]; - snprintf(mailbox_name, 79, "receiver-%ld", i); - sg_mailbox_t mbox = sg_mailbox_by_name(mailbox_name); - mboxes[i] = mbox; - } - - /* Start dispatching all messages to receivers, in a round robin fashion */ - for (long i = 0; i < messages_count; i++) { - char msg_content[80]; - snprintf(msg_content, 79, "Message %ld", i); - sg_mailbox_t mbox = mboxes[i % receivers_count]; - XBT_INFO("Send '%s' to '%s'", msg_content, sg_mailbox_get_name(mbox)); - - /* Create a communication representing the ongoing communication, and store it in pending_comms */ - pending_comms[pending_comms_count++] = sg_mailbox_put_async(mbox, xbt_strdup(msg_content), msg_size); - } - /* Start sending messages to let the workers know that they should stop */ - for (long i = 0; i < receivers_count; i++) { - XBT_INFO("Send 'finalize' to 'receiver-%ld'", i); - char* end_msg = xbt_strdup("finalize"); - sg_mailbox_t mbox = mboxes[i % receivers_count]; - pending_comms[pending_comms_count++] = sg_mailbox_put_async(mbox, end_msg, 0); - } - - XBT_INFO("Done dispatching all messages"); - - /* Now that all message exchanges were initiated, wait for their completion, in order of termination. - * - * This loop waits for first terminating message with wait_any() and remove it from the array (with a memmove), - * until all comms are terminated. - * Even in this simple example, the pending comms do not terminate in the exact same order of creation. - */ - while (pending_comms_count != 0) { - ssize_t changed_pos = sg_comm_wait_any(pending_comms, pending_comms_count); - memmove(pending_comms + changed_pos, pending_comms + changed_pos + 1, - sizeof(sg_comm_t) * (pending_comms_count - changed_pos - 1)); - pending_comms_count--; - - if (changed_pos != 0) - XBT_INFO("Remove the %zdth pending comm: it terminated earlier than another comm that was initiated first.", - changed_pos); - } - - xbt_free(pending_comms); - xbt_free(mboxes); - - XBT_INFO("Goodbye now!"); -} - -static void receiver(int argc, char* argv[]) -{ - xbt_assert(argc == 2, "Expecting one parameter from the XML deployment file but got %d", argc); - int id = (int)xbt_str_parse_int(argv[1], "ID should be numerical"); - char mailbox_name[80]; - snprintf(mailbox_name, 79, "receiver-%d", id); - sg_mailbox_t mbox = sg_mailbox_by_name(mailbox_name); - XBT_INFO("Wait for my first message on '%s'", mailbox_name); - while (1) { - char* received = (char*)sg_mailbox_get(mbox); - XBT_INFO("I got a '%s'.", received); - if (!strcmp(received, "finalize")) { // If it's a finalize message, we're done - xbt_free(received); - break; - } - xbt_free(received); - } - - XBT_INFO("I'm done. See you!"); -} - -int main(int argc, char* argv[]) -{ - simgrid_init(&argc, argv); - xbt_assert(argc > 2, - "Usage: %s platform_file deployment_file\n" - "\tExample: %s platform.xml deployment.xml\n", - argv[0], argv[0]); - - simgrid_load_platform(argv[1]); - - simgrid_register_function("sender", sender); - simgrid_register_function("receiver", receiver); - simgrid_load_deployment(argv[2]); - - simgrid_run(); - XBT_INFO("Simulation time %g", simgrid_get_clock()); - - return 0; -} diff --git a/examples/c/comm-waitany/comm-waitany.tesh b/examples/c/comm-waitany/comm-waitany.tesh deleted file mode 100644 index b9e4a98bf4..0000000000 --- a/examples/c/comm-waitany/comm-waitany.tesh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 -$ ${bindir:=.}/c-comm-waitany ${platfdir:=.}/small_platform.xml ${srcdir:=.}/comm-waitany_d.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (1:sender@Tremblay) Send 'Message 0' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 1' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 2' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 3' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 4' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 5' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Done dispatching all messages -> [ 0.000000] (2:receiver@Fafard) Wait for my first message on 'receiver-0' -> [ 0.000000] (3:receiver@Jupiter) Wait for my first message on 'receiver-1' -> [ 0.158397] (2:receiver@Fafard) I got a 'Message 0'. -> [ 0.169155] (3:receiver@Jupiter) I got a 'Message 1'. -> [ 0.316794] (2:receiver@Fafard) I got a 'Message 2'. -> [ 0.338309] (3:receiver@Jupiter) I got a 'Message 3'. -> [ 0.475190] (2:receiver@Fafard) I got a 'Message 4'. -> [ 0.500898] (1:sender@Tremblay) Remove the 1th pending comm: it terminated earlier than another comm that was initiated first. -> [ 0.500898] (2:receiver@Fafard) I got a 'finalize'. -> [ 0.500898] (2:receiver@Fafard) I'm done. See you! -> [ 0.507464] (3:receiver@Jupiter) I got a 'Message 5'. -> [ 0.526478] (0:maestro@) Simulation time 0.526478 -> [ 0.526478] (1:sender@Tremblay) Goodbye now! -> [ 0.526478] (3:receiver@Jupiter) I got a 'finalize'. -> [ 0.526478] (3:receiver@Jupiter) I'm done. See you! \ No newline at end of file diff --git a/examples/c/comm-waitany/comm-waitany_d.xml b/examples/c/comm-waitany/comm-waitany_d.xml deleted file mode 100644 index dd639f5fbe..0000000000 --- a/examples/c/comm-waitany/comm-waitany_d.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/examples/c/dht-kademlia/answer.c b/examples/c/dht-kademlia/answer.c index abc7296de1..9d8e9a7beb 100644 --- a/examples/c/dht-kademlia/answer.c +++ b/examples/c/dht-kademlia/answer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/dht-kademlia/answer.h b/examples/c/dht-kademlia/answer.h index f46487db02..ae150e778d 100644 --- a/examples/c/dht-kademlia/answer.h +++ b/examples/c/dht-kademlia/answer.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/dht-kademlia/common.h b/examples/c/dht-kademlia/common.h index b41e95dac3..3039b78720 100644 --- a/examples/c/dht-kademlia/common.h +++ b/examples/c/dht-kademlia/common.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/dht-kademlia/dht-kademlia.c b/examples/c/dht-kademlia/dht-kademlia.c index c87c082ee8..9297eafc5b 100644 --- a/examples/c/dht-kademlia/dht-kademlia.c +++ b/examples/c/dht-kademlia/dht-kademlia.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/dht-kademlia/generate.py b/examples/c/dht-kademlia/generate.py index 9986fb88d4..f7994217ad 100755 --- a/examples/c/dht-kademlia/generate.py +++ b/examples/c/dht-kademlia/generate.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright (c) 2012-2022. The SimGrid Team. +# Copyright (c) 2012-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/dht-kademlia/message.c b/examples/c/dht-kademlia/message.c index 24b6a355f9..32a618a78d 100644 --- a/examples/c/dht-kademlia/message.c +++ b/examples/c/dht-kademlia/message.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/dht-kademlia/message.h b/examples/c/dht-kademlia/message.h index 213d9dd34b..d3ac7d2124 100644 --- a/examples/c/dht-kademlia/message.h +++ b/examples/c/dht-kademlia/message.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -23,8 +23,6 @@ typedef s_kademlia_message_t* kademlia_message_t; typedef const s_kademlia_message_t* const_kademlia_message_t; // Task handling functions -kademlia_message_t task_new_find_node(unsigned int sender_id, unsigned int destination_id, sg_mailbox_t mailbox, - const char* hostname); kademlia_message_t new_message(unsigned int sender_id, unsigned int destination_id, answer_t answer, sg_mailbox_t mailbox, const char* hostname); void free_message(void* message); diff --git a/examples/c/dht-kademlia/node.c b/examples/c/dht-kademlia/node.c index d8204d35aa..f118c64f5e 100644 --- a/examples/c/dht-kademlia/node.c +++ b/examples/c/dht-kademlia/node.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -156,7 +156,7 @@ void routing_table_update(const_node_t node, unsigned int id) // check if the id is already in the bucket. unsigned int id_pos = bucket_find_id(bucket, id); - if (id_pos == -1) { + if (id_pos == (unsigned int)-1) { /* We check if the bucket is full or not. If it is, we evict an old element */ if (xbt_dynar_length(bucket->nodes) >= BUCKET_SIZE) xbt_dynar_pop(bucket->nodes, NULL); diff --git a/examples/c/dht-kademlia/node.h b/examples/c/dht-kademlia/node.h index bbbcac0ed8..d545cbe477 100644 --- a/examples/c/dht-kademlia/node.h +++ b/examples/c/dht-kademlia/node.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/dht-kademlia/routing_table.c b/examples/c/dht-kademlia/routing_table.c index 28b2ea8e56..722b530701 100644 --- a/examples/c/dht-kademlia/routing_table.c +++ b/examples/c/dht-kademlia/routing_table.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/dht-kademlia/routing_table.h b/examples/c/dht-kademlia/routing_table.h index e916ca89b9..67cab89a3d 100644 --- a/examples/c/dht-kademlia/routing_table.h +++ b/examples/c/dht-kademlia/routing_table.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/dht-pastry/dht-pastry.c b/examples/c/dht-pastry/dht-pastry.c index 2658603d6e..c50c6a4fbb 100644 --- a/examples/c/dht-pastry/dht-pastry.c +++ b/examples/c/dht-pastry/dht-pastry.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -265,7 +265,7 @@ static void handle_message(node_t node, pastry_message_t message) } node->namespace_set[NAMESPACE_SIZE / 2 + j] = message->sender_id; node->ready += message->steps + 1; - /* no break */ + /* fallthrough */ case JOIN_REPLY: XBT_DEBUG("Joining Reply"); @@ -520,7 +520,7 @@ int main(int argc, char* argv[]) char** options = &argv[1]; while (!strncmp(options[0], "-", 1)) { - int length = strlen("-nb_bits="); + size_t length = strlen("-nb_bits="); if (!strncmp(options[0], "-nb_bits=", length) && strlen(options[0]) > length) { nb_bits = (int)xbt_str_parse_int(options[0] + length, "Invalid nb_bits parameter"); XBT_DEBUG("Set nb_bits to %d", nb_bits); diff --git a/examples/c/dht-pastry/generate.py b/examples/c/dht-pastry/generate.py index 0db8029686..e0d9ca7224 100755 --- a/examples/c/dht-pastry/generate.py +++ b/examples/c/dht-pastry/generate.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright (c) 2011-2022. The SimGrid Team. +# Copyright (c) 2011-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/energy-exec-ptask/energy-exec-ptask.c b/examples/c/energy-exec-ptask/energy-exec-ptask.c index 54dae6cbb6..988f7fcc03 100644 --- a/examples/c/energy-exec-ptask/energy-exec-ptask.c +++ b/examples/c/energy-exec-ptask/energy-exec-ptask.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/energy-exec/energy-exec.c b/examples/c/energy-exec/energy-exec.c index bff6b2f31c..7820d77bc7 100644 --- a/examples/c/energy-exec/energy-exec.c +++ b/examples/c/energy-exec/energy-exec.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/energy-vm/energy-vm.c b/examples/c/energy-vm/energy-vm.c index eb73451f63..4b5aa6d1fb 100644 --- a/examples/c/energy-vm/energy-vm.c +++ b/examples/c/energy-vm/energy-vm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/exec-async/exec-async.c b/examples/c/exec-async/exec-async.c index 64430fd9f5..fab0ebc30c 100644 --- a/examples/c/exec-async/exec-async.c +++ b/examples/c/exec-async/exec-async.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/exec-basic/exec-basic.c b/examples/c/exec-basic/exec-basic.c index 52cb35ed53..40577f839b 100644 --- a/examples/c/exec-basic/exec-basic.c +++ b/examples/c/exec-basic/exec-basic.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/exec-dvfs/exec-dvfs.c b/examples/c/exec-dvfs/exec-dvfs.c index bdb4de4fe2..c9cd32aa98 100644 --- a/examples/c/exec-dvfs/exec-dvfs.c +++ b/examples/c/exec-dvfs/exec-dvfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/exec-dvfs/exec-dvfs.tesh b/examples/c/exec-dvfs/exec-dvfs.tesh index 882c433589..5485497ca6 100644 --- a/examples/c/exec-dvfs/exec-dvfs.tesh +++ b/examples/c/exec-dvfs/exec-dvfs.tesh @@ -7,9 +7,9 @@ $ ${bindir:=.}/c-exec-dvfs ${platfdir}/energy_platform.xml "--log=root.fmt:[%10. > [ 0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000 > [ 1.000000] (1:dvfs_test@MyHost1) Task1 simulation time: 1.000000e+00 > [ 1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2) +> [ 1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Task1 simulation time: 1.000000e+00 > [ 1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2) -> [ 1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000 > [ 6.000000] (1:dvfs_test@MyHost1) Task2 simulation time: 5.000000e+00 > [ 6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3 @@ -28,9 +28,9 @@ $ ${bindir:=.}/c-exec-dvfs ${platfdir}/energy_cluster.xml "--log=root.fmt:[%10.6 > [ 0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000 > [ 1.000000] (1:dvfs_test@MyHost1) Task1 simulation time: 1.000000e+00 > [ 1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2) +> [ 1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Task1 simulation time: 1.000000e+00 > [ 1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2) -> [ 1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000 > [ 6.000000] (1:dvfs_test@MyHost1) Task2 simulation time: 5.000000e+00 > [ 6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3 diff --git a/examples/c/exec-remote/exec-remote.c b/examples/c/exec-remote/exec-remote.c index a6e4a12ca6..a36567069b 100644 --- a/examples/c/exec-remote/exec-remote.c +++ b/examples/c/exec-remote/exec-remote.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/exec-waitany/exec-waitany.c b/examples/c/exec-waitany/exec-waitany.c deleted file mode 100644 index f866c6d3de..0000000000 --- a/examples/c/exec-waitany/exec-waitany.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/actor.h" -#include "simgrid/engine.h" -#include "simgrid/exec.h" -#include "simgrid/host.h" - -#include "xbt/log.h" -#include "xbt/sysdep.h" - -XBT_LOG_NEW_DEFAULT_CATEGORY(exec_waitany, "Messages specific for this example"); - -static void worker(int argc, char* argv[]) -{ - xbt_assert(argc > 1); - int with_timeout = !strcmp(argv[1], "true"); - - /* Vector in which we store all pending executions*/ - sg_exec_t* pending_execs = xbt_malloc(sizeof(sg_exec_t) * 3); - int pending_execs_count = 0; - - for (int i = 0; i < 3; i++) { - char* name = bprintf("Exec-%d", i); - double amount = (6 * (i % 2) + i + 1) * sg_host_get_speed(sg_host_self()); - - sg_exec_t exec = sg_actor_exec_init(amount); - sg_exec_set_name(exec, name); - pending_execs[pending_execs_count++] = exec; - sg_exec_start(exec); - - XBT_INFO("Activity %s has started for %.0f seconds", name, amount / sg_host_get_speed(sg_host_self())); - free(name); - } - - /* Now that executions were initiated, wait for their completion, in order of termination. - * - * This loop waits for first terminating execution with wait_any() and remove it with erase(), until all execs are - * terminated. - */ - while (pending_execs_count > 0) { - ssize_t pos; - if (with_timeout) - pos = sg_exec_wait_any_for(pending_execs, pending_execs_count, 4); - else - pos = sg_exec_wait_any(pending_execs, pending_execs_count); - - if (pos < 0) { - XBT_INFO("Do not wait any longer for an activity"); - pending_execs_count = 0; - } else { - XBT_INFO("Activity at position %zd is complete", pos); - memmove(pending_execs + pos, pending_execs + pos + 1, sizeof(sg_exec_t) * (pending_execs_count - pos - 1)); - pending_execs_count--; - } - XBT_INFO("%d activities remain pending", pending_execs_count); - } - - xbt_free(pending_execs); -} - -int main(int argc, char* argv[]) -{ - simgrid_init(&argc, argv); - simgrid_load_platform(argv[1]); - - const char* worker_argv[] = {"worker", "false"}; - sg_actor_create_("worker", sg_host_by_name("Tremblay"), worker, 2, worker_argv); - - worker_argv[1] = "true"; - sg_actor_create_("worker_timeout", sg_host_by_name("Tremblay"), worker, 2, worker_argv); - - simgrid_run(); - return 0; -} diff --git a/examples/c/exec-waitany/exec-waitany.tesh b/examples/c/exec-waitany/exec-waitany.tesh deleted file mode 100644 index 2ea0293135..0000000000 --- a/examples/c/exec-waitany/exec-waitany.tesh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 -$ ${bindir:=.}/c-exec-waitany ${platfdir}/multicore_machine.xml "--log=root.fmt:[%10.6r]%e[%14P]%e%m%n" -> [ 0.000000] [ worker] Activity Exec-0 has started for 1 seconds -> [ 0.000000] [worker_timeout] Activity Exec-0 has started for 1 seconds -> [ 0.000000] [ worker] Activity Exec-1 has started for 8 seconds -> [ 0.000000] [worker_timeout] Activity Exec-1 has started for 8 seconds -> [ 0.000000] [ worker] Activity Exec-2 has started for 3 seconds -> [ 0.000000] [worker_timeout] Activity Exec-2 has started for 3 seconds -> [ 1.000000] [worker_timeout] Activity at position 0 is complete -> [ 1.000000] [worker_timeout] 2 activities remain pending -> [ 1.000000] [ worker] Activity at position 0 is complete -> [ 1.000000] [ worker] 2 activities remain pending -> [ 3.000000] [worker_timeout] Activity at position 1 is complete -> [ 3.000000] [worker_timeout] 1 activities remain pending -> [ 3.000000] [ worker] Activity at position 1 is complete -> [ 3.000000] [ worker] 1 activities remain pending -> [ 7.000000] [worker_timeout] Do not wait any longer for an activity -> [ 7.000000] [worker_timeout] 0 activities remain pending -> [ 8.000000] [ worker] Activity at position 0 is complete -> [ 8.000000] [ worker] 0 activities remain pending diff --git a/examples/c/io-disk-raw/io-disk-raw.c b/examples/c/io-disk-raw/io-disk-raw.c index e7902e2cd0..526874d27d 100644 --- a/examples/c/io-disk-raw/io-disk-raw.c +++ b/examples/c/io-disk-raw/io-disk-raw.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -66,7 +66,7 @@ int main(int argc, char* argv[]) size_t host_count = sg_host_count(); sg_host_t* hosts = sg_host_list(); - for (long i = 0; i < host_count; i++) { + for (size_t i = 0; i < host_count; i++) { XBT_INFO("*** %s properties ****", sg_host_get_name(hosts[i])); xbt_dict_t props = sg_host_get_properties(hosts[i]); xbt_dict_cursor_t cursor = NULL; diff --git a/examples/c/io-file-remote/io-file-remote.c b/examples/c/io-file-remote/io-file-remote.c index 003a10974f..123e8b6928 100644 --- a/examples/c/io-file-remote/io-file-remote.c +++ b/examples/c/io-file-remote/io-file-remote.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -53,7 +53,7 @@ int main(int argc, char** argv) size_t host_count = sg_host_count(); sg_host_t* hosts = sg_host_list(); - for (long i = 0; i < host_count; i++) { + for (size_t i = 0; i < host_count; i++) { unsigned int disk_count; sg_disk_t* disks; sg_host_get_disks(hosts[i], &disk_count, &disks); @@ -66,7 +66,7 @@ int main(int argc, char** argv) simgrid_run(); - for (long i = 0; i < host_count; i++) { + for (size_t i = 0; i < host_count; i++) { unsigned int disk_count; sg_disk_t* disks; sg_host_get_disks(hosts[i], &disk_count, &disks); diff --git a/examples/c/io-file-remote/io-file-remote.tesh b/examples/c/io-file-remote/io-file-remote.tesh index c6dbc0274a..6246761a3e 100644 --- a/examples/c/io-file-remote/io-file-remote.tesh +++ b/examples/c/io-file-remote/io-file-remote.tesh @@ -5,15 +5,15 @@ $ ${bindir:=.}/c-io-file-remote ${platfdir}/hosts_with_disks.xml io-file-remote_ > [ 0.000000] (0@ ) Init: bob: 35/511964 MiB used/free on 'Disk1@bob' > [ 0.000000] (0@ ) Init: bob: 0/512000 MiB used/free on 'Disk2@bob' > [ 0.000000] (0@ ) Init: carl: 35/511964 MiB used/free on 'Disk1@bob' -> [ 0.000000] (1@alice) Opened file '/include/surf/simgrid_dtd.h' +> [ 0.000000] (1@alice) Opened file '/include/simgrid_dtd.h' > [ 0.000000] (1@alice) File Descriptor information: -> Full path: '/include/surf/simgrid_dtd.h' +> Full path: '/include/simgrid_dtd.h' > Size: 23583 > Mount point: '/' > Disk Id: 'Disk1' > Host Id: 'alice' > File Descriptor Id: 0 -> [ 0.000000] (1@alice) Try to write 23 MiB to '/include/surf/simgrid_dtd.h' +> [ 0.000000] (1@alice) Try to write 23 MiB to '/include/simgrid_dtd.h' > [ 0.000000] (2@ bob) Opened file '/scratch/doc/simgrid/examples/platforms/g5k.xml' > [ 0.000000] (2@ bob) File Descriptor information: > Full path: '/scratch/doc/simgrid/examples/platforms/g5k.xml' @@ -23,20 +23,20 @@ $ ${bindir:=.}/c-io-file-remote ${platfdir}/hosts_with_disks.xml io-file-remote_ > Host Id: 'bob' > File Descriptor Id: 0 > [ 0.000000] (2@ bob) Try to write 16 MiB to '/scratch/doc/simgrid/examples/platforms/g5k.xml' -> [ 0.000000] (3@ carl) Opened file '/scratch/include/surf/simgrid_dtd.h' +> [ 0.000000] (3@ carl) Opened file '/scratch/include/simgrid_dtd.h' > [ 0.000000] (3@ carl) File Descriptor information: -> Full path: '/scratch/include/surf/simgrid_dtd.h' +> Full path: '/scratch/include/simgrid_dtd.h' > Size: 23583 > Mount point: '/scratch' > Disk Id: 'Disk1' > Host Id: 'bob' > File Descriptor Id: 0 -> [ 0.000000] (3@ carl) Try to write 23 MiB to '/scratch/include/surf/simgrid_dtd.h' -> [ 0.301862] (1@alice) Have written 23 MiB to '/include/surf/simgrid_dtd.h'. -> [ 0.301862] (1@alice) Move '/include/surf/simgrid_dtd.h' (of size 24148992) from 'alice' to 'bob' +> [ 0.000000] (3@ carl) Try to write 23 MiB to '/scratch/include/simgrid_dtd.h' +> [ 0.301862] (1@alice) Have written 23 MiB to '/include/simgrid_dtd.h'. +> [ 0.301862] (1@alice) Move '/include/simgrid_dtd.h' (of size 24148992) from 'alice' to 'bob' > [ 0.660757] (2@ bob) Have written 16 MiB to '/scratch/doc/simgrid/examples/platforms/g5k.xml'. > [ 0.660757] (2@ bob) Copy '/scratch/doc/simgrid/examples/platforms/g5k.xml' (of size 17436672) from 'bob' to 'alice' -> [ 1.234522] (3@ carl) Have written 23 MiB to '/scratch/include/surf/simgrid_dtd.h'. +> [ 1.234522] (3@ carl) Have written 23 MiB to '/scratch/include/simgrid_dtd.h'. > [ 1.643366] (0@ ) End: 29/511970 MiB used/free on 'Disk1@alice' > [ 1.643366] (0@ ) End: 97/511902 MiB used/free on 'Disk1@bob' > [ 1.643366] (0@ ) End: 0/512000 MiB used/free on 'Disk2@bob' diff --git a/examples/c/io-file-remote/io-file-remote_d.xml b/examples/c/io-file-remote/io-file-remote_d.xml index d14901b8fb..205ca815b2 100644 --- a/examples/c/io-file-remote/io-file-remote_d.xml +++ b/examples/c/io-file-remote/io-file-remote_d.xml @@ -2,9 +2,9 @@ - + - + @@ -14,6 +14,6 @@ - + diff --git a/examples/c/io-file-system/io-file-system.c b/examples/c/io-file-system/io-file-system.c index 01849d4b2e..efa9fe4992 100644 --- a/examples/c/io-file-system/io-file-system.c +++ b/examples/c/io-file-system/io-file-system.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/io-file-system/io-file-system.tesh b/examples/c/io-file-system/io-file-system.tesh index 3953211c6e..2010eceeb4 100644 --- a/examples/c/io-file-system/io-file-system.tesh +++ b/examples/c/io-file-system/io-file-system.tesh @@ -2,20 +2,20 @@ $ ${bindir:=.}/c-io-file-system ${platfdir}/hosts_with_disks.xml > [bob:host:(1) 0.000000] [io_file_system/INFO] Storage info on bob: -> [bob:host:(1) 0.000000] [io_file_system/INFO] Disk1 (/scratch) Used: 36933331; Free: 536833978669; Total: 536870912000. +> [bob:host:(1) 0.000000] [io_file_system/INFO] Disk1 (/scratch) Used: 36924298; Free: 536833987702; Total: 536870912000. > [bob:host:(1) 0.000000] [io_file_system/INFO] Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000. > [bob:host:(1) 0.005000] [io_file_system/INFO] Create a 200000 bytes file named '/scratch/tmp/data.txt' on /scratch > [bob:host:(1) 0.005000] [io_file_system/INFO] Storage info on bob: -> [bob:host:(1) 0.005000] [io_file_system/INFO] Disk1 (/scratch) Used: 37133331; Free: 536833778669; Total: 536870912000. +> [bob:host:(1) 0.005000] [io_file_system/INFO] Disk1 (/scratch) Used: 37124298; Free: 536833787702; Total: 536870912000. > [bob:host:(1) 0.005000] [io_file_system/INFO] Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000. > [bob:host:(1) 0.007000] [io_file_system/INFO] Read 200000 bytes on /scratch/tmp/data.txt > [bob:host:(1) 0.009500] [io_file_system/INFO] Write 100000 bytes on /scratch/tmp/data.txt > [bob:host:(1) 0.009500] [io_file_system/INFO] Move '/scratch/tmp/data.txt' to '/scratch/tmp/simgrid.readme' > [bob:host:(1) 0.009500] [io_file_system/INFO] User data attached to the file: 777 > [bob:host:(1) 0.009500] [io_file_system/INFO] Storage info on bob: -> [bob:host:(1) 0.009500] [io_file_system/INFO] Disk1 (/scratch) Used: 37233331; Free: 536833678669; Total: 536870912000. +> [bob:host:(1) 0.009500] [io_file_system/INFO] Disk1 (/scratch) Used: 37224298; Free: 536833687702; Total: 536870912000. > [bob:host:(1) 0.009500] [io_file_system/INFO] Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000. > [bob:host:(1) 0.009500] [io_file_system/INFO] Unlink file: '/scratch/tmp/simgrid.readme' > [bob:host:(1) 0.009500] [io_file_system/INFO] Storage info on bob: -> [bob:host:(1) 0.009500] [io_file_system/INFO] Disk1 (/scratch) Used: 36933331; Free: 536833978669; Total: 536870912000. +> [bob:host:(1) 0.009500] [io_file_system/INFO] Disk1 (/scratch) Used: 36924298; Free: 536833987702; Total: 536870912000. > [bob:host:(1) 0.009500] [io_file_system/INFO] Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000. diff --git a/examples/c/platform-failures/platform-failures.c b/examples/c/platform-failures/platform-failures.c index 59f10a271c..4b34418c1f 100644 --- a/examples/c/platform-failures/platform-failures.c +++ b/examples/c/platform-failures/platform-failures.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/platform-failures/platform-failures.tesh b/examples/c/platform-failures/platform-failures.tesh index 54fae56b0e..5aadcd8178 100644 --- a/examples/c/platform-failures/platform-failures.tesh +++ b/examples/c/platform-failures/platform-failures.tesh @@ -3,7 +3,7 @@ p Testing a simple master/worker example application handling failures TCP crosstraffic DISABLED ! output sort 19 -$ ${bindir:=.}/c-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/../../cpp/platform-failures/s4u-platform-failures_d.xml --cfg=path:${srcdir} --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose +$ ${bindir:=.}/c-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/../../cpp/platform-failures/s4u-platform-failures_d.xml --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose > [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard' > [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off. > [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process @@ -108,7 +108,7 @@ $ ${bindir:=.}/c-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${p p Testing a simple master/worker example application handling failures. TCP crosstraffic ENABLED ! output sort 19 -$ ${bindir:=.}/c-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/../../cpp/platform-failures/s4u-platform-failures_d.xml --cfg=path:${srcdir} "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose +$ ${bindir:=.}/c-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/../../cpp/platform-failures/s4u-platform-failures_d.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose > [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard' > [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off. > [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process @@ -214,7 +214,7 @@ p NOT testing the mixture of failures and CpuTI: p This test leads to a deadlock because of a bug somewhere in EngineImpl::solve. p We should debug this instead of ignoring the issue, but it's utterly p complex with such an integration test. One day, we will setup a set of -p unit tests for the surf solver, and such issues will be addressable again. +p unit tests for the model's solver, and such issues will be addressable again. p For the time being, I just give up, sorry. -p $ ${bindir:=.}/c-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/../../cpp/platform-failures/s4u-platform-failures_d.xml --cfg=path:${srcdir} --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose +p $ ${bindir:=.}/c-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/../../cpp/platform-failures/s4u-platform-failures_d.xml --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose diff --git a/examples/c/platform-properties/platform-properties.c b/examples/c/platform-properties/platform-properties.c index 444589e77f..b7909accdb 100644 --- a/examples/c/platform-properties/platform-properties.c +++ b/examples/c/platform-properties/platform-properties.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/c/plugin-host-load/plugin-host-load.c b/examples/c/plugin-host-load/plugin-host-load.c index 6a5a013212..0b4c3aa869 100644 --- a/examples/c/plugin-host-load/plugin-host-load.c +++ b/examples/c/plugin-host-load/plugin-host-load.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/c/synchro-semaphore/synchro-semaphore.c b/examples/c/synchro-semaphore/synchro-semaphore.c index c7124a40f2..d5f3828b80 100644 --- a/examples/c/synchro-semaphore/synchro-semaphore.c +++ b/examples/c/synchro-semaphore/synchro-semaphore.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt index cacac73fab..0361ccb114 100644 --- a/examples/cpp/CMakeLists.txt +++ b/examples/cpp/CMakeLists.txt @@ -13,67 +13,23 @@ set(_dht-kademlia_sources dht-kademlia/s4u-dht-kademlia.cpp dht-kademlia/s4u-dht set(_actor-stacksize_factories "^thread") # Threads ignore modifications of the stack size -# The maestro-set example only works for threads and when not using windows. +# The maestro-set example only works for threads set(_maestro-set_factories "thread") -if(WIN32) - set(_maestro-set_disable 1) -endif() if(SIMGRID_HAVE_MC) - # These tests timeout with threads, maybe because of dwarf parsing? not sure + # These tests timeout with threads, not sure why foreach(example mc-bugged1 mc-bugged2 mc-failing-assert mc-electric-fence) - set(_${example}_factories "^thread") # Timeout - add_dependencies(tests-mc s4u-${example}) + set(_${example}_factories "^thread") # Timeout + add_dependencies(tests-mc s4u-${example}) endforeach() - if(HAVE_C_STACK_CLEANER) - add_executable (s4u-mc-bugged1-liveness-cleaner-on EXCLUDE_FROM_ALL s4u-mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp) - target_link_libraries(s4u-mc-bugged1-liveness-cleaner-on simgrid) - set_target_properties(s4u-mc-bugged1-liveness-cleaner-on PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fstack-cleaner") - add_dependencies(tests-mc s4u-mc-bugged1-liveness-cleaner-on) - - add_executable (s4u-mc-bugged1-liveness-cleaner-off EXCLUDE_FROM_ALL s4u-mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp) - target_link_libraries(s4u-mc-bugged1-liveness-cleaner-off simgrid) - set_target_properties(s4u-mc-bugged1-liveness-cleaner-off PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fno-stack-cleaner") - add_dependencies(tests-mc s4u-mc-bugged1-liveness-cleaner-off) - endif() - - # Model-checking liveness - if(HAVE_UCONTEXT_CONTEXTS AND SIMGRID_PROCESSOR_x86_64) - # liveness model-checking works only on 64bits (for now ...) - set(_mc-bugged1-liveness_factories "ucontext") - add_dependencies(tests-mc s4u-mc-bugged1-liveness) - set(_mc-bugged2-liveness_factories "ucontext") - - # This example never ends, disable it for now - set(_mc-bugged2-liveness_disable 1) - - ADD_TESH(s4u-mc-bugged1-liveness-visited-ucontext --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/mc-bugged1-liveness - --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms - --cd ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness - ${CMAKE_HOME_DIRECTORY}/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh) - IF(HAVE_C_STACK_CLEANER) - add_dependencies(tests-mc s4u-mc-bugged1-liveness-stack-cleaner) - # This test checks if the stack cleaner is making a difference: - ADD_TEST(s4u-mc-bugged1-liveness-stack-cleaner ${CMAKE_HOME_DIRECTORY}/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner - ${CMAKE_HOME_DIRECTORY}/examples/cpp/mc-bugged1-liveness/ - ${CMAKE_CURRENT_BINARY_DIR}/mc-bugged1-liveness/) - ENDIF() - else() - set(_mc-bugged1-liveness_disable 1) - set(_mc-bugged2-liveness_disable 1) - endif() - if(enable_coverage) foreach (example mc-bugged1 mc-bugged2 mc-electric-fence mc-failing-assert) ADD_TEST(cover-${example} ${CMAKE_CURRENT_BINARY_DIR}/${example}/s4u-${example} ${CMAKE_HOME_DIRECTORY}/examples/platforms/model_checker_platform.xml) endforeach() - ADD_TEST(cover-mc-bugged1-liveness ${CMAKE_CURRENT_BINARY_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness ${CMAKE_HOME_DIRECTORY}/examples/platforms/small_platform.xml 1 1001) endif() - else() - foreach (example mc-bugged1 mc-bugged2 mc-centralized-mutex mc-failing-assert mc-electric-fence - mc-bugged1-liveness mc-bugged2-liveness) + foreach (example mc-bugged1 mc-bugged2 mc-centralized-mutex mc-failing-assert mc-electric-fence) set(_${example}_disable 1) endforeach() endif() @@ -84,21 +40,51 @@ foreach (example synchro-barrier synchro-mutex synchro-semaphore) if (SIMGRID_HAVE_MC) ADD_TESH(s4u-mc-${example} - --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example} - --setenv libdir=${CMAKE_BINARY_DIR}/lib - --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms - --setenv srcdir=${CMAKE_CURRENT_SOURCE_DIR}/${example} - --cd ${CMAKE_CURRENT_SOURCE_DIR}/${example} - ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-mc-${example}.tesh) + --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example} + --setenv libdir=${CMAKE_BINARY_DIR}/lib + --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms + --setenv srcdir=${CMAKE_CURRENT_SOURCE_DIR}/${example} + --cd ${CMAKE_CURRENT_SOURCE_DIR}/${example} + ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-mc-${example}.tesh) + + add_dependencies(tests-mc s4u-${example}) endif() endforeach() +if (SIMGRID_HAVE_MC) + # Dependency on the regular tests + foreach(example mc-centralized-mutex) + add_dependencies(tests-mc s4u-${example}) + endforeach() +endif() if(NOT HAVE_GRAPHVIZ) set(_dag-from-dot_disable 1) + set(_dag-from-dot-simple_disable 1) +endif() + +if (NOT SIMGRID_HAVE_JSON) + set(_dag-from-json-simple_disable 1) endif() -if(NOT SIMGRID_HAVE_NS3) +if(SIMGRID_HAVE_NS3) + if(NS3_VERSION VERSION_GREATER_EQUAL 3.37) + set(_network-ns3_teshfile ${CMAKE_HOME_DIRECTORY}/examples/cpp/network-ns3/s4u-network-ns3-timed.tesh) + set(tesh_files ${tesh_files} ${CMAKE_HOME_DIRECTORY}/examples/cpp/network-ns3/s4u-network-ns3-notime.tesh) + else() + set(_network-ns3_teshfile ${CMAKE_HOME_DIRECTORY}/examples/cpp/network-ns3/s4u-network-ns3-notime.tesh) + set(tesh_files ${tesh_files} ${CMAKE_HOME_DIRECTORY}/examples/cpp/network-ns3/s4u-network-ns3-timed.tesh) + endif() + +foreach (example network-ns3 network-ns3-wifi) + add_dependencies(tests-ns3 s4u-${example}) +endforeach() + +else() + # Even if ns3 is not found, we need to override the teshfile name and make sure that everything gets included in the archive + set(_network-ns3_teshfile ${CMAKE_HOME_DIRECTORY}/examples/cpp/network-ns3/s4u-network-ns3-notime.tesh) + set(tesh_files ${tesh_files} ${CMAKE_HOME_DIRECTORY}/examples/cpp/network-ns3/s4u-network-ns3-timed.tesh) + foreach (example network-ns3 network-ns3-wifi) set(_${example}_disable 1) endforeach() @@ -106,25 +92,30 @@ endif() # Deal with each example -foreach (example activity-testany activity-waitany +foreach (example activityset-testany activityset-waitany activityset-waitall activityset-waitallfor actor-create actor-daemon actor-exiting actor-join actor-kill actor-lifetime actor-migrate actor-suspend actor-yield actor-stacksize app-bittorrent app-chainsend app-token-ring - comm-pingpong comm-ready comm-serialize comm-suspend comm-testany comm-wait comm-waitany comm-waitall comm-waituntil + battery-chiller-solar battery-connector battery-degradation battery-simple battery-energy + chiller-simple + comm-pingpong comm-ready comm-suspend comm-wait comm-waituntil comm-dependent comm-host2host comm-failure comm-throttling cloud-capping cloud-migration cloud-simple - dag-comm dag-from-dax dag-from-dot dag-failure dag-io dag-scheduling dag-simple + dag-comm dag-from-json-simple dag-from-dax-simple dag-from-dax dag-from-dot-simple dag-from-dot dag-failure dag-io dag-scheduling dag-simple dag-tuto dht-chord dht-kademlia energy-exec energy-boot energy-link energy-vm energy-exec-ptask energy-wifi engine-filtering engine-run-partial - exec-async exec-basic exec-dvfs exec-remote exec-waitany exec-waitfor exec-dependent exec-unassigned + exec-async exec-basic exec-dvfs exec-remote exec-waitfor exec-dependent exec-unassigned exec-ptask-multicore exec-ptask-multicore-latency exec-cpu-nonlinear exec-cpu-factors exec-failure exec-threads maestro-set - mc-bugged1 mc-bugged1-liveness mc-bugged2 mc-bugged2-liveness mc-centralized-mutex mc-electric-fence mc-failing-assert + mc-bugged1 mc-bugged2 mc-centralized-mutex mc-electric-fence mc-failing-assert + mess-wait network-ns3 network-ns3-wifi network-wifi io-async io-priority io-degradation io-file-system io-file-remote io-disk-raw io-dependent - platform-failures platform-profile platform-properties - plugin-host-load plugin-link-load plugin-prodcons + task-dispatch task-io task-microservice task-parallelism task-simple task-storm task-switch-host task-variable-load + solar-panel-simple + platform-comm-serialize platform-failures platform-profile platform-properties + plugin-host-load plugin-jbod plugin-link-load plugin-prodcons replay-comm replay-io routing-get-clusters synchro-barrier synchro-condition-variable synchro-condition-variable-waituntil synchro-mutex synchro-semaphore @@ -135,6 +126,11 @@ foreach (example activity-testany activity-waitany set(_${example}_sources ${example}/s4u-${example}.cpp) endif() + # Use default tesh file unless specified otherwise + if(NOT DEFINED _${example}_teshfile) + set(_${example}_teshfile ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}.tesh) + endif() + if(NOT DEFINED _${example}_disable) add_executable (s4u-${example} EXCLUDE_FROM_ALL ${_${example}_sources}) add_dependencies (tests s4u-${example}) @@ -154,19 +150,20 @@ foreach (example activity-testany activity-waitany --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv srcdir=${CMAKE_CURRENT_SOURCE_DIR}/${example} --cd ${CMAKE_CURRENT_SOURCE_DIR}/${example} - ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}.tesh) + ${_${example}_teshfile}) else() message(STATUS "Example ${example} disabled, thus not compiled.") unset(_${example}_disable) endif() - set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/s4u-${example}.tesh) + set(tesh_files ${tesh_files} ${_${example}_teshfile}) foreach(file ${_${example}_sources}) set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${file}) endforeach() unset(_${example}_factories) unset(_${example}_sources) + unset(_${example}_teshfile) endforeach() @@ -204,6 +201,20 @@ foreach(example app-bittorrent app-masterworkers ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}.tesh) endforeach() +# Test non-DPOR reductions on a given MC test +foreach(example mc-failing-assert) + + if(SIMGRID_HAVE_MC) + ADD_TESH(s4u-${example}-nodpor --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example} + --setenv libdir=${CMAKE_BINARY_DIR}/lib + --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms + --setenv srcdir=${CMAKE_CURRENT_SOURCE_DIR}/${example} + --cd ${CMAKE_CURRENT_SOURCE_DIR}/${example} + ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}-nodpor.tesh) + endif() + set(tesh_files ${tesh_files} ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}-nodpor.tesh) +endforeach() + # Examples not accepting factories ################################## @@ -224,7 +235,7 @@ foreach (example exec-ptask trace-categories trace-masterworkers trace-platform ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}.tesh) endforeach() -if (NOT enable_memcheck AND NOT WIN32) +if (NOT enable_memcheck) ADD_TESH(debug-breakpoint --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/comm-pingpong --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms ${CMAKE_CURRENT_SOURCE_DIR}/comm-pingpong/debug-breakpoint.tesh) @@ -232,10 +243,8 @@ endif() # Add all extra files to the archive #################################### -set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp PARENT_SCOPE) -set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/comm-pingpong/debug-breakpoint.tesh - ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh - ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh PARENT_SCOPE) +set(examples_src ${examples_src} PARENT_SCOPE) +set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/comm-pingpong/debug-breakpoint.tesh PARENT_SCOPE) set(xml_files ${xml_files} ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/s4u-actor-create_d.xml ${CMAKE_CURRENT_SOURCE_DIR}/actor-lifetime/s4u-actor-lifetime_d.xml ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/s4u-app-bittorrent_d.xml @@ -255,14 +264,15 @@ set(xml_files ${xml_files} ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/s4u-a ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/dogbone_d.xml ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/onelink_d.xml ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/one_cluster_d.xml PARENT_SCOPE) -set(bin_files ${bin_files} ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/generate.py - ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner - ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/promela_bugged1_liveness - ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged2-liveness/promela_bugged2_liveness PARENT_SCOPE) +set(bin_files ${bin_files} ${CMAKE_CURRENT_SOURCE_DIR}/battery-degradation/plot_battery_degradation.py + ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/generate.py PARENT_SCOPE) set(txt_files ${txt_files} ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-dax/simple_dax_with_cycle.xml ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-dax/smalldax.xml + ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-dax-simple/dag.xml ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-dot/dag.dot + ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-dot-simple/dag.dot ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-dot/dag_with_cycle.dot + ${CMAKE_CURRENT_SOURCE_DIR}/dag-from-json-simple/dag.json ${CMAKE_CURRENT_SOURCE_DIR}/replay-comm/s4u-replay-comm-split-p0.txt ${CMAKE_CURRENT_SOURCE_DIR}/replay-comm/s4u-replay-comm-split-p1.txt ${CMAKE_CURRENT_SOURCE_DIR}/replay-comm/s4u-replay-comm.txt diff --git a/examples/cpp/activity-waitany/s4u-activity-waitany.cpp b/examples/cpp/activity-waitany/s4u-activity-waitany.cpp deleted file mode 100644 index aa13b415dc..0000000000 --- a/examples/cpp/activity-waitany/s4u-activity-waitany.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/s4u.hpp" -#include -#include -#include -namespace sg4 = simgrid::s4u; - -XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waittany, "Messages specific for this s4u example"); - -static void bob() -{ - sg4::Mailbox* mbox = sg4::Mailbox::by_name(std::string("mbox")); - const sg4::Disk* disk = sg4::Host::current()->get_disks().front(); - std::string* payload; - - XBT_INFO("Create my asynchronous activities"); - auto exec = sg4::this_actor::exec_async(5e9); - auto comm = mbox->get_async(&payload); - auto io = disk->read_async(3e8); - - std::vector pending_activities = {boost::dynamic_pointer_cast(exec), - boost::dynamic_pointer_cast(comm), - boost::dynamic_pointer_cast(io)}; - - XBT_INFO("Wait for asynchrounous activities to complete"); - while (not pending_activities.empty()) { - ssize_t changed_pos = sg4::Activity::wait_any(pending_activities); - if (changed_pos != -1) { - auto* completed_one = pending_activities[changed_pos].get(); - if (dynamic_cast(completed_one)) - XBT_INFO("Completed a Comm"); - if (dynamic_cast(completed_one)) - XBT_INFO("Completed an Exec"); - if (dynamic_cast(completed_one)) - XBT_INFO("Completed an I/O"); - pending_activities.erase(pending_activities.begin() + changed_pos); - } - } - XBT_INFO("Last activity is complete"); - delete payload; -} - -static void alice() -{ - auto* payload = new std::string("Message"); - XBT_INFO("Send '%s'", payload->c_str()); - sg4::Mailbox::by_name(std::string("mbox"))->put(payload, 6e8); -} - -int main(int argc, char* argv[]) -{ - sg4::Engine e(&argc, argv); - - e.load_platform(argv[1]); - - sg4::Actor::create("bob", e.host_by_name("bob"), bob); - sg4::Actor::create("alice", e.host_by_name("alice"), alice); - - e.run(); - - return 0; -} diff --git a/examples/cpp/activity-testany/s4u-activity-testany.cpp b/examples/cpp/activityset-testany/s4u-activityset-testany.cpp similarity index 55% rename from examples/cpp/activity-testany/s4u-activity-testany.cpp rename to examples/cpp/activityset-testany/s4u-activityset-testany.cpp index 6dc8769d28..d782094435 100644 --- a/examples/cpp/activity-testany/s4u-activity-testany.cpp +++ b/examples/cpp/activityset-testany/s4u-activityset-testany.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,54 +7,64 @@ #include #include #include + namespace sg4 = simgrid::s4u; XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_testany, "Messages specific for this s4u example"); static void bob() { - sg4::Mailbox* mbox = sg4::Mailbox::by_name(std::string("mbox")); - const sg4::Disk* disk = sg4::Host::current()->get_disks().front(); + sg4::Mailbox* mbox = sg4::Mailbox::by_name("mbox"); + sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("mqueue"); + const sg4::Disk* disk = sg4::Host::current()->get_disks().front(); std::string* payload; + std::string* message; XBT_INFO("Create my asynchronous activities"); auto exec = sg4::this_actor::exec_async(5e9); auto comm = mbox->get_async(&payload); + auto mess = mqueue->get_async(&message); auto io = disk->read_async(3e8); - std::vector pending_activities = {boost::dynamic_pointer_cast(exec), - boost::dynamic_pointer_cast(comm), - boost::dynamic_pointer_cast(io)}; - + sg4::ActivitySet pending_activities({exec, comm, mess, io}); XBT_INFO("Sleep_for a while"); sg4::this_actor::sleep_for(1); XBT_INFO("Test for completed activities"); while (not pending_activities.empty()) { - ssize_t changed_pos = sg4::Activity::test_any(pending_activities); - if (changed_pos != -1) { - auto* completed_one = pending_activities[changed_pos].get(); - if (dynamic_cast(completed_one)) + auto completed_one = pending_activities.test_any(); + if (completed_one != nullptr) { + if (boost::dynamic_pointer_cast(completed_one)) XBT_INFO("Completed a Comm"); - if (dynamic_cast(completed_one)) + if (boost::dynamic_pointer_cast(completed_one)) + XBT_INFO("Completed a Mess"); + if (boost::dynamic_pointer_cast(completed_one)) XBT_INFO("Completed an Exec"); - if (dynamic_cast(completed_one)) + if (boost::dynamic_pointer_cast(completed_one)) XBT_INFO("Completed an I/O"); - pending_activities.erase(pending_activities.begin() + changed_pos); - } else { // nothing matches, wait for a little bit + } else { XBT_INFO("Nothing matches, test again in 0.5s"); sg4::this_actor::sleep_for(.5); } } XBT_INFO("Last activity is complete"); delete payload; + delete message; } static void alice() { auto* payload = new std::string("Message"); XBT_INFO("Send '%s'", payload->c_str()); - sg4::Mailbox::by_name(std::string("mbox"))->put(payload, 6e8); + sg4::Mailbox::by_name("mbox")->put(payload, 6e8); +} + +static void carl() +{ + sg4::this_actor::sleep_for(1.99); + auto* payload = new std::string("Control Message"); + XBT_INFO("Send '%s'", payload->c_str()); + sg4::MessageQueue::by_name("mqueue")->put(payload); } int main(int argc, char* argv[]) @@ -65,6 +75,7 @@ int main(int argc, char* argv[]) sg4::Actor::create("bob", e.host_by_name("bob"), bob); sg4::Actor::create("alice", e.host_by_name("alice"), alice); + sg4::Actor::create("carl", e.host_by_name("carl"), carl); e.run(); diff --git a/examples/cpp/activityset-testany/s4u-activityset-testany.tesh b/examples/cpp/activityset-testany/s4u-activityset-testany.tesh new file mode 100644 index 0000000000..029e90b8cc --- /dev/null +++ b/examples/cpp/activityset-testany/s4u-activityset-testany.tesh @@ -0,0 +1,22 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-activityset-testany ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%4.2r]%e[%5a]%e%m%n" +> [0.00] [alice] Send 'Message' +> [0.00] [ bob] Create my asynchronous activities +> [0.00] [ bob] Sleep_for a while +> [1.00] [ bob] Test for completed activities +> [1.00] [ bob] Nothing matches, test again in 0.5s +> [1.50] [ bob] Nothing matches, test again in 0.5s +> [1.99] [ carl] Send 'Control Message' +> [2.00] [ bob] Completed a Mess +> [2.00] [ bob] Nothing matches, test again in 0.5s +> [2.50] [ bob] Nothing matches, test again in 0.5s +> [3.00] [ bob] Completed an I/O +> [3.00] [ bob] Nothing matches, test again in 0.5s +> [3.50] [ bob] Nothing matches, test again in 0.5s +> [4.00] [ bob] Nothing matches, test again in 0.5s +> [4.50] [ bob] Nothing matches, test again in 0.5s +> [5.00] [ bob] Completed an Exec +> [5.00] [ bob] Nothing matches, test again in 0.5s +> [5.50] [ bob] Completed a Comm +> [5.50] [ bob] Last activity is complete diff --git a/examples/cpp/activityset-waitall/s4u-activityset-waitall.cpp b/examples/cpp/activityset-waitall/s4u-activityset-waitall.cpp new file mode 100644 index 0000000000..2c9cf1ad8b --- /dev/null +++ b/examples/cpp/activityset-waitall/s4u-activityset-waitall.cpp @@ -0,0 +1,64 @@ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" +#include +#include +#include +namespace sg4 = simgrid::s4u; + +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waitall, "Messages specific for this s4u example"); + +static void bob() +{ + sg4::Mailbox* mbox = sg4::Mailbox::by_name("mbox"); + sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("mqueue"); + const sg4::Disk* disk = sg4::Host::current()->get_disks().front(); + std::string* payload; + std::string* message; + + XBT_INFO("Create my asynchronous activities"); + auto exec = sg4::this_actor::exec_async(5e9); + auto comm = mbox->get_async(&payload); + auto io = disk->read_async(3e8); + auto mess = mqueue->get_async(&message); + + sg4::ActivitySet pending_activities({exec, comm, io, mess}); + + XBT_INFO("Wait for asynchronous activities to complete, all in one shot."); + pending_activities.wait_all(); + + XBT_INFO("All activities are completed."); + delete payload; + delete message; +} + +static void alice() +{ + auto* payload = new std::string("Message"); + XBT_INFO("Send '%s'", payload->c_str()); + sg4::Mailbox::by_name("mbox")->put(payload, 6e8); +} + +static void carl() +{ + auto* payload = new std::string("Control Message"); + sg4::MessageQueue::by_name("mqueue")->put(payload); +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + + e.load_platform(argv[1]); + + sg4::Actor::create("bob", e.host_by_name("bob"), bob); + sg4::Actor::create("alice", e.host_by_name("alice"), alice); + sg4::Actor::create("carl", e.host_by_name("carl"), carl); + + e.run(); + + return 0; +} diff --git a/examples/cpp/activityset-waitall/s4u-activityset-waitall.tesh b/examples/cpp/activityset-waitall/s4u-activityset-waitall.tesh new file mode 100644 index 0000000000..889b405865 --- /dev/null +++ b/examples/cpp/activityset-waitall/s4u-activityset-waitall.tesh @@ -0,0 +1,7 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-activityset-waitall ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%7.6r]%e[%5a]%e%m%n" +> [0.000000] [alice] Send 'Message' +> [0.000000] [ bob] Create my asynchronous activities +> [0.000000] [ bob] Wait for asynchronous activities to complete, all in one shot. +> [5.197828] [ bob] All activities are completed. diff --git a/examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.cpp b/examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.cpp new file mode 100644 index 0000000000..a322cc4f1b --- /dev/null +++ b/examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.cpp @@ -0,0 +1,81 @@ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" +#include +#include +#include +namespace sg4 = simgrid::s4u; + +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waitallfor, "Messages specific for this s4u example"); + +static void bob() +{ + sg4::Mailbox* mbox = sg4::Mailbox::by_name("mbox"); + sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("mqueue"); + const sg4::Disk* disk = sg4::Host::current()->get_disks().front(); + std::string* payload; + std::string* message; + + XBT_INFO("Create my asynchronous activities"); + auto exec = sg4::this_actor::exec_async(5e9); + auto comm = mbox->get_async(&payload); + auto io = disk->read_async(3e8); + auto mess = mqueue->get_async(&message); + + sg4::ActivitySet pending_activities({exec, comm, io, mess}); + + XBT_INFO("Wait for asynchronous activities to complete"); + while (not pending_activities.empty()) { + try { + pending_activities.wait_all_for(1); + } catch (simgrid::TimeoutException& e) { + XBT_INFO("Not all activities are terminated yet."); + } + while (auto completed_one = pending_activities.test_any()) { + if (boost::dynamic_pointer_cast(completed_one)) + XBT_INFO("Completed a Comm"); + if (boost::dynamic_pointer_cast(completed_one)) + XBT_INFO("Completed a Mess"); + if (boost::dynamic_pointer_cast(completed_one)) + XBT_INFO("Completed an Exec"); + if (boost::dynamic_pointer_cast(completed_one)) + XBT_INFO("Completed an I/O"); + } + } + XBT_INFO("Last activity is complete"); + delete payload; + delete message; +} + +static void alice() +{ + auto* payload = new std::string("Message"); + XBT_INFO("Send '%s'", payload->c_str()); + sg4::Mailbox::by_name("mbox")->put(payload, 6e8); +} + +static void carl() +{ + sg4::this_actor::sleep_for(1.99); + auto* payload = new std::string("Control Message"); + XBT_INFO("Send '%s'", payload->c_str()); + sg4::MessageQueue::by_name("mqueue")->put(payload); +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + + e.load_platform(argv[1]); + + sg4::Actor::create("bob", e.host_by_name("bob"), bob); + sg4::Actor::create("alice", e.host_by_name("alice"), alice); + sg4::Actor::create("carl", e.host_by_name("carl"), carl); + + e.run(); + + return 0; +} diff --git a/examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.tesh b/examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.tesh new file mode 100644 index 0000000000..ce8db4ac50 --- /dev/null +++ b/examples/cpp/activityset-waitallfor/s4u-activityset-waitallfor.tesh @@ -0,0 +1,17 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-activityset-waitallfor ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%7.6r]%e[%5a]%e%m%n" +> [0.000000] [alice] Send 'Message' +> [0.000000] [ bob] Create my asynchronous activities +> [0.000000] [ bob] Wait for asynchronous activities to complete +> [1.000000] [ bob] Not all activities are terminated yet. +> [1.990000] [ carl] Send 'Control Message' +> [2.000000] [ bob] Not all activities are terminated yet. +> [2.000000] [ bob] Completed a Mess +> [3.000000] [ bob] Not all activities are terminated yet. +> [3.000000] [ bob] Completed an I/O +> [4.000000] [ bob] Not all activities are terminated yet. +> [5.000000] [ bob] Not all activities are terminated yet. +> [5.000000] [ bob] Completed an Exec +> [5.197828] [ bob] Completed a Comm +> [5.197828] [ bob] Last activity is complete diff --git a/examples/cpp/activityset-waitany/s4u-activityset-waitany.cpp b/examples/cpp/activityset-waitany/s4u-activityset-waitany.cpp new file mode 100644 index 0000000000..6c8baef61e --- /dev/null +++ b/examples/cpp/activityset-waitany/s4u-activityset-waitany.cpp @@ -0,0 +1,77 @@ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" +#include +#include +#include +namespace sg4 = simgrid::s4u; + +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_activity_waitany, "Messages specific for this s4u example"); + +static void bob() +{ + sg4::Mailbox* mbox = sg4::Mailbox::by_name("mbox"); + sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("mqueue"); + const sg4::Disk* disk = sg4::Host::current()->get_disks().front(); + std::string* payload; + std::string* message; + + XBT_INFO("Create my asynchronous activities"); + auto exec = sg4::this_actor::exec_async(5e9); + auto comm = mbox->get_async(&payload); + auto io = disk->read_async(3e8); + auto mess = mqueue->get_async(&message); + + sg4::ActivitySet pending_activities({exec, comm, io, mess}); + + XBT_INFO("Wait for asynchronous activities to complete"); + while (not pending_activities.empty()) { + auto completed_one = pending_activities.wait_any(); + if (completed_one != nullptr) { + if (boost::dynamic_pointer_cast(completed_one)) + XBT_INFO("Completed a Comm"); + if (boost::dynamic_pointer_cast(completed_one)) + XBT_INFO("Completed a Mess"); + if (boost::dynamic_pointer_cast(completed_one)) + XBT_INFO("Completed an Exec"); + if (boost::dynamic_pointer_cast(completed_one)) + XBT_INFO("Completed an I/O"); + } + } + XBT_INFO("Last activity is complete"); + delete payload; + delete message; +} + +static void alice() +{ + auto* payload = new std::string("Message"); + XBT_INFO("Send '%s'", payload->c_str()); + sg4::Mailbox::by_name("mbox")->put(payload, 6e8); +} + +static void carl() +{ + sg4::this_actor::sleep_for(2); + auto* payload = new std::string("Control Message"); + XBT_INFO("Send '%s'", payload->c_str()); + sg4::MessageQueue::by_name("mqueue")->put(payload); +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + + e.load_platform(argv[1]); + + sg4::Actor::create("bob", e.host_by_name("bob"), bob); + sg4::Actor::create("alice", e.host_by_name("alice"), alice); + sg4::Actor::create("carl", e.host_by_name("carl"), carl); + + e.run(); + + return 0; +} diff --git a/examples/cpp/activityset-waitany/s4u-activityset-waitany.tesh b/examples/cpp/activityset-waitany/s4u-activityset-waitany.tesh new file mode 100644 index 0000000000..e665de5b6c --- /dev/null +++ b/examples/cpp/activityset-waitany/s4u-activityset-waitany.tesh @@ -0,0 +1,12 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-activityset-waitany ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%7.6r]%e[%5a]%e%m%n" +> [0.000000] [alice] Send 'Message' +> [0.000000] [ bob] Create my asynchronous activities +> [0.000000] [ bob] Wait for asynchronous activities to complete +> [2.000000] [ carl] Send 'Control Message' +> [2.000000] [ bob] Completed a Mess +> [3.000000] [ bob] Completed an I/O +> [5.000000] [ bob] Completed an Exec +> [5.197828] [ bob] Completed a Comm +> [5.197828] [ bob] Last activity is complete diff --git a/examples/cpp/actor-create/s4u-actor-create.cpp b/examples/cpp/actor-create/s4u-actor-create.cpp index 15059a7471..a3c1f38690 100644 --- a/examples/cpp/actor-create/s4u-actor-create.cpp +++ b/examples/cpp/actor-create/s4u-actor-create.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -90,7 +90,7 @@ int main(int argc, char** argv) sg4::Engine e(&argc, argv); /* Then you should load a platform file, describing your simulated platform */ - e.load_platform("../../platforms/small_platform.xml"); + e.load_platform(argc > 1 ? argv[1] : "../../platforms/small_platform.xml"); /* And now you have to ask SimGrid to actually start your actors. * @@ -118,7 +118,7 @@ int main(int argc, char** argv) e.register_actor("sender"); // The sender class is passed as a template parameter here e.register_function("forwarder", &forwarder); /* Once actors and functions are registered, just load the deployment file */ - e.load_deployment("s4u-actor-create_d.xml"); + e.load_deployment(argc > 2 ? argv[2] : "s4u-actor-create_d.xml"); /* Once every actors are started in the engine, the simulation can start */ e.run(); diff --git a/examples/cpp/actor-daemon/s4u-actor-daemon.cpp b/examples/cpp/actor-daemon/s4u-actor-daemon.cpp index e6862ae7c0..b023e81051 100644 --- a/examples/cpp/actor-daemon/s4u-actor-daemon.cpp +++ b/examples/cpp/actor-daemon/s4u-actor-daemon.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/actor-exiting/s4u-actor-exiting.cpp b/examples/cpp/actor-exiting/s4u-actor-exiting.cpp index 5cef906dc5..2b6a3866f8 100644 --- a/examples/cpp/actor-exiting/s4u-actor-exiting.cpp +++ b/examples/cpp/actor-exiting/s4u-actor-exiting.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/actor-exiting/s4u-actor-exiting.tesh b/examples/cpp/actor-exiting/s4u-actor-exiting.tesh index cb819512b1..660b0839f5 100644 --- a/examples/cpp/actor-exiting/s4u-actor-exiting.tesh +++ b/examples/cpp/actor-exiting/s4u-actor-exiting.tesh @@ -12,7 +12,7 @@ $ ${bindir:=.}/s4u-actor-exiting ${platfdir}/small_platform.xml "--log=root.fmt: > [ 3.000000] (maestro@) Oops! Deadlock detected, some activities are still around but will never complete. This usually happens when the user code is not perfectly clean. > [ 3.000000] (maestro@) 1 actors are still running, waiting for something. > [ 3.000000] (maestro@) Legend of the following listing: "Actor (@): " -> [ 3.000000] (maestro@) Actor 3 (C@Ginette): waiting for communication activity 0xdeadbeef () in state WAITING to finish +> [ 3.000000] (maestro@) Actor 3 (C@Ginette): waiting for communication activity 0xdeadbeef () in state WAITING to finish > [ 3.000000] (C@Ginette) I was killed! > [ 3.000000] (C@Ginette) The backtrace would be displayed here if --log=no_loc would not have been passed > [ 3.000000] (maestro@) Actor C terminates now diff --git a/examples/cpp/actor-join/s4u-actor-join.cpp b/examples/cpp/actor-join/s4u-actor-join.cpp index 3c56614f50..f565df8646 100644 --- a/examples/cpp/actor-join/s4u-actor-join.cpp +++ b/examples/cpp/actor-join/s4u-actor-join.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/actor-kill/s4u-actor-kill.cpp b/examples/cpp/actor-kill/s4u-actor-kill.cpp index 05dc2a39e7..1fc1598368 100644 --- a/examples/cpp/actor-kill/s4u-actor-kill.cpp +++ b/examples/cpp/actor-kill/s4u-actor-kill.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/actor-lifetime/s4u-actor-lifetime.cpp b/examples/cpp/actor-lifetime/s4u-actor-lifetime.cpp index 79d430c978..45df8433ed 100644 --- a/examples/cpp/actor-lifetime/s4u-actor-lifetime.cpp +++ b/examples/cpp/actor-lifetime/s4u-actor-lifetime.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/actor-migrate/s4u-actor-migrate.cpp b/examples/cpp/actor-migrate/s4u-actor-migrate.cpp index 5b1c97c928..5146a5acfd 100644 --- a/examples/cpp/actor-migrate/s4u-actor-migrate.cpp +++ b/examples/cpp/actor-migrate/s4u-actor-migrate.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/actor-stacksize/s4u-actor-stacksize.cpp b/examples/cpp/actor-stacksize/s4u-actor-stacksize.cpp index 227f1c1185..9876ad6f89 100644 --- a/examples/cpp/actor-stacksize/s4u-actor-stacksize.cpp +++ b/examples/cpp/actor-stacksize/s4u-actor-stacksize.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/actor-suspend/s4u-actor-suspend.cpp b/examples/cpp/actor-suspend/s4u-actor-suspend.cpp index 337c42e2c0..ba30d6fe47 100644 --- a/examples/cpp/actor-suspend/s4u-actor-suspend.cpp +++ b/examples/cpp/actor-suspend/s4u-actor-suspend.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/actor-yield/s4u-actor-yield.cpp b/examples/cpp/actor-yield/s4u-actor-yield.cpp index bb1e0a791b..aaa3a6a9a7 100644 --- a/examples/cpp/actor-yield/s4u-actor-yield.cpp +++ b/examples/cpp/actor-yield/s4u-actor-yield.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/app-bittorrent/s4u-bittorrent.cpp b/examples/cpp/app-bittorrent/s4u-bittorrent.cpp index 216ebeaa8c..647b8ce092 100644 --- a/examples/cpp/app-bittorrent/s4u-bittorrent.cpp +++ b/examples/cpp/app-bittorrent/s4u-bittorrent.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/app-bittorrent/s4u-bittorrent.hpp b/examples/cpp/app-bittorrent/s4u-bittorrent.hpp index e57d696ddc..a05072fd78 100644 --- a/examples/cpp/app-bittorrent/s4u-bittorrent.hpp +++ b/examples/cpp/app-bittorrent/s4u-bittorrent.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/app-bittorrent/s4u-peer.cpp b/examples/cpp/app-bittorrent/s4u-peer.cpp index bcbde2c05c..43f7f46a74 100644 --- a/examples/cpp/app-bittorrent/s4u-peer.cpp +++ b/examples/cpp/app-bittorrent/s4u-peer.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -43,14 +43,14 @@ constexpr unsigned message_size(MessageType type) /* REQUEST */ 17, /* PIECE */ 13, /* CANCEL */ 17}}; - return sizes[static_cast(type)]; + return sizes.at(static_cast(type)); } constexpr const char* message_name(MessageType type) { constexpr std::array names{{"HANDSHAKE", "CHOKE", "UNCHOKE", "INTERESTED", "NOTINTERESTED", "HAVE", "BITFIELD", "REQUEST", "PIECE", "CANCEL"}}; - return names[static_cast(type)]; + return names.at(static_cast(type)); } Peer::Peer(std::vector args) diff --git a/examples/cpp/app-bittorrent/s4u-peer.hpp b/examples/cpp/app-bittorrent/s4u-peer.hpp index c7a67928dd..25415d9957 100644 --- a/examples/cpp/app-bittorrent/s4u-peer.hpp +++ b/examples/cpp/app-bittorrent/s4u-peer.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/app-bittorrent/s4u-tracker.cpp b/examples/cpp/app-bittorrent/s4u-tracker.cpp index c94b0fa262..c74207239c 100644 --- a/examples/cpp/app-bittorrent/s4u-tracker.cpp +++ b/examples/cpp/app-bittorrent/s4u-tracker.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/app-bittorrent/s4u-tracker.hpp b/examples/cpp/app-bittorrent/s4u-tracker.hpp index 8cb26e6173..fb7edc0678 100644 --- a/examples/cpp/app-bittorrent/s4u-tracker.hpp +++ b/examples/cpp/app-bittorrent/s4u-tracker.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/app-chainsend/s4u-app-chainsend.cpp b/examples/cpp/app-chainsend/s4u-app-chainsend.cpp index bddfeb45c3..bd7e25d56a 100644 --- a/examples/cpp/app-chainsend/s4u-app-chainsend.cpp +++ b/examples/cpp/app-chainsend/s4u-app-chainsend.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -34,8 +34,8 @@ public: sg4::Mailbox* prev = nullptr; sg4::Mailbox* next = nullptr; sg4::Mailbox* me = nullptr; - std::vector pending_recvs; - std::vector pending_sends; + sg4::ActivitySet pending_recvs; + sg4::ActivitySet pending_sends; unsigned long long received_bytes = 0; unsigned int received_pieces = 0; @@ -60,17 +60,16 @@ public: while (not done) { sg4::CommPtr comm = me->get_async(&received); - pending_recvs.push_back(comm); + pending_recvs.push(comm); - ssize_t idx = sg4::Comm::wait_any(pending_recvs); - if (idx != -1) { - comm = pending_recvs.at(idx); + auto completed_one = pending_recvs.wait_any(); + if (completed_one != nullptr) { + comm = boost::dynamic_pointer_cast(completed_one); XBT_DEBUG("Peer %s got a 'SEND_DATA' message", me->get_cname()); - pending_recvs.erase(pending_recvs.begin() + idx); if (next != nullptr) { XBT_DEBUG("Sending (asynchronously) from %s to %s", me->get_cname(), next->get_cname()); sg4::CommPtr send = next->put_async(received, MESSAGE_SEND_DATA_HEADER_SIZE + PIECE_SIZE); - pending_sends.push_back(send); + pending_sends.push(send); } else delete received; @@ -110,20 +109,20 @@ public: void sendFile() { - std::vector pending_sends; + sg4::ActivitySet pending_sends; for (unsigned int current_piece = 0; current_piece < piece_count; current_piece++) { XBT_DEBUG("Sending (send) piece %u from %s into mailbox %s", current_piece, sg4::Host::current()->get_cname(), first->get_cname()); sg4::CommPtr comm = first->put_async(new FilePiece(), MESSAGE_SEND_DATA_HEADER_SIZE + PIECE_SIZE); - pending_sends.push_back(comm); + pending_sends.push(comm); } - sg4::Comm::wait_all(pending_sends); + pending_sends.wait_all(); } Broadcaster(int hostcount, unsigned int piece_count) : piece_count(piece_count) { for (int i = 1; i <= hostcount; i++) { - std::string name = std::string("node-") + std::to_string(i) + ".simgrid.org"; + std::string name = "node-" + std::to_string(i) + ".simgrid.org"; XBT_DEBUG("%s", name.c_str()); mailboxes.push_back(sg4::Mailbox::by_name(name)); } @@ -140,7 +139,7 @@ static void peer() p.joinChain(); p.forwardFile(); - sg4::Comm::wait_all(p.pending_sends); + p.pending_sends.wait_all(); double end_time = sg4::Engine::get_clock(); XBT_INFO("### %f %llu bytes (Avg %f MB/s); copy finished (simulated).", end_time - start_time, p.received_bytes, diff --git a/examples/cpp/app-masterworkers/s4u-app-masterworkers-class.cpp b/examples/cpp/app-masterworkers/s4u-app-masterworkers-class.cpp index 4324bad811..8df29b90a5 100644 --- a/examples/cpp/app-masterworkers/s4u-app-masterworkers-class.cpp +++ b/examples/cpp/app-masterworkers/s4u-app-masterworkers-class.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/app-masterworkers/s4u-app-masterworkers-fun.cpp b/examples/cpp/app-masterworkers/s4u-app-masterworkers-fun.cpp index fe07ce7a34..cc020c3bb5 100644 --- a/examples/cpp/app-masterworkers/s4u-app-masterworkers-fun.cpp +++ b/examples/cpp/app-masterworkers/s4u-app-masterworkers-fun.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/app-token-ring/s4u-app-token-ring.cpp b/examples/cpp/app-token-ring/s4u-app-token-ring.cpp index 6f8a4ce11b..7a36d1d1cd 100644 --- a/examples/cpp/app-token-ring/s4u-app-token-ring.cpp +++ b/examples/cpp/app-token-ring/s4u-app-token-ring.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.cpp b/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.cpp new file mode 100644 index 0000000000..00fff065c0 --- /dev/null +++ b/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.cpp @@ -0,0 +1,124 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example combine the battery plugin, the chiller plugin and the solar + panel plugin. It illustrates how to use them together to evaluate the amount + of brown energy (from the electrical grid) and green energy (from the solar + panel) consumed by several machines. + + In this scenario we have two host placed in a room. + The room is maintained at 24°C by a chiller, powered by the electrical grid + and consumes brown energy. + The two hosts are powered by a battery when available, and the electrical + grid otherwise. The battery is charged by a solar panel. + + We simulate two days from 00h00 to 00h00. + The solar panel generates power from 8h to 20h with a peak at 14h. + During the simulation, when the charge of the battery goes: + - below 75% the solar panel is connected to the battery + - above 80% the solar panel is disconnected from the battery + - below 20% the hosts are disconnected from the battery + - above 25% the hosts are connected to the battery + + The two hosts are always idle, except from 12h to 16h on the first day. +*/ + +#include "simgrid/plugins/battery.hpp" +#include "simgrid/plugins/chiller.hpp" +#include "simgrid/plugins/energy.h" +#include "simgrid/plugins/solar_panel.hpp" +#include "simgrid/s4u.hpp" +#include + +XBT_LOG_NEW_DEFAULT_CATEGORY(battery_chiller_solar, "Messages specific for this s4u example"); +namespace sg4 = simgrid::s4u; +namespace sp = simgrid::plugins; + +static void irradiance_manager(sp::SolarPanelPtr solar_panel) +{ + int time = 0; + int time_step = 10; + double amplitude = 1000 / 2.0; + double period = 24 * 60 * 60; + double shift = 16 * 60 * 60; + double irradiance; + while (true) { + irradiance = amplitude * sin(2 * M_PI * (time + shift) / period); + irradiance = irradiance < 0 ? 0 : irradiance; + solar_panel->set_solar_irradiance(irradiance); + sg4::this_actor::sleep_for(time_step); + time += time_step; + } +} + +static void host_job_manager(double start, double duration) +{ + sg4::this_actor::sleep_until(start); + sg4::this_actor::get_host()->execute(duration * sg4::this_actor::get_host()->get_speed()); +} + +static void end_manager(sp::BatteryPtr b) +{ + sg4::this_actor::sleep_until(86400 * 2); + for (auto& handler : b->get_handlers()) + b->delete_handler(handler); +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + sg_host_energy_plugin_init(); + + auto myhost1 = e.host_by_name("MyHost1"); + auto myhost2 = e.host_by_name("MyHost2"); + + auto battery = sp::Battery::init("Battery", 0.2, -1e3, 1e3, 0.9, 0.9, 2000, 1000); + auto chiller = sp::Chiller::init("Chiller", 50, 1006, 0.2, 0.9, 24, 24, 1e3); + auto solar_panel = sp::SolarPanel::init("Solar Panel", 1.1, 0.9, 0, 0, 1e3); + chiller->add_host(myhost1); + chiller->add_host(myhost2); + solar_panel->on_this_power_change_cb( + [battery](sp::SolarPanel* s) { battery->set_load("Solar Panel", s->get_power() * -1); }); + + // These handlers connect/disconnect the solar panel and the hosts depending on the state of charge of the battery + battery->schedule_handler(0.8, sp::Battery::CHARGE, sp::Battery::Handler::PERSISTANT, + [battery]() { battery->set_load("Solar Panel", false); }); + battery->schedule_handler(0.75, sp::Battery::DISCHARGE, sp::Battery::Handler::PERSISTANT, + [battery]() { battery->set_load("Solar Panel", true); }); + battery->schedule_handler(0.2, sp::Battery::DISCHARGE, sp::Battery::Handler::PERSISTANT, + [battery, &myhost1, &myhost2]() { + battery->connect_host(myhost1, false); + battery->connect_host(myhost2, false); + }); + battery->schedule_handler(0.25, sp::Battery::CHARGE, sp::Battery::Handler::PERSISTANT, + [battery, &myhost1, &myhost2]() { + battery->connect_host(myhost1); + battery->connect_host(myhost2); + }); + + /* Handlers create simulation events preventing the simulation from finishing + To avoid this behaviour this actor sleeps for 2 days and then delete all handlers + */ + sg4::Actor::create("end_manager", myhost1, end_manager, battery); + + // This actor updates the solar irradiance of the solar panel + sg4::Actor::create("irradiance_manager", myhost1, irradiance_manager, solar_panel)->daemonize(); + + // These actors start a job on a host for a specific duration + sg4::Actor::create("host_job_manager", myhost1, host_job_manager, 12 * 60 * 60, 4 * 60 * 60); + sg4::Actor::create("host_job_manager", myhost2, host_job_manager, 12 * 60 * 60, 4 * 60 * 60); + + e.run(); + XBT_INFO("State of charge of the battery: %0.1f%%", battery->get_state_of_charge() * 100); + XBT_INFO( + "Energy consumed by the hosts (green / brown): %.2fMJ " + "/ %.2fMJ", + battery->get_energy_provided() / 1e6, + (sg_host_get_consumed_energy(myhost1) + sg_host_get_consumed_energy(myhost2) - battery->get_energy_provided()) / + 1e6); + XBT_INFO("Energy consumed by the chiller (brown): %.2fMJ", chiller->get_energy_consumed() / 1e6); + return 0; +} diff --git a/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.tesh b/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.tesh new file mode 100644 index 0000000000..f2cddf46e3 --- /dev/null +++ b/examples/cpp/battery-chiller-solar/s4u-battery-chiller-solar.tesh @@ -0,0 +1,10 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-battery-chiller-solar ${platfdir}/energy_platform.xml +> [172800.000000] [host_energy/INFO] Total energy consumption: 53568000.000000 Joules (used hosts: 36288000.000000 Joules; unused/idle hosts: 17280000.000000) +> [172800.000000] [battery_chiller_solar/INFO] State of charge of the battery: 20.4% +> [172800.000000] [battery_chiller_solar/INFO] Energy consumed by the hosts (green / brown): 21.60MJ / 14.69MJ +> [172800.000000] [battery_chiller_solar/INFO] Energy consumed by the chiller (brown): 48.38MJ +> [172800.000000] [host_energy/INFO] Energy consumption of host MyHost1: 17568000.000000 Joules +> [172800.000000] [host_energy/INFO] Energy consumption of host MyHost2: 18720000.000000 Joules +> [172800.000000] [host_energy/INFO] Energy consumption of host MyHost3: 17280000.000000 Joules \ No newline at end of file diff --git a/examples/cpp/battery-connector/s4u-battery-connector.cpp b/examples/cpp/battery-connector/s4u-battery-connector.cpp new file mode 100644 index 0000000000..b3a8588b28 --- /dev/null +++ b/examples/cpp/battery-connector/s4u-battery-connector.cpp @@ -0,0 +1,65 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example shows how to use the battery as a connector. + A connector has no capacity and only delivers as much power as it receives + with a transfer efficiency of 100%. + A solar panel is connected to the connector and power a host. +*/ + +#include "simgrid/plugins/battery.hpp" +#include "simgrid/plugins/chiller.hpp" +#include "simgrid/plugins/energy.h" +#include "simgrid/plugins/solar_panel.hpp" +#include "simgrid/s4u.hpp" +#include +#include +#include + +XBT_LOG_NEW_DEFAULT_CATEGORY(battery_chiller_solar, "Messages specific for this s4u example"); +namespace sg4 = simgrid::s4u; +namespace sp = simgrid::plugins; + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + sg_host_energy_plugin_init(); + + auto myhost1 = e.host_by_name("MyHost1"); + + auto connector = sp::Battery::init(); + auto solar_panel = sp::SolarPanel::init("Solar Panel", 1, 1, 200, 0, 1e3); + + connector->set_load("Solar Panel", solar_panel->get_power() * -1); + connector->connect_host(myhost1); + + solar_panel->on_this_power_change_cb([connector](sp::SolarPanel *s) { + connector->set_load("Solar Panel", s->get_power() * -1); + }); + + sg4::Actor::create("manager", myhost1, [&myhost1, & solar_panel, &connector]{ + XBT_INFO("Solar Panel power = %.2fW, MyHost1 power = %.2fW. The Solar Panel provides more than needed.", solar_panel->get_power(), sg_host_get_current_consumption(myhost1)); + simgrid::s4u::this_actor::sleep_for(100); + XBT_INFO("Energy consumption MyHost1: %.2fkJ, Energy from the Solar Panel %.2fkJ", sg_host_get_consumed_energy(myhost1) / 1e3, connector->get_energy_provided() / 1e3); + + solar_panel->set_solar_irradiance(100); + XBT_INFO("Solar Panel power = %.2fW, MyHost1 power = %.2fW. The Solar Panel provides exactly what is needed.", solar_panel->get_power(), sg_host_get_current_consumption(myhost1)); + double last_measure_host_energy = sg_host_get_consumed_energy(myhost1); + double last_measure_connector_energy = connector->get_energy_provided(); + + simgrid::s4u::this_actor::sleep_for(100); + XBT_INFO("Energy consumption MyHost1: %.2fkJ, Energy from the Solar Panel %.2fkJ", (sg_host_get_consumed_energy(myhost1) - last_measure_host_energy) / 1e3, (connector->get_energy_provided() - last_measure_connector_energy) / 1e3); + + XBT_INFO("MyHost1 executes something for 100s. The Solar Panel does not provide enough energy."); + last_measure_host_energy = sg_host_get_consumed_energy(myhost1); + last_measure_connector_energy = connector->get_energy_provided(); + myhost1->execute(100 * myhost1->get_speed()); + XBT_INFO("Energy MyHost1: %.2fkJ, Energy from the Solar Panel %.2fkJ", (sg_host_get_consumed_energy(myhost1) - last_measure_host_energy) / 1e3, (connector->get_energy_provided() - last_measure_connector_energy) / 1e3); + }); + + e.run(); + return 0; +} diff --git a/examples/cpp/battery-connector/s4u-battery-connector.tesh b/examples/cpp/battery-connector/s4u-battery-connector.tesh new file mode 100644 index 0000000000..2dd264da3f --- /dev/null +++ b/examples/cpp/battery-connector/s4u-battery-connector.tesh @@ -0,0 +1,13 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-battery-connector ${platfdir}/energy_platform.xml +> [MyHost1:manager:(1) 0.000000] [battery_chiller_solar/INFO] Solar Panel power = 200.00W, MyHost1 power = 100.00W. The Solar Panel provides more than needed. +> [MyHost1:manager:(1) 100.000000] [battery_chiller_solar/INFO] Energy consumption MyHost1: 10.00kJ, Energy from the Solar Panel 10.00kJ +> [MyHost1:manager:(1) 100.000000] [battery_chiller_solar/INFO] Solar Panel power = 100.00W, MyHost1 power = 100.00W. The Solar Panel provides exactly what is needed. +> [MyHost1:manager:(1) 200.000000] [battery_chiller_solar/INFO] Energy consumption MyHost1: 10.00kJ, Energy from the Solar Panel 10.00kJ +> [MyHost1:manager:(1) 200.000000] [battery_chiller_solar/INFO] MyHost1 executes something for 100s. The Solar Panel does not provide enough energy. +> [MyHost1:manager:(1) 300.000000] [battery_chiller_solar/INFO] Energy MyHost1: 12.00kJ, Energy from the Solar Panel 10.00kJ +> [300.000000] [host_energy/INFO] Total energy consumption: 92000.000000 Joules (used hosts: 32000.000000 Joules; unused/idle hosts: 60000.000000) +> [300.000000] [host_energy/INFO] Energy consumption of host MyHost1: 32000.000000 Joules +> [300.000000] [host_energy/INFO] Energy consumption of host MyHost2: 30000.000000 Joules +> [300.000000] [host_energy/INFO] Energy consumption of host MyHost3: 30000.000000 Joules \ No newline at end of file diff --git a/examples/cpp/battery-degradation/plot_battery_degradation.py b/examples/cpp/battery-degradation/plot_battery_degradation.py new file mode 100644 index 0000000000..6863832a64 --- /dev/null +++ b/examples/cpp/battery-degradation/plot_battery_degradation.py @@ -0,0 +1,16 @@ +# Copyright (c) 2003-2023. The SimGrid Team. +# All rights reserved. + +# This program is free software; you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +import sys +import pandas as pd +import seaborn as sns + +df = pd.read_csv(sys.argv[1], names=['Time','Value', 'SoC - SoH']) +df['Time'] = df['Time'].apply(lambda x: float(x.split(" ")[-1])) +sns.set_theme() +sns.set(rc={'figure.figsize':(16,8)}) +g = sns.lineplot(data=df, x='Time', y='Value', hue='SoC - SoH') +g.get_figure().savefig('battery_degradation.svg') \ No newline at end of file diff --git a/examples/cpp/battery-degradation/s4u-battery-degradation.cpp b/examples/cpp/battery-degradation/s4u-battery-degradation.cpp new file mode 100644 index 0000000000..4973587089 --- /dev/null +++ b/examples/cpp/battery-degradation/s4u-battery-degradation.cpp @@ -0,0 +1,44 @@ +/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/plugins/battery.hpp" +#include "simgrid/s4u.hpp" +#include +#include + +XBT_LOG_NEW_DEFAULT_CATEGORY(battery_degradation, "Messages specific for this s4u example"); + +int main(int argc, char* argv[]) +{ + simgrid::s4u::Engine e(&argc, argv); + e.load_platform(argv[1]); + + auto battery = simgrid::plugins::Battery::init("Battery", 0.8, -200, 200, 0.9, 0.9, 10, 100); + + battery->set_load("load", 100.0); + + auto handler1 = battery->schedule_handler( + 0.2, simgrid::plugins::Battery::DISCHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, [&battery]() { + XBT_INFO("%f,%f,SoC", simgrid::s4u::Engine::get_clock(), battery->get_state_of_charge()); + XBT_INFO("%f,%f,SoH", simgrid::s4u::Engine::get_clock(), battery->get_state_of_health()); + battery->set_load("load", -100.0); + }); + + std::shared_ptr handler2; + handler2 = battery->schedule_handler( + 0.8, simgrid::plugins::Battery::CHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, + [&battery, &handler1, &handler2]() { + XBT_INFO("%f,%f,SoC", simgrid::s4u::Engine::get_clock(), battery->get_state_of_charge()); + XBT_INFO("%f,%f,SoH", simgrid::s4u::Engine::get_clock(), battery->get_state_of_health()); + if (battery->get_state_of_health() < 0.1) { + battery->delete_handler(handler1); + battery->delete_handler(handler2); + } + battery->set_load("load", 100.0); + }); + + e.run(); + return 0; +} diff --git a/examples/cpp/battery-degradation/s4u-battery-degradation.tesh b/examples/cpp/battery-degradation/s4u-battery-degradation.tesh new file mode 100644 index 0000000000..5af472879c --- /dev/null +++ b/examples/cpp/battery-degradation/s4u-battery-degradation.tesh @@ -0,0 +1,5 @@ +#!/usr/bin/env tesh + +! output ignore + +$ ${bindir:=.}/s4u-battery-degradation ${platfdir}/energy_platform.xml diff --git a/examples/cpp/battery-energy/s4u-battery-energy.cpp b/examples/cpp/battery-energy/s4u-battery-energy.cpp new file mode 100644 index 0000000000..6db88125a4 --- /dev/null +++ b/examples/cpp/battery-energy/s4u-battery-energy.cpp @@ -0,0 +1,64 @@ +/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/plugins/battery.hpp" +#include "simgrid/plugins/energy.h" +#include "simgrid/s4u.hpp" +#include +#include + +XBT_LOG_NEW_DEFAULT_CATEGORY(battery_energy, "Messages specific for this s4u example"); + +static void manager() +{ + auto battery = simgrid::plugins::Battery::init("Battery", 0.8, -300, 300, 0.9, 0.9, 10, 1000); + + auto* host1 = simgrid::s4u::Engine::get_instance()->host_by_name("MyHost1"); + auto* host2 = simgrid::s4u::Engine::get_instance()->host_by_name("MyHost2"); + auto* host3 = simgrid::s4u::Engine::get_instance()->host_by_name("MyHost3"); + + battery->schedule_handler( + 0.2, simgrid::plugins::Battery::DISCHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, + [&battery, &host1, &host2, &host3]() { + XBT_INFO("Handler -> Battery low: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ", + battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(), + battery->get_energy_provided(), battery->get_energy_consumed()); + XBT_INFO("Disconnecting hosts %s and %s", host1->get_cname(), host2->get_cname()); + battery->connect_host(host1, false); + battery->connect_host(host2, false); + XBT_INFO("Energy consumed this far by: %s: %fJ, %s: %fJ, %s: %fJ", host1->get_cname(), + sg_host_get_consumed_energy(host1), host2->get_cname(), sg_host_get_consumed_energy(host2), + host3->get_cname(), sg_host_get_consumed_energy(host3)); + }); + + XBT_INFO("Battery state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ", + battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(), + battery->get_energy_provided(), battery->get_energy_consumed()); + XBT_INFO("Connecting hosts %s and %s to the battery", host1->get_cname(), host2->get_cname()); + battery->connect_host(host1); + battery->connect_host(host2); + + double flops = 1e9; + XBT_INFO("Host %s will now execute %f flops", host1->get_cname(), flops); + host2->execute(flops); + + simgrid::s4u::this_actor::sleep_until(200); + XBT_INFO("Battery state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ", + battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(), + battery->get_energy_provided(), battery->get_energy_consumed()); +} + +int main(int argc, char* argv[]) +{ + simgrid::s4u::Engine e(&argc, argv); + // if you plan to use Battery::connect_host you have to init the energy plugin at start. + sg_host_energy_plugin_init(); + e.load_platform(argv[1]); + + simgrid::s4u::Actor::create("manager", e.host_by_name("MyHost1"), manager); + + e.run(); + return 0; +} diff --git a/examples/cpp/battery-energy/s4u-battery-energy.tesh b/examples/cpp/battery-energy/s4u-battery-energy.tesh new file mode 100644 index 0000000000..ee9b4a72c9 --- /dev/null +++ b/examples/cpp/battery-energy/s4u-battery-energy.tesh @@ -0,0 +1,14 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-battery-energy ${platfdir}/energy_platform.xml +> [MyHost1:manager:(1) 0.000000] [battery_energy/INFO] Battery state: SoC: 0.800000 SoH: 1.000000 Energy stored: 28800.000000J Energy provided: 0.000000J Energy consumed 0.000000J +> [MyHost1:manager:(1) 0.000000] [battery_energy/INFO] Connecting hosts MyHost1 and MyHost2 to the battery +> [MyHost1:manager:(1) 0.000000] [battery_energy/INFO] Host MyHost1 will now execute 1000000000.000000 flops +> [93.709721] [battery_energy/INFO] Handler -> Battery low: SoC: 0.200000 SoH: 0.999700 Energy stored: 7197.839784J Energy provided: 19441.944194J Energy consumed 0.000000J +> [93.709721] [battery_energy/INFO] Disconnecting hosts MyHost1 and MyHost2 +> [93.709721] [battery_energy/INFO] Energy consumed this far by: MyHost1: 9370.972097J, MyHost2: 10370.972097J, MyHost3: 9370.972097J +> [MyHost1:manager:(1) 200.000000] [battery_energy/INFO] Battery state: SoC: 0.200000 SoH: 0.999700 Energy stored: 7197.839784J Energy provided: 19441.944194J Energy consumed 0.000000J +> [200.000000] [host_energy/INFO] Total energy consumption: 61000.000000 Joules (used hosts: 21000.000000 Joules; unused/idle hosts: 40000.000000) +> [200.000000] [host_energy/INFO] Energy consumption of host MyHost1: 20000.000000 Joules +> [200.000000] [host_energy/INFO] Energy consumption of host MyHost2: 21000.000000 Joules +> [200.000000] [host_energy/INFO] Energy consumption of host MyHost3: 20000.000000 Joules diff --git a/examples/cpp/battery-simple/s4u-battery-simple.cpp b/examples/cpp/battery-simple/s4u-battery-simple.cpp new file mode 100644 index 0000000000..61a4186239 --- /dev/null +++ b/examples/cpp/battery-simple/s4u-battery-simple.cpp @@ -0,0 +1,50 @@ +/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/plugins/battery.hpp" +#include "simgrid/s4u.hpp" +#include + +XBT_LOG_NEW_DEFAULT_CATEGORY(battery_simple, "Messages specific for this s4u example"); + +int main(int argc, char* argv[]) +{ + simgrid::s4u::Engine e(&argc, argv); + e.load_platform(argv[1]); + + auto battery = simgrid::plugins::Battery::init("Battery", 0.8, -100, 100, 0.9, 0.9, 10, 1000); + + XBT_INFO("Initial state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ", + battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(), + battery->get_energy_provided(), battery->get_energy_consumed()); + + /* This power is beyond the nominal values of the battery + * see documentation for more info + */ + double load_w = 150; + battery->set_load("load", load_w); + XBT_INFO("Set load to %fW", load_w); + + battery->schedule_handler( + 0.2, simgrid::plugins::Battery::DISCHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, [&battery, &load_w]() { + XBT_INFO("Discharged state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ", + battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(), + battery->get_energy_provided(), battery->get_energy_consumed()); + battery->set_load("load", -load_w); + XBT_INFO("Set load to %fW", -load_w); + }); + + battery->schedule_handler( + 0.8, simgrid::plugins::Battery::CHARGE, simgrid::plugins::Battery::Handler::PERSISTANT, [&battery]() { + XBT_INFO("Charged state: SoC: %f SoH: %f Energy stored: %fJ Energy provided: %fJ Energy consumed %fJ", + battery->get_state_of_charge(), battery->get_state_of_health(), battery->get_energy_stored(), + battery->get_energy_provided(), battery->get_energy_consumed()); + XBT_INFO("Set load to %fW", 0.0); + }); + + e.run(); + + return 0; +} \ No newline at end of file diff --git a/examples/cpp/battery-simple/s4u-battery-simple.tesh b/examples/cpp/battery-simple/s4u-battery-simple.tesh new file mode 100644 index 0000000000..3674d1f28d --- /dev/null +++ b/examples/cpp/battery-simple/s4u-battery-simple.tesh @@ -0,0 +1,10 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-battery-simple ${platfdir}/energy_platform.xml +> [0.000000] [battery_simple/INFO] Initial state: SoC: 0.800000 SoH: 1.000000 Energy stored: 28800.000000J Energy provided: 0.000000J Energy consumed 0.000000J +> [0.000000] [battery_simple/INFO] Set load to 150.000000W +> [216.021602] [battery_simple/INFO] Discharged state: SoC: 0.200000 SoH: 0.999700 Energy stored: 7197.839784J Energy provided: 19441.944194J Energy consumed 0.000000J +> [216.021602] [battery_simple/INFO] Set load to -150.000000W +> [455.853662] [battery_simple/INFO] Charged state: SoC: 0.800000 SoH: 0.999400 Energy stored: 28782.725182J Energy provided: 19441.944194J Energy consumed 23983.205998J +> [455.853662] [battery_simple/INFO] Set load to 0.000000W + diff --git a/examples/cpp/chiller-simple/s4u-chiller-simple.cpp b/examples/cpp/chiller-simple/s4u-chiller-simple.cpp new file mode 100644 index 0000000000..db48b653e7 --- /dev/null +++ b/examples/cpp/chiller-simple/s4u-chiller-simple.cpp @@ -0,0 +1,63 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/plugins/chiller.hpp" +#include "simgrid/plugins/energy.h" +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(chiller_simple, "Messages specific for this s4u example"); +namespace sg4 = simgrid::s4u; + +static void display_chiller(simgrid::plugins::ChillerPtr c) +{ + XBT_INFO("%s: Power: %.2fW T_in: %.2f°C Energy consumed: %.2fJ", c->get_cname(), c->get_power(), c->get_temp_in(), + c->get_energy_consumed()); +} + +static void manager(simgrid::plugins::ChillerPtr c) +{ + display_chiller(c); + + simgrid::s4u::this_actor::sleep_for(c->get_time_to_goal_temp()); + XBT_INFO("The input temperature is now equal to the goal temperature. After this point the Chiller will compensate " + "heat with electrical power."); + display_chiller(c); + + simgrid::s4u::this_actor::sleep_for(1); + display_chiller(c); + + XBT_INFO("Let's compute something."); + sg4::this_actor::execute(1e10); + XBT_INFO("Computation done."); + display_chiller(c); + XBT_INFO("Now let's stress the chiller by decreasing the goal temperature to 23°C."); + c->set_goal_temp(23); + + simgrid::s4u::this_actor::sleep_for(1); + display_chiller(c); + + simgrid::s4u::this_actor::sleep_for(c->get_time_to_goal_temp()); + XBT_INFO("The input temperature is back to the goal temperature."); + display_chiller(c); + + simgrid::s4u::this_actor::sleep_for(1); + display_chiller(c); +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + sg_host_energy_plugin_init(); + + auto chiller = simgrid::plugins::Chiller::init("Chiller", 294, 1006, 0.2, 0.9, 23, 24, 1000); + chiller->add_host(e.host_by_name("MyHost1")); + chiller->add_host(e.host_by_name("MyHost2")); + chiller->add_host(e.host_by_name("MyHost3")); + sg4::Actor::create("manager", e.host_by_name("MyHost1"), manager, chiller); + + e.run(); + return 0; +} diff --git a/examples/cpp/chiller-simple/s4u-chiller-simple.tesh b/examples/cpp/chiller-simple/s4u-chiller-simple.tesh new file mode 100644 index 0000000000..33e196f9b1 --- /dev/null +++ b/examples/cpp/chiller-simple/s4u-chiller-simple.tesh @@ -0,0 +1,19 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-chiller-simple ${platfdir}/energy_platform.xml +> [MyHost1:manager:(1) 0.000000] [chiller_simple/INFO] Chiller: Power: 0.00W T_in: 23.00°C Energy consumed: 0.00J +> [MyHost1:manager:(1) 821.566667] [chiller_simple/INFO] The input temperature is now equal to the goal temperature. After this point the Chiller will compensate heat with electrical power. +> [MyHost1:manager:(1) 821.566667] [chiller_simple/INFO] Chiller: Power: 0.00W T_in: 24.00°C Energy consumed: 0.00J +> [MyHost1:manager:(1) 822.566667] [chiller_simple/INFO] Chiller: Power: 400.00W T_in: 24.00°C Energy consumed: 400.00J +> [MyHost1:manager:(1) 822.566667] [chiller_simple/INFO] Let's compute something. +> [MyHost1:manager:(1) 922.566667] [chiller_simple/INFO] Computation done. +> [MyHost1:manager:(1) 922.566667] [chiller_simple/INFO] Chiller: Power: 426.67W T_in: 24.00°C Energy consumed: 43066.67J +> [MyHost1:manager:(1) 922.566667] [chiller_simple/INFO] Now let's stress the chiller by decreasing the goal temperature to 23°C. +> [MyHost1:manager:(1) 923.566667] [chiller_simple/INFO] Chiller: Power: 1000.00W T_in: 24.00°C Energy consumed: 44066.67J +> [MyHost1:manager:(1) 1470.277778] [chiller_simple/INFO] The input temperature is back to the goal temperature. +> [MyHost1:manager:(1) 1470.277778] [chiller_simple/INFO] Chiller: Power: 1000.00W T_in: 23.00°C Energy consumed: 590777.78J +> [MyHost1:manager:(1) 1471.277778] [chiller_simple/INFO] Chiller: Power: 400.00W T_in: 23.00°C Energy consumed: 591177.78J +> [1471.277778] [host_energy/INFO] Total energy consumption: 443383.333333 Joules (used hosts: 149127.777778 Joules; unused/idle hosts: 294255.555556) +> [1471.277778] [host_energy/INFO] Energy consumption of host MyHost1: 149127.777778 Joules +> [1471.277778] [host_energy/INFO] Energy consumption of host MyHost2: 147127.777778 Joules +> [1471.277778] [host_energy/INFO] Energy consumption of host MyHost3: 147127.777778 Joules \ No newline at end of file diff --git a/examples/cpp/cloud-capping/s4u-cloud-capping.cpp b/examples/cpp/cloud-capping/s4u-cloud-capping.cpp index 358646422b..7c98eb2cec 100644 --- a/examples/cpp/cloud-capping/s4u-cloud-capping.cpp +++ b/examples/cpp/cloud-capping/s4u-cloud-capping.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/cloud-migration/s4u-cloud-migration.cpp b/examples/cpp/cloud-migration/s4u-cloud-migration.cpp index 6e0db95459..3da751bfbc 100644 --- a/examples/cpp/cloud-migration/s4u-cloud-migration.cpp +++ b/examples/cpp/cloud-migration/s4u-cloud-migration.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/cloud-simple/s4u-cloud-simple.cpp b/examples/cpp/cloud-simple/s4u-cloud-simple.cpp index 9c5134c7a9..f5dc292139 100644 --- a/examples/cpp/cloud-simple/s4u-cloud-simple.cpp +++ b/examples/cpp/cloud-simple/s4u-cloud-simple.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -57,7 +57,7 @@ static void communication_rx_fun(std::vector args) static void launch_communication_worker(s4u_Host* tx_host, s4u_Host* rx_host) { - std::string mbox_name = std::string("MBOX:") + tx_host->get_cname() + "-" + rx_host->get_cname(); + std::string mbox_name = "MBOX:" + tx_host->get_name() + "-" + rx_host->get_name(); std::vector args; args.push_back(mbox_name); diff --git a/examples/cpp/clusters-multicpu/s4u-clusters-multicpu.cpp b/examples/cpp/clusters-multicpu/s4u-clusters-multicpu.cpp index 8ae7a7a03c..b2ca2e78f7 100644 --- a/examples/cpp/clusters-multicpu/s4u-clusters-multicpu.cpp +++ b/examples/cpp/clusters-multicpu/s4u-clusters-multicpu.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -24,30 +24,29 @@ public: void operator()() const { /* Vector in which we store all ongoing communications */ - std::vector pending_comms; + sg4::ActivitySet pending_comms; /* Make a vector of the mailboxes to use */ std::vector mboxes; /* Start dispatching 1 message to all receivers */ - std::string msg_content = - std::string("Hello, I'm alive and running on ") + std::string(sg4::this_actor::get_host()->get_name()); + std::string msg_content = "Hello, I'm alive and running on " + sg4::this_actor::get_host()->get_name(); for (const auto* host : hosts_) { /* Copy the data we send: the 'msg_content' variable is not a stable storage location. * It will be destroyed when this actor leaves the loop, ie before the receiver gets it */ auto* payload = new std::string(msg_content); /* Create a communication representing the ongoing communication, and store it in pending_comms */ - auto mbox = sg4::Mailbox::by_name(host->get_name()); + auto* mbox = sg4::Mailbox::by_name(host->get_name()); mboxes.push_back(mbox); sg4::CommPtr comm = mbox->put_async(payload, msg_size); - pending_comms.push_back(comm); + pending_comms.push(comm); } XBT_INFO("Done dispatching all messages"); /* Now that all message exchanges were initiated, wait for their completion in one single call */ - sg4::Comm::wait_all(pending_comms); + pending_comms.wait_all(); XBT_INFO("Goodbye now!"); } @@ -58,7 +57,7 @@ class Receiver { public: void operator()() const { - auto mbox = sg4::Mailbox::by_name(sg4::this_actor::get_host()->get_name()); + auto* mbox = sg4::Mailbox::by_name(sg4::this_actor::get_host()->get_name()); auto received = mbox->get_unique(); XBT_INFO("I got a '%s'.", received->c_str()); } @@ -88,8 +87,7 @@ public: * @param id Internal identifier in the torus (for information) * @return netpoint, gateway: the netpoint to the StarZone and CPU0 as gateway */ -static std::pair -create_hostzone(const sg4::NetZone* zone, const std::vector& /*coord*/, unsigned long id) +static sg4::NetZone* create_hostzone(const sg4::NetZone* zone, const std::vector& /*coord*/, unsigned long id) { constexpr int num_cpus = 8; //!< Number of CPUs in the zone constexpr double speed = 1e9; //!< Speed of each CPU @@ -102,24 +100,21 @@ create_hostzone(const sg4::NetZone* zone, const std::vector& /*co /* setting my Torus parent zone */ host_zone->set_parent(zone); - simgrid::kernel::routing::NetPoint* gateway = nullptr; /* create CPUs */ for (int i = 0; i < num_cpus; i++) { std::string cpu_name = hostname + "-cpu" + std::to_string(i); - const sg4::Host* host = host_zone->create_host(cpu_name, speed)->seal(); + const sg4::Host* host = host_zone->create_host(cpu_name, speed); /* the first CPU is the gateway */ if (i == 0) - gateway = host->get_netpoint(); + host_zone->set_gateway(host->get_netpoint()); /* create split-duplex link */ - sg4::SplitDuplexLink* link = host_zone->create_split_duplex_link("link-" + cpu_name, link_bw); - link->set_latency(link_lat)->seal(); + auto* link = host_zone->create_split_duplex_link("link-" + cpu_name, link_bw)->set_latency(link_lat); /* connecting CPU to outer world */ - host_zone->add_route(host->get_netpoint(), nullptr, nullptr, nullptr, {{link, sg4::LinkInRoute::Direction::UP}}, - true); + host_zone->add_route(host, nullptr, {{link, sg4::LinkInRoute::Direction::UP}}, true); } /* seal newly created netzone */ host_zone->seal(); - return std::make_pair(host_zone->get_netpoint(), gateway); + return host_zone; } /*************************************************************************************************/ @@ -307,7 +302,7 @@ int main(int argc, char* argv[]) sg4::Actor::create("sender", host_list[0], Sender(host_list)); /* create receiver in every host */ for (auto* host : host_list) { - sg4::Actor::create(std::string("receiver-") + std::string(host->get_name()), host, Receiver()); + sg4::Actor::create("receiver-" + host->get_name(), host, Receiver()); } /* runs the simulation */ diff --git a/examples/cpp/comm-dependent/s4u-comm-dependent.cpp b/examples/cpp/comm-dependent/s4u-comm-dependent.cpp index 9cfafe5039..d40c99feff 100644 --- a/examples/cpp/comm-dependent/s4u-comm-dependent.cpp +++ b/examples/cpp/comm-dependent/s4u-comm-dependent.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,7 +15,7 @@ static void sender(sg4::Mailbox* mailbox) sg4::CommPtr comm = mailbox->put_init(computation_amount, 7e6); exec->set_name("exec on sender")->add_successor(comm)->start(); - comm->set_name("comm to receiver")->vetoable_start(); + comm->set_name("comm to receiver")->start(); exec->wait(); comm->wait(); } @@ -28,7 +28,7 @@ static void receiver(sg4::Mailbox* mailbox) sg4::CommPtr comm = mailbox->get_init()->set_dst_data((void**)&received, sizeof(double)); comm->set_name("comm from sender")->add_successor(exec)->start(); - exec->set_name("exec on receiver")->vetoable_start(); + exec->set_name("exec on receiver")->start(); comm->wait(); exec->wait(); diff --git a/examples/cpp/comm-dependent/s4u-comm-dependent.tesh b/examples/cpp/comm-dependent/s4u-comm-dependent.tesh index 613464dc69..7faa65ee7b 100644 --- a/examples/cpp/comm-dependent/s4u-comm-dependent.tesh +++ b/examples/cpp/comm-dependent/s4u-comm-dependent.tesh @@ -3,6 +3,8 @@ p Testing with default compound $ ${bindir:=.}/s4u-comm-dependent ${platfdir}/small_platform.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%6.2r]%e(%i:%a@%h)%e%m%n" +> [ 0.00] (1:sender@Tremblay) 'exec on sender' is assigned to a resource and all dependencies are solved. Let's start +> [ 0.00] (2:receiver@Jupiter) 'comm from sender' is assigned to a resource and all dependencies are solved. Let's start > [ 2.00] (1:sender@Tremblay) Remove a dependency from 'exec on sender' on 'comm to receiver' > [ 2.00] (1:sender@Tremblay) 'comm to receiver' is assigned to a resource and all dependencies are solved. Let's start > [ 3.07] (2:receiver@Jupiter) Remove a dependency from 'comm from sender' on 'exec on receiver' diff --git a/examples/cpp/comm-failure/s4u-comm-failure.cpp b/examples/cpp/comm-failure/s4u-comm-failure.cpp index 5c31aaa48b..33c7729e00 100644 --- a/examples/cpp/comm-failure/s4u-comm-failure.cpp +++ b/examples/cpp/comm-failure/s4u-comm-failure.cpp @@ -1,18 +1,10 @@ -/* Copyright (c) 2021-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2021-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -/* This example shows how to serialize a set of communications going through a link - * - * As for the other asynchronous examples, the sender initiates all the messages it wants to send and - * pack the resulting simgrid::s4u::CommPtr objects in a vector. - * At the same time, the receiver starts receiving all messages asynchronously. Without serialization, - * all messages would be received at the same timestamp in the receiver. - * - * However, as they will be serialized in a link of the platform, the messages arrive 2 by 2. - * - * The sender then blocks until all ongoing communication terminate, using simgrid::s4u::Comm::wait_all() +/* This example shows how to react to a failed communication, which occurs when a link is turned off, + * or when the actor with whom you communicate fails because its host is turned off. */ #include @@ -32,8 +24,8 @@ public: void operator()() const { - auto mailbox1 = sg4::Mailbox::by_name(mailbox1_name); - auto mailbox2 = sg4::Mailbox::by_name(mailbox2_name); + auto* mailbox1 = sg4::Mailbox::by_name(mailbox1_name); + auto* mailbox2 = sg4::Mailbox::by_name(mailbox2_name); XBT_INFO("Initiating asynchronous send to %s", mailbox1->get_cname()); auto comm1 = mailbox1->put_async((void*)666, 5); @@ -41,40 +33,37 @@ public: auto comm2 = mailbox2->put_async((void*)666, 2); XBT_INFO("Calling wait_any.."); - std::vector pending_comms; - pending_comms.push_back(comm1); - pending_comms.push_back(comm2); + sg4::ActivitySet pending_comms; + pending_comms.push(comm1); + pending_comms.push(comm2); try { - long index = sg4::Comm::wait_any(pending_comms); - XBT_INFO("Wait any returned index %ld (comm to %s)", index, pending_comms.at(index)->get_mailbox()->get_cname()); + auto* acti = pending_comms.wait_any().get(); + XBT_INFO("Wait any returned comm to %s", dynamic_cast(acti)->get_mailbox()->get_cname()); } catch (const simgrid::NetworkFailureException&) { XBT_INFO("Sender has experienced a network failure exception, so it knows that something went wrong"); - XBT_INFO("Now it needs to figure out which of the two comms failed by looking at their state"); + XBT_INFO("Now it needs to figure out which of the two comms failed by looking at their state:"); + XBT_INFO(" Comm to %s has state: %s", comm1->get_mailbox()->get_cname(), comm1->get_state_str()); + XBT_INFO(" Comm to %s has state: %s", comm2->get_mailbox()->get_cname(), comm2->get_state_str()); } - XBT_INFO("Comm to %s has state: %s", comm1->get_mailbox()->get_cname(), comm1->get_state_str()); - XBT_INFO("Comm to %s has state: %s", comm2->get_mailbox()->get_cname(), comm2->get_state_str()); - try { comm1->wait(); } catch (const simgrid::NetworkFailureException& e) { XBT_INFO("Waiting on a FAILED comm raises an exception: '%s'", e.what()); } XBT_INFO("Wait for remaining comm, just to be nice"); - pending_comms.erase(pending_comms.begin()); - sg4::Comm::wait_any(pending_comms); + pending_comms.wait_all(); } }; class Receiver { - std::string mailbox_name; + sg4::Mailbox* mailbox; public: - explicit Receiver(const std::string& mailbox_name) : mailbox_name(mailbox_name) {} + explicit Receiver(const std::string& mailbox_name) : mailbox(sg4::Mailbox::by_name(mailbox_name)) {} void operator()() const { - auto mailbox = sg4::Mailbox::by_name(mailbox_name); XBT_INFO("Receiver posting a receive..."); try { mailbox->get(); @@ -85,23 +74,6 @@ public: } }; -class LinkKiller { - std::string link_name; - -public: - explicit LinkKiller(const std::string& link_name) : link_name(link_name) {} - - void operator()() const - { - auto link_to_kill = sg4::Link::by_name(link_name); - XBT_INFO("LinkKiller sleeping 10 seconds..."); - sg4::this_actor::sleep_for(10.0); - XBT_INFO("LinkKiller turning off link %s", link_to_kill->get_cname()); - link_to_kill->turn_off(); - XBT_INFO("LinkKiller killed. exiting"); - } -}; - int main(int argc, char** argv) { sg4::Engine engine(&argc, argv); @@ -109,18 +81,22 @@ int main(int argc, char** argv) auto* host1 = zone->create_host("Host1", "1f"); auto* host2 = zone->create_host("Host2", "1f"); auto* host3 = zone->create_host("Host3", "1f"); + auto* link2 = zone->create_link("linkto2", "1bps")->seal(); + auto* link3 = zone->create_link("linkto3", "1bps")->seal(); - sg4::LinkInRoute linkto2{zone->create_link("linkto2", "1bps")->seal()}; - sg4::LinkInRoute linkto3{zone->create_link("linkto3", "1bps")->seal()}; - - zone->add_route(host1->get_netpoint(), host2->get_netpoint(), nullptr, nullptr, {linkto2}, false); - zone->add_route(host1->get_netpoint(), host3->get_netpoint(), nullptr, nullptr, {linkto3}, false); + zone->add_route(host1, host2, {link2}); + zone->add_route(host1, host3, {link3}); zone->seal(); sg4::Actor::create("Sender", host1, Sender("mailbox2", "mailbox3")); - sg4::Actor::create("Receiver", host2, Receiver("mailbox2"))->daemonize(); - sg4::Actor::create("Receiver", host3, Receiver("mailbox3"))->daemonize(); - sg4::Actor::create("LinkKiller", host1, LinkKiller("linkto2"))->daemonize(); + sg4::Actor::create("Receiver", host2, Receiver("mailbox2")); + sg4::Actor::create("Receiver", host3, Receiver("mailbox3")); + + sg4::Actor::create("LinkKiller", host1, [](){ + sg4::this_actor::sleep_for(10.0); + XBT_INFO("Turning off link 'linkto2'"); + sg4::Link::by_name("linkto2")->turn_off(); + }); engine.run(); diff --git a/examples/cpp/comm-failure/s4u-comm-failure.tesh b/examples/cpp/comm-failure/s4u-comm-failure.tesh index c0b12090f4..8a5887156d 100644 --- a/examples/cpp/comm-failure/s4u-comm-failure.tesh +++ b/examples/cpp/comm-failure/s4u-comm-failure.tesh @@ -1,19 +1,17 @@ #!/usr/bin/env tesh $ ${bindir:=.}/s4u-comm-failure "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (4:LinkKiller@Host1) LinkKiller sleeping 10 seconds... > [ 0.000000] (2:Receiver@Host2) Receiver posting a receive... > [ 0.000000] (3:Receiver@Host3) Receiver posting a receive... > [ 0.000000] (1:Sender@Host1) Initiating asynchronous send to mailbox2 > [ 0.000000] (1:Sender@Host1) Initiating asynchronous send to mailbox3 > [ 0.000000] (1:Sender@Host1) Calling wait_any.. -> [ 10.000000] (4:LinkKiller@Host1) LinkKiller turning off link linkto2 -> [ 10.000000] (4:LinkKiller@Host1) LinkKiller killed. exiting +> [ 10.000000] (4:LinkKiller@Host1) Turning off link 'linkto2' > [ 10.000000] (2:Receiver@Host2) Receiver has experience a network failure exception > [ 10.000000] (1:Sender@Host1) Sender has experienced a network failure exception, so it knows that something went wrong -> [ 10.000000] (1:Sender@Host1) Now it needs to figure out which of the two comms failed by looking at their state -> [ 10.000000] (1:Sender@Host1) Comm to mailbox2 has state: FAILED -> [ 10.000000] (1:Sender@Host1) Comm to mailbox3 has state: STARTED +> [ 10.000000] (1:Sender@Host1) Now it needs to figure out which of the two comms failed by looking at their state: +> [ 10.000000] (1:Sender@Host1) Comm to mailbox2 has state: FAILED +> [ 10.000000] (1:Sender@Host1) Comm to mailbox3 has state: STARTED > [ 10.000000] (1:Sender@Host1) Waiting on a FAILED comm raises an exception: 'Cannot wait for a failed communication' > [ 10.000000] (1:Sender@Host1) Wait for remaining comm, just to be nice -> [ 16.494845] (3:Receiver@Host3) Receiver has received successfully! +> [ 17.319588] (3:Receiver@Host3) Receiver has received successfully! diff --git a/examples/cpp/comm-host2host/s4u-comm-host2host.cpp b/examples/cpp/comm-host2host/s4u-comm-host2host.cpp index ae5bd31139..b2c8bbc1df 100644 --- a/examples/cpp/comm-host2host/s4u-comm-host2host.cpp +++ b/examples/cpp/comm-host2host/s4u-comm-host2host.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/comm-pingpong/s4u-comm-pingpong.cpp b/examples/cpp/comm-pingpong/s4u-comm-pingpong.cpp index a252b82c5b..c4c934e2b3 100644 --- a/examples/cpp/comm-pingpong/s4u-comm-pingpong.cpp +++ b/examples/cpp/comm-pingpong/s4u-comm-pingpong.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/comm-pingpong/s4u-comm-pingpong.tesh b/examples/cpp/comm-pingpong/s4u-comm-pingpong.tesh index f4ced5d2dd..72785640cb 100644 --- a/examples/cpp/comm-pingpong/s4u-comm-pingpong.tesh +++ b/examples/cpp/comm-pingpong/s4u-comm-pingpong.tesh @@ -39,17 +39,16 @@ $ ${bindir:=.}/s4u-comm-pingpong ${platfdir}/small_platform.xml --cfg=cpu/model: > [145.639041] (1:pinger@Tremblay) Pong time (bandwidth bound): 145.638 > [145.639041] (0:maestro@) Total simulation time: 145.639 -p Testing the surf network constant model +p Testing the network constant model -$ ${bindir:=.}/s4u-comm-pingpong ${platfdir}/small_platform_routing_none.xml "--cfg=host/model:compound cpu/model:Cas01 network/model:Constant" "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ${bindir:=.}/s4u-comm-pingpong ${platfdir}/small_platform_routing_none.xml "--cfg=cpu/model:Cas01 network/model:Constant" "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/model' to 'Cas01' > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'Constant' > [ 0.000000] (1:pinger@Tremblay) Ping from mailbox Mailbox 1 to mailbox Mailbox 2 > [ 0.000000] (2:ponger@Jupiter) Pong from mailbox Mailbox 2 to mailbox Mailbox 1 -> [ 13.010000] (2:ponger@Jupiter) Payload received : small communication (latency bound) -> [ 13.010000] (2:ponger@Jupiter) Ping time (latency bound) 13.010000 -> [ 13.010000] (2:ponger@Jupiter) payload = 13.010 -> [ 26.020000] (1:pinger@Tremblay) Payload received : large communication (bandwidth bound) -> [ 26.020000] (1:pinger@Tremblay) Pong time (bandwidth bound): 13.010 -> [ 26.020000] (0:maestro@) Total simulation time: 26.020 +> [ 1.000000] (2:ponger@Jupiter) Payload received : small communication (latency bound) +> [ 1.000000] (2:ponger@Jupiter) Ping time (latency bound) 1.000000 +> [ 1.000000] (2:ponger@Jupiter) payload = 1.000 +> [ 2.000000] (1:pinger@Tremblay) Payload received : large communication (bandwidth bound) +> [ 2.000000] (1:pinger@Tremblay) Pong time (bandwidth bound): 1.000 +> [ 2.000000] (0:maestro@) Total simulation time: 2.000 diff --git a/examples/cpp/comm-ready/s4u-comm-ready.cpp b/examples/cpp/comm-ready/s4u-comm-ready.cpp index edb9575f49..f46ee8d73f 100644 --- a/examples/cpp/comm-ready/s4u-comm-ready.cpp +++ b/examples/cpp/comm-ready/s4u-comm-ready.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -30,22 +30,22 @@ static void peer(int my_id, int messages_count, size_t payload_size, int peers_c { /* Set myself as the persistent receiver of my mailbox so that messages start flowing to me as soon as they are put * into it */ - sg4::Mailbox* my_mbox = sg4::Mailbox::by_name(std::string("peer-") + std::to_string(my_id)); + sg4::Mailbox* my_mbox = sg4::Mailbox::by_name("peer-" + std::to_string(my_id)); my_mbox->set_receiver(sg4::Actor::self()); - std::vector pending_comms; + sg4::ActivitySet pending_comms; /* Start dispatching all messages to peers others that myself */ for (int i = 0; i < messages_count; i++) { for (int peer_id = 0; peer_id < peers_count; peer_id++) { if (peer_id != my_id) { - sg4::Mailbox* mbox = sg4::Mailbox::by_name(std::string("peer-") + std::to_string(peer_id)); - std::string message = std::string("Message ") + std::to_string(i) + " from peer " + std::to_string(my_id); + sg4::Mailbox* mbox = sg4::Mailbox::by_name("peer-" + std::to_string(peer_id)); + std::string message = "Message " + std::to_string(i) + " from peer " + std::to_string(my_id); auto* payload = new std::string(message); // copy the data we send: // 'message' is not a stable storage location XBT_INFO("Send '%s' to '%s'", message.c_str(), mbox->get_cname()); /* Create a communication representing the ongoing communication */ - pending_comms.push_back(mbox->put_async(payload, payload_size)); + pending_comms.push(mbox->put_async(payload, payload_size)); } } } @@ -53,9 +53,9 @@ static void peer(int my_id, int messages_count, size_t payload_size, int peers_c /* Start sending messages to let peers know that they should stop */ for (int peer_id = 0; peer_id < peers_count; peer_id++) { if (peer_id != my_id) { - sg4::Mailbox* mbox = sg4::Mailbox::by_name(std::string("peer-") + std::to_string(peer_id)); + sg4::Mailbox* mbox = sg4::Mailbox::by_name("peer-" + std::to_string(peer_id)); auto* payload = new std::string("finalize"); // Make a copy of the data we will send - pending_comms.push_back(mbox->put_async(payload, payload_size)); + pending_comms.push(mbox->put_async(payload, payload_size)); XBT_INFO("Send 'finalize' to 'peer-%d'", peer_id); } } @@ -84,7 +84,7 @@ static void peer(int my_id, int messages_count, size_t payload_size, int peers_c } XBT_INFO("I'm done, just waiting for my peers to receive the messages before exiting"); - sg4::Comm::wait_all(pending_comms); + pending_comms.wait_all(); XBT_INFO("Goodbye now!"); } diff --git a/examples/cpp/comm-suspend/s4u-comm-suspend.cpp b/examples/cpp/comm-suspend/s4u-comm-suspend.cpp index c3a7be7cfb..f3ec48e920 100644 --- a/examples/cpp/comm-suspend/s4u-comm-suspend.cpp +++ b/examples/cpp/comm-suspend/s4u-comm-suspend.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/comm-testany/s4u-comm-testany.cpp b/examples/cpp/comm-testany/s4u-comm-testany.cpp deleted file mode 100644 index 3c673c8b19..0000000000 --- a/examples/cpp/comm-testany/s4u-comm-testany.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/s4u.hpp" -#include -#include -#include -namespace sg4 = simgrid::s4u; - -XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_comm_testany, "Messages specific for this s4u example"); - -static void rank0() -{ - sg4::Mailbox* mbox = sg4::Mailbox::by_name(std::string("rank0")); - std::string* msg1; - std::string* msg2; - std::string* msg3; - - XBT_INFO("Post my asynchronous receives"); - auto comm1 = mbox->get_async(&msg1); - auto comm2 = mbox->get_async(&msg2); - auto comm3 = mbox->get_async(&msg3); - std::vector pending_comms = {comm1, comm2, comm3}; - - XBT_INFO("Send some data to rank-1"); - for (int i = 0; i < 3; i++) - sg4::Mailbox::by_name(std::string("rank1"))->put(new int(i), 1); - - XBT_INFO("Test for completed comms"); - while (not pending_comms.empty()) { - ssize_t flag = sg4::Comm::test_any(pending_comms); - if (flag != -1) { - pending_comms.erase(pending_comms.begin() + flag); - XBT_INFO("Remove a pending comm."); - } else // nothing matches, wait for a little bit - sg4::this_actor::sleep_for(0.1); - } - XBT_INFO("Last comm is complete"); - delete msg1; - delete msg2; - delete msg3; -} - -static void rank1() -{ - sg4::Mailbox* rank0_mbox = sg4::Mailbox::by_name(std::string("rank0")); - sg4::Mailbox* rank1_mbox = sg4::Mailbox::by_name(std::string("rank1")); - - for (int i = 0; i < 3; i++) { - auto res = rank1_mbox->get_unique(); - XBT_INFO("Received %d", *res); - std::string msg_content = std::string("Message ") + std::to_string(i); - auto* payload = new std::string(msg_content); - XBT_INFO("Send '%s'", msg_content.c_str()); - rank0_mbox->put(payload, 1e6); - } -} - -int main(int argc, char* argv[]) -{ - sg4::Engine e(&argc, argv); - - e.load_platform(argv[1]); - - sg4::Actor::create("rank-0", e.host_by_name("Tremblay"), rank0); - sg4::Actor::create("rank-1", e.host_by_name("Fafard"), rank1); - - e.run(); - - return 0; -} diff --git a/examples/cpp/comm-testany/s4u-comm-testany.tesh b/examples/cpp/comm-testany/s4u-comm-testany.tesh deleted file mode 100644 index 0f19916447..0000000000 --- a/examples/cpp/comm-testany/s4u-comm-testany.tesh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env tesh - -$ ${bindir:=.}/s4u-comm-testany ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e[%8h]%e[%a]%e%m%n" -> [ 0.000000] [Tremblay] [rank-0] Post my asynchronous receives -> [ 0.000000] [Tremblay] [rank-0] Send some data to rank-1 -> [ 0.025708] [ Fafard] [rank-1] Received 0 -> [ 0.025708] [ Fafard] [rank-1] Send 'Message 0' -> [ 0.209813] [ Fafard] [rank-1] Received 1 -> [ 0.209813] [ Fafard] [rank-1] Send 'Message 1' -> [ 0.393918] [Tremblay] [rank-0] Test for completed comms -> [ 0.393918] [ Fafard] [rank-1] Received 2 -> [ 0.393918] [ Fafard] [rank-1] Send 'Message 2' -> [ 0.393918] [Tremblay] [rank-0] Remove a pending comm. -> [ 0.393918] [Tremblay] [rank-0] Remove a pending comm. -> [ 0.593918] [Tremblay] [rank-0] Remove a pending comm. -> [ 0.593918] [Tremblay] [rank-0] Last comm is complete diff --git a/examples/cpp/comm-throttling/s4u-comm-throttling.cpp b/examples/cpp/comm-throttling/s4u-comm-throttling.cpp index 42b05488d9..622e5ef622 100644 --- a/examples/cpp/comm-throttling/s4u-comm-throttling.cpp +++ b/examples/cpp/comm-throttling/s4u-comm-throttling.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/comm-wait/s4u-comm-wait.cpp b/examples/cpp/comm-wait/s4u-comm-wait.cpp index 74edc64152..4f882f2474 100644 --- a/examples/cpp/comm-wait/s4u-comm-wait.cpp +++ b/examples/cpp/comm-wait/s4u-comm-wait.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -30,7 +30,7 @@ static void sender(int messages_count, size_t payload_size) sg4::this_actor::sleep_for(sleep_start_time); for (int i = 0; i < messages_count; i++) { - std::string msg_content = std::string("Message ") + std::to_string(i); + std::string msg_content = "Message " + std::to_string(i); // Copy the data we send: the 'msg_content' variable is not a stable storage location. // It will be destroyed when this actor leaves the loop, ie before the receiver gets the data auto* payload = new std::string(msg_content); diff --git a/examples/cpp/comm-waitall/s4u-comm-waitall.cpp b/examples/cpp/comm-waitall/s4u-comm-waitall.cpp deleted file mode 100644 index c0b347314c..0000000000 --- a/examples/cpp/comm-waitall/s4u-comm-waitall.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/* This example shows how to block on the completion of a set of communications. - * - * As for the other asynchronous examples, the sender initiate all the messages it wants to send and - * pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occur concurrently. - * - * The sender then blocks until all ongoing communication terminate, using simgrid::s4u::Comm::wait_all() - * - */ - -#include "simgrid/s4u.hpp" -#include -#include -#include -namespace sg4 = simgrid::s4u; - -XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_async_waitall, "Messages specific for this s4u example"); - -static void sender(unsigned int messages_count, unsigned int receivers_count, long msg_size) -{ - if (messages_count == 0 || receivers_count == 0) { - XBT_WARN("Sender has nothing to do. Bail out!"); - return; - } - // sphinx-doc: init-begin (this line helps the doc to build; ignore it) - /* Vector in which we store all ongoing communications */ - std::vector pending_comms; - - /* Make a vector of the mailboxes to use */ - std::vector mboxes; - for (unsigned int i = 0; i < receivers_count; i++) - mboxes.push_back(sg4::Mailbox::by_name(std::string("receiver-") + std::to_string(i))); - // sphinx-doc: init-end - - /* Start dispatching all messages to receivers, in a round robin fashion */ - for (unsigned int i = 0; i < messages_count; i++) { - std::string msg_content = std::string("Message ") + std::to_string(i); - // Copy the data we send: the 'msg_content' variable is not a stable storage location. - // It will be destroyed when this actor leaves the loop, ie before the receiver gets it - auto* payload = new std::string(msg_content); - - XBT_INFO("Send '%s' to '%s'", msg_content.c_str(), mboxes[i % receivers_count]->get_cname()); - - /* Create a communication representing the ongoing communication, and store it in pending_comms */ - sg4::CommPtr comm = mboxes[i % receivers_count]->put_async(payload, msg_size); - pending_comms.push_back(comm); - } - - /* Start sending messages to let the workers know that they should stop */ // sphinx-doc: put-begin - for (unsigned int i = 0; i < receivers_count; i++) { - XBT_INFO("Send 'finalize' to 'receiver-%u'", i); - sg4::CommPtr comm = mboxes[i]->put_async(new std::string("finalize"), 0); - pending_comms.push_back(comm); - } - XBT_INFO("Done dispatching all messages"); - - /* Now that all message exchanges were initiated, wait for their completion in one single call */ - sg4::Comm::wait_all(pending_comms); - // sphinx-doc: put-end - - XBT_INFO("Goodbye now!"); -} - -/* Receiver actor expects 1 argument: its ID */ -static void receiver(int id) -{ - sg4::Mailbox* mbox = sg4::Mailbox::by_name(std::string("receiver-") + std::to_string(id)); - XBT_INFO("Wait for my first message"); - for (bool cont = true; cont;) { - auto received = mbox->get_unique(); - XBT_INFO("I got a '%s'.", received->c_str()); - cont = (*received != "finalize"); // If it's a finalize message, we're done - // Receiving the message was all we were supposed to do - } -} - -int main(int argc, char* argv[]) -{ - sg4::Engine e(&argc, argv); - - e.load_platform(argv[1]); - - sg4::Actor::create("sender", e.host_by_name("Tremblay"), sender, 5, 2, 1e6); - sg4::Actor::create("receiver", e.host_by_name("Ruby"), receiver, 0); - sg4::Actor::create("receiver", e.host_by_name("Perl"), receiver, 1); - - e.run(); - - return 0; -} diff --git a/examples/cpp/comm-waitall/s4u-comm-waitall.tesh b/examples/cpp/comm-waitall/s4u-comm-waitall.tesh deleted file mode 100644 index cdf73659e3..0000000000 --- a/examples/cpp/comm-waitall/s4u-comm-waitall.tesh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env tesh - -$ ${bindir:=.}/s4u-comm-waitall ${platfdir}/small_platform_fatpipe.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (2:receiver@Ruby) Wait for my first message -> [ 0.000000] (3:receiver@Perl) Wait for my first message -> [ 0.000000] (1:sender@Tremblay) Send 'Message 0' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 1' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 2' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 3' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 4' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Done dispatching all messages -> [ 0.004022] (2:receiver@Ruby) I got a 'Message 0'. -> [ 0.004022] (3:receiver@Perl) I got a 'Message 1'. -> [ 0.008043] (2:receiver@Ruby) I got a 'Message 2'. -> [ 0.008043] (3:receiver@Perl) I got a 'Message 3'. -> [ 0.009995] (3:receiver@Perl) I got a 'finalize'. -> [ 0.012065] (2:receiver@Ruby) I got a 'Message 4'. -> [ 0.014016] (2:receiver@Ruby) I got a 'finalize'. -> [ 0.014016] (1:sender@Tremblay) Goodbye now! diff --git a/examples/cpp/comm-waitany/s4u-comm-waitany.cpp b/examples/cpp/comm-waitany/s4u-comm-waitany.cpp deleted file mode 100644 index 30cd1e7bc4..0000000000 --- a/examples/cpp/comm-waitany/s4u-comm-waitany.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/* This example shows how to use simgrid::s4u::this_actor::wait_any() to wait for the first occurring event. - * - * As for the other asynchronous examples, the sender initiate all the messages it wants to send and - * pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occur concurrently. - * - * The sender then loops until there is no ongoing communication. Using wait_any() ensures that the sender - * will notice events as soon as they occur even if it does not follow the order of the container. - * - * Here, finalize messages will terminate earlier because their size is 0, so they travel faster than the - * other messages of this application. As expected, the trace shows that the finalize of worker 1 is - * processed before 'Message 5' that is sent to worker 0. - * - */ - -#include "simgrid/s4u.hpp" -#include -#include -#include -namespace sg4 = simgrid::s4u; - -XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_comm_waitall, "Messages specific for this s4u example"); - -static void sender(unsigned int messages_count, unsigned int receivers_count, long msg_size) -{ - if (messages_count == 0 || receivers_count == 0) { - XBT_WARN("Sender has nothing to do. Bail out!"); - return; - } - /* Vector in which we store all ongoing communications */ - std::vector pending_comms; - - /* Make a vector of the mailboxes to use */ - std::vector mboxes; - for (unsigned int i = 0; i < receivers_count; i++) - mboxes.push_back(sg4::Mailbox::by_name(std::string("receiver-") + std::to_string(i))); - - /* Start dispatching all messages to receivers, in a round robin fashion */ - for (unsigned int i = 0; i < messages_count; i++) { - std::string msg_content = std::string("Message ") + std::to_string(i); - // Copy the data we send: the 'msg_content' variable is not a stable storage location. - // It will be destroyed when this actor leaves the loop, ie before the receiver gets it - auto* payload = new std::string(msg_content); - - XBT_INFO("Send '%s' to '%s'", msg_content.c_str(), mboxes[i % receivers_count]->get_cname()); - - /* Create a communication representing the ongoing communication, and store it in pending_comms */ - sg4::CommPtr comm = mboxes[i % receivers_count]->put_async(payload, msg_size); - pending_comms.push_back(comm); - } - - /* Start sending messages to let the workers know that they should stop */ - for (unsigned int i = 0; i < receivers_count; i++) { - XBT_INFO("Send 'finalize' to 'receiver-%u'", i); - sg4::CommPtr comm = mboxes[i]->put_async(new std::string("finalize"), 0); - pending_comms.push_back(comm); - } - XBT_INFO("Done dispatching all messages"); - - /* Now that all message exchanges were initiated, wait for their completion, in order of termination. - * - * This loop waits for first terminating message with wait_any() and remove it with erase(), until all comms are - * terminated - * Even in this simple example, the pending comms do not terminate in the exact same order of creation. - */ - while (not pending_comms.empty()) { - ssize_t changed_pos = sg4::Comm::wait_any(pending_comms); - pending_comms.erase(pending_comms.begin() + changed_pos); - if (changed_pos != 0) - XBT_INFO("Remove the %zdth pending comm: it terminated earlier than another comm that was initiated first.", - changed_pos); - } - - XBT_INFO("Goodbye now!"); -} - -/* Receiver actor expects 1 argument: its ID */ -static void receiver(int id) -{ - sg4::Mailbox* mbox = sg4::Mailbox::by_name(std::string("receiver-") + std::to_string(id)); - XBT_INFO("Wait for my first message"); - for (bool cont = true; cont;) { - auto received = mbox->get_unique(); - XBT_INFO("I got a '%s'.", received->c_str()); - cont = (*received != "finalize"); // If it's a finalize message, we're done - // Receiving the message was all we were supposed to do - } -} - -int main(int argc, char* argv[]) -{ - sg4::Engine e(&argc, argv); - - e.load_platform(argv[1]); - - sg4::Actor::create("sender", e.host_by_name("Tremblay"), sender, 6, 2, 1e6); - sg4::Actor::create("receiver", e.host_by_name("Fafard"), receiver, 0); - sg4::Actor::create("receiver", e.host_by_name("Jupiter"), receiver, 1); - - e.run(); - - return 0; -} diff --git a/examples/cpp/comm-waitany/s4u-comm-waitany.tesh b/examples/cpp/comm-waitany/s4u-comm-waitany.tesh deleted file mode 100644 index 5fe9dc925e..0000000000 --- a/examples/cpp/comm-waitany/s4u-comm-waitany.tesh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env tesh - -p Testing this_actor->wait_any() - -! output sort 19 -$ ${bindir:=.}/s4u-comm-waitany ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (1:sender@Tremblay) Send 'Message 0' to 'receiver-0' -> [ 0.000000] (2:receiver@Fafard) Wait for my first message -> [ 0.000000] (3:receiver@Jupiter) Wait for my first message -> [ 0.000000] (1:sender@Tremblay) Send 'Message 1' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 2' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 3' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 4' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 5' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-1' -> [ 0.000000] (1:sender@Tremblay) Done dispatching all messages -> [ 0.158397] (2:receiver@Fafard) I got a 'Message 0'. -> [ 0.169155] (3:receiver@Jupiter) I got a 'Message 1'. -> [ 0.316794] (2:receiver@Fafard) I got a 'Message 2'. -> [ 0.338309] (3:receiver@Jupiter) I got a 'Message 3'. -> [ 0.475190] (2:receiver@Fafard) I got a 'Message 4'. -> [ 0.500898] (2:receiver@Fafard) I got a 'finalize'. -> [ 0.500898] (1:sender@Tremblay) Remove the 1th pending comm: it terminated earlier than another comm that was initiated first. -> [ 0.507464] (3:receiver@Jupiter) I got a 'Message 5'. -> [ 0.526478] (3:receiver@Jupiter) I got a 'finalize'. -> [ 0.526478] (1:sender@Tremblay) Goodbye now! diff --git a/examples/cpp/comm-waituntil/s4u-comm-waituntil.cpp b/examples/cpp/comm-waituntil/s4u-comm-waituntil.cpp index a24ca3ab67..9b1d885341 100644 --- a/examples/cpp/comm-waituntil/s4u-comm-waituntil.cpp +++ b/examples/cpp/comm-waituntil/s4u-comm-waituntil.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -25,7 +25,7 @@ static void sender(int messages_count, size_t payload_size) /* Start dispatching all messages to the receiver */ for (int i = 0; i < messages_count; i++) { - std::string message = std::string("Message ") + std::to_string(i); + std::string message = "Message " + std::to_string(i); auto* payload = new std::string(message); // copy the data we send: // 'msgName' is not a stable storage location diff --git a/examples/cpp/dag-comm/s4u-dag-comm.cpp b/examples/cpp/dag-comm/s4u-dag-comm.cpp index a6d4a98c06..77cb31d1de 100644 --- a/examples/cpp/dag-comm/s4u-dag-comm.cpp +++ b/examples/cpp/dag-comm/s4u-dag-comm.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,44 +13,47 @@ namespace sg4 = simgrid::s4u; int main(int argc, char* argv[]) { sg4::Engine e(&argc, argv); - sg_storage_file_system_init(); e.load_platform(argv[1]); - auto tremblay = e.host_by_name("Tremblay"); - auto jupiter = e.host_by_name("Jupiter"); + auto* tremblay = e.host_by_name("Tremblay"); + auto* jupiter = e.host_by_name("Jupiter"); // Display the details on vetoed activities - sg4::Activity::on_veto_cb([](const sg4::Activity& a) { - XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", a.get_cname(), - (a.dependencies_solved() ? "solved" : "NOT solved"), (a.is_assigned() ? "assigned" : "NOT assigned")); + sg4::Exec::on_veto_cb([](sg4::Exec const& exec) { + XBT_INFO("Execution '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(), + (exec.dependencies_solved() ? "solved" : "NOT solved"), (exec.is_assigned() ? "assigned" : "NOT assigned")); + }); + sg4::Comm::on_veto_cb([](sg4::Comm const& comm) { + XBT_INFO("Communication '%s' vetoed. Dependencies: %s; Ressources: %s", comm.get_cname(), + (comm.dependencies_solved() ? "solved" : "NOT solved"), (comm.is_assigned() ? "assigned" : "NOT assigned")); }); - sg4::Activity::on_completion_cb([](sg4::Activity const& activity) { - if (const auto* exec = dynamic_cast(&activity)) - XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(), - exec->get_finish_time()); - if (const auto* comm = dynamic_cast(&activity)) - XBT_INFO("Activity '%s' is complete", comm->get_cname()); + sg4::Exec::on_completion_cb([](sg4::Exec const& exec) { + XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(), + exec.get_finish_time()); + }); + sg4::Comm::on_completion_cb([](sg4::Comm const& comm) { + XBT_INFO("Comm '%s' is complete", comm.get_cname()); }); - // Create a small DAG: parent->transfert->child - sg4::ExecPtr parent = sg4::Exec::init(); - sg4::CommPtr transfert = sg4::Comm::sendto_init(); - sg4::ExecPtr child = sg4::Exec::init(); - parent->add_successor(transfert); - transfert->add_successor(child); + // Create a small DAG: parent->transfer->child + sg4::ExecPtr parent = sg4::Exec::init(); + sg4::CommPtr transfer = sg4::Comm::sendto_init(); + sg4::ExecPtr child = sg4::Exec::init(); + parent->add_successor(transfer); + transfer->add_successor(child); // Set the parameters (the name is for logging purposes only) // + parent and child end after 1 second - parent->set_name("parent")->set_flops_amount(tremblay->get_speed())->vetoable_start(); - transfert->set_name("transfert")->set_payload_size(125e6)->vetoable_start(); - child->set_name("child")->set_flops_amount(jupiter->get_speed())->vetoable_start(); + parent->set_name("parent")->set_flops_amount(tremblay->get_speed())->start(); + transfer->set_name("transfer")->set_payload_size(125e6)->start(); + child->set_name("child")->set_flops_amount(jupiter->get_speed())->start(); // Schedule the different activities parent->set_host(tremblay); - transfert->set_source(tremblay); + transfer->set_source(tremblay); child->set_host(jupiter); - transfert->set_destination(jupiter); + transfer->set_destination(jupiter); e.run(); diff --git a/examples/cpp/dag-comm/s4u-dag-comm.tesh b/examples/cpp/dag-comm/s4u-dag-comm.tesh index 04824f8c7d..abe40f4159 100644 --- a/examples/cpp/dag-comm/s4u-dag-comm.tesh +++ b/examples/cpp/dag-comm/s4u-dag-comm.tesh @@ -1,18 +1,18 @@ #!/usr/bin/env tesh $ ${bindir:=.}/s4u-dag-comm ${platfdir}/two_hosts.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Activity 'parent' vetoed. Dependencies: solved; Ressources: NOT assigned -> [ 0.000000] (0:maestro@) Activity 'transfert' vetoed. Dependencies: NOT solved; Ressources: NOT assigned -> [ 0.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned +> [ 0.000000] (0:maestro@) Execution 'parent' vetoed. Dependencies: solved; Ressources: NOT assigned +> [ 0.000000] (0:maestro@) Communication 'transfer' vetoed. Dependencies: NOT solved; Ressources: NOT assigned +> [ 0.000000] (0:maestro@) Execution 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned > [ 0.000000] (0:maestro@) 'parent' is assigned to a resource and all dependencies are solved. Let's start -> [ 0.000000] (0:maestro@) Activity 'transfert' vetoed. Dependencies: NOT solved; Ressources: NOT assigned -> [ 0.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: assigned -> [ 0.000000] (0:maestro@) Activity 'transfert' vetoed. Dependencies: NOT solved; Ressources: assigned -> [ 1.000000] (0:maestro@) Activity 'parent' is complete (start time: 0.000000, finish time: 1.000000) -> [ 1.000000] (0:maestro@) Remove a dependency from 'parent' on 'transfert' -> [ 1.000000] (0:maestro@) 'transfert' is assigned to a resource and all dependencies are solved. Let's start -> [ 2.083775] (0:maestro@) Activity 'transfert' is complete -> [ 2.083775] (0:maestro@) Remove a dependency from 'transfert' on 'child' +> [ 0.000000] (0:maestro@) Communication 'transfer' vetoed. Dependencies: NOT solved; Ressources: NOT assigned +> [ 0.000000] (0:maestro@) Execution 'child' vetoed. Dependencies: NOT solved; Ressources: assigned +> [ 0.000000] (0:maestro@) Communication 'transfer' vetoed. Dependencies: NOT solved; Ressources: assigned +> [ 1.000000] (0:maestro@) Exec 'parent' is complete (start time: 0.000000, finish time: 1.000000) +> [ 1.000000] (0:maestro@) Remove a dependency from 'parent' on 'transfer' +> [ 1.000000] (0:maestro@) 'transfer' is assigned to a resource and all dependencies are solved. Let's start +> [ 2.083775] (0:maestro@) Remove a dependency from 'transfer' on 'child' > [ 2.083775] (0:maestro@) 'child' is assigned to a resource and all dependencies are solved. Let's start -> [ 3.083775] (0:maestro@) Activity 'child' is complete (start time: 2.083775, finish time: 3.083775) +> [ 2.083775] (0:maestro@) Comm 'transfer' is complete +> [ 3.083775] (0:maestro@) Exec 'child' is complete (start time: 2.083775, finish time: 3.083775) > [ 3.083775] (0:maestro@) Simulation time 3.08378 diff --git a/examples/cpp/dag-failure/s4u-dag-failure.cpp b/examples/cpp/dag-failure/s4u-dag-failure.cpp index 4d6fa4b92f..c2ab8d58c2 100644 --- a/examples/cpp/dag-failure/s4u-dag-failure.cpp +++ b/examples/cpp/dag-failure/s4u-dag-failure.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. +/* Copyright (c) 2006-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -18,25 +18,22 @@ int main(int argc, char** argv) auto* faulty = e.host_by_name("Faulty Host"); auto* safe = e.host_by_name("Safe Host"); - sg4::Activity::on_completion_cb([](sg4::Activity const& activity) { - const auto* exec = dynamic_cast(&activity); - if (exec == nullptr) // Only Execs are concerned here - return; - if (exec->get_state() == sg4::Activity::State::FINISHED) - XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(), - exec->get_finish_time()); - if (exec->get_state() == sg4::Activity::State::FAILED) { - if (exec->is_parallel()) - XBT_INFO("Activity '%s' has failed. %.f %% remain to be done", exec->get_cname(), - 100 * exec->get_remaining_ratio()); + sg4::Exec::on_completion_cb([](sg4::Exec const& exec) { + if (exec.get_state() == sg4::Activity::State::FINISHED) + XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(), + exec.get_finish_time()); + if (exec.get_state() == sg4::Activity::State::FAILED) { + if (exec.is_parallel()) + XBT_INFO("Activity '%s' has failed. %.f %% remain to be done", exec.get_cname(), + 100 * exec.get_remaining_ratio()); else - XBT_INFO("Activity '%s' has failed. %.f flops remain to be done", exec->get_cname(), exec->get_remaining()); + XBT_INFO("Activity '%s' has failed. %.f flops remain to be done", exec.get_cname(), exec.get_remaining()); } }); /* creation of a single Exec that will poorly fail when the workstation will stop */ XBT_INFO("First test: sequential Exec activity"); - sg4::ExecPtr exec = sg4::Exec::init()->set_name("Poor task")->set_flops_amount(2e10)->vetoable_start(); + sg4::ExecPtr exec = sg4::Exec::init()->set_name("Poor task")->set_flops_amount(2e10)->start(); XBT_INFO("Schedule Activity '%s' on 'Faulty Host'", exec->get_cname()); exec->set_host(faulty); @@ -44,7 +41,7 @@ int main(int argc, char** argv) /* Add a child Exec that depends on the Poor task' */ sg4::ExecPtr child = sg4::Exec::init()->set_name("Child")->set_flops_amount(2e10)->set_host(safe); exec->add_successor(child); - child->vetoable_start(); + child->start(); XBT_INFO("Run the simulation"); e.run(); @@ -57,7 +54,7 @@ int main(int argc, char** argv) e.run(); XBT_INFO("Second test: parallel Exec activity"); - exec = sg4::Exec::init()->set_name("Poor parallel task")->set_flops_amounts({2e10, 2e10})->vetoable_start(); + exec = sg4::Exec::init()->set_name("Poor parallel task")->set_flops_amounts({2e10, 2e10})->start(); XBT_INFO("Schedule Activity '%s' on 'Safe Host' and 'Faulty Host'", exec->get_cname()); exec->set_hosts({safe, faulty}); @@ -65,7 +62,7 @@ int main(int argc, char** argv) /* Add a child Exec that depends on the Poor parallel task' */ child = sg4::Exec::init()->set_name("Child")->set_flops_amount(2e10)->set_host(safe); exec->add_successor(child); - child->vetoable_start(); + child->start(); XBT_INFO("Run the simulation"); e.run(); diff --git a/examples/cpp/dag-from-dax-simple/dag.xml b/examples/cpp/dag-from-dax-simple/dag.xml new file mode 100644 index 0000000000..2572f7cbdb --- /dev/null +++ b/examples/cpp/dag-from-dax-simple/dag.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple.cpp b/examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple.cpp new file mode 100644 index 0000000000..aa8e17d8a0 --- /dev/null +++ b/examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple.cpp @@ -0,0 +1,47 @@ +/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(dag_from_dax_simple, "Messages specific for this s4u example"); + +int main(int argc, char* argv[]) +{ + simgrid::s4u::Engine e(&argc, argv); + e.load_platform(argv[1]); + + std::vector dag = simgrid::s4u::create_DAG_from_DAX(argv[2]); + + simgrid::s4u::Host* tremblay = e.host_by_name("Tremblay"); + simgrid::s4u::Host* jupiter = e.host_by_name("Jupiter"); + simgrid::s4u::Host* fafard = e.host_by_name("Fafard"); + + dynamic_cast(dag[0].get())->set_host(fafard); + dynamic_cast(dag[1].get())->set_host(tremblay); + dynamic_cast(dag[2].get())->set_host(jupiter); + dynamic_cast(dag[3].get())->set_host(jupiter); + dynamic_cast(dag[8].get())->set_host(jupiter); + + for (const auto& a : dag) { + if (auto* comm = dynamic_cast(a.get())) { + const auto* pred = dynamic_cast((*comm->get_dependencies().begin()).get()); + const auto* succ = dynamic_cast(comm->get_successors().front().get()); + comm->set_source(pred->get_host())->set_destination(succ->get_host()); + } + } + + simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) { + XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), + exec.get_start_time(), exec.get_finish_time()); + }); + + simgrid::s4u::Comm::on_completion_cb([](simgrid::s4u::Comm const& comm) { + XBT_INFO("Comm '%s' is complete (start time: %f, finish time: %f)", comm.get_cname(), + comm.get_start_time(), comm.get_finish_time()); + }); + + e.run(); + return 0; +} diff --git a/examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple.tesh b/examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple.tesh new file mode 100644 index 0000000000..af5a6f274f --- /dev/null +++ b/examples/cpp/dag-from-dax-simple/s4u-dag-from-dax-simple.tesh @@ -0,0 +1,12 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-dag-from-dax-simple --log=no_loc ${platfdir}/small_platform.xml ${srcdir:=.}/dag.xml +> [0.000000] [dag_from_dax_simple/INFO] Exec 'root' is complete (start time: 0.000000, finish time: 0.000000) +> [33.394394] [dag_from_dax_simple/INFO] Comm 'root_i2_2@c2' is complete (start time: 0.000000, finish time: 33.394394) +> [39.832311] [dag_from_dax_simple/INFO] Comm 'root_i1_1@c1' is complete (start time: 0.000000, finish time: 39.832311) +> [467.988690] [dag_from_dax_simple/INFO] Exec '1@c1' is complete (start time: 39.832311, finish time: 467.988690) +> [543.077868] [dag_from_dax_simple/INFO] Comm '1@c1_o1_3@c3' is complete (start time: 467.988690, finish time: 543.077868) +> [2785.832267] [dag_from_dax_simple/INFO] Exec '2@c2' is complete (start time: 33.394394, finish time: 2785.832267) +> [3886.807417] [dag_from_dax_simple/INFO] Exec '3@c3' is complete (start time: 2785.832267, finish time: 3886.807417) +> [3887.221639] [dag_from_dax_simple/INFO] Comm '3@c3_o3_end' is complete (start time: 3886.807417, finish time: 3887.221639) +> [3887.221639] [dag_from_dax_simple/INFO] Exec 'end' is complete (start time: 3887.221639, finish time: 3887.221639) \ No newline at end of file diff --git a/examples/cpp/dag-from-dax/s4u-dag-from-dax.cpp b/examples/cpp/dag-from-dax/s4u-dag-from-dax.cpp index a6c253886d..9c62ac8d50 100644 --- a/examples/cpp/dag-from-dax/s4u-dag-from-dax.cpp +++ b/examples/cpp/dag-from-dax/s4u-dag-from-dax.cpp @@ -1,6 +1,6 @@ /* simple test trying to load a DAX file. */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -51,8 +51,8 @@ int main(int argc, char** argv) cursor++; } if (auto* comm = dynamic_cast(a.get())) { - auto pred = dynamic_cast((*comm->get_dependencies().begin()).get()); - auto succ = dynamic_cast(comm->get_successors().front().get()); + const auto* pred = dynamic_cast((*comm->get_dependencies().begin()).get()); + const auto* succ = dynamic_cast(comm->get_successors().front().get()); comm->set_source(pred->get_host())->set_destination(succ->get_host()); } } diff --git a/examples/cpp/dag-from-dot-simple/dag.dot b/examples/cpp/dag-from-dot-simple/dag.dot new file mode 100644 index 0000000000..603409fa01 --- /dev/null +++ b/examples/cpp/dag-from-dot-simple/dag.dot @@ -0,0 +1,10 @@ +digraph G { + c1 [size="1e9"]; + c2 [size="5e9"]; + c3 [size="2e9"]; + root->c1 [size="2e8"]; + root->c2 [size="1e8"]; + c1->c3 [size="5e8"]; + c2->c3 [size="-1."]; + c3->end [size="2e8"]; +} diff --git a/examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.cpp b/examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.cpp new file mode 100644 index 0000000000..a6972b0915 --- /dev/null +++ b/examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.cpp @@ -0,0 +1,47 @@ +/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(dag_from_dot_simple, "Messages specific for this s4u example"); + +int main(int argc, char* argv[]) +{ + simgrid::s4u::Engine e(&argc, argv); + e.load_platform(argv[1]); + + std::vector dag = simgrid::s4u::create_DAG_from_dot(argv[2]); + + simgrid::s4u::Host* tremblay = e.host_by_name("Tremblay"); + simgrid::s4u::Host* jupiter = e.host_by_name("Jupiter"); + simgrid::s4u::Host* fafard = e.host_by_name("Fafard"); + + dynamic_cast(dag[0].get())->set_host(fafard); + dynamic_cast(dag[1].get())->set_host(tremblay); + dynamic_cast(dag[2].get())->set_host(jupiter); + dynamic_cast(dag[3].get())->set_host(jupiter); + dynamic_cast(dag[8].get())->set_host(jupiter); + + for (const auto& a : dag) { + if (auto* comm = dynamic_cast(a.get())) { + const auto* pred = dynamic_cast((*comm->get_dependencies().begin()).get()); + const auto* succ = dynamic_cast(comm->get_successors().front().get()); + comm->set_source(pred->get_host())->set_destination(succ->get_host()); + } + } + + simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) { + XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), + exec.get_start_time(), exec.get_finish_time()); + }); + + simgrid::s4u::Comm::on_completion_cb([](simgrid::s4u::Comm const& comm) { + XBT_INFO("Comm '%s' is complete (start time: %f, finish time: %f)", comm.get_cname(), + comm.get_start_time(), comm.get_finish_time()); + }); + + e.run(); + return 0; +} diff --git a/examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.tesh b/examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.tesh new file mode 100644 index 0000000000..6133b1bd57 --- /dev/null +++ b/examples/cpp/dag-from-dot-simple/s4u-dag-from-dot-simple.tesh @@ -0,0 +1,12 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-dag-from-dot-simple --log=no_loc ${platfdir}/small_platform.xml ${srcdir:=.}/dag.dot +> [0.000000] [dag_from_dot_simple/INFO] Exec 'root' is complete (start time: 0.000000, finish time: 0.000000) +> [33.394394] [dag_from_dot_simple/INFO] Comm 'root->c2' is complete (start time: 0.000000, finish time: 33.394394) +> [39.832311] [dag_from_dot_simple/INFO] Comm 'root->c1' is complete (start time: 0.000000, finish time: 39.832311) +> [50.026511] [dag_from_dot_simple/INFO] Exec 'c1' is complete (start time: 39.832311, finish time: 50.026511) +> [98.928629] [dag_from_dot_simple/INFO] Exec 'c2' is complete (start time: 33.394394, finish time: 98.928629) +> [125.115689] [dag_from_dot_simple/INFO] Comm 'c1->c3' is complete (start time: 50.026511, finish time: 125.115689) +> [151.329383] [dag_from_dot_simple/INFO] Exec 'c3' is complete (start time: 125.115689, finish time: 151.329383) +> [151.743605] [dag_from_dot_simple/INFO] Comm 'c3->end' is complete (start time: 151.329383, finish time: 151.743605) +> [151.743605] [dag_from_dot_simple/INFO] Exec 'end' is complete (start time: 151.743605, finish time: 151.743605) \ No newline at end of file diff --git a/examples/cpp/dag-from-dot/s4u-dag-from-dot.cpp b/examples/cpp/dag-from-dot/s4u-dag-from-dot.cpp index ef2d22f344..30d2b751d4 100644 --- a/examples/cpp/dag-from-dot/s4u-dag-from-dot.cpp +++ b/examples/cpp/dag-from-dot/s4u-dag-from-dot.cpp @@ -1,6 +1,6 @@ /* simple test trying to load a DOT file. */ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -49,8 +49,8 @@ int main(int argc, char** argv) cursor++; } if (auto* comm = dynamic_cast(a.get())) { - auto pred = dynamic_cast((*comm->get_dependencies().begin()).get()); - auto succ = dynamic_cast(comm->get_successors().front().get()); + const auto* pred = dynamic_cast((*comm->get_dependencies().begin()).get()); + const auto* succ = dynamic_cast(comm->get_successors().front().get()); comm->set_source(pred->get_host())->set_destination(succ->get_host()); } } diff --git a/examples/cpp/dag-from-json-simple/dag.json b/examples/cpp/dag-from-json-simple/dag.json new file mode 100644 index 0000000000..fecb6e4ca6 --- /dev/null +++ b/examples/cpp/dag-from-json-simple/dag.json @@ -0,0 +1,42 @@ +{ + "name": "simple_json", + "schemaVersion": "1.0", + "workflow": { + "makespanInSeconds": 0, + "executedAt": "2023-03-09T00:00:00-00:00", + "tasks": [ + { + "name": "c1", + "type": "compute", + "parents": [], + "runtimeInSeconds": 1e9, + "machine": "Tremblay" + }, + { + "name": "t1", + "type": "transfer", + "parents": ["c1"], + "writtenBytes": 5e8, + "machine": "Jupiter" + }, + { + "name": "c2", + "type": "compute", + "parents": [], + "runtimeInSeconds": 5e9, + "machine": "Jupiter" + }, + { + "name": "c3", + "type": "compute", + "parents": ["t1","c2"], + "runtimeInSeconds": 2e9, + "machine": "Jupiter" + } + ], + "machines": [ + {"nodeName": "Tremblay"}, + {"nodeName": "Jupiter"} + ] + } +} \ No newline at end of file diff --git a/examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.cpp b/examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.cpp new file mode 100644 index 0000000000..bf878977a0 --- /dev/null +++ b/examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.cpp @@ -0,0 +1,29 @@ +/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(dag_from_json_simple, "Messages specific for this s4u example"); + +int main(int argc, char* argv[]) +{ + simgrid::s4u::Engine e(&argc, argv); + e.load_platform(argv[1]); + + std::vector dag = simgrid::s4u::create_DAG_from_json(argv[2]); + + simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) { + XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), + exec.get_start_time(), exec.get_finish_time()); + }); + + simgrid::s4u::Comm::on_completion_cb([](simgrid::s4u::Comm const& comm) { + XBT_INFO("Comm '%s' is complete (start time: %f, finish time: %f)", comm.get_cname(), + comm.get_start_time(), comm.get_finish_time()); + }); + + e.run(); + return 0; +} diff --git a/examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.tesh b/examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.tesh new file mode 100644 index 0000000000..cd41320c00 --- /dev/null +++ b/examples/cpp/dag-from-json-simple/s4u-dag-from-json-simple.tesh @@ -0,0 +1,7 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-dag-from-json-simple --log=no_loc ${platfdir}/small_platform.xml ${srcdir:=.}/dag.json +> [10.194200] [dag_from_json_simple/INFO] Exec 'c1' is complete (start time: 0.000000, finish time: 10.194200) +> [65.534235] [dag_from_json_simple/INFO] Exec 'c2' is complete (start time: 0.000000, finish time: 65.534235) +> [85.283378] [dag_from_json_simple/INFO] Comm 't1' is complete (start time: 10.194200, finish time: 85.283378) +> [111.497072] [dag_from_json_simple/INFO] Exec 'c3' is complete (start time: 85.283378, finish time: 111.497072) \ No newline at end of file diff --git a/examples/cpp/dag-io/s4u-dag-io.cpp b/examples/cpp/dag-io/s4u-dag-io.cpp index a75dbc0769..738f35682c 100644 --- a/examples/cpp/dag-io/s4u-dag-io.cpp +++ b/examples/cpp/dag-io/s4u-dag-io.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,24 +13,24 @@ namespace sg4 = simgrid::s4u; int main(int argc, char* argv[]) { sg4::Engine e(&argc, argv); - sg_storage_file_system_init(); e.load_platform(argv[1]); - auto bob = e.host_by_name("bob"); - auto carl = e.host_by_name("carl"); + auto* bob = e.host_by_name("bob"); + auto* carl = e.host_by_name("carl"); // Display the details on vetoed activities - sg4::Activity::on_veto_cb([](const sg4::Activity& a) { - XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", a.get_cname(), - (a.dependencies_solved() ? "solved" : "NOT solved"), (a.is_assigned() ? "assigned" : "NOT assigned")); + sg4::Exec::on_veto_cb([](sg4::Exec const& exec) { + XBT_INFO("Exec '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(), + (exec.dependencies_solved() ? "solved" : "NOT solved"), (exec.is_assigned() ? "assigned" : "NOT assigned")); + }); + sg4::Io::on_veto_cb([](sg4::Io const& io) { + XBT_INFO("Io '%s' vetoed. Dependencies: %s; Ressources: %s", io.get_cname(), + (io.dependencies_solved() ? "solved" : "NOT solved"), (io.is_assigned() ? "assigned" : "NOT assigned")); }); - sg4::Activity::on_completion_cb([](sg4::Activity const& activity) { - const auto* exec = dynamic_cast(&activity); - if (exec == nullptr) // Only Execs are concerned here - return; - XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(), - exec->get_finish_time()); + sg4::Exec::on_completion_cb([](sg4::Exec const& exec) { + XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(), + exec.get_finish_time()); }); // Create a small DAG: parent->write_output->read_input->child @@ -50,10 +50,10 @@ int main(int argc, char* argv[]) child->set_name("child")->set_flops_amount(carl->get_speed()); // Schedule and try to start the different activities - parent->set_host(bob)->vetoable_start(); - write_output->set_disk(bob->get_disks().front())->vetoable_start(); - read_input->set_disk(carl->get_disks().front())->vetoable_start(); - child->set_host(carl)->vetoable_start(); + parent->set_host(bob)->start(); + write_output->set_disk(bob->get_disks().front())->start(); + read_input->set_disk(carl->get_disks().front())->start(); + child->set_host(carl)->start(); e.run(); diff --git a/examples/cpp/dag-io/s4u-dag-io.tesh b/examples/cpp/dag-io/s4u-dag-io.tesh index 186126ba96..8c1c3ca51c 100644 --- a/examples/cpp/dag-io/s4u-dag-io.tesh +++ b/examples/cpp/dag-io/s4u-dag-io.tesh @@ -2,15 +2,15 @@ $ ${bindir:=.}/s4u-dag-io ${platfdir}/hosts_with_disks.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) 'parent' is assigned to a resource and all dependencies are solved. Let's start -> [ 0.000000] (0:maestro@) Activity 'write' vetoed. Dependencies: NOT solved; Ressources: assigned -> [ 0.000000] (0:maestro@) Activity 'read' vetoed. Dependencies: NOT solved; Ressources: assigned -> [ 0.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: assigned -> [ 1.000000] (0:maestro@) Activity 'parent' is complete (start time: 0.000000, finish time: 1.000000) +> [ 0.000000] (0:maestro@) Io 'write' vetoed. Dependencies: NOT solved; Ressources: assigned +> [ 0.000000] (0:maestro@) Io 'read' vetoed. Dependencies: NOT solved; Ressources: assigned +> [ 0.000000] (0:maestro@) Exec 'child' vetoed. Dependencies: NOT solved; Ressources: assigned +> [ 1.000000] (0:maestro@) Exec 'parent' is complete (start time: 0.000000, finish time: 1.000000) > [ 1.000000] (0:maestro@) Remove a dependency from 'parent' on 'write' > [ 1.000000] (0:maestro@) 'write' is assigned to a resource and all dependencies are solved. Let's start > [ 26.000000] (0:maestro@) Remove a dependency from 'write' on 'read' > [ 26.000000] (0:maestro@) 'read' is assigned to a resource and all dependencies are solved. Let's start > [ 36.000000] (0:maestro@) Remove a dependency from 'read' on 'child' > [ 36.000000] (0:maestro@) 'child' is assigned to a resource and all dependencies are solved. Let's start -> [ 37.000000] (0:maestro@) Activity 'child' is complete (start time: 36.000000, finish time: 37.000000) +> [ 37.000000] (0:maestro@) Exec 'child' is complete (start time: 36.000000, finish time: 37.000000) > [ 37.000000] (0:maestro@) Simulation time 37 diff --git a/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp b/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp index 47c77e46a3..51dde09ae9 100644 --- a/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp +++ b/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,46 +12,12 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(dag_scheduling, "Logging specific to this example"); namespace sg4 = simgrid::s4u; -struct HostAttribute { - /* Earliest time at which a host is ready to execute a task */ - double available_at = 0.0; - sg4::Exec* last_scheduled_task = nullptr; -}; - -static double sg_host_get_available_at(const sg4::Host* host) -{ - return host->get_data()->available_at; -} - -static void sg_host_set_available_at(const sg4::Host* host, double time) -{ - host->get_data()->available_at = time; -} - -static sg4::Exec* sg_host_get_last_scheduled_task(const sg4::Host* host) -{ - return host->get_data()->last_scheduled_task; -} - -static void sg_host_set_last_scheduled_task(const sg4::Host* host, sg4::ExecPtr task) -{ - host->get_data()->last_scheduled_task = task.get(); -} - -static bool dependency_exists(const sg4::Exec* src, sg4::Exec* dst) -{ - const auto& dependencies = src->get_dependencies(); - const auto& successors = src->get_successors(); - return (std::find(successors.begin(), successors.end(), dst) != successors.end() || - dependencies.find(dst) != dependencies.end()); -} - static std::vector get_ready_tasks(const std::vector& dax) { std::vector ready_tasks; std::map candidate_execs; - for (auto& a : dax) { + for (const auto& a : dax) { // Only look at activity that have their dependencies solved but are not assigned if (a->dependencies_solved() && not a->is_assigned()) { // if it is an exec, it's ready @@ -71,61 +37,65 @@ static std::vector get_ready_tasks(const std::vectorget_dependencies()) { - /* normal case */ - if (const auto* comm = dynamic_cast(parent.get())) { - auto source = comm->get_source(); - XBT_DEBUG("transfer from %s to %s", source->get_cname(), host->get_cname()); - /* Estimate the redistribution time from this parent */ - double redist_time; - if (comm->get_remaining() <= 1e-6) { - redist_time = 0; - } else { - redist_time = - sg_host_get_route_latency(source, host) + comm->get_remaining() / sg_host_get_route_bandwidth(source, host); + sg4::Host* best_host = nullptr; + *min_finish_time = std::numeric_limits::max(); + + for (const auto& host : sg4::Engine::get_instance()->get_all_hosts()) { + double data_available = 0.; + double last_data_available = -1.0; + /* compute last_data_available */ + for (const auto& parent : exec->get_dependencies()) { + /* normal case */ + if (const auto* comm = dynamic_cast(parent.get())) { + const auto* source = comm->get_source(); + XBT_DEBUG("transfer from %s to %s", source->get_cname(), host->get_cname()); + /* Estimate the redistribution time from this parent */ + double redist_time; + if (comm->get_remaining() <= 1e-6) { + redist_time = 0; + } else { + double bandwidth = std::numeric_limits::max(); + auto [links, latency] = source->route_to(host); + for (auto const& link : links) + bandwidth = std::min(bandwidth, link->get_bandwidth()); + + redist_time = latency + comm->get_remaining() / bandwidth; + } + // We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential + // start time + data_available = *comm->get_data() + redist_time; } - // We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential start - // time - data_available = *comm->get_data() + redist_time; - } - /* no transfer, control dependency */ - if (const auto* exec = dynamic_cast(parent.get())) - data_available = exec->get_finish_time(); - - if (last_data_available < data_available) - last_data_available = data_available; - } + /* no transfer, control dependency */ + if (const auto* parent_exec = dynamic_cast(parent.get())) + data_available = parent_exec->get_finish_time(); - return std::max(sg_host_get_available_at(host), last_data_available) + task->get_remaining() / host->get_speed(); -} + if (last_data_available < data_available) + last_data_available = data_available; + } -static sg4::Host* get_best_host(const sg4::ExecPtr exec) -{ - std::vector hosts = sg4::Engine::get_instance()->get_all_hosts(); - auto best_host = hosts.front(); - double min_EFT = finish_on_at(exec, best_host); + double finish_time = std::max(*host->get_data(), last_data_available) + + exec->get_remaining() / host->get_speed(); - for (const auto& h : hosts) { - double EFT = finish_on_at(exec, h); - XBT_DEBUG("%s finishes on %s at %f", exec->get_cname(), h->get_cname(), EFT); + XBT_DEBUG("%s finishes on %s at %f", exec->get_cname(), host->get_cname(), finish_time); - if (EFT < min_EFT) { - min_EFT = EFT; - best_host = h; + if (finish_time < *min_finish_time) { + *min_finish_time = finish_time; + best_host = host; } } + return best_host; } -static void schedule_on(sg4::ExecPtr exec, sg4::Host* host) +static void schedule_on(sg4::ExecPtr exec, sg4::Host* host, double busy_until = 0.0) { exec->set_host(host); + // We use the user data field to store up to when the host is busy + delete host->get_data(); // In case we're erasing a previous value + host->set_data(new double(busy_until)); // we can also set the destination of all the input comms of this exec for (const auto& pred : exec->get_dependencies()) { auto* comm = dynamic_cast(pred.get()); @@ -148,15 +118,12 @@ int main(int argc, char** argv) std::set vetoed; e.track_vetoed_activities(&vetoed); - sg4::Activity::on_completion_cb([](sg4::Activity const& activity) { + sg4::Exec::on_completion_cb([](sg4::Exec const& exec) { // when an Exec completes, we need to set the potential start time of all its ouput comms - const auto* exec = dynamic_cast(&activity); - if (exec == nullptr) // Only Execs are concerned here - return; - for (const auto& succ : exec->get_successors()) { + for (const auto& succ : exec.get_successors()) { auto* comm = dynamic_cast(succ.get()); if (comm != nullptr) { - auto* finish_time = new double(exec->get_finish_time()); + auto* finish_time = new double(exec.get_finish_time()); // We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential start // time comm->set_data(finish_time); @@ -166,19 +133,21 @@ int main(int argc, char** argv) e.load_platform(argv[1]); - /* Allocating the host attribute */ - unsigned long total_nhosts = e.get_host_count(); - const auto hosts = e.get_all_hosts(); - std::vector host_attributes(total_nhosts); - for (unsigned long i = 0; i < total_nhosts; i++) - hosts[i]->set_data(&host_attributes[i]); - + /* Mark all hosts as sequential, as it ought to be in such a scheduling example. + * + * It means that the hosts can only compute one thing at a given time. If an execution already takes place on a given + * host, any subsequently started execution will be queued until after the first execution terminates */ + for (auto const& host : e.get_all_hosts()) { + host->set_concurrency_limit(1); + host->set_data(new double(0.0)); + } /* load the DAX file */ auto dax = sg4::create_DAG_from_DAX(argv[2]); /* Schedule the root first */ + double root_finish_time; auto* root = static_cast(dax.front().get()); - auto host = get_best_host(root); + auto* host = get_best_host(root, &root_finish_time); schedule_on(root, host); e.run(); @@ -190,54 +159,40 @@ int main(int argc, char** argv) vetoed.clear(); if (ready_tasks.empty()) { - /* there is no ready task, let advance the simulation */ + /* there is no ready exec, let advance the simulation */ e.run(); continue; } - /* For each ready task: + /* For each ready exec: * get the host that minimizes the completion time. - * select the task that has the minimum completion time on its best host. + * select the exec that has the minimum completion time on its best host. */ - double min_finish_time = -1.0; - sg4::Exec* selected_task = nullptr; - sg4::Host* selected_host = nullptr; - - for (auto task : ready_tasks) { - XBT_DEBUG("%s is ready", task->get_cname()); - host = get_best_host(task); - double finish_time = finish_on_at(task, host); - if (min_finish_time < 0 || finish_time < min_finish_time) { + double min_finish_time = std::numeric_limits::max(); + sg4::Exec* selected_task = nullptr; + sg4::Host* selected_host = nullptr; + + for (auto* exec : ready_tasks) { + XBT_DEBUG("%s is ready", exec->get_cname()); + double finish_time; + host = get_best_host(exec, &finish_time); + if (finish_time < min_finish_time) { min_finish_time = finish_time; - selected_task = task; + selected_task = exec; selected_host = host; } } XBT_INFO("Schedule %s on %s", selected_task->get_cname(), selected_host->get_cname()); - schedule_on(selected_task, selected_host); - - /* - * tasks can be executed concurrently when they can by default. - * Yet schedulers take decisions assuming that tasks wait for resource availability to start. - * The solution (well crude hack is to keep track of the last task scheduled on a host and add a special type of - * dependency if needed to force the sequential execution meant by the scheduler. - * If the last scheduled task is already done, has failed or is a predecessor of the current task, no need for a - * new dependency - */ - - if (auto last_scheduled_task = sg_host_get_last_scheduled_task(selected_host); - last_scheduled_task && (last_scheduled_task->get_state() != sg4::Activity::State::FINISHED) && - (last_scheduled_task->get_state() != sg4::Activity::State::FAILED) && - not dependency_exists(sg_host_get_last_scheduled_task(selected_host), selected_task)) - last_scheduled_task->add_successor(selected_task); - - sg_host_set_last_scheduled_task(selected_host, selected_task); - sg_host_set_available_at(selected_host, min_finish_time); + schedule_on(selected_task, selected_host, min_finish_time); ready_tasks.clear(); e.run(); } + /* Cleanup memory */ + for (auto const* h : e.get_all_hosts()) + delete h->get_data(); + XBT_INFO("Simulation Time: %f", simgrid_get_clock()); return 0; diff --git a/examples/cpp/dag-simple/s4u-dag-simple.cpp b/examples/cpp/dag-simple/s4u-dag-simple.cpp index f6411a636d..6f60e2e2ae 100644 --- a/examples/cpp/dag-simple/s4u-dag-simple.cpp +++ b/examples/cpp/dag-simple/s4u-dag-simple.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -16,23 +16,18 @@ int main(int argc, char* argv[]) std::set vetoed; e.track_vetoed_activities(&vetoed); - auto fafard = e.host_by_name("Fafard"); + auto* fafard = e.host_by_name("Fafard"); // Display the details on vetoed activities - sg4::Activity::on_veto_cb([](const sg4::Activity& a) { - const auto& exec = static_cast(a); // all activities are execs in this example - - XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(), + sg4::Exec::on_veto_cb([](sg4::Exec const& exec) { + XBT_INFO("Execution '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(), (exec.dependencies_solved() ? "solved" : "NOT solved"), (exec.is_assigned() ? "assigned" : "NOT assigned")); }); - sg4::Activity::on_completion_cb([](sg4::Activity const& activity) { - const auto* exec = dynamic_cast(&activity); - if (exec == nullptr) // Only Execs are concerned here - return; - XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(), - exec->get_finish_time()); + sg4::Exec::on_completion_cb([](sg4::Exec const& exec) { + XBT_INFO("Execution '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(), + exec.get_finish_time()); }); // Define an amount of work that should take 1 second to execute. @@ -56,9 +51,9 @@ int main(int argc, char* argv[]) second_parent->set_host(fafard); // Start all activities that can actually start. - first_parent->vetoable_start(); - second_parent->vetoable_start(); - child->vetoable_start(); + first_parent->start(); + second_parent->start(); + child->start(); while (child->get_state() != sg4::Activity::State::FINISHED) { e.run(); diff --git a/examples/cpp/dag-simple/s4u-dag-simple.tesh b/examples/cpp/dag-simple/s4u-dag-simple.tesh index e41d10ee99..18b0d0b43a 100644 --- a/examples/cpp/dag-simple/s4u-dag-simple.tesh +++ b/examples/cpp/dag-simple/s4u-dag-simple.tesh @@ -3,14 +3,14 @@ $ ${bindir:=.}/s4u-dag-simple ${platfdir}/small_platform.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) 'parent 1' is assigned to a resource and all dependencies are solved. Let's start > [ 0.000000] (0:maestro@) 'parent 2' is assigned to a resource and all dependencies are solved. Let's start -> [ 0.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned -> [ 2.000000] (0:maestro@) Activity 'parent 1' is complete (start time: 0.000000, finish time: 2.000000) +> [ 0.000000] (0:maestro@) Execution 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned +> [ 2.000000] (0:maestro@) Execution 'parent 1' is complete (start time: 0.000000, finish time: 2.000000) > [ 2.000000] (0:maestro@) Remove a dependency from 'parent 1' on 'child' > [ 2.000000] (0:maestro@) Activity child not ready. -> [ 3.000000] (0:maestro@) Activity 'parent 2' is complete (start time: 0.000000, finish time: 3.000000) +> [ 3.000000] (0:maestro@) Execution 'parent 2' is complete (start time: 0.000000, finish time: 3.000000) > [ 3.000000] (0:maestro@) Remove a dependency from 'parent 2' on 'child' -> [ 3.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: solved; Ressources: NOT assigned +> [ 3.000000] (0:maestro@) Execution 'child' vetoed. Dependencies: solved; Ressources: NOT assigned > [ 3.000000] (0:maestro@) Activity child's dependencies are resolved. Let's assign it to Fafard. > [ 3.000000] (0:maestro@) 'child' is assigned to a resource and all dependencies are solved. Let's start -> [ 4.000000] (0:maestro@) Activity 'child' is complete (start time: 3.000000, finish time: 4.000000) +> [ 4.000000] (0:maestro@) Execution 'child' is complete (start time: 3.000000, finish time: 4.000000) > [ 4.000000] (0:maestro@) Simulation time 4 diff --git a/examples/cpp/dag-tuto/s4u-dag-tuto.cpp b/examples/cpp/dag-tuto/s4u-dag-tuto.cpp new file mode 100644 index 0000000000..f90c9f90be --- /dev/null +++ b/examples/cpp/dag-tuto/s4u-dag-tuto.cpp @@ -0,0 +1,57 @@ +/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(dag_tuto, "Messages specific for this s4u tutorial"); + +int main(int argc, char* argv[]) +{ + simgrid::s4u::Engine e(&argc, argv); + e.load_platform(argv[1]); + + simgrid::s4u::Host* tremblay = e.host_by_name("Tremblay"); + simgrid::s4u::Host* jupiter = e.host_by_name("Jupiter"); + + simgrid::s4u::ExecPtr c1 = simgrid::s4u::Exec::init(); + simgrid::s4u::ExecPtr c2 = simgrid::s4u::Exec::init(); + simgrid::s4u::ExecPtr c3 = simgrid::s4u::Exec::init(); + simgrid::s4u::CommPtr t1 = simgrid::s4u::Comm::sendto_init(); + + c1->set_name("c1"); + c2->set_name("c2"); + c3->set_name("c3"); + t1->set_name("t1"); + + c1->set_flops_amount(1e9); + c2->set_flops_amount(5e9); + c3->set_flops_amount(2e9); + t1->set_payload_size(5e8); + + c1->add_successor(t1); + t1->add_successor(c3); + c2->add_successor(c3); + + c1->set_host(tremblay); + c2->set_host(jupiter); + c3->set_host(jupiter); + t1->set_source(tremblay); + t1->set_destination(jupiter); + + c1->start(); + c2->start(); + + simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) { + XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), + exec.get_start_time(), exec.get_finish_time()); + }); + simgrid::s4u::Comm::on_completion_cb([](simgrid::s4u::Comm const& comm) { + XBT_INFO("Comm '%s' is complete (start time: %f, finish time: %f)", comm.get_cname(), + comm.get_start_time(), comm.get_finish_time()); + }); + + e.run(); + return 0; +} diff --git a/examples/cpp/dag-tuto/s4u-dag-tuto.tesh b/examples/cpp/dag-tuto/s4u-dag-tuto.tesh new file mode 100644 index 0000000000..f5b8b156bf --- /dev/null +++ b/examples/cpp/dag-tuto/s4u-dag-tuto.tesh @@ -0,0 +1,7 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-dag-tuto --log=no_loc ${platfdir}/small_platform.xml +> [10.194200] [dag_tuto/INFO] Exec 'c1' is complete (start time: 0.000000, finish time: 10.194200) +> [65.534235] [dag_tuto/INFO] Exec 'c2' is complete (start time: 0.000000, finish time: 65.534235) +> [85.283378] [dag_tuto/INFO] Comm 't1' is complete (start time: 10.194200, finish time: 85.283378) +> [111.497072] [dag_tuto/INFO] Exec 'c3' is complete (start time: 85.283378, finish time: 111.497072) \ No newline at end of file diff --git a/examples/cpp/dht-chord/s4u-dht-chord-node.cpp b/examples/cpp/dht-chord/s4u-dht-chord-node.cpp index 4e412f2981..9dda4d544b 100644 --- a/examples/cpp/dht-chord/s4u-dht-chord-node.cpp +++ b/examples/cpp/dht-chord/s4u-dht-chord-node.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,9 +8,14 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(s4u_chord); namespace sg4 = simgrid::s4u; +void ChordMessage::destroy(void* message) +{ + delete static_cast(message); +} + /* Returns whether an id belongs to the interval [start, end]. * - * The parameters are normalized to make sure they are between 0 and nb_keys - 1). + * The parameters are normalized to make sure they are between 0 and nb_keys_ - 1). * 1 belongs to [62, 3] * 1 does not belong to [3, 62] * 63 belongs to [62, 3] @@ -23,27 +28,29 @@ namespace sg4 = simgrid::s4u; * @param end upper bound * @return true if id in in [start, end] */ -static bool is_in_interval(int id, int start, int end) +bool Node::is_in_interval(int id, int start, int end) { - int i = id % nb_keys; - int s = start % nb_keys; - int e = end % nb_keys; + int i = id % nb_keys_; + int s = start % nb_keys_; + int e = end % nb_keys_; // make sure end >= start and id >= start if (e < s) { - e += nb_keys; + e += nb_keys_; } if (i < s) { - i += nb_keys; + i += nb_keys_; } return i <= e; } -void ChordMessage::destroy(void* message) +void Node::set_parameters(int nb_bits, int nb_keys, int timeout) { - delete static_cast(message); + nb_bits_ = nb_bits; + nb_keys_ = nb_keys; + timeout_ = timeout; } /* Initializes the current node as the first one of the system */ @@ -54,10 +61,10 @@ Node::Node(std::vector args) // initialize my node id_ = std::stoi(args[1]); XBT_DEBUG("Initialize node with id: %d", id_); - random.set_seed(id_); + random_.set_seed(id_); mailbox_ = sg4::Mailbox::by_name(std::to_string(id_)); - next_finger_to_fix = 0; - fingers_.resize(nb_bits, id_); + next_finger_to_fix_ = 0; + fingers_.resize(nb_bits_, id_); if (args.size() == 3) { // first ring deadline_ = std::stod(args[2]); @@ -89,7 +96,7 @@ void Node::join(int known_id) } else { setFinger(0, successor_id); printFingerTable(); - joined = true; + joined_ = true; } } @@ -98,7 +105,7 @@ void Node::leave() { XBT_INFO("Well Guys! I Think it's time for me to leave ;)"); notifyAndQuit(); - joined = false; + joined_ = false; } /* Notifies the successor and the predecessor of the current node before leaving */ @@ -111,7 +118,7 @@ void Node::notifyAndQuit() XBT_DEBUG("Sending a 'PREDECESSOR_LEAVING' to my successor %d", fingers_[0]); try { - sg4::Mailbox::by_name(std::to_string(fingers_[0]))->put(pred_msg, 10, timeout); + sg4::Mailbox::by_name(std::to_string(fingers_[0]))->put(pred_msg, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Timeout expired when sending a 'PREDECESSOR_LEAVING' to my successor %d", fingers_[0]); delete pred_msg; @@ -125,7 +132,7 @@ void Node::notifyAndQuit() XBT_DEBUG("Sending a 'SUCCESSOR_LEAVING' to my predecessor %d", pred_id_); try { - sg4::Mailbox::by_name(std::to_string(pred_id_))->put(succ_msg, 10, timeout); + sg4::Mailbox::by_name(std::to_string(pred_id_))->put(succ_msg, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Timeout expired when sending a 'SUCCESSOR_LEAVING' to my predecessor %d", pred_id_); delete succ_msg; @@ -137,7 +144,7 @@ void Node::notifyAndQuit() void Node::randomLookup() { int res = id_; - int random_index = random.uniform_int(0, nb_bits - 1); + int random_index = random_.uniform_int(0, nb_bits_ - 1); int random_id = fingers_[random_index]; XBT_DEBUG("Making a lookup request for id %d", random_id); if (random_id != id_) @@ -148,7 +155,7 @@ void Node::randomLookup() /* Sets a finger of the current node. * * @param node the current node - * @param finger_index index of the finger to set (0 to nb_bits - 1) + * @param finger_index index of the finger to set (0 to nb_bits_ - 1) * @param id the id to set for this finger */ void Node::setFinger(int finger_index, int id) @@ -174,13 +181,13 @@ void Node::setPredecessor(int predecessor_id) void Node::fixFingers() { XBT_DEBUG("Fixing fingers"); - int id = findSuccessor(id_ + (1U << next_finger_to_fix)); + int id = findSuccessor(id_ + (1U << next_finger_to_fix_)); if (id != -1) { - if (id != fingers_[next_finger_to_fix]) { - setFinger(next_finger_to_fix, id); + if (id != fingers_[next_finger_to_fix_]) { + setFinger(next_finger_to_fix_, id); printFingerTable(); } - next_finger_to_fix = (next_finger_to_fix + 1) % nb_bits; + next_finger_to_fix_ = (next_finger_to_fix_ + 1) % nb_bits_; } } @@ -190,8 +197,8 @@ void Node::printFingerTable() if (XBT_LOG_ISENABLED(s4u_chord, xbt_log_priority_verbose)) { XBT_VERB("My finger table:"); XBT_VERB("Start | Succ"); - for (int i = 0; i < nb_bits; i++) { - XBT_VERB(" %3u | %3d", (id_ + (1U << i)) % nb_keys, fingers_[i]); + for (int i = 0; i < nb_bits_; i++) { + XBT_VERB(" %3u | %3d", (id_ + (1U << i)) % nb_keys_, fingers_[i]); } XBT_VERB("Predecessor: %d", pred_id_); @@ -214,7 +221,7 @@ void Node::checkPredecessor() XBT_DEBUG("Sending a 'Predecessor Alive' request to my predecessor %d", pred_id_); try { - mailbox->put(message, 10, timeout); + mailbox->put(message, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Failed to send the 'Predecessor Alive' request to %d", pred_id_); delete message; @@ -228,7 +235,7 @@ void Node::checkPredecessor() sg4::CommPtr comm = return_mailbox->get_async(&answer); try { - comm->wait_for(timeout); + comm->wait_for(timeout_); XBT_DEBUG("Received the answer to my 'Predecessor Alive': my predecessor %d is alive", pred_id_); delete answer; } catch (const simgrid::TimeoutException&) { @@ -255,7 +262,7 @@ int Node::remoteGetPredecessor(int ask_to) // send a "Get Predecessor" request to ask_to_id XBT_DEBUG("Sending a 'Get Predecessor' request to %d", ask_to); try { - mailbox->put(message, 10, timeout); + mailbox->put(message, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Failed to send the 'Get Predecessor' request to %d", ask_to); delete message; @@ -269,7 +276,7 @@ int Node::remoteGetPredecessor(int ask_to) sg4::CommPtr comm = return_mailbox->get_async(&answer); try { - comm->wait_for(timeout); + comm->wait_for(timeout_); XBT_DEBUG("Received the answer to my 'Get Predecessor' request: the predecessor of node %d is %d", ask_to, answer->answer_id); predecessor_id = answer->answer_id; @@ -289,7 +296,7 @@ int Node::remoteGetPredecessor(int ask_to) */ int Node::closestPrecedingFinger(int id) { - for (int i = nb_bits - 1; i >= 0; i--) { + for (int i = nb_bits_ - 1; i >= 0; i--) { if (is_in_interval(fingers_[i], id_ + 1, id - 1)) { return fingers_[i]; } @@ -326,7 +333,7 @@ int Node::remoteFindSuccessor(int ask_to, int id) // send a "Find Successor" request to ask_to_id XBT_DEBUG("Sending a 'Find Successor' request to %d for id %d", ask_to, id); try { - mailbox->put(message, 10, timeout); + mailbox->put(message, 10, timeout_); } catch (const simgrid::TimeoutException&) { XBT_DEBUG("Failed to send the 'Find Successor' request to %d for id %d", ask_to, id_); delete message; @@ -338,7 +345,7 @@ int Node::remoteFindSuccessor(int ask_to, int id) sg4::CommPtr comm = return_mailbox->get_async(&answer); try { - comm->wait_for(timeout); + comm->wait_for(timeout_); XBT_DEBUG("Received the answer to my 'Find Successor' request for id %d: the successor of key %d is %d", answer->request_id, id_, answer->answer_id); successor = answer->answer_id; @@ -483,12 +490,12 @@ void Node::operator()() if (known_id_ == -1) { setPredecessor(-1); // -1 means that I have no predecessor printFingerTable(); - joined = true; + joined_ = true; } else { join(known_id_); } - if (not joined) + if (not joined_) return; ChordMessage* message = nullptr; double now = sg4::Engine::get_clock(); diff --git a/examples/cpp/dht-chord/s4u-dht-chord.cpp b/examples/cpp/dht-chord/s4u-dht-chord.cpp index 313d93325c..08934aafaf 100644 --- a/examples/cpp/dht-chord/s4u-dht-chord.cpp +++ b/examples/cpp/dht-chord/s4u-dht-chord.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,10 +7,6 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_chord, "Messages specific for this s4u example"); -int nb_bits = 24; -int nb_keys = 0; -int timeout = 50; - int main(int argc, char* argv[]) { simgrid::s4u::Engine e(&argc, argv); @@ -20,6 +16,8 @@ int main(int argc, char* argv[]) argv[0], argv[0]); std::string platform_file(argv[argc - 2]); std::string deployment_file(argv[argc - 1]); + int nb_bits = 24; + int timeout = 50; for (const auto& option : std::vector(argv + 1, argv + argc - 2)) { if (option.rfind("-nb_bits=", 0) == 0) { nb_bits = std::stoi(option.substr(option.find('=') + 1)); @@ -31,12 +29,13 @@ int main(int argc, char* argv[]) xbt_die("Invalid chord option '%s'", option.c_str()); } } + int nb_keys = 1U << nb_bits; + XBT_DEBUG("Sets nb_keys to %d", nb_keys); e.load_platform(platform_file); /* Global initialization of the Chord simulation. */ - nb_keys = 1U << nb_bits; - XBT_DEBUG("Sets nb_keys to %d", nb_keys); + Node::set_parameters(nb_bits, nb_keys, timeout); e.register_actor("node"); e.load_deployment(deployment_file); diff --git a/examples/cpp/dht-chord/s4u-dht-chord.hpp b/examples/cpp/dht-chord/s4u-dht-chord.hpp index 2f8bce5538..ab93cbff06 100644 --- a/examples/cpp/dht-chord/s4u-dht-chord.hpp +++ b/examples/cpp/dht-chord/s4u-dht-chord.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -18,10 +18,6 @@ constexpr double PERIODIC_CHECK_PREDECESSOR_DELAY = 120; constexpr double PERIODIC_LOOKUP_DELAY = 10; constexpr double SLEEP_DELAY = 4.9999; -extern int nb_bits; -extern int nb_keys; -extern int timeout; - /* Types of tasks exchanged between nodes. */ enum class MessageType { FIND_SUCCESSOR, @@ -50,18 +46,26 @@ public: }; class Node { + inline static int nb_bits_; + inline static int nb_keys_; + inline static int timeout_; + int known_id_ = -1; double start_time_ = -1; double deadline_ = -1; - bool joined = false; + bool joined_ = false; int id_; // my id int pred_id_ = -1; // predecessor id - simgrid::xbt::random::XbtRandom random; // random number generator for this node - sg4::Mailbox* mailbox_; // my mailbox + simgrid::xbt::random::XbtRandom random_; // random number generator for this node + sg4::Mailbox* mailbox_; // my mailbox std::vector fingers_; // finger table,(fingers[0] is my successor) - int next_finger_to_fix; // index of the next finger to fix in fix_fingers() + int next_finger_to_fix_; // index of the next finger to fix in fix_fingers() + + static bool is_in_interval(int id, int start, int end); public: + static void set_parameters(int nb_bits, int nb_keys, int timeout); + explicit Node(std::vector args); Node(const Node&) = delete; Node& operator=(const Node&) = delete; diff --git a/examples/cpp/dht-kademlia/answer.cpp b/examples/cpp/dht-kademlia/answer.cpp index 8e98e767ff..f7eabef890 100644 --- a/examples/cpp/dht-kademlia/answer.cpp +++ b/examples/cpp/dht-kademlia/answer.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/dht-kademlia/answer.hpp b/examples/cpp/dht-kademlia/answer.hpp index 91a6828a71..e942b9905a 100644 --- a/examples/cpp/dht-kademlia/answer.hpp +++ b/examples/cpp/dht-kademlia/answer.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/dht-kademlia/generate.py b/examples/cpp/dht-kademlia/generate.py index 9986fb88d4..f7994217ad 100755 --- a/examples/cpp/dht-kademlia/generate.py +++ b/examples/cpp/dht-kademlia/generate.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright (c) 2012-2022. The SimGrid Team. +# Copyright (c) 2012-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/dht-kademlia/message.hpp b/examples/cpp/dht-kademlia/message.hpp index e47c385195..4840f2987e 100644 --- a/examples/cpp/dht-kademlia/message.hpp +++ b/examples/cpp/dht-kademlia/message.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -6,6 +6,7 @@ #ifndef _KADEMLIA_TASK_HPP_ #define _KADEMLIA_TASK_HPP_ +#include "answer.hpp" #include "s4u-dht-kademlia.hpp" #include "simgrid/s4u.hpp" diff --git a/examples/cpp/dht-kademlia/node.cpp b/examples/cpp/dht-kademlia/node.cpp index 4e64641b7d..68d56ebd08 100644 --- a/examples/cpp/dht-kademlia/node.cpp +++ b/examples/cpp/dht-kademlia/node.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/dht-kademlia/node.hpp b/examples/cpp/dht-kademlia/node.hpp index ae99d17324..afe2cc70c7 100644 --- a/examples/cpp/dht-kademlia/node.hpp +++ b/examples/cpp/dht-kademlia/node.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/dht-kademlia/routing_table.cpp b/examples/cpp/dht-kademlia/routing_table.cpp index 11ce04ebd7..338c6f6c6c 100644 --- a/examples/cpp/dht-kademlia/routing_table.cpp +++ b/examples/cpp/dht-kademlia/routing_table.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/dht-kademlia/routing_table.hpp b/examples/cpp/dht-kademlia/routing_table.hpp index 8d6022d865..de213a62c0 100644 --- a/examples/cpp/dht-kademlia/routing_table.hpp +++ b/examples/cpp/dht-kademlia/routing_table.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/dht-kademlia/s4u-dht-kademlia.cpp b/examples/cpp/dht-kademlia/s4u-dht-kademlia.cpp index 58b4eadbc2..c9a9062541 100644 --- a/examples/cpp/dht-kademlia/s4u-dht-kademlia.cpp +++ b/examples/cpp/dht-kademlia/s4u-dht-kademlia.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/dht-kademlia/s4u-dht-kademlia.hpp b/examples/cpp/dht-kademlia/s4u-dht-kademlia.hpp index 4693bf743b..5a67572ec5 100644 --- a/examples/cpp/dht-kademlia/s4u-dht-kademlia.hpp +++ b/examples/cpp/dht-kademlia/s4u-dht-kademlia.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/cpp/energy-boot/s4u-energy-boot.cpp b/examples/cpp/energy-boot/s4u-energy-boot.cpp index 607e3e2848..a791508421 100644 --- a/examples/cpp/energy-boot/s4u-energy-boot.cpp +++ b/examples/cpp/energy-boot/s4u-energy-boot.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/energy-exec-ptask/s4u-energy-exec-ptask.cpp b/examples/cpp/energy-exec-ptask/s4u-energy-exec-ptask.cpp index 39c52d5435..0ef425382d 100644 --- a/examples/cpp/energy-exec-ptask/s4u-energy-exec-ptask.cpp +++ b/examples/cpp/energy-exec-ptask/s4u-energy-exec-ptask.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -141,10 +141,10 @@ static void runner() // ========= A new ptask with computation and a timeout ========= start = sg4::Engine::get_clock(); - std::vector cpu_amounts5{flopAmount, flopAmount}; - std::vector com_amounts5{0, 0, 0, 0}; XBT_INFO("Run a task with computation on two hosts and a timeout of 20s."); try { + std::vector cpu_amounts5{flopAmount, flopAmount}; + std::vector com_amounts5{0, 0, 0, 0}; sg4::this_actor::exec_init(hosts, cpu_amounts5, com_amounts5)->wait_for(20); } catch (const simgrid::TimeoutException &){ XBT_INFO("Finished WITH timeout"); diff --git a/examples/cpp/energy-exec/s4u-energy-exec.cpp b/examples/cpp/energy-exec/s4u-energy-exec.cpp index 1c573c30fd..eda7455fc0 100644 --- a/examples/cpp/energy-exec/s4u-energy-exec.cpp +++ b/examples/cpp/energy-exec/s4u-energy-exec.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/energy-link/s4u-energy-link.cpp b/examples/cpp/energy-link/s4u-energy-link.cpp index 66e849c337..b20ad0ad84 100644 --- a/examples/cpp/energy-link/s4u-energy-link.cpp +++ b/examples/cpp/energy-link/s4u-energy-link.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,7 +22,7 @@ static void sender(std::vector args) long comm_size = std::stol(args.at(1)); XBT_INFO("Send %ld bytes, in %d flows", comm_size, flow_amount); - sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::string("message")); + sg4::Mailbox* mailbox = sg4::Mailbox::by_name("message"); /* Sleep a while before starting the example */ sg4::this_actor::sleep_for(10); @@ -33,10 +33,10 @@ static void sender(std::vector args) mailbox->put(payload, comm_size); } else { // Start all comms in parallel, and wait for all completions in one shot - std::vector comms; + sg4::ActivitySet comms; for (int i = 0; i < flow_amount; i++) - comms.push_back(mailbox->put_async(bprintf("%d", i), comm_size)); - sg4::Comm::wait_all(comms); + comms.push(mailbox->put_async(bprintf("%d", i), comm_size)); + comms.wait_all(); } XBT_INFO("sender done."); } @@ -47,7 +47,7 @@ static void receiver(std::vector args) XBT_INFO("Receiving %d flows ...", flow_amount); - sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::string("message")); + sg4::Mailbox* mailbox = sg4::Mailbox::by_name("message"); if (flow_amount == 1) { char* res = mailbox->get(); @@ -56,11 +56,11 @@ static void receiver(std::vector args) std::vector data(flow_amount); // Start all comms in parallel, and wait for their completion in one shot - std::vector comms; + sg4::ActivitySet comms; for (int i = 0; i < flow_amount; i++) - comms.push_back(mailbox->get_async(&data[i])); + comms.push(mailbox->get_async(&data[i])); - sg4::Comm::wait_all(comms); + comms.wait_all(); for (int i = 0; i < flow_amount; i++) xbt_free(data[i]); } diff --git a/examples/cpp/energy-vm/s4u-energy-vm.cpp b/examples/cpp/energy-vm/s4u-energy-vm.cpp index e81f2e0002..fedc429184 100644 --- a/examples/cpp/energy-vm/s4u-energy-vm.cpp +++ b/examples/cpp/energy-vm/s4u-energy-vm.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/energy-wifi/s4u-energy-wifi.cpp b/examples/cpp/energy-wifi/s4u-energy-wifi.cpp index 84047a6d3c..a9266a30e8 100644 --- a/examples/cpp/energy-wifi/s4u-energy-wifi.cpp +++ b/examples/cpp/energy-wifi/s4u-energy-wifi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2020-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2020-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/engine-filtering/s4u-engine-filtering.cpp b/examples/cpp/engine-filtering/s4u-engine-filtering.cpp index 7136e330c5..0bf14e5b45 100644 --- a/examples/cpp/engine-filtering/s4u-engine-filtering.cpp +++ b/examples/cpp/engine-filtering/s4u-engine-filtering.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/engine-run-partial/s4u-engine-run-partial.cpp b/examples/cpp/engine-run-partial/s4u-engine-run-partial.cpp index 399efa7b38..bf0ada9831 100644 --- a/examples/cpp/engine-run-partial/s4u-engine-run-partial.cpp +++ b/examples/cpp/engine-run-partial/s4u-engine-run-partial.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/exec-async/s4u-exec-async.cpp b/examples/cpp/exec-async/s4u-exec-async.cpp index 6d2dcd972c..d84cc93646 100644 --- a/examples/cpp/exec-async/s4u-exec-async.cpp +++ b/examples/cpp/exec-async/s4u-exec-async.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/exec-basic/s4u-exec-basic.cpp b/examples/cpp/exec-basic/s4u-exec-basic.cpp index c2b33b4d31..837c4b3d34 100644 --- a/examples/cpp/exec-basic/s4u-exec-basic.cpp +++ b/examples/cpp/exec-basic/s4u-exec-basic.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/exec-cpu-factors/s4u-exec-cpu-factors.cpp b/examples/cpp/exec-cpu-factors/s4u-exec-cpu-factors.cpp index 6f6ce5381e..ea80a2231d 100644 --- a/examples/cpp/exec-cpu-factors/s4u-exec-cpu-factors.cpp +++ b/examples/cpp/exec-cpu-factors/s4u-exec-cpu-factors.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/exec-cpu-nonlinear/s4u-exec-cpu-nonlinear.cpp b/examples/cpp/exec-cpu-nonlinear/s4u-exec-cpu-nonlinear.cpp index 56bad89157..8f94ee9d5a 100644 --- a/examples/cpp/exec-cpu-nonlinear/s4u-exec-cpu-nonlinear.cpp +++ b/examples/cpp/exec-cpu-nonlinear/s4u-exec-cpu-nonlinear.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/exec-dependent/s4u-exec-dependent.cpp b/examples/cpp/exec-dependent/s4u-exec-dependent.cpp index 7f37d61d00..08129e44fc 100644 --- a/examples/cpp/exec-dependent/s4u-exec-dependent.cpp +++ b/examples/cpp/exec-dependent/s4u-exec-dependent.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,16 +14,14 @@ static void worker() // Define an amount of work that should take 1 second to execute. double computation_amount = sg4::this_actor::get_host()->get_speed(); - std::vector pending_execs; // Create a small DAG // + Two parents and a child // + First parent ends after 1 second and the Second parent after 2 seconds. sg4::ExecPtr first_parent = sg4::this_actor::exec_init(computation_amount); - pending_execs.push_back(first_parent); sg4::ExecPtr second_parent = sg4::this_actor::exec_init(2 * computation_amount); - pending_execs.push_back(second_parent); sg4::ExecPtr child = sg4::Exec::init()->set_flops_amount(computation_amount); - pending_execs.push_back(child); + + sg4::ActivitySet pending_execs ({first_parent, second_parent, child}); // Name the activities (for logging purposes only) first_parent->set_name("parent 1"); @@ -37,14 +35,13 @@ static void worker() // Start the activities. first_parent->start(); second_parent->start(); - // child uses a vetoable start to force it to wait for the completion of its predecessors - child->vetoable_start(); + child->start(); // wait for the completion of all activities while (not pending_execs.empty()) { - ssize_t changed_pos = sg4::Exec::wait_any_for(pending_execs, -1); - XBT_INFO("Exec '%s' is complete", pending_execs[changed_pos]->get_cname()); - pending_execs.erase(pending_execs.begin() + changed_pos); + auto completed_one = pending_execs.wait_any(); + if (completed_one != nullptr) + XBT_INFO("Exec '%s' is complete", completed_one->get_cname()); } } @@ -55,9 +52,7 @@ int main(int argc, char* argv[]) sg4::Actor::create("worker", e.host_by_name("Fafard"), worker); - sg4::Activity::on_veto_cb([&e](sg4::Activity& a) { - auto& exec = static_cast(a); - + sg4::Exec::on_veto_cb([&e](sg4::Exec& exec) { // First display the situation XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(), (exec.dependencies_solved() ? "solved" : "NOT solved"), diff --git a/examples/cpp/exec-dependent/s4u-exec-dependent.tesh b/examples/cpp/exec-dependent/s4u-exec-dependent.tesh index a376e10d03..5c504006d2 100644 --- a/examples/cpp/exec-dependent/s4u-exec-dependent.tesh +++ b/examples/cpp/exec-dependent/s4u-exec-dependent.tesh @@ -1,6 +1,8 @@ #!/usr/bin/env tesh $ ${bindir:=.}/s4u-exec-dependent ${platfdir}/small_platform.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" +> [ 0.000000] (1:worker@Fafard) 'parent 1' is assigned to a resource and all dependencies are solved. Let's start +> [ 0.000000] (1:worker@Fafard) 'parent 2' is assigned to a resource and all dependencies are solved. Let's start > [ 0.000000] (1:worker@Fafard) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned > [ 2.000000] (1:worker@Fafard) Remove a dependency from 'parent 1' on 'child' > [ 2.000000] (1:worker@Fafard) Exec 'parent 1' is complete diff --git a/examples/cpp/exec-dvfs/s4u-exec-dvfs.cpp b/examples/cpp/exec-dvfs/s4u-exec-dvfs.cpp index dfcca1d2f5..d85e06bdd6 100644 --- a/examples/cpp/exec-dvfs/s4u-exec-dvfs.cpp +++ b/examples/cpp/exec-dvfs/s4u-exec-dvfs.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/exec-dvfs/s4u-exec-dvfs.tesh b/examples/cpp/exec-dvfs/s4u-exec-dvfs.tesh index 8ad80a9493..f0febb1893 100644 --- a/examples/cpp/exec-dvfs/s4u-exec-dvfs.tesh +++ b/examples/cpp/exec-dvfs/s4u-exec-dvfs.tesh @@ -9,9 +9,9 @@ $ ${bindir:=.}/s4u-exec-dvfs ${platfdir}/energy_platform.xml "--log=root.fmt:[%1 > [ 0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000 > [ 1.000000] (1:dvfs_test@MyHost1) Computation1 duration: 1.00 > [ 1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2) +> [ 1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Computation1 duration: 1.00 > [ 1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2) -> [ 1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000 > [ 6.000000] (1:dvfs_test@MyHost1) Computation2 duration: 5.00 > [ 6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3 @@ -28,9 +28,9 @@ $ ${bindir:=.}/s4u-exec-dvfs ${platfdir}/energy_cluster.xml "--log=root.fmt:[%10 > [ 0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000 > [ 1.000000] (1:dvfs_test@MyHost1) Computation1 duration: 1.00 > [ 1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2) +> [ 1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Computation1 duration: 1.00 > [ 1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2) -> [ 1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000 > [ 6.000000] (1:dvfs_test@MyHost1) Computation2 duration: 5.00 > [ 6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3 diff --git a/examples/cpp/exec-failure/s4u-exec-failure.cpp b/examples/cpp/exec-failure/s4u-exec-failure.cpp index 9ad7b479de..4a4063bda6 100644 --- a/examples/cpp/exec-failure/s4u-exec-failure.cpp +++ b/examples/cpp/exec-failure/s4u-exec-failure.cpp @@ -1,80 +1,105 @@ -/* Copyright (c) 2021-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2021-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -/* This example shows how to serialize a set of communications going through a link +/* This examples shows how to survive to host failure exceptions that occur when an host is turned off. * - * As for the other asynchronous examples, the sender initiates all the messages it wants to send and - * pack the resulting simgrid::s4u::CommPtr objects in a vector. - * At the same time, the receiver starts receiving all messages asynchronously. Without serialization, - * all messages would be received at the same timestamp in the receiver. + * The actors do not get notified when the host on which they run is turned off: they are just terminated + * in this case, and their ``on_exit()`` callback gets executed. * - * However, as they will be serialized in a link of the platform, the messages arrive 2 by 2. - * - * The sender then blocks until all ongoing communication terminate, using simgrid::s4u::Comm::wait_all() + * For remote executions on failing hosts however, any blocking operation such as ``exec`` or ``wait`` will + * raise an exception that you can catch and react to, as illustrated in this example. */ #include +#include "simgrid/kernel/ProfileBuilder.hpp" XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_exec_failure, "Messages specific for this s4u example"); namespace sg4 = simgrid::s4u; -static void dispatcher(sg4::Host* host1, sg4::Host* host2) +static void dispatcher(std::vector const& hosts) { std::vector pending_execs; - XBT_INFO("Initiating asynchronous exec on %s", host1->get_cname()); - auto exec1 = sg4::this_actor::exec_init(20)->set_host(host1); - pending_execs.push_back(exec1); - exec1->start(); - XBT_INFO("Initiating asynchronous exec on %s", host2->get_cname()); - auto exec2 = sg4::this_actor::exec_init(20)->set_host(host2); - pending_execs.push_back(exec2); - exec2->start(); - - XBT_INFO("Calling wait_any.."); + for (auto* host: hosts) { + XBT_INFO("Initiating asynchronous exec on %s", host->get_cname()); + // Computing 20 flops on an host which speed is 1f takes 20 seconds (when it does not fail) + auto exec = sg4::this_actor::exec_init(20)->set_host(host); + pending_execs.push_back(exec); + exec->start(); + } + + XBT_INFO("---------------------------------"); + XBT_INFO("Wait on the first exec, which host is turned off at t=10 by the another actor."); try { - long index = sg4::Exec::wait_any(pending_execs); - XBT_INFO("Wait any returned index %ld (exec on %s)", index, pending_execs.at(index)->get_host()->get_cname()); + pending_execs[0]->wait(); + xbt_assert("This wait was not supposed to succeed."); } catch (const simgrid::HostFailureException&) { - XBT_INFO("Dispatcher has experienced a host failure exception, so it knows that something went wrong"); - XBT_INFO("Now it needs to figure out which of the two execs failed by looking at their state"); + XBT_INFO("Dispatcher has experienced a host failure exception, so it knows that something went wrong."); } - XBT_INFO("Exec on %s has state: %s", pending_execs[0]->get_host()->get_cname(), pending_execs[0]->get_state_str()); - XBT_INFO("Exec on %s has state: %s", pending_execs[1]->get_host()->get_cname(), pending_execs[1]->get_state_str()); + XBT_INFO("State of each exec:"); + for (auto const& exec : pending_execs) + XBT_INFO(" Exec on %s has state: %s", exec->get_host()->get_cname(), exec->get_state_str()); + XBT_INFO("---------------------------------"); + XBT_INFO("Wait on the second exec, which host is turned off at t=12 by the state profile."); try { pending_execs[1]->wait(); - } catch (const simgrid::HostFailureException& e) { - XBT_INFO("Waiting on a FAILED exec raises an exception: '%s'", e.what()); + xbt_assert("This wait was not supposed to succeed."); + } catch (const simgrid::HostFailureException&) { + XBT_INFO("Dispatcher has experienced a host failure exception, so it knows that something went wrong."); + } + XBT_INFO("State of each exec:"); + for (auto const& exec : pending_execs) + XBT_INFO(" Exec on %s has state: %s", exec->get_host()->get_cname(), exec->get_state_str()); + + XBT_INFO("---------------------------------"); + XBT_INFO("Wait on the third exec, which should succeed."); + try { + pending_execs[2]->wait(); + XBT_INFO("No exception occured."); + } catch (const simgrid::HostFailureException&) { + xbt_assert("This wait was not supposed to fail."); } - pending_execs.pop_back(); - XBT_INFO("Wait for remaining exec, just to be nice"); - sg4::Exec::wait_any(pending_execs); - XBT_INFO("Dispatcher ends"); + XBT_INFO("State of each exec:"); + for (auto const& exec : pending_execs) + XBT_INFO(" Exec on %s has state: %s", exec->get_host()->get_cname(), exec->get_state_str()); } static void host_killer(sg4::Host* to_kill) { - XBT_INFO("HostKiller sleeping 10 seconds..."); sg4::this_actor::sleep_for(10.0); - XBT_INFO("HostKiller turning off host %s", to_kill->get_cname()); + XBT_INFO("HostKiller turns off the host '%s'.", to_kill->get_cname()); to_kill->turn_off(); - XBT_INFO("HostKiller ends"); } int main(int argc, char** argv) { sg4::Engine engine(&argc, argv); - auto* zone = sg4::create_full_zone("AS0"); - auto* host1 = zone->create_host("Host1", "1f"); - auto* host2 = zone->create_host("Host2", "1f"); + auto* zone = sg4::create_full_zone("world"); + std::vector hosts; + for (const auto* name : {"Host1", "Host2", "Host3"}) { + auto* host = zone->create_host(name, "1f"); + hosts.push_back(host); + } + /* Attaching a state profile (ie a list of events changing the on/off state of the resource) to host3. + * The syntax of the profile (second parameter) is a list of: "date state\n" + * The R"( )" thing is the C++ way of writing multiline strings, including literals \n. + * You'd have the same behavior by using "12 0\n20 1\n" instead. + * So here, the link is turned off at t=12 and back on at t=20. + * The last parameter is the period of that profile, meaning that it loops after 30 seconds. + */ + hosts[1]->set_state_profile(simgrid::kernel::profile::ProfileBuilder::from_string("profile name", R"( +12 0 +20 1 +)", 30)); + zone->seal(); - sg4::Actor::create("Dispatcher", host1, dispatcher, host1, host2); - sg4::Actor::create("HostKiller", host1, host_killer, host2)->daemonize(); + sg4::Actor::create("Dispatcher", hosts[2], dispatcher, hosts); + sg4::Actor::create("HostKiller", hosts[2], host_killer, hosts[0]); engine.run(); diff --git a/examples/cpp/exec-failure/s4u-exec-failure.tesh b/examples/cpp/exec-failure/s4u-exec-failure.tesh index 8c37127462..b06bff287f 100644 --- a/examples/cpp/exec-failure/s4u-exec-failure.tesh +++ b/examples/cpp/exec-failure/s4u-exec-failure.tesh @@ -1,16 +1,28 @@ #!/usr/bin/env tesh $ ${bindir:=.}/s4u-exec-failure "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (1:Dispatcher@Host1) Initiating asynchronous exec on Host1 -> [ 0.000000] (2:HostKiller@Host1) HostKiller sleeping 10 seconds... -> [ 0.000000] (1:Dispatcher@Host1) Initiating asynchronous exec on Host2 -> [ 0.000000] (1:Dispatcher@Host1) Calling wait_any.. -> [ 10.000000] (2:HostKiller@Host1) HostKiller turning off host Host2 -> [ 10.000000] (1:Dispatcher@Host1) Dispatcher has experienced a host failure exception, so it knows that something went wrong -> [ 10.000000] (1:Dispatcher@Host1) Now it needs to figure out which of the two execs failed by looking at their state -> [ 10.000000] (1:Dispatcher@Host1) Exec on Host1 has state: STARTED -> [ 10.000000] (1:Dispatcher@Host1) Exec on Host2 has state: FAILED -> [ 10.000000] (1:Dispatcher@Host1) Waiting on a FAILED exec raises an exception: 'Cannot wait for a failed exec' -> [ 10.000000] (1:Dispatcher@Host1) Wait for remaining exec, just to be nice -> [ 10.000000] (2:HostKiller@Host1) HostKiller ends -> [ 20.000000] (1:Dispatcher@Host1) Dispatcher ends +> [ 0.000000] (1:Dispatcher@Host3) Initiating asynchronous exec on Host1 +> [ 0.000000] (1:Dispatcher@Host3) Initiating asynchronous exec on Host2 +> [ 0.000000] (1:Dispatcher@Host3) Initiating asynchronous exec on Host3 +> [ 0.000000] (1:Dispatcher@Host3) --------------------------------- +> [ 0.000000] (1:Dispatcher@Host3) Wait on the first exec, which host is turned off at t=10 by the another actor. +> [ 10.000000] (2:HostKiller@Host3) HostKiller turns off the host 'Host1'. +> [ 10.000000] (1:Dispatcher@Host3) Dispatcher has experienced a host failure exception, so it knows that something went wrong. +> [ 10.000000] (1:Dispatcher@Host3) State of each exec: +> [ 10.000000] (1:Dispatcher@Host3) Exec on Host1 has state: FAILED +> [ 10.000000] (1:Dispatcher@Host3) Exec on Host2 has state: STARTED +> [ 10.000000] (1:Dispatcher@Host3) Exec on Host3 has state: STARTED +> [ 10.000000] (1:Dispatcher@Host3) --------------------------------- +> [ 10.000000] (1:Dispatcher@Host3) Wait on the second exec, which host is turned off at t=12 by the state profile. +> [ 12.000000] (1:Dispatcher@Host3) Dispatcher has experienced a host failure exception, so it knows that something went wrong. +> [ 12.000000] (1:Dispatcher@Host3) State of each exec: +> [ 12.000000] (1:Dispatcher@Host3) Exec on Host1 has state: FAILED +> [ 12.000000] (1:Dispatcher@Host3) Exec on Host2 has state: FAILED +> [ 12.000000] (1:Dispatcher@Host3) Exec on Host3 has state: STARTED +> [ 12.000000] (1:Dispatcher@Host3) --------------------------------- +> [ 12.000000] (1:Dispatcher@Host3) Wait on the third exec, which should succeed. +> [ 20.000000] (1:Dispatcher@Host3) No exception occured. +> [ 20.000000] (1:Dispatcher@Host3) State of each exec: +> [ 20.000000] (1:Dispatcher@Host3) Exec on Host1 has state: FAILED +> [ 20.000000] (1:Dispatcher@Host3) Exec on Host2 has state: FAILED +> [ 20.000000] (1:Dispatcher@Host3) Exec on Host3 has state: FINISHED \ No newline at end of file diff --git a/examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.cpp b/examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.cpp index c896313fc2..e4ec699997 100644 --- a/examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.cpp +++ b/examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,7 +11,7 @@ namespace sg4 = simgrid::s4u; static void runner() { - auto e = sg4::Engine::get_instance(); + const auto* e = sg4::Engine::get_instance(); std::vector comp(2, 1e9); std::vector comm(4, 0.0); // Different hosts. diff --git a/examples/cpp/exec-ptask-multicore/s4u-exec-ptask-multicore.cpp b/examples/cpp/exec-ptask-multicore/s4u-exec-ptask-multicore.cpp index ffc11d06ff..e7a17cb90f 100644 --- a/examples/cpp/exec-ptask-multicore/s4u-exec-ptask-multicore.cpp +++ b/examples/cpp/exec-ptask-multicore/s4u-exec-ptask-multicore.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,7 +10,7 @@ namespace sg4 = simgrid::s4u; static void runner() { - auto e = sg4::Engine::get_instance(); + const auto* e = sg4::Engine::get_instance(); std::vector comp(2, 1e9); std::vector comm(4, 0.0); // Different hosts. @@ -60,7 +60,7 @@ static void runner() XBT_INFO("Computed 2-core activity on two different hosts. Took %g s", e->get_clock() - start_time); // Add a background task and change ptask on the fly - auto MyHost1 = e->host_by_name("MyHost1"); + auto* MyHost1 = e->host_by_name("MyHost1"); sg4::ExecPtr background_task = MyHost1->exec_async(5e9); XBT_INFO("Start a 1-core background task on the 4-core host."); diff --git a/examples/cpp/exec-ptask/s4u-exec-ptask.cpp b/examples/cpp/exec-ptask/s4u-exec-ptask.cpp index 67f2f194a0..dbec2a9cff 100644 --- a/examples/cpp/exec-ptask/s4u-exec-ptask.cpp +++ b/examples/cpp/exec-ptask/s4u-exec-ptask.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/exec-remote/s4u-exec-remote.cpp b/examples/cpp/exec-remote/s4u-exec-remote.cpp index 54ee50badf..9990d2f44a 100644 --- a/examples/cpp/exec-remote/s4u-exec-remote.cpp +++ b/examples/cpp/exec-remote/s4u-exec-remote.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/exec-threads/s4u-exec-threads.cpp b/examples/cpp/exec-threads/s4u-exec-threads.cpp index cbc8b59524..1de40a201b 100644 --- a/examples/cpp/exec-threads/s4u-exec-threads.cpp +++ b/examples/cpp/exec-threads/s4u-exec-threads.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,7 +11,7 @@ namespace sg4 = simgrid::s4u; static void runner() { - auto e = sg4::Engine::get_instance(); + const auto* e = sg4::Engine::get_instance(); sg4::Host* multicore_host = e->host_by_name("MyHost1"); // First test with less than, same number as, and more threads than cores double start_time = sg4::Engine::get_clock(); diff --git a/examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp b/examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp index be32587835..054f81da8f 100644 --- a/examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp +++ b/examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,8 +14,8 @@ static void worker() // Define an amount of work that should take 1 second to execute. double computation_amount = sg4::this_actor::get_host()->get_speed(); - // Create an unassigned activity and start it - sg4::ExecPtr exec = sg4::Exec::init()->set_flops_amount(computation_amount)->set_name("exec")->vetoable_start(); + // Create an unassigned activity and start it. It will not actually start, because it's not assigned to any host yet + sg4::ExecPtr exec = sg4::Exec::init()->set_flops_amount(computation_amount)->set_name("exec")->start(); // Wait for a while sg4::this_actor::sleep_for(10); diff --git a/examples/cpp/exec-waitany/s4u-exec-waitany.cpp b/examples/cpp/exec-waitany/s4u-exec-waitany.cpp deleted file mode 100644 index 1a2b87d53b..0000000000 --- a/examples/cpp/exec-waitany/s4u-exec-waitany.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/s4u.hpp" -#include -#include -#include - -XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_exec_waitany, "Messages specific for this s4u example"); -namespace sg4 = simgrid::s4u; - -static void worker(bool with_timeout) -{ - /* Vector in which we store all pending executions*/ - std::vector pending_executions; - - for (int i = 0; i < 3; i++) { - std::string name = std::string("Exec-") + std::to_string(i); - double amount = (6 * (i % 2) + i + 1) * sg4::this_actor::get_host()->get_speed(); - - sg4::ExecPtr exec = sg4::this_actor::exec_init(amount)->set_name(name); - pending_executions.push_back(exec); - exec->start(); - - XBT_INFO("Activity %s has started for %.0f seconds", name.c_str(), - amount / sg4::this_actor::get_host()->get_speed()); - } - - /* Now that executions were initiated, wait for their completion, in order of termination. - * - * This loop waits for first terminating execution with wait_any() and remove it with erase(), until all execs are - * terminated. - */ - while (not pending_executions.empty()) { - ssize_t pos; - if (with_timeout) - pos = sg4::Exec::wait_any_for(pending_executions, 4); - else - pos = sg4::Exec::wait_any(pending_executions); - - if (pos < 0) { - XBT_INFO("Do not wait any longer for an activity"); - pending_executions.clear(); - } else { - XBT_INFO("Activity '%s' (at position %zd) is complete", pending_executions[pos]->get_cname(), pos); - pending_executions.erase(pending_executions.begin() + pos); - } - XBT_INFO("%zu activities remain pending", pending_executions.size()); - } -} - -int main(int argc, char* argv[]) -{ - sg4::Engine e(&argc, argv); - e.load_platform(argv[1]); - sg4::Actor::create("worker", e.host_by_name("Tremblay"), worker, false); - sg4::Actor::create("worker_timeout", e.host_by_name("Tremblay"), worker, true); - e.run(); - - return 0; -} diff --git a/examples/cpp/exec-waitany/s4u-exec-waitany.tesh b/examples/cpp/exec-waitany/s4u-exec-waitany.tesh deleted file mode 100644 index 072cab5269..0000000000 --- a/examples/cpp/exec-waitany/s4u-exec-waitany.tesh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 -$ ${bindir:=.}/s4u-exec-waitany ${platfdir}/multicore_machine.xml "--log=root.fmt:[%10.6r]%e[%14P]%e%m%n" -> [ 0.000000] [ worker] Activity Exec-0 has started for 1 seconds -> [ 0.000000] [worker_timeout] Activity Exec-0 has started for 1 seconds -> [ 0.000000] [ worker] Activity Exec-1 has started for 8 seconds -> [ 0.000000] [worker_timeout] Activity Exec-1 has started for 8 seconds -> [ 0.000000] [ worker] Activity Exec-2 has started for 3 seconds -> [ 0.000000] [worker_timeout] Activity Exec-2 has started for 3 seconds -> [ 1.000000] [worker_timeout] Activity 'Exec-0' (at position 0) is complete -> [ 1.000000] [worker_timeout] 2 activities remain pending -> [ 1.000000] [ worker] Activity 'Exec-0' (at position 0) is complete -> [ 1.000000] [ worker] 2 activities remain pending -> [ 3.000000] [worker_timeout] Activity 'Exec-2' (at position 1) is complete -> [ 3.000000] [worker_timeout] 1 activities remain pending -> [ 3.000000] [ worker] Activity 'Exec-2' (at position 1) is complete -> [ 3.000000] [ worker] 1 activities remain pending -> [ 7.000000] [worker_timeout] Do not wait any longer for an activity -> [ 7.000000] [worker_timeout] 0 activities remain pending -> [ 8.000000] [ worker] Activity 'Exec-1' (at position 0) is complete -> [ 8.000000] [ worker] 0 activities remain pending diff --git a/examples/cpp/exec-waitfor/s4u-exec-waitfor.cpp b/examples/cpp/exec-waitfor/s4u-exec-waitfor.cpp index f5baa0c8c1..7495c16975 100644 --- a/examples/cpp/exec-waitfor/s4u-exec-waitfor.cpp +++ b/examples/cpp/exec-waitfor/s4u-exec-waitfor.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/io-async/s4u-io-async.cpp b/examples/cpp/io-async/s4u-io-async.cpp index 3c828ff7e6..9d96fe32ed 100644 --- a/examples/cpp/io-async/s4u-io-async.cpp +++ b/examples/cpp/io-async/s4u-io-async.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/io-degradation/s4u-io-degradation.cpp b/examples/cpp/io-degradation/s4u-io-degradation.cpp index 41a5ed34aa..9ab897a285 100644 --- a/examples/cpp/io-degradation/s4u-io-degradation.cpp +++ b/examples/cpp/io-degradation/s4u-io-degradation.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/io-dependent/s4u-io-dependent.cpp b/examples/cpp/io-dependent/s4u-io-dependent.cpp index 11785ff832..f64c4c2e46 100644 --- a/examples/cpp/io-dependent/s4u-io-dependent.cpp +++ b/examples/cpp/io-dependent/s4u-io-dependent.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,16 +12,12 @@ namespace sg4 = simgrid::s4u; static void test() { - std::vector pending_activities; - sg4::ExecPtr bob_compute = sg4::this_actor::exec_init(1e9); - pending_activities.push_back(boost::dynamic_pointer_cast(bob_compute)); sg4::IoPtr bob_write = sg4::Host::current()->get_disks().front()->io_init(4000000, sg4::Io::OpType::WRITE); - pending_activities.push_back(boost::dynamic_pointer_cast(bob_write)); sg4::IoPtr carl_read = sg4::Host::by_name("carl")->get_disks().front()->io_init(4000000, sg4::Io::OpType::READ); - pending_activities.push_back(boost::dynamic_pointer_cast(carl_read)); sg4::ExecPtr carl_compute = sg4::Host::by_name("carl")->exec_init(1e9); - pending_activities.push_back(boost::dynamic_pointer_cast(carl_compute)); + + sg4::ActivitySet pending_activities ({bob_compute, bob_write, carl_read, carl_compute}); // Name the activities (for logging purposes only) bob_compute->set_name("bob compute"); @@ -39,22 +35,21 @@ static void test() // Start the activities. bob_compute->start(); - bob_write->vetoable_start(); - carl_read->vetoable_start(); - carl_compute->vetoable_start(); + bob_write->start(); + carl_read->start(); + carl_compute->start(); // wait for the completion of all activities while (not pending_activities.empty()) { - ssize_t changed_pos = sg4::Activity::wait_any(pending_activities); - XBT_INFO("Activity '%s' is complete", pending_activities[changed_pos]->get_cname()); - pending_activities.erase(pending_activities.begin() + changed_pos); + auto completed_one = pending_activities.wait_any(); + if (completed_one != nullptr) + XBT_INFO("Activity '%s' is complete", completed_one->get_cname()); } } int main(int argc, char* argv[]) { sg4::Engine e(&argc, argv); - sg_storage_file_system_init(); e.load_platform(argv[1]); sg4::Actor::create("bob", e.host_by_name("bob"), test); diff --git a/examples/cpp/io-dependent/s4u-io-dependent.tesh b/examples/cpp/io-dependent/s4u-io-dependent.tesh index b44775f299..8feb8524d2 100644 --- a/examples/cpp/io-dependent/s4u-io-dependent.tesh +++ b/examples/cpp/io-dependent/s4u-io-dependent.tesh @@ -2,6 +2,7 @@ ! output sort $ ${bindir:=.}/s4u-io-dependent ${platfdir}/hosts_with_disks.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" +> [ 0.000000] (1:bob@bob) 'bob compute' is assigned to a resource and all dependencies are solved. Let's start > [ 1.000000] (1:bob@bob) 'bob write' is assigned to a resource and all dependencies are solved. Let's start > [ 1.000000] (1:bob@bob) Remove a dependency from 'bob compute' on 'bob write' > [ 1.000000] (1:bob@bob) Activity 'bob compute' is complete diff --git a/examples/cpp/io-disk-raw/s4u-io-disk-raw.cpp b/examples/cpp/io-disk-raw/s4u-io-disk-raw.cpp index 92958f884b..3c50a7bc79 100644 --- a/examples/cpp/io-disk-raw/s4u-io-disk-raw.cpp +++ b/examples/cpp/io-disk-raw/s4u-io-disk-raw.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -43,14 +43,13 @@ static void host() /* - Attach some user data to disk1 */ XBT_INFO("*** Get/set data for storage element: Disk1 ***"); - const auto* data = disk->get_data(); + auto data = disk->get_unique_data(); XBT_INFO("Get storage data: '%s'", data ? data->c_str() : "No user data"); disk->set_data(new std::string("Some user data")); - data = disk->get_data(); + data = disk->get_unique_data(); XBT_INFO("Set and get data: '%s'", data->c_str()); - delete data; } int main(int argc, char** argv) diff --git a/examples/cpp/io-file-remote/s4u-io-file-remote.cpp b/examples/cpp/io-file-remote/s4u-io-file-remote.cpp index 251f0c0d2c..72743be8f6 100644 --- a/examples/cpp/io-file-remote/s4u-io-file-remote.cpp +++ b/examples/cpp/io-file-remote/s4u-io-file-remote.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/io-file-remote/s4u-io-file-remote.tesh b/examples/cpp/io-file-remote/s4u-io-file-remote.tesh index 180ba09971..2660d763f4 100644 --- a/examples/cpp/io-file-remote/s4u-io-file-remote.tesh +++ b/examples/cpp/io-file-remote/s4u-io-file-remote.tesh @@ -5,15 +5,15 @@ $ ${bindir:=.}/s4u-io-file-remote ${platfdir}/hosts_with_disks.xml s4u-io-file-r > [ 0.000000] (0@ ) Init: bob: 35/511964 MiB used/free on 'Disk1@bob' > [ 0.000000] (0@ ) Init: bob: 0/512000 MiB used/free on 'Disk2@bob' > [ 0.000000] (0@ ) Init: carl: 35/511964 MiB used/free on 'Disk1@bob' -> [ 0.000000] (1@alice) Opened file '/include/surf/simgrid_dtd.h' +> [ 0.000000] (1@alice) Opened file '/include/simgrid_dtd.h' > [ 0.000000] (1@alice) File Descriptor information: -> Full path: '/include/surf/simgrid_dtd.h' +> Full path: '/include/simgrid_dtd.h' > Size: 23583 > Mount point: '/' > Disk Id: 'Disk1' > Host Id: 'alice' > File Descriptor Id: 0 -> [ 0.000000] (1@alice) Try to write 23 MiB to '/include/surf/simgrid_dtd.h' +> [ 0.000000] (1@alice) Try to write 23 MiB to '/include/simgrid_dtd.h' > [ 0.000000] (2@ bob) Opened file '/scratch/doc/simgrid/examples/platforms/g5k.xml' > [ 0.000000] (2@ bob) File Descriptor information: > Full path: '/scratch/doc/simgrid/examples/platforms/g5k.xml' @@ -23,20 +23,20 @@ $ ${bindir:=.}/s4u-io-file-remote ${platfdir}/hosts_with_disks.xml s4u-io-file-r > Host Id: 'bob' > File Descriptor Id: 0 > [ 0.000000] (2@ bob) Try to write 16 MiB to '/scratch/doc/simgrid/examples/platforms/g5k.xml' -> [ 0.000000] (3@ carl) Opened file '/scratch/include/surf/simgrid_dtd.h' +> [ 0.000000] (3@ carl) Opened file '/scratch/include/simgrid_dtd.h' > [ 0.000000] (3@ carl) File Descriptor information: -> Full path: '/scratch/include/surf/simgrid_dtd.h' +> Full path: '/scratch/include/simgrid_dtd.h' > Size: 23583 > Mount point: '/scratch' > Disk Id: 'Disk1' > Host Id: 'bob' > File Descriptor Id: 0 -> [ 0.000000] (3@ carl) Try to write 23 MiB to '/scratch/include/surf/simgrid_dtd.h' -> [ 0.301862] (1@alice) Have written 23 MiB to '/include/surf/simgrid_dtd.h'. -> [ 0.301862] (1@alice) Move '/include/surf/simgrid_dtd.h' (of size 24148992) from 'alice' to 'bob' +> [ 0.000000] (3@ carl) Try to write 23 MiB to '/scratch/include/simgrid_dtd.h' +> [ 0.301862] (1@alice) Have written 23 MiB to '/include/simgrid_dtd.h'. +> [ 0.301862] (1@alice) Move '/include/simgrid_dtd.h' (of size 24148992) from 'alice' to 'bob' > [ 0.660757] (2@ bob) Have written 16 MiB to '/scratch/doc/simgrid/examples/platforms/g5k.xml'. > [ 0.660757] (2@ bob) Copy '/scratch/doc/simgrid/examples/platforms/g5k.xml' (of size 17436672) from 'bob' to 'alice' -> [ 1.234522] (3@ carl) Have written 23 MiB to '/scratch/include/surf/simgrid_dtd.h'. +> [ 1.234522] (3@ carl) Have written 23 MiB to '/scratch/include/simgrid_dtd.h'. > [ 1.643366] (0@ ) End: 29/511970 MiB used/free on 'Disk1@alice' > [ 1.643366] (0@ ) End: 97/511902 MiB used/free on 'Disk1@bob' > [ 1.643366] (0@ ) End: 0/512000 MiB used/free on 'Disk2@bob' diff --git a/examples/cpp/io-file-remote/s4u-io-file-remote_d.xml b/examples/cpp/io-file-remote/s4u-io-file-remote_d.xml index d14901b8fb..205ca815b2 100644 --- a/examples/cpp/io-file-remote/s4u-io-file-remote_d.xml +++ b/examples/cpp/io-file-remote/s4u-io-file-remote_d.xml @@ -2,9 +2,9 @@ - + - + @@ -14,6 +14,6 @@ - + diff --git a/examples/cpp/io-file-system/s4u-io-file-system.cpp b/examples/cpp/io-file-system/s4u-io-file-system.cpp index 24ba9bdff8..40e0048e09 100644 --- a/examples/cpp/io-file-system/s4u-io-file-system.cpp +++ b/examples/cpp/io-file-system/s4u-io-file-system.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -58,9 +58,8 @@ public: // Test attaching some user data to the file file->set_data(new std::string("777")); - const auto* file_data = file->get_data(); + auto file_data = file->get_unique_data(); XBT_INFO("User data attached to the file: %s", file_data->c_str()); - delete file_data; // Close the file file->close(); diff --git a/examples/cpp/io-file-system/s4u-io-file-system.tesh b/examples/cpp/io-file-system/s4u-io-file-system.tesh index b2ad152bd1..226c5c6242 100644 --- a/examples/cpp/io-file-system/s4u-io-file-system.tesh +++ b/examples/cpp/io-file-system/s4u-io-file-system.tesh @@ -2,20 +2,20 @@ $ ${bindir:=.}/s4u-io-file-system ${platfdir}/hosts_with_disks.xml > [bob:host:(1) 0.000000] [s4u_test/INFO] Storage info on bob: -> [bob:host:(1) 0.000000] [s4u_test/INFO] Disk1 (/scratch) Used: 36933331; Free: 536833978669; Total: 536870912000. +> [bob:host:(1) 0.000000] [s4u_test/INFO] Disk1 (/scratch) Used: 36924298; Free: 536833987702; Total: 536870912000. > [bob:host:(1) 0.000000] [s4u_test/INFO] Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000. > [bob:host:(1) 0.005000] [s4u_test/INFO] Create a 200000 bytes file named '/scratch/tmp/data.txt' on /scratch > [bob:host:(1) 0.005000] [s4u_test/INFO] Storage info on bob: -> [bob:host:(1) 0.005000] [s4u_test/INFO] Disk1 (/scratch) Used: 37133331; Free: 536833778669; Total: 536870912000. +> [bob:host:(1) 0.005000] [s4u_test/INFO] Disk1 (/scratch) Used: 37124298; Free: 536833787702; Total: 536870912000. > [bob:host:(1) 0.005000] [s4u_test/INFO] Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000. > [bob:host:(1) 0.007000] [s4u_test/INFO] Read 200000 bytes on /scratch/tmp/data.txt > [bob:host:(1) 0.009500] [s4u_test/INFO] Write 100000 bytes on /scratch/tmp/data.txt > [bob:host:(1) 0.009500] [s4u_test/INFO] Move '/scratch/tmp/data.txt' to '/scratch/tmp/simgrid.readme' > [bob:host:(1) 0.009500] [s4u_test/INFO] User data attached to the file: 777 > [bob:host:(1) 0.009500] [s4u_test/INFO] Storage info on bob: -> [bob:host:(1) 0.009500] [s4u_test/INFO] Disk1 (/scratch) Used: 37233331; Free: 536833678669; Total: 536870912000. +> [bob:host:(1) 0.009500] [s4u_test/INFO] Disk1 (/scratch) Used: 37224298; Free: 536833687702; Total: 536870912000. > [bob:host:(1) 0.009500] [s4u_test/INFO] Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000. > [bob:host:(1) 0.009500] [s4u_test/INFO] Unlink file: '/scratch/tmp/simgrid.readme' > [bob:host:(1) 0.009500] [s4u_test/INFO] Storage info on bob: -> [bob:host:(1) 0.009500] [s4u_test/INFO] Disk1 (/scratch) Used: 36933331; Free: 536833978669; Total: 536870912000. +> [bob:host:(1) 0.009500] [s4u_test/INFO] Disk1 (/scratch) Used: 36924298; Free: 536833987702; Total: 536870912000. > [bob:host:(1) 0.009500] [s4u_test/INFO] Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000. diff --git a/examples/cpp/io-priority/s4u-io-priority.cpp b/examples/cpp/io-priority/s4u-io-priority.cpp index 46dbe93533..8f09c4c07c 100644 --- a/examples/cpp/io-priority/s4u-io-priority.cpp +++ b/examples/cpp/io-priority/s4u-io-priority.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/maestro-set/s4u-maestro-set.cpp b/examples/cpp/maestro-set/s4u-maestro-set.cpp index afc56c5a0b..8b92c0b49b 100644 --- a/examples/cpp/maestro-set/s4u-maestro-set.cpp +++ b/examples/cpp/maestro-set/s4u-maestro-set.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -77,7 +77,7 @@ int main(int argc, char* argv[]) /* Become one of the simulated actors (must be done after the platform creation, or the host won't exist). */ sg_actor_attach("sender", nullptr, e.host_by_name("Tremblay"), nullptr); - ensure_root_tid(); // Only useful in this test: we ensure that simgrid is not broken and that this code is executed in + ensure_root_tid(); // Only useful in this test: we ensure that SimGrid is not broken and that this code is executed in // the correct system thread // Execute the sender code. The root thread was actually turned into a regular actor diff --git a/examples/cpp/mc-bugged1-liveness/promela_bugged1_liveness b/examples/cpp/mc-bugged1-liveness/promela_bugged1_liveness deleted file mode 100644 index 96b491d6af..0000000000 --- a/examples/cpp/mc-bugged1-liveness/promela_bugged1_liveness +++ /dev/null @@ -1,11 +0,0 @@ -never { /* !G(r->Fcs) */ -T0_init : /* init */ - if - :: (1) -> goto T0_init - :: (!cs && r) -> goto accept_S2 - fi; -accept_S2 : /* 1 */ - if - :: (!cs) -> goto accept_S2 - fi; -} diff --git a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner b/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner deleted file mode 100755 index 0552ca2898..0000000000 --- a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-stack-cleaner +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env sh -# Run the same test compiled with -fstack-cleaner / f-no-stack-cleaner -# and compare the output. - -srcdir="$1" -bindir="$2" - -cd "$srcdir" - -die() { - echo "$@" >&2 - exit 1 -} - -assert() { - if ! eval "$1"; then - die "Assertion failed: $*" - fi -} - -# If we don't have timeout, fake it: -if ! which timeout > /dev/null; then - timeout() { - shift - "$@" - } -fi - -run() { - state=$1 - shift - timeout 30s ${bindir:=.}/bugged1_liveness_cleaner_$state \ - ${srcdir:=.}/../../platforms/platform.xml \ - ${srcdir:=.}/deploy_bugged1_liveness.xml \ - "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" \ - --cfg=contexts/factory:ucontext \ - --cfg=contexts/stack-size:256 - assert 'test $? = 134' -} - -get_states() { - echo "$1" | grep "Expanded pairs = " | sed "s/^.*Expanded pairs = //" | head -n1 -} - -RES_ON="$(run on 2>&1 1>/dev/null)" -RES_OFF="$(run off 2>&1 1>/dev/null)" - -STATES_ON=$(get_states "$RES_ON") -STATES_OFF=$(get_states "$RES_OFF") - -# Both runs finished: -assert 'test -n "$STATES_ON"' -assert 'test -n "$STATES_OFF"' - -# We expect 21 visited pairs with the stack cleaner: -assert 'test "$STATES_ON" = 21' - -# We expect more states without the stack cleaner: -assert 'test "$STATES_ON" -lt "$STATES_OFF"' diff --git a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh b/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh deleted file mode 100644 index 4e13f97131..0000000000 --- a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env tesh - -! expect return 2 -! timeout 30 -! output display -$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged1-liveness ${platfdir:=.}/small_platform.xml 1 --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/visited:100 --cfg=contexts/stack-size:256 --cfg=model-check/property:promela_bugged1_liveness -> [ 0.000000] (0:maestro@) Check the liveness property promela_bugged1_liveness -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (3:client@Fafard) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (1:coordinator@Tremblay) CS already used. Queue the request. -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (3:client@Fafard) Propositions changed : r=1, cs=0 -> [ 0.000000] (1:coordinator@Tremblay) CS release. Grant to queued requests (queue size: 1) -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (2:client@Boivin) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (0:maestro@) Pair 58 already reached (equal to pair 46) ! -> [ 0.000000] (0:maestro@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* -> [ 0.000000] (0:maestro@) | ACCEPTANCE CYCLE | -> [ 0.000000] (0:maestro@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* -> [ 0.000000] (0:maestro@) Counter-example that violates formula : -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(3)Fafard (client)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (2)Boivin (client)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) Expanded pairs = 58 -> [ 0.000000] (0:maestro@) Visited pairs = 202 -> [ 0.000000] (0:maestro@) Executed transitions = 208 -> [ 0.000000] (0:maestro@) Counter-example depth : 51 diff --git a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp b/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp deleted file mode 100644 index fa15f3fd24..0000000000 --- a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/***************** Centralized Mutual Exclusion Algorithm *******************/ -/* This example implements a centralized mutual exclusion algorithm. */ -/* Bug : CS requests of client 1 not satisfied */ -/* LTL property checked : G(r->F(cs)); (r=request of CS, cs=CS ok) */ -/****************************************************************************/ - -#ifdef GARBAGE_STACK -#include -#include -#include -#endif - -#include -#include -#include - -XBT_LOG_NEW_DEFAULT_CATEGORY(bugged1_liveness, "my log messages"); -namespace sg4 = simgrid::s4u; - -class Message { -public: - enum class Kind { GRANT, REQUEST, RELEASE }; - Kind kind = Kind::GRANT; - sg4::Mailbox* return_mailbox = nullptr; - explicit Message(Message::Kind kind, sg4::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {} -}; - -int r = 0; -int cs = 0; - -#ifdef GARBAGE_STACK -/** Do not use a clean stack */ -static void garbage_stack(void) -{ - const size_t size = 256; - int fd = open("/dev/urandom", O_RDONLY); - char foo[size]; - read(fd, foo, size); - close(fd); -} -#endif - -static void coordinator() -{ - bool CS_used = false; - std::queue requests; - - sg4::Mailbox* mbox = sg4::Mailbox::by_name("coordinator"); - - while (true) { - auto m = mbox->get_unique(); - if (m->kind == Message::Kind::REQUEST) { - if (CS_used) { - XBT_INFO("CS already used. Queue the request."); - requests.push(m->return_mailbox); - } else { - if (m->return_mailbox->get_name() != "1") { - XBT_INFO("CS idle. Grant immediately"); - m->return_mailbox->put(new Message(Message::Kind::GRANT, mbox), 1000); - CS_used = true; - } - } - } else { - if (not requests.empty()) { - XBT_INFO("CS release. Grant to queued requests (queue size: %zu)", requests.size()); - sg4::Mailbox* req = requests.front(); - requests.pop(); - if (req->get_name() != "1") { - req->put(new Message(Message::Kind::GRANT, mbox), 1000); - } else { - requests.push(req); - CS_used = false; - } - } else { - XBT_INFO("CS release. resource now idle"); - CS_used = false; - } - } - } -} - -static void client(int id) -{ - aid_t my_pid = sg4::this_actor::get_pid(); - - sg4::Mailbox* my_mailbox = sg4::Mailbox::by_name(std::to_string(id)); - - while (true) { - XBT_INFO("Ask the request"); - sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000); - - if (id == 1) { - r = 1; - cs = 0; - XBT_INFO("Propositions changed : r=1, cs=0"); - } - - auto grant = my_mailbox->get_unique(); - xbt_assert(grant->kind == Message::Kind::GRANT); - - if (id == 1) { - cs = 1; - r = 0; - XBT_INFO("Propositions changed : r=0, cs=1"); - } - - XBT_INFO("%d got the answer. Sleep a bit and release it", id); - - sg4::this_actor::sleep_for(1); - - sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::RELEASE, my_mailbox), 1000); - - sg4::this_actor::sleep_for(static_cast(my_pid)); - - if (id == 1) { - cs = 0; - r = 0; - XBT_INFO("Propositions changed : r=0, cs=0"); - } - } -} - -static void raw_client(int id) -{ -#ifdef GARBAGE_STACK - // At this point the stack of the callee (client) is probably filled with - // zeros and uninitialized variables will contain 0. This call will place - // random byes in the stack of the callee: - garbage_stack(); -#endif - client(id); -} - -int main(int argc, char* argv[]) -{ - sg4::Engine e(&argc, argv); - - MC_automaton_new_propositional_symbol_pointer("r", &r); - MC_automaton_new_propositional_symbol_pointer("cs", &cs); - - e.load_platform(argv[1]); - - sg4::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator) - ->set_kill_time(argc > 3 ? std::stod(argv[3]) : -1.0); - if (std::stod(argv[2]) == 0) { - sg4::Actor::create("client", e.host_by_name("Boivin"), raw_client, 1); - sg4::Actor::create("client", e.host_by_name("Fafard"), raw_client, 2); - } else { // "Visited" case - sg4::Actor::create("client", e.host_by_name("Boivin"), raw_client, 2); - sg4::Actor::create("client", e.host_by_name("Fafard"), raw_client, 1); - } - e.run(); - - return 0; -} diff --git a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh b/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh deleted file mode 100644 index 658e032b3e..0000000000 --- a/examples/cpp/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env tesh - -! expect return 2 -! timeout 20 -! output display -$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged1-liveness ${platfdir:=.}/small_platform.xml 0 --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/stack-size:256 --cfg=model-check/property:promela_bugged1_liveness -> [ 0.000000] (0:maestro@) Check the liveness property promela_bugged1_liveness -> [ 0.000000] (2:client@Boivin) Ask the request -> [ 0.000000] (3:client@Fafard) Ask the request -> [ 0.000000] (2:client@Boivin) Propositions changed : r=1, cs=0 -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (3:client@Fafard) 2 got the answer. Sleep a bit and release it -> [ 0.000000] (1:coordinator@Tremblay) CS release. resource now idle -> [ 0.000000] (3:client@Fafard) Ask the request -> [ 0.000000] (1:coordinator@Tremblay) CS idle. Grant immediately -> [ 0.000000] (0:maestro@) Pair 22 already reached (equal to pair 10) ! -> [ 0.000000] (0:maestro@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* -> [ 0.000000] (0:maestro@) | ACCEPTANCE CYCLE | -> [ 0.000000] (0:maestro@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* -> [ 0.000000] (0:maestro@) Counter-example that violates formula : -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iSend(src=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] Wait(comm=(verbose only) [(2)Boivin (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(2)Boivin (client)] iRecv(dst=(2)Boivin (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iSend(src=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(3)Fafard (client)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(3)Fafard (client)] iRecv(dst=(3)Fafard (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (3)Fafard (client)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(3)Fafard (client)] Wait(comm=(verbose only) [(1)Tremblay (coordinator)-> (3)Fafard (client)]) -> [ 0.000000] (0:maestro@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] iRecv(dst=(1)Tremblay (coordinator), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(3)Fafard (client)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) [(3)Fafard (client)] iSend(src=(3)Fafard (client), buff=(verbose only), size=(verbose only)) -> [ 0.000000] (0:maestro@) [(1)Tremblay (coordinator)] Wait(comm=(verbose only) [(3)Fafard (client)-> (1)Tremblay (coordinator)]) -> [ 0.000000] (0:maestro@) Expanded pairs = 22 -> [ 0.000000] (0:maestro@) Visited pairs = 20 -> [ 0.000000] (0:maestro@) Executed transitions = 20 -> [ 0.000000] (0:maestro@) Counter-example depth : 21 diff --git a/examples/cpp/mc-bugged1/s4u-mc-bugged1.cpp b/examples/cpp/mc-bugged1/s4u-mc-bugged1.cpp index fe40d93b28..e10b78a902 100644 --- a/examples/cpp/mc-bugged1/s4u-mc-bugged1.cpp +++ b/examples/cpp/mc-bugged1/s4u-mc-bugged1.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/mc-bugged1/s4u-mc-bugged1.tesh b/examples/cpp/mc-bugged1/s4u-mc-bugged1.tesh index bd135cf7bf..022c225f4b 100644 --- a/examples/cpp/mc-bugged1/s4u-mc-bugged1.tesh +++ b/examples/cpp/mc-bugged1/s4u-mc-bugged1.tesh @@ -2,7 +2,7 @@ ! expect return 1 ! timeout 20 -$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged1 ${platfdir:=.}/model_checker_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=xbt_cfg.thresh:warning --cfg=contexts/stack-size:256 +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged1 ${platfdir:=.}/model_checker_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=xbt_cfg.thresh:warning --cfg=contexts/stack-size:256 > [ 0.000000] (0:maestro@) Start a DFS exploration. Reduction is: dpor. > [ 0.000000] (2:client@HostB) Sent! > [ 0.000000] (3:client@HostC) Sent! @@ -11,25 +11,19 @@ $ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged1 ${platfdir:=. > [ 0.000000] (2:client@HostB) Sent! > [ 0.000000] (3:client@HostC) Sent! > [ 0.000000] (2:client@HostB) Sent! -> [ 0.000000] (3:client@HostC) Sent! -> [ 0.000000] (1:server@HostA) OK -> [ 0.000000] (4:client@HostD) Sent! -> [ 0.000000] (2:client@HostB) Sent! -> [ 0.000000] (3:client@HostC) Sent! -> [ 0.000000] (2:client@HostB) Sent! > [ 0.000000] (0:maestro@) ************************** > [ 0.000000] (0:maestro@) *** PROPERTY NOT VALID *** > [ 0.000000] (0:maestro@) ************************** > [ 0.000000] (0:maestro@) Counter-example execution trace: -> [ 0.000000] (0:maestro@) 1: iRecv(mbox=0) -> [ 0.000000] (0:maestro@) 2: iSend(mbox=0) -> [ 0.000000] (0:maestro@) 1: WaitComm(from 2 to 1, mbox=0, no timeout) -> [ 0.000000] (0:maestro@) 1: iRecv(mbox=0) -> [ 0.000000] (0:maestro@) 2: WaitComm(from 2 to 1, mbox=0, no timeout) -> [ 0.000000] (0:maestro@) 4: iSend(mbox=0) -> [ 0.000000] (0:maestro@) 1: WaitComm(from 4 to 1, mbox=0, no timeout) -> [ 0.000000] (0:maestro@) 1: iRecv(mbox=0) -> [ 0.000000] (0:maestro@) 3: iSend(mbox=0) -> [ 0.000000] (0:maestro@) 1: WaitComm(from 3 to 1, mbox=0, no timeout) -> [ 0.000000] (0:maestro@) Path = 1;2;1;1;2;4;1;1;3;1 -> [ 0.000000] (0:maestro@) DFS exploration ended. 22 unique states visited; 4 backtracks (56 transition replays, 30 states visited overall) \ No newline at end of file +> [ 0.000000] (0:maestro@) Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [ 0.000000] (0:maestro@) Actor 2 in Isend ==> simcall: iSend(mbox=0) +> [ 0.000000] (0:maestro@) Actor 1 in Wait ==> simcall: WaitComm(from 2 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [ 0.000000] (0:maestro@) Actor 2 in Wait ==> simcall: WaitComm(from 2 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) Actor 4 in Isend ==> simcall: iSend(mbox=0) +> [ 0.000000] (0:maestro@) Actor 1 in Wait ==> simcall: WaitComm(from 4 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [ 0.000000] (0:maestro@) Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [ 0.000000] (0:maestro@) Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;2;1;1;2;4;1;1;3;1' +> [ 0.000000] (0:maestro@) DFS exploration ended. 19 unique states visited; 2 backtracks (12 transition replays, 33 states visited overall) diff --git a/examples/cpp/mc-bugged2-liveness/promela_bugged2_liveness b/examples/cpp/mc-bugged2-liveness/promela_bugged2_liveness deleted file mode 100644 index 5361f88099..0000000000 --- a/examples/cpp/mc-bugged2-liveness/promela_bugged2_liveness +++ /dev/null @@ -1,12 +0,0 @@ -never { /* !(!(GFcs)) */ -T0_init : /* init */ - if - :: (cs) -> goto accept_S1 - :: (1) -> goto T0_init - fi; -accept_S1 : /* 1 */ - if - :: (cs) -> goto accept_S1 - :: (1) -> goto T0_init - fi; -} diff --git a/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.cpp b/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.cpp deleted file mode 100644 index eb1c34e1dc..0000000000 --- a/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/***************************** Bugged2 ****************************************/ -/* This example implements a centralized mutual exclusion algorithm. */ -/* One client stay always in critical section */ -/* LTL property checked : !(GFcs) */ -/******************************************************************************/ - -#include -#include - -XBT_LOG_NEW_DEFAULT_CATEGORY(bugged2_liveness, "my log messages"); -namespace sg4 = simgrid::s4u; - -class Message { -public: - enum class Kind { GRANT, NOT_GRANT, REQUEST }; - Kind kind = Kind::GRANT; - sg4::Mailbox* return_mailbox = nullptr; - explicit Message(Message::Kind kind, sg4::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {} -}; - -int cs = 0; - -static void coordinator() -{ - bool CS_used = false; // initially the CS is idle - std::queue requests; - - sg4::Mailbox* mbox = sg4::Mailbox::by_name("coordinator"); - - while (true) { - auto m = mbox->get_unique(); - if (m->kind == Message::Kind::REQUEST) { - if (CS_used) { - XBT_INFO("CS already used."); - m->return_mailbox->put(new Message(Message::Kind::NOT_GRANT, mbox), 1000); - } else { // can serve it immediately - XBT_INFO("CS idle. Grant immediately"); - m->return_mailbox->put(new Message(Message::Kind::GRANT, mbox), 1000); - CS_used = true; - } - } else { // that's a release. Check if someone was waiting for the lock - XBT_INFO("CS release. resource now idle"); - CS_used = false; - } - } -} - -static void client(int id) -{ - aid_t my_pid = sg4::this_actor::get_pid(); - - sg4::Mailbox* my_mailbox = sg4::Mailbox::by_name(std::to_string(id)); - - while (true) { - XBT_INFO("Client (%d) asks the request", id); - sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000); - - auto grant = my_mailbox->get_unique(); - - if (grant->kind == Message::Kind::GRANT) { - XBT_INFO("Client (%d) got the answer (grant). Sleep a bit and release it", id); - if (id == 1) - cs = 1; - } else { - XBT_INFO("Client (%d) got the answer (not grant). Try again", id); - } - - sg4::this_actor::sleep_for(my_pid); - } -} - -int main(int argc, char* argv[]) -{ - sg4::Engine e(&argc, argv); - - MC_automaton_new_propositional_symbol_pointer("cs", &cs); - - e.load_platform(argv[1]); - - sg4::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator); - sg4::Actor::create("client", e.host_by_name("Fafard"), client, 1); - sg4::Actor::create("client", e.host_by_name("Boivin"), client, 2); - - e.run(); - - return 0; -} diff --git a/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.tesh b/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.tesh deleted file mode 100644 index a48a2ab5a3..0000000000 --- a/examples/cpp/mc-bugged2-liveness/s4u-mc-bugged2-liveness.tesh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env tesh - -! expect return 2 -! timeout 20 -! output ignore -$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged2-liveness ${platfdir:=.}/small_platform.xml --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/stack-size:256 --cfg=model-check/property:promela_bugged2_liveness diff --git a/examples/cpp/mc-bugged2/s4u-mc-bugged2.cpp b/examples/cpp/mc-bugged2/s4u-mc-bugged2.cpp index df16578d49..1fd55a88d2 100644 --- a/examples/cpp/mc-bugged2/s4u-mc-bugged2.cpp +++ b/examples/cpp/mc-bugged2/s4u-mc-bugged2.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/mc-bugged2/s4u-mc-bugged2.tesh b/examples/cpp/mc-bugged2/s4u-mc-bugged2.tesh index 9badbef5d1..83991dad80 100644 --- a/examples/cpp/mc-bugged2/s4u-mc-bugged2.tesh +++ b/examples/cpp/mc-bugged2/s4u-mc-bugged2.tesh @@ -2,554 +2,55 @@ ! expect return 1 ! timeout 20 -$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged2 ${platfdir:=.}/model_checker_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=xbt_cfg.thresh:warning --cfg=contexts/stack-size:256 -> [ 0.000000] (0:maestro@) Start a DFS exploration. Reduction is: dpor. -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 1 2 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) Second pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 1 -> [ 0.000000] (1:server@HostA) First pair received: 2 2 -> [ 0.000000] (0:maestro@) ************************** -> [ 0.000000] (0:maestro@) *** PROPERTY NOT VALID *** -> [ 0.000000] (0:maestro@) ************************** -> [ 0.000000] (0:maestro@) Counter-example execution trace: -> [ 0.000000] (0:maestro@) 1: iRecv(mbox=0) -> [ 0.000000] (0:maestro@) 3: iSend(mbox=0) -> [ 0.000000] (0:maestro@) 1: WaitComm(from 3 to 1, mbox=0, no timeout) -> [ 0.000000] (0:maestro@) 3: WaitComm(from 3 to 1, mbox=0, no timeout) -> [ 0.000000] (0:maestro@) 1: iRecv(mbox=0) -> [ 0.000000] (0:maestro@) 3: iSend(mbox=0) -> [ 0.000000] (0:maestro@) 1: WaitComm(from 3 to 1, mbox=0, no timeout) -> [ 0.000000] (0:maestro@) Path = 1;3;1;3;1;3;1 -> [ 0.000000] (0:maestro@) DFS exploration ended. 1006 unique states visited; 350 backtracks (5319 transition replays, 3963 states visited overall) +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-bugged2 ${platfdir:=.}/model_checker_platform.xml --log=root.thresh:critical --log=mc.thresh:info +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] *** PROPERTY NOT VALID *** +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] Counter-example execution trace: +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 3 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;3;1;1;3;3;1' +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 98 unique states visited; 21 backtracks (153 transition replays, 272 states visited overall) + +! expect return 1 +! timeout 20 +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/strategy:min_match_comm ${bindir:=.}/s4u-mc-bugged2 ${platfdir:=.}/model_checker_platform.xml --log=root.thresh:critical --log=mc.thresh:info +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] *** PROPERTY NOT VALID *** +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] Counter-example execution trace: +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 3 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 2 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;3;1;1;3;3;2;1' +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 83 unique states visited; 12 backtracks (65 transition replays, 160 states visited overall) + +! expect return 1 +! timeout 20 +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/strategy:max_match_comm ${bindir:=.}/s4u-mc-bugged2 ${platfdir:=.}/model_checker_platform.xml --log=root.thresh:critical --log=mc.thresh:info +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] *** PROPERTY NOT VALID *** +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] Counter-example execution trace: +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 3 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;3;1;3;1;3;1' +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 44 unique states visited; 3 backtracks (11 transition replays, 58 states visited overall) diff --git a/examples/cpp/mc-centralized-mutex/s4u-mc-centralized-mutex.cpp b/examples/cpp/mc-centralized-mutex/s4u-mc-centralized-mutex.cpp index b2e11ca048..0579294e37 100644 --- a/examples/cpp/mc-centralized-mutex/s4u-mc-centralized-mutex.cpp +++ b/examples/cpp/mc-centralized-mutex/s4u-mc-centralized-mutex.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/mc-electric-fence/s4u-mc-electric-fence.cpp b/examples/cpp/mc-electric-fence/s4u-mc-electric-fence.cpp index 49827004ab..bdeecebd41 100644 --- a/examples/cpp/mc-electric-fence/s4u-mc-electric-fence.cpp +++ b/examples/cpp/mc-electric-fence/s4u-mc-electric-fence.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/mc-electric-fence/s4u-mc-electric-fence.tesh b/examples/cpp/mc-electric-fence/s4u-mc-electric-fence.tesh index e974265688..8516a98894 100644 --- a/examples/cpp/mc-electric-fence/s4u-mc-electric-fence.tesh +++ b/examples/cpp/mc-electric-fence/s4u-mc-electric-fence.tesh @@ -1,12 +1,14 @@ #!/usr/bin/env tesh -$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-electric-fence ${platfdir}/model_checker_platform.xml +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-electric-fence ${platfdir}/model_checker_platform.xml > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. > [HostB:client:(2) 0.000000] [electric_fence/INFO] Sent! > [HostA:server:(1) 0.000000] [electric_fence/INFO] OK > [HostC:client:(3) 0.000000] [electric_fence/INFO] Sent! -> [HostB:client:(2) 0.000000] [electric_fence/INFO] Sent! > [HostA:server:(1) 0.000000] [electric_fence/INFO] OK > [HostB:client:(2) 0.000000] [electric_fence/INFO] Sent! > [HostC:client:(3) 0.000000] [electric_fence/INFO] Sent! -> [0.000000] [mc_dfs/INFO] DFS exploration ended. 15 unique states visited; 5 backtracks (32 transition replays, 13 states visited overall) +> [HostC:client:(3) 0.000000] [electric_fence/INFO] Sent! +> [HostB:client:(2) 0.000000] [electric_fence/INFO] Sent! +> [HostC:client:(3) 0.000000] [electric_fence/INFO] Sent! +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 26 unique states visited; 6 backtracks (8 transition replays, 40 states visited overall) diff --git a/examples/cpp/mc-failing-assert/s4u-mc-failing-assert-nodpor.tesh b/examples/cpp/mc-failing-assert/s4u-mc-failing-assert-nodpor.tesh new file mode 100644 index 0000000000..0a7b1709d2 --- /dev/null +++ b/examples/cpp/mc-failing-assert/s4u-mc-failing-assert-nodpor.tesh @@ -0,0 +1,60 @@ +#!/usr/bin/env tesh + +! expect return 1 +! timeout 300 +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/reduction:none -- ${bindir:=.}/s4u-mc-failing-assert ${platfdir}/small_platform.xml --log=root.thresh:critical +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'none' +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: none. +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] *** PROPERTY NOT VALID *** +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] Counter-example execution trace: +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 2 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 2 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;3;1;1;2;1' +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 24 unique states visited; 8 backtracks (26 transition replays, 58 states visited overall) + +! expect return 1 +! timeout 300 +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/reduction:none --cfg=model-check/strategy:max_match_comm -- ${bindir:=.}/s4u-mc-failing-assert ${platfdir}/small_platform.xml --log=root.thresh:critical +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'none' +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/strategy' to 'max_match_comm' +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: none. +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] *** PROPERTY NOT VALID *** +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] Counter-example execution trace: +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 3 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 2 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 2 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;3;1;3;1;2;1' +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 14 unique states visited; 1 backtracks (1 transition replays, 16 states visited overall) + + +! expect return 1 +! timeout 300 +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/reduction:none --cfg=model-check/strategy:min_match_comm -- ${bindir:=.}/s4u-mc-failing-assert ${platfdir}/small_platform.xml --log=root.thresh:critical +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'none' +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/strategy' to 'min_match_comm' +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: none. +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] *** PROPERTY NOT VALID *** +> [0.000000] [mc_explo/INFO] ************************** +> [0.000000] [mc_explo/INFO] Counter-example execution trace: +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 2 in Isend ==> simcall: iSend(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 3 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [0.000000] [mc_explo/INFO] Actor 1 in Wait ==> simcall: WaitComm(from 2 to 1, mbox=0, no timeout) +> [0.000000] [mc_explo/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;3;2;1;3;1;1' +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 29 unique states visited; 10 backtracks (26 transition replays, 65 states visited overall) \ No newline at end of file diff --git a/examples/cpp/mc-failing-assert/s4u-mc-failing-assert.cpp b/examples/cpp/mc-failing-assert/s4u-mc-failing-assert.cpp index eb91637442..5f9549d674 100644 --- a/examples/cpp/mc-failing-assert/s4u-mc-failing-assert.cpp +++ b/examples/cpp/mc-failing-assert/s4u-mc-failing-assert.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/mc-failing-assert/s4u-mc-failing-assert.tesh b/examples/cpp/mc-failing-assert/s4u-mc-failing-assert.tesh index d49289dafb..1d5166eb2c 100644 --- a/examples/cpp/mc-failing-assert/s4u-mc-failing-assert.tesh +++ b/examples/cpp/mc-failing-assert/s4u-mc-failing-assert.tesh @@ -2,25 +2,65 @@ ! expect return 1 ! timeout 20 -$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-failing-assert ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=xbt_cfg.thresh:warning +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-failing-assert ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=xbt_cfg.thresh:warning > [ 0.000000] (0:maestro@) Start a DFS exploration. Reduction is: dpor. > [ 0.000000] (2:client1@Bourassa) Sent! > [ 0.000000] (1:server@Boivin) OK > [ 0.000000] (3:client2@Fafard) Sent! > [ 0.000000] (2:client1@Bourassa) Sent! +> [ 0.000000] (0:maestro@) ************************** +> [ 0.000000] (0:maestro@) *** PROPERTY NOT VALID *** +> [ 0.000000] (0:maestro@) ************************** +> [ 0.000000] (0:maestro@) Counter-example execution trace: +> [ 0.000000] (0:maestro@) Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [ 0.000000] (0:maestro@) Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [ 0.000000] (0:maestro@) Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [ 0.000000] (0:maestro@) Actor 2 in Isend ==> simcall: iSend(mbox=0) +> [ 0.000000] (0:maestro@) Actor 1 in Wait ==> simcall: WaitComm(from 2 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;3;1;1;2;1' +> [ 0.000000] (0:maestro@) DFS exploration ended. 15 unique states visited; 2 backtracks (4 transition replays, 21 states visited overall) + +! expect return 1 +! timeout 20 +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/strategy:min_match_comm ${bindir:=.}/s4u-mc-failing-assert ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=xbt_cfg.thresh:warning +> [ 0.000000] (0:maestro@) Start a DFS exploration. Reduction is: dpor. > [ 0.000000] (2:client1@Bourassa) Sent! > [ 0.000000] (1:server@Boivin) OK > [ 0.000000] (3:client2@Fafard) Sent! +> [ 0.000000] (3:client2@Fafard) Sent! +> [ 0.000000] (0:maestro@) ************************** +> [ 0.000000] (0:maestro@) *** PROPERTY NOT VALID *** +> [ 0.000000] (0:maestro@) ************************** +> [ 0.000000] (0:maestro@) Counter-example execution trace: +> [ 0.000000] (0:maestro@) Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [ 0.000000] (0:maestro@) Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [ 0.000000] (0:maestro@) Actor 2 in Isend ==> simcall: iSend(mbox=0) +> [ 0.000000] (0:maestro@) Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) Actor 3 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [ 0.000000] (0:maestro@) Actor 1 in Wait ==> simcall: WaitComm(from 2 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;3;2;1;3;1;1' +> [ 0.000000] (0:maestro@) DFS exploration ended. 18 unique states visited; 3 backtracks (1 transition replays, 22 states visited overall) + +! expect return 1 +! timeout 20 +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/strategy:max_match_comm ${bindir:=.}/s4u-mc-failing-assert ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=xbt_cfg.thresh:warning +> [ 0.000000] (0:maestro@) Start a DFS exploration. Reduction is: dpor. > [ 0.000000] (2:client1@Bourassa) Sent! +> [ 0.000000] (1:server@Boivin) OK +> [ 0.000000] (3:client2@Fafard) Sent! +> [ 0.000000] (3:client2@Fafard) Sent! > [ 0.000000] (0:maestro@) ************************** > [ 0.000000] (0:maestro@) *** PROPERTY NOT VALID *** > [ 0.000000] (0:maestro@) ************************** > [ 0.000000] (0:maestro@) Counter-example execution trace: -> [ 0.000000] (0:maestro@) 1: iRecv(mbox=0) -> [ 0.000000] (0:maestro@) 3: iSend(mbox=0) -> [ 0.000000] (0:maestro@) 1: WaitComm(from 3 to 1, mbox=0, no timeout) -> [ 0.000000] (0:maestro@) 1: iRecv(mbox=0) -> [ 0.000000] (0:maestro@) 2: iSend(mbox=0) -> [ 0.000000] (0:maestro@) 1: WaitComm(from 2 to 1, mbox=0, no timeout) -> [ 0.000000] (0:maestro@) Path = 1;3;1;1;2;1 -> [ 0.000000] (0:maestro@) DFS exploration ended. 18 unique states visited; 4 backtracks (36 transition replays, 14 states visited overall) +> [ 0.000000] (0:maestro@) Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [ 0.000000] (0:maestro@) Actor 3 in Isend ==> simcall: iSend(mbox=0) +> [ 0.000000] (0:maestro@) Actor 1 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) Actor 3 in Wait ==> simcall: WaitComm(from 3 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) Actor 1 in Irecv ==> simcall: iRecv(mbox=0) +> [ 0.000000] (0:maestro@) Actor 2 in Isend ==> simcall: iSend(mbox=0) +> [ 0.000000] (0:maestro@) Actor 1 in Wait ==> simcall: WaitComm(from 2 to 1, mbox=0, no timeout) +> [ 0.000000] (0:maestro@) You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;3;1;3;1;2;1' +> [ 0.000000] (0:maestro@) DFS exploration ended. 14 unique states visited; 1 backtracks (1 transition replays, 16 states visited overall) \ No newline at end of file diff --git a/examples/cpp/mess-wait/s4u-mess-wait.cpp b/examples/cpp/mess-wait/s4u-mess-wait.cpp new file mode 100644 index 0000000000..086dc474c2 --- /dev/null +++ b/examples/cpp/mess-wait/s4u-mess-wait.cpp @@ -0,0 +1,79 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example shows how to use simgrid::s4u::this_actor::wait() to wait for a given communication. + * + * As for the other asynchronous examples, the sender initiate all the messages it wants to send and + * pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occurs concurrently. + * + * The sender then loops until there is no ongoing communication. + */ + +#include "simgrid/s4u.hpp" +#include +#include +#include +namespace sg4 = simgrid::s4u; + +XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_mess_wait, "Messages specific for this s4u example"); + +static void sender(int messages_count) +{ + sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("control"); + + sg4::this_actor::sleep_for(0.5); + + for (int i = 0; i < messages_count; i++) { + std::string msg_content = "Message " + std::to_string(i); + // Copy the data we send: the 'msg_content' variable is not a stable storage location. + // It will be destroyed when this actor leaves the loop, ie before the receiver gets the data + auto* payload = new std::string(msg_content); + + /* Create a control message and put it in the message queue */ + sg4::MessPtr mess = mqueue->put_async(payload); + XBT_INFO("Send '%s' to '%s'", msg_content.c_str(), mqueue->get_cname()); + mess->wait(); + } + + /* Send message to let the receiver know that it should stop */ + XBT_INFO("Send 'finalize' to 'receiver'"); + mqueue->put(new std::string("finalize")); +} + +/* Receiver actor expects 1 argument: its ID */ +static void receiver() +{ + sg4::MessageQueue* mqueue = sg4::MessageQueue::by_name("control"); + + sg4::this_actor::sleep_for(1); + + XBT_INFO("Wait for my first message"); + for (bool cont = true; cont;) { + std::string* received; + sg4::MessPtr mess = mqueue->get_async(&received); + + sg4::this_actor::sleep_for(0.1); + mess->wait(); + + XBT_INFO("I got a '%s'.", received->c_str()); + if (*received == "finalize") + cont = false; // If it's a finalize message, we're done. + delete received; + } +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + + e.load_platform(argv[1]); + + sg4::Actor::create("sender", e.host_by_name("Tremblay"), sender, 3); + sg4::Actor::create("receiver", e.host_by_name("Fafard"), receiver); + + e.run(); + + return 0; +} diff --git a/examples/cpp/mess-wait/s4u-mess-wait.tesh b/examples/cpp/mess-wait/s4u-mess-wait.tesh new file mode 100644 index 0000000000..fe7bcee8f9 --- /dev/null +++ b/examples/cpp/mess-wait/s4u-mess-wait.tesh @@ -0,0 +1,12 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-mess-wait ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" +> [ 0.500000] (1:sender@Tremblay) Send 'Message 0' to 'control' +> [ 1.000000] (2:receiver@Fafard) Wait for my first message +> [ 1.000000] (1:sender@Tremblay) Send 'Message 1' to 'control' +> [ 1.100000] (2:receiver@Fafard) I got a 'Message 0'. +> [ 1.100000] (1:sender@Tremblay) Send 'Message 2' to 'control' +> [ 1.200000] (2:receiver@Fafard) I got a 'Message 1'. +> [ 1.200000] (1:sender@Tremblay) Send 'finalize' to 'receiver' +> [ 1.300000] (2:receiver@Fafard) I got a 'Message 2'. +> [ 1.400000] (2:receiver@Fafard) I got a 'finalize'. \ No newline at end of file diff --git a/examples/cpp/network-factors/s4u-network-factors.cpp b/examples/cpp/network-factors/s4u-network-factors.cpp index 4eca7b86a2..83b9cf2596 100644 --- a/examples/cpp/network-factors/s4u-network-factors.cpp +++ b/examples/cpp/network-factors/s4u-network-factors.cpp @@ -1,22 +1,20 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -/* This example shows how to build set customized communication factors +/* This example shows how to build set custom communication factors * - * It uses the interface provided by NetworkModelIntf to register 2 callbacks that - * are called everytime a communication occurs. + * It uses the netzone interface to register 2 callbacks that are called for every communications. * * These factors are used to change the communication time depending on the message size * and destination. * * This example uses factors obtained by some experiments on dahu cluster in Grid'5000. - * You must change the values according to the calibration of your enviroment. + * You should change the values according to the calibration of your enviroment. */ #include -#include #include namespace sg4 = simgrid::s4u; @@ -73,15 +71,15 @@ static void load_platform() for (int id = 0; id < 32; id++) { std::string hostname = prefix + std::to_string(id) + suffix; /* create host */ - const sg4::Host* host = root->create_host(hostname, 1)->set_core_count(32)->seal(); + const sg4::Host* host = root->create_host(hostname, 1)->set_core_count(32); /* create UP/DOWN link */ - const sg4::Link* l = root->create_split_duplex_link(hostname, BW_REMOTE)->set_latency(LATENCY)->seal(); + const sg4::Link* l = root->create_split_duplex_link(hostname, BW_REMOTE)->set_latency(LATENCY); /* add link UP/DOWN for communications from the host */ - root->add_route(host->get_netpoint(), nullptr, nullptr, nullptr, {{l, sg4::LinkInRoute::Direction::UP}}, true); + root->add_route(host, nullptr, {{l, sg4::LinkInRoute::Direction::UP}}, true); - const sg4::Link* loopback = root->create_link(hostname + "_loopback", BW_LOCAL)->set_latency(LATENCY)->seal(); - root->add_route(host->get_netpoint(), host->get_netpoint(), nullptr, nullptr, {sg4::LinkInRoute(loopback)}); + sg4::Link* loopback = root->create_link(hostname + "_loopback", BW_LOCAL)->set_latency(LATENCY); + root->add_route(host, host, {loopback}); } root->seal(); @@ -185,7 +183,7 @@ public: } /* Create a communication representing the ongoing communication */ - auto mbox = sg4::Mailbox::by_name(host->get_name()); + auto* mbox = sg4::Mailbox::by_name(host->get_name()); auto* payload = new std::string(msg); mbox->put(payload, static_cast(size)); } @@ -194,7 +192,7 @@ public: XBT_INFO("Done dispatching all messages"); /* sending message to stop receivers */ for (const auto* host : hosts_) { - auto mbox = sg4::Mailbox::by_name(host->get_name()); + auto* mbox = sg4::Mailbox::by_name(host->get_name()); mbox->put(new std::string("finalize"), 0); } } @@ -205,7 +203,7 @@ class Receiver { public: void operator()() const { - auto mbox = sg4::Mailbox::by_name(sg4::this_actor::get_host()->get_name()); + auto* mbox = sg4::Mailbox::by_name(sg4::this_actor::get_host()->get_name()); // Receiving the message was all we were supposed to do for (bool cont = true; cont;) { auto received = mbox->get_unique(); @@ -232,16 +230,14 @@ int main(int argc, char* argv[]) /* create platform */ load_platform(); /* setting network factors callbacks */ - simgrid::kernel::resource::NetworkModelIntf* model = e.get_netzone_root()->get_network_model(); - model->set_lat_factor_cb(latency_factor_cb); - model->set_bw_factor_cb(bandwidth_factor_cb); + e.get_netzone_root()->set_latency_factor_cb(latency_factor_cb); + e.get_netzone_root()->set_bandwidth_factor_cb(bandwidth_factor_cb); sg4::Host* host = e.host_by_name("dahu-1.grid5000.fr"); sg4::Host* host_remote = e.host_by_name("dahu-10.grid5000.fr"); - sg4::Actor::create(std::string("receiver-local"), host, Receiver()); - sg4::Actor::create(std::string("receiver-remote"), host_remote, Receiver()); - sg4::Actor::create(std::string("sender") + std::string(host->get_name()), host, - Sender({host, host_remote}, crosstraffic)); + sg4::Actor::create("receiver-local", host, Receiver()); + sg4::Actor::create("receiver-remote", host_remote, Receiver()); + sg4::Actor::create("sender" + host->get_name(), host, Sender({host, host_remote}, crosstraffic)); /* runs the simulation */ e.run(); diff --git a/examples/cpp/network-nonlinear/s4u-network-nonlinear.cpp b/examples/cpp/network-nonlinear/s4u-network-nonlinear.cpp index 292503e52b..d109be7d88 100644 --- a/examples/cpp/network-nonlinear/s4u-network-nonlinear.cpp +++ b/examples/cpp/network-nonlinear/s4u-network-nonlinear.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,6 +8,7 @@ */ #include +#include namespace sg4 = simgrid::s4u; @@ -23,16 +24,16 @@ public: void operator()() const { // sphinx-doc: init-begin (this line helps the doc to build; ignore it) - /* Vector in which we store all ongoing communications */ - std::vector pending_comms; + /* ActivitySet in which we store all ongoing communications */ + sg4::ActivitySet pending_comms; - /* Make a vector of the mailboxes to use */ + /* Mailbox to use */ sg4::Mailbox* mbox = sg4::Mailbox::by_name("receiver"); // sphinx-doc: init-end /* Start dispatching all messages to receiver */ for (int i = 0; i < messages_count; i++) { - std::string msg_content = std::string("Message ") + std::to_string(i); + std::string msg_content = "Message " + std::to_string(i); // Copy the data we send: the 'msg_content' variable is not a stable storage location. // It will be destroyed when this actor leaves the loop, ie before the receiver gets it auto* payload = new std::string(msg_content); @@ -41,13 +42,13 @@ public: /* Create a communication representing the ongoing communication, and store it in pending_comms */ sg4::CommPtr comm = mbox->put_async(payload, size); - pending_comms.push_back(comm); + pending_comms.push(comm); } XBT_INFO("Done dispatching all messages"); /* Now that all message exchanges were initiated, wait for their completion in one single call */ - sg4::Comm::wait_all(pending_comms); + pending_comms.wait_all(); // sphinx-doc: put-end XBT_INFO("Goodbye now!"); @@ -63,23 +64,28 @@ public: explicit Receiver(int count) : messages_count(count) { mbox = sg4::Mailbox::by_name("receiver"); } void operator()() { - /* Vector in which we store all incoming msgs */ - std::vector> pending_msgs; - std::vector pending_comms; + /* Where we store all incoming msgs */ + std::unordered_map> pending_msgs; + sg4::ActivitySet pending_comms; XBT_INFO("Wait for %d messages asynchronously", messages_count); for (int i = 0; i < messages_count; i++) { - pending_msgs.push_back(std::make_unique()); - pending_comms.emplace_back(mbox->get_async(pending_msgs[i].get())); + std::shared_ptr msg =std::make_shared(); + auto comm = mbox->get_async(msg.get()); + pending_comms.push(comm); + pending_msgs.insert({comm, msg}); } + while (not pending_comms.empty()) { - ssize_t index = sg4::Comm::wait_any(pending_comms); - std::string* msg = *pending_msgs[index]; - XBT_INFO("I got '%s'.", msg->c_str()); - /* cleanup memory and remove from vectors */ - delete msg; - pending_comms.erase(pending_comms.begin() + index); - pending_msgs.erase(pending_msgs.begin() + index); + auto completed_one = pending_comms.wait_any(); + if (completed_one != nullptr){ + auto comm = boost::dynamic_pointer_cast(completed_one); + auto msg = *pending_msgs[comm]; + XBT_INFO("I got '%s'.", msg->c_str()); + /* cleanup memory and remove from map */ + delete msg; + pending_msgs.erase(comm); + } } } }; @@ -125,8 +131,7 @@ static void load_platform() link->set_latency(10e-6)->seal(); /* create routes between nodes */ - zone->add_route(sender->get_netpoint(), receiver->get_netpoint(), nullptr, nullptr, - {{link, sg4::LinkInRoute::Direction::UP}}, true); + zone->add_route(sender, receiver, {link}); zone->seal(); /* create actors Sender/Receiver */ diff --git a/examples/cpp/network-ns3-wifi/s4u-network-ns3-wifi.cpp b/examples/cpp/network-ns3-wifi/s4u-network-ns3-wifi.cpp index d3ec019100..cd1386d203 100644 --- a/examples/cpp/network-ns3-wifi/s4u-network-ns3-wifi.cpp +++ b/examples/cpp/network-ns3-wifi/s4u-network-ns3-wifi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/network-ns3/s4u-network-ns3.tesh b/examples/cpp/network-ns3/s4u-network-ns3-notime.tesh similarity index 76% rename from examples/cpp/network-ns3/s4u-network-ns3.tesh rename to examples/cpp/network-ns3/s4u-network-ns3-notime.tesh index 0f06cbb3c3..33ab7cc1ee 100644 --- a/examples/cpp/network-ns3/s4u-network-ns3.tesh +++ b/examples/cpp/network-ns3/s4u-network-ns3-notime.tesh @@ -47,10 +47,22 @@ $ ${bindir:=.}/s4u-network-ns3 ${platfdir}/onelink.xml ${srcdir}/onelink_d.xml - > [:maestro(0)] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' > [C1:worker(2)] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1 +! output sort p Crosstraffic TCP option DISABLED -! output ignore -$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/crosstraffic.xml ${srcdir}/crosstraffic_d.xml --cfg=network/model:ns-3 --cfg=network/crosstraffic:0 +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/crosstraffic.xml ${srcdir}/crosstraffic_d.xml --cfg=network/model:ns-3 --cfg=network/crosstraffic:0 "--log=root.fmt:[%h:%a(%i)]%e[%c/%p]%e%m%n" +> [:maestro(0)] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [:maestro(0)] [xbt_cfg/INFO] Configuration change: Set 'network/crosstraffic' to '0' +> [C1:worker(2)] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1 +> [C1:worker(4)] [s4u_test/INFO] FLOW[2] : Receive 10000 bytes from S1 to C1 +> [C1:worker(6)] [s4u_test/INFO] FLOW[3] : Receive 10000 bytes from S1 to C1 +> [S1:worker(8)] [s4u_test/INFO] FLOW[4] : Receive 10000 bytes from C1 to S1 +! output sort p Crosstraffic TCP option ENABLED -! output ignore -$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/crosstraffic.xml ${srcdir}/crosstraffic_d.xml --cfg=network/model:ns-3 --cfg=network/crosstraffic:1 +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/crosstraffic.xml ${srcdir}/crosstraffic_d.xml --cfg=network/model:ns-3 --cfg=network/crosstraffic:1 "--log=root.fmt:[%h:%a(%i)]%e[%c/%p]%e%m%n" +> [:maestro(0)] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [:maestro(0)] [xbt_cfg/INFO] Configuration change: Set 'network/crosstraffic' to '1' +> [C1:worker(2)] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1 +> [C1:worker(4)] [s4u_test/INFO] FLOW[2] : Receive 10000 bytes from S1 to C1 +> [C1:worker(6)] [s4u_test/INFO] FLOW[3] : Receive 10000 bytes from S1 to C1 +> [S1:worker(8)] [s4u_test/INFO] FLOW[4] : Receive 10000 bytes from C1 to S1 diff --git a/examples/cpp/network-ns3/s4u-network-ns3-timed.tesh b/examples/cpp/network-ns3/s4u-network-ns3-timed.tesh new file mode 100644 index 0000000000..23ec6c55de --- /dev/null +++ b/examples/cpp/network-ns3/s4u-network-ns3-timed.tesh @@ -0,0 +1,89 @@ +#!/usr/bin/env tesh + +p In the ns-3 tests, the timings are valid only with the very latest version of ns3 (the exact values may vary with your ns-3 version). + +p 3hosts 2links + +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/small_platform_one_link_routes.xml ${srcdir}/3hosts_2links_d.xml --cfg=network/model:ns-3 "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n" +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [Jupiter:worker(2) 0.000249] [s4u_test/INFO] FLOW[1] : Receive 100 bytes from Tremblay to Jupiter + +p 6hosts 3links + +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/small_platform_one_link_routes.xml ${srcdir}/3links_d.xml --cfg=network/model:ns-3 "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n" +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [Jupiter:worker(2) 0.000498] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from Tremblay to Jupiter +> [Ginette:worker(4) 0.007323] [s4u_test/INFO] FLOW[2] : Receive 10000 bytes from Fafard to Ginette +> [Lovelace:worker(6) 0.037450] [s4u_test/INFO] FLOW[3] : Receive 10000 bytes from Bourassa to Lovelace + +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/small_platform_one_link_routes.xml ${srcdir}/3links-timer_d.xml --cfg=network/model:ns-3 "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n" +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [Jupiter:worker(2) 0.000498] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from Tremblay to Jupiter +> [Ginette:worker(4) 0.007323] [s4u_test/INFO] FLOW[2] : Receive 10000 bytes from Fafard to Ginette +> [Lovelace:worker(6) 0.037450] [s4u_test/INFO] FLOW[3] : Receive 10000 bytes from Bourassa to Lovelace +> [Lovelace:worker(7) 2.037450] [s4u_test/INFO] FLOW[4] : Receive 10000 bytes from Bourassa to Lovelace + +p One cluster + +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/cluster_backbone.xml ${srcdir}/one_cluster_d.xml --cfg=network/model:ns-3 "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n" +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [node-6.simgrid.org:worker(2) 0.021502] [s4u_test/INFO] FLOW[1] : Receive 100 bytes from node-2.simgrid.org to node-6.simgrid.org + +p Dogbone + +! timeout 10 +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/dogbone.xml ${srcdir}/dogbone_d.xml --cfg=network/model:ns-3 "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n" +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [:maestro(0) 0.000000] [res_ns3/WARNING] Ignoring a route between S1 and C1 of length 3: Only routes of length 1 are considered with ns-3. +> WARNING: You can ignore this warning if your hosts can still communicate when only considering routes of length 1. +> WARNING: Remove long routes to avoid this harmless message; subsequent long routes will be silently ignored. +> [C1:worker(3) 0.120224] [s4u_test/INFO] FLOW[0] : Receive 10000 bytes from S1 to C1 +> [C2:worker(4) 0.120234] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S2 to C2 + +p 2hosts 1link + +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/onelink.xml ${srcdir}/onelink_d.xml --cfg=network/model:ns-3 "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n" +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [C1:worker(2) 1.104600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1 + +p 2hosts 1link NewReno (no timing change) + +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/onelink.xml ${srcdir}/onelink_d.xml --cfg=network/model:ns-3 --cfg=ns3/NetworkModel:NewReno "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n" +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'ns3/NetworkModel' to 'NewReno' +> [:maestro(0) 0.000000] [res_ns3/INFO] Switching Tcp protocol to 'NewReno' +> [C1:worker(2) 1.104600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1 + +p 2hosts 1link Cubic (no timing change) + +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/onelink.xml ${srcdir}/onelink_d.xml --cfg=network/model:ns-3 --cfg=ns3/NetworkModel:Cubic "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n" +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'ns3/NetworkModel' to 'Cubic' +> [:maestro(0) 0.000000] [res_ns3/INFO] Switching Tcp protocol to 'Cubic' +> [C1:worker(2) 1.104600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1 + +p 2hosts 1link UDP + +# $ ${bindir:=.}/s4u-network-ns3 ${platfdir}/onelink.xml ${srcdir}/onelink_d.xml --cfg=network/model:ns-3 --cfg=ns3/NetworkModel:UDP "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n" +# > [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +# > [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'ns3/NetworkModel' to 'UDP' +# > [:maestro(0) 0.000000] [res_ns3/INFO] Switching network protocol to 'UDP' +# > [C1:worker(2) 1.104600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1 + +p Crosstraffic TCP option DISABLED +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/crosstraffic.xml ${srcdir}/crosstraffic_d.xml --cfg=network/model:ns-3 --cfg=network/crosstraffic:0 +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/crosstraffic' to '0' +> [C1:worker:(2) 1.236600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1 +> [C1:worker:(4) 2.150800] [s4u_test/INFO] FLOW[2] : Receive 10000 bytes from S1 to C1 +> [C1:worker:(6) 3.197000] [s4u_test/INFO] FLOW[3] : Receive 10000 bytes from S1 to C1 +> [S1:worker:(8) 3.537400] [s4u_test/INFO] FLOW[4] : Receive 10000 bytes from C1 to S1 + +p Crosstraffic TCP option ENABLED +$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/crosstraffic.xml ${srcdir}/crosstraffic_d.xml --cfg=network/model:ns-3 --cfg=network/crosstraffic:1 +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/crosstraffic' to '1' +> [C1:worker:(2) 1.236600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1 +> [C1:worker:(4) 2.150800] [s4u_test/INFO] FLOW[2] : Receive 10000 bytes from S1 to C1 +> [C1:worker:(6) 3.197000] [s4u_test/INFO] FLOW[3] : Receive 10000 bytes from S1 to C1 +> [S1:worker:(8) 3.537400] [s4u_test/INFO] FLOW[4] : Receive 10000 bytes from C1 to S1 diff --git a/examples/cpp/network-ns3/s4u-network-ns3.cpp b/examples/cpp/network-ns3/s4u-network-ns3.cpp index ae6b990f15..e1c8b39399 100644 --- a/examples/cpp/network-ns3/s4u-network-ns3.cpp +++ b/examples/cpp/network-ns3/s4u-network-ns3.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,11 +10,18 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example"); namespace sg4 = simgrid::s4u; -double start_time; -std::unordered_map workernames; -std::unordered_map masternames; +struct MasterWorkerNames { + std::string master; + std::string worker; +}; +using MasterWorkerNamesMap = std::unordered_map; -static void master(std::vector args) +struct Payload { + double msg_size; + double start_time; +}; + +static void master(MasterWorkerNamesMap& names, const std::vector& args) { xbt_assert(args.size() == 4, "Strange number of arguments expected 3 got %zu", args.size() - 1); @@ -24,23 +31,18 @@ static void master(std::vector args) double msg_size = std::stod(args[1]); int id = std::stoi(args[3]); // unique id to control statistics - /* worker name */ - workernames[id] = args[2]; + /* master and worker names */ + names.try_emplace(id, MasterWorkerNames{sg4::Host::current()->get_name(), args[2]}); sg4::Mailbox* mbox = sg4::Mailbox::by_name(args[3]); - masternames[id] = sg4::Host::current()->get_name(); - - auto* payload = new double(msg_size); - - /* time measurement */ - start_time = sg4::Engine::get_clock(); + auto* payload = new Payload{msg_size, sg4::Engine::get_clock()}; mbox->put(payload, static_cast(msg_size)); XBT_DEBUG("Finished"); } -static void worker(std::vector args) +static void worker(const MasterWorkerNamesMap& names, const std::vector& args) { xbt_assert(args.size() == 2, "Strange number of arguments expected 1 got %zu", args.size() - 1); @@ -49,12 +51,12 @@ static void worker(std::vector args) XBT_DEBUG("Worker started"); - auto payload = mbox->get_unique(); + auto payload = mbox->get_unique(); - double elapsed_time = sg4::Engine::get_clock() - start_time; + double elapsed_time = sg4::Engine::get_clock() - payload->start_time; - XBT_INFO("FLOW[%d] : Receive %.0f bytes from %s to %s", id, *payload, masternames.at(id).c_str(), - workernames.at(id).c_str()); + XBT_INFO("FLOW[%d] : Receive %.0f bytes from %s to %s", id, payload->msg_size, names.at(id).master.c_str(), + names.at(id).worker.c_str()); XBT_DEBUG("FLOW[%d] : transferred in %f seconds", id, elapsed_time); XBT_DEBUG("Finished"); @@ -70,8 +72,9 @@ int main(int argc, char* argv[]) e.load_platform(argv[1]); - e.register_function("master", master); - e.register_function("worker", worker); + MasterWorkerNamesMap master_worker_names; + e.register_function("master", [&master_worker_names](auto args) { master(master_worker_names, args); }); + e.register_function("worker", [&master_worker_names](auto args) { worker(master_worker_names, args); }); e.load_deployment(argv[2]); diff --git a/examples/cpp/network-wifi/s4u-network-wifi.cpp b/examples/cpp/network-wifi/s4u-network-wifi.cpp index e02106162d..13eae66730 100644 --- a/examples/cpp/network-wifi/s4u-network-wifi.cpp +++ b/examples/cpp/network-wifi/s4u-network-wifi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -35,14 +35,14 @@ int main(int argc, char* argv[]) e.load_platform(argv[1]); /* Exchange a message between the 2 stations */ - auto mailbox = sg4::Mailbox::by_name("mailbox"); - auto station1 = e.host_by_name("Station 1"); - auto station2 = e.host_by_name("Station 2"); + auto* mailbox = sg4::Mailbox::by_name("mailbox"); + auto* station1 = e.host_by_name("Station 1"); + auto* station2 = e.host_by_name("Station 2"); sg4::Actor::create("sender", station1, sender, mailbox, 1e7); sg4::Actor::create("receiver", station2, receiver, mailbox); /* Declare that the stations are not at the same distance from their AP */ - auto ap = e.link_by_name("AP1"); + const auto* ap = e.link_by_name("AP1"); ap->set_host_wifi_rate(station1, 1); // The host "Station 1" uses the second level of bandwidths on that AP ap->set_host_wifi_rate(station2, 0); // This is perfectly useless as level 0 is used by default diff --git a/examples/cpp/comm-serialize/s4u-comm-serialize.cpp b/examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.cpp similarity index 62% rename from examples/cpp/comm-serialize/s4u-comm-serialize.cpp rename to examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.cpp index 4c81a75aea..1e637ffab2 100644 --- a/examples/cpp/comm-serialize/s4u-comm-serialize.cpp +++ b/examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.cpp @@ -1,18 +1,14 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -/* This example shows how to serialize a set of communications going through a link +/* This example shows how to serialize a set of communications going through a link using Link::set_concurrency_limit() * - * As for the other asynchronous examples, the sender initiates all the messages it wants to send and - * pack the resulting simgrid::s4u::CommPtr objects in a vector. - * At the same time, the receiver starts receiving all messages asynchronously. Without serialization, - * all messages would be received at the same timestamp in the receiver. - * - * However, as they will be serialized in a link of the platform, the messages arrive 2 by 2. - * - * The sender then blocks until all ongoing communication terminate, using simgrid::s4u::Comm::wait_all() + * This example is very similar to the other asynchronous communication examples, but messages get serialized by the platform. + * Without this call to Link::set_concurrency_limit(2) in main, all messages would be received at the exact same timestamp since + * they are initiated at the same instant and are of the same size. But with this extra configuration to the link, at most 2 + * messages can travel through the link at the same time. */ #include "simgrid/s4u.hpp" @@ -30,16 +26,16 @@ public: void operator()() const { // sphinx-doc: init-begin (this line helps the doc to build; ignore it) - /* Vector in which we store all ongoing communications */ - std::vector pending_comms; + /* ActivitySet in which we store all ongoing communications */ + sg4::ActivitySet pending_comms; - /* Make a vector of the mailboxes to use */ + /* Mailbox to use */ sg4::Mailbox* mbox = sg4::Mailbox::by_name("receiver"); // sphinx-doc: init-end /* Start dispatching all messages to receiver */ for (int i = 0; i < messages_count; i++) { - std::string msg_content = std::string("Message ") + std::to_string(i); + std::string msg_content = "Message " + std::to_string(i); // Copy the data we send: the 'msg_content' variable is not a stable storage location. // It will be destroyed when this actor leaves the loop, ie before the receiver gets it auto* payload = new std::string(msg_content); @@ -48,13 +44,13 @@ public: /* Create a communication representing the ongoing communication, and store it in pending_comms */ sg4::CommPtr comm = mbox->put_async(payload, msg_size); - pending_comms.push_back(comm); + pending_comms.push(comm); } XBT_INFO("Done dispatching all messages"); /* Now that all message exchanges were initiated, wait for their completion in one single call */ - sg4::Comm::wait_all(pending_comms); + pending_comms.wait_all(); // sphinx-doc: put-end XBT_INFO("Goodbye now!"); @@ -70,23 +66,28 @@ public: explicit Receiver(int count) : messages_count(count) { mbox = sg4::Mailbox::by_name("receiver"); } void operator()() { - /* Vector in which we store all incoming msgs */ - std::vector> pending_msgs; - std::vector pending_comms; + /* Where we store all incoming msgs */ + std::unordered_map> pending_msgs; + sg4::ActivitySet pending_comms; XBT_INFO("Wait for %d messages asynchronously", messages_count); for (int i = 0; i < messages_count; i++) { - pending_msgs.push_back(std::make_unique()); - pending_comms.emplace_back(mbox->get_async(pending_msgs[i].get())); + std::shared_ptr msg =std::make_shared(); + auto comm = mbox->get_async(msg.get()); + pending_comms.push(comm); + pending_msgs.insert({comm, msg}); } + while (not pending_comms.empty()) { - ssize_t index = sg4::Comm::wait_any(pending_comms); - std::string* msg = *pending_msgs[index]; - XBT_INFO("I got '%s'.", msg->c_str()); - /* cleanup memory and remove from vectors */ - delete msg; - pending_comms.erase(pending_comms.begin() + index); - pending_msgs.erase(pending_msgs.begin() + index); + auto completed_one = pending_comms.wait_any(); + if (completed_one != nullptr){ + auto comm = boost::dynamic_pointer_cast(completed_one); + auto msg = *pending_msgs[comm]; + XBT_INFO("I got '%s'.", msg->c_str()); + /* cleanup memory and remove from map */ + delete msg; + pending_msgs.erase(comm); + } } } }; @@ -108,8 +109,7 @@ int main(int argc, char* argv[]) zone->create_split_duplex_link("link1", 10e9)->set_latency(10e-6)->set_concurrency_limit(2)->seal(); /* create routes between nodes */ - zone->add_route(sender->get_netpoint(), receiver->get_netpoint(), nullptr, nullptr, - {{link, sg4::LinkInRoute::Direction::UP}}, true); + zone->add_route(sender, receiver, {link}); zone->seal(); /* create actors Sender/Receiver */ diff --git a/examples/cpp/comm-serialize/s4u-comm-serialize.tesh b/examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.tesh similarity index 94% rename from examples/cpp/comm-serialize/s4u-comm-serialize.tesh rename to examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.tesh index dee2d01923..3c88222a91 100644 --- a/examples/cpp/comm-serialize/s4u-comm-serialize.tesh +++ b/examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.tesh @@ -1,6 +1,6 @@ #!/usr/bin/env tesh -$ ${bindir:=.}/s4u-comm-serialize "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" +$ ${bindir:=.}/s4u-platform-comm-serialize "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (1:receiver@receiver) Wait for 10 messages asynchronously > [ 0.000000] (2:sender@sender) Send 'Message 0' to 'receiver' > [ 0.000000] (2:sender@sender) Send 'Message 1' to 'receiver' diff --git a/examples/cpp/platform-failures/s4u-platform-failures.cpp b/examples/cpp/platform-failures/s4u-platform-failures.cpp index c728cd3536..f622d905ad 100644 --- a/examples/cpp/platform-failures/s4u-platform-failures.cpp +++ b/examples/cpp/platform-failures/s4u-platform-failures.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -38,7 +38,7 @@ static void master(std::vector args) XBT_INFO("Got %ld workers and %ld tasks to process", workers_count, number_of_tasks); for (int i = 0; i < number_of_tasks; i++) { - mailbox = sg4::Mailbox::by_name(std::string("worker-") + std::to_string(i % workers_count)); + mailbox = sg4::Mailbox::by_name("worker-" + std::to_string(i % workers_count)); auto* payload = new double(comp_size); try { XBT_INFO("Send a message to %s", mailbox->get_cname()); @@ -56,7 +56,7 @@ static void master(std::vector args) XBT_INFO("All tasks have been dispatched. Let's tell everybody the computation is over."); for (int i = 0; i < workers_count; i++) { /* - Eventually tell all the workers to stop by sending a "finalize" task */ - mailbox = sg4::Mailbox::by_name(std::string("worker-") + std::to_string(i)); + mailbox = sg4::Mailbox::by_name("worker-" + std::to_string(i)); auto* payload = new double(-1.0); try { mailbox->put(payload, 0, 1.0); @@ -76,7 +76,7 @@ static void worker(std::vector args) { xbt_assert(args.size() == 2, "Expecting one parameter"); long id = std::stol(args[1]); - sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::string("worker-") + std::to_string(id)); + sg4::Mailbox* mailbox = sg4::Mailbox::by_name("worker-" + std::to_string(id)); while (true) { try { XBT_INFO("Waiting a message on %s", mailbox->get_cname()); @@ -118,8 +118,8 @@ int main(int argc, char* argv[]) // Add a new host programatically, and attach a state profile to it auto* root = e.get_netzone_root(); auto* lilibeth = root->create_host("Lilibeth", 1e15); - auto link = sg4::LinkInRoute(e.link_by_name("10")); - root->add_route(e.host_by_name("Tremblay")->get_netpoint(), lilibeth->get_netpoint(), nullptr, nullptr, {link}, true); + auto link = e.link_by_name("10"); + root->add_route(e.host_by_name("Tremblay"), lilibeth, {link}); lilibeth->set_state_profile(simgrid::kernel::profile::ProfileBuilder::from_string("lilibeth_profile", R"( 4 0 5 1 diff --git a/examples/cpp/platform-failures/s4u-platform-failures.tesh b/examples/cpp/platform-failures/s4u-platform-failures.tesh index 8a7311f26f..2369ec0351 100644 --- a/examples/cpp/platform-failures/s4u-platform-failures.tesh +++ b/examples/cpp/platform-failures/s4u-platform-failures.tesh @@ -3,7 +3,7 @@ p Testing a simple master/worker example application handling failures TCP crosstraffic DISABLED ! output sort 19 -$ ${bindir:=.}/s4u-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/s4u-platform-failures_d.xml --cfg=path:${srcdir} --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose +$ ${bindir:=.}/s4u-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/s4u-platform-failures_d.xml --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose > [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard' > [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off. > [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process @@ -123,7 +123,7 @@ $ ${bindir:=.}/s4u-platform-failures --log=xbt_cfg.thres:critical --log=no_loc $ p Testing a simple master/worker example application handling failures. TCP crosstraffic ENABLED ! output sort 19 -$ ${bindir:=.}/s4u-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/s4u-platform-failures_d.xml --cfg=path:${srcdir} "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose +$ ${bindir:=.}/s4u-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/s4u-platform-failures_d.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose > [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard' > [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off. > [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process diff --git a/examples/cpp/platform-profile/s4u-platform-profile.cpp b/examples/cpp/platform-profile/s4u-platform-profile.cpp index 5e3602a8d1..f5455db479 100644 --- a/examples/cpp/platform-profile/s4u-platform-profile.cpp +++ b/examples/cpp/platform-profile/s4u-platform-profile.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -26,7 +26,7 @@ static void watcher() std::string path; for (const auto* l : links) - path += (path.empty() ? "" : ", ") + std::string("link '") + l->get_name() + std::string("'"); + path += std::string(path.empty() ? "" : ", ") + "link '" + l->get_name() + "'"; XBT_INFO("Path from Jupiter to Fafard: %s (latency: %fs).", path.c_str(), lat); for (int i = 0; i < 10; i++) { diff --git a/examples/cpp/platform-properties/s4u-platform-properties.cpp b/examples/cpp/platform-properties/s4u-platform-properties.cpp index 05de2f310e..ee12e6dc5c 100644 --- a/examples/cpp/platform-properties/s4u-platform-properties.cpp +++ b/examples/cpp/platform-properties/s4u-platform-properties.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/plugin-host-load/s4u-plugin-host-load.cpp b/examples/cpp/plugin-host-load/s4u-plugin-host-load.cpp index 09d69eedd8..c981c691e9 100644 --- a/examples/cpp/plugin-host-load/s4u-plugin-host-load.cpp +++ b/examples/cpp/plugin-host-load/s4u-plugin-host-load.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/plugin-jbod/s4u-plugin-jbod.cpp b/examples/cpp/plugin-jbod/s4u-plugin-jbod.cpp new file mode 100644 index 0000000000..bb3b20b171 --- /dev/null +++ b/examples/cpp/plugin-jbod/s4u-plugin-jbod.cpp @@ -0,0 +1,87 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" +#include "simgrid/plugins/jbod.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(jbod_test, "Messages specific for this simulation"); +namespace sg4 = simgrid::s4u; + +static void write_then_read(simgrid::plugin::JbodPtr jbod) +{ + simgrid::plugin::JbodIoPtr io = jbod->write_async(1e7); + XBT_INFO("asynchronous write posted, wait for it"); + io->wait(); + XBT_INFO("asynchronous write done"); + jbod->read(1e7); + XBT_INFO("synchonous read done"); + jbod->write(1e7); + XBT_INFO("synchonous write done"); + io = jbod->read_async(1e7); + XBT_INFO("asynchronous read posted, wait for it"); + io->wait(); + XBT_INFO("asynchonous read done"); + jbod->write(1e7); + XBT_INFO("synchonous write done"); + jbod->read(1e7); + XBT_INFO("synchonous read done"); + jbod->read(1e7); + XBT_INFO("synchonous read done"); +} + +int main(int argc, char** argv) +{ + sg4::Engine e(&argc, argv); + auto* zone = sg4::create_full_zone("zone"); + auto* host = zone->create_host("host", "1Gf"); + // set up link so that data transfer from host to JBOD takes exactly 1 second (without crosstraffic) + auto* link = zone->create_link("link", 1e7/0.97)->set_latency(0); + + auto jbod_raid0 = + simgrid::plugin::Jbod::create_jbod(zone, "jbod_raid0", 1e9, 4, simgrid::plugin::Jbod::RAID::RAID0, 1e7, 5e6); + zone->add_route(host, jbod_raid0->get_controller(), {link}); + + auto jbod_raid1 = + simgrid::plugin::Jbod::create_jbod(zone, "jbod_raid1", 1e9, 4, simgrid::plugin::Jbod::RAID::RAID1, 1e7, 5e6); + zone->add_route(host, jbod_raid1->get_controller(), {link}); + + auto jbod_raid4 = + simgrid::plugin::Jbod::create_jbod(zone, "jbod_raid4", 1e9, 4, simgrid::plugin::Jbod::RAID::RAID4, 1e7, 5e6); + zone->add_route(host, jbod_raid4->get_controller(), {link}); + + auto jbod_raid5 = + simgrid::plugin::Jbod::create_jbod(zone, "jbod_raid5", 1e9, 4, simgrid::plugin::Jbod::RAID::RAID5, 1e7, 5e6); + zone->add_route(host, jbod_raid5->get_controller(), {link}); + + auto jbod_raid6 = + simgrid::plugin::Jbod::create_jbod(zone, "jbod_raid6", 1e9, 4, simgrid::plugin::Jbod::RAID::RAID6, 1e7, 5e6); + zone->add_route(host, jbod_raid6->get_controller(), {link}); + + zone->seal(); + + XBT_INFO("XXXXXXXXXXXXXXX RAID 0 XXXXXXXXXXXXXXXX"); + sg4::Actor::create("", host, write_then_read, jbod_raid0); + e.run(); + + XBT_INFO("XXXXXXXXXXXXXXX RAID 1 XXXXXXXXXXXXXXXX"); + sg4::Actor::create("", host, write_then_read, jbod_raid1); + e.run(); + + XBT_INFO("XXXXXXXXXXXXXXX RAID 4 XXXXXXXXXXXXXXXX"); + sg4::Actor::create("", host, write_then_read, jbod_raid4); + e.run(); + + XBT_INFO("XXXXXXXXXXXXXXX RAID 5 XXXXXXXXXXXXXXXX"); + sg4::Actor::create("", host, write_then_read, jbod_raid5); + e.run(); + + XBT_INFO("XXXXXXXXXXXXXXX RAID 6 XXXXXXXXXXXXXXXX"); + sg4::Actor::create("", host, write_then_read, jbod_raid6); + e.run(); + + XBT_INFO("Simulated time: %g", sg4::Engine::get_clock()); + + return 0; +} diff --git a/examples/cpp/plugin-jbod/s4u-plugin-jbod.tesh b/examples/cpp/plugin-jbod/s4u-plugin-jbod.tesh new file mode 100644 index 0000000000..cfb05a0a25 --- /dev/null +++ b/examples/cpp/plugin-jbod/s4u-plugin-jbod.tesh @@ -0,0 +1,55 @@ +#!/usr/bin/env tesh + +$ ${bindir}/s4u-plugin-jbod --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e%m%n" +> [ 0.000000] Configuration change: Set 'network/crosstraffic' to '0' +> [ 0.000000] XXXXXXXXXXXXXXX RAID 0 XXXXXXXXXXXXXXXX +> [ 0.000000] asynchronous write posted, wait for it +> [ 1.500000] asynchronous write done +> [ 2.750000] synchonous read done +> [ 4.250000] synchonous write done +> [ 4.250000] asynchronous read posted, wait for it +> [ 5.500000] asynchonous read done +> [ 7.000000] synchonous write done +> [ 8.250000] synchonous read done +> [ 9.500000] synchonous read done +> [ 9.500000] XXXXXXXXXXXXXXX RAID 1 XXXXXXXXXXXXXXXX +> [ 9.500000] asynchronous write posted, wait for it +> [ 12.500000] asynchronous write done +> [ 14.500000] synchonous read done +> [ 17.500000] synchonous write done +> [ 17.500000] asynchronous read posted, wait for it +> [ 19.500000] asynchonous read done +> [ 22.500000] synchonous write done +> [ 24.500000] synchonous read done +> [ 26.500000] synchonous read done +> [ 26.500000] XXXXXXXXXXXXXXX RAID 4 XXXXXXXXXXXXXXXX +> [ 26.500000] asynchronous write posted, wait for it +> [ 28.170000] asynchronous write done +> [ 29.503333] synchonous read done +> [ 31.173333] synchonous write done +> [ 31.173333] asynchronous read posted, wait for it +> [ 32.506666] asynchonous read done +> [ 34.176666] synchonous write done +> [ 35.510000] synchonous read done +> [ 36.843333] synchonous read done +> [ 36.843333] XXXXXXXXXXXXXXX RAID 5 XXXXXXXXXXXXXXXX +> [ 36.843333] asynchronous write posted, wait for it +> [ 38.513333] asynchronous write done +> [ 39.846666] synchonous read done +> [ 41.516666] synchonous write done +> [ 41.516666] asynchronous read posted, wait for it +> [ 42.849999] asynchonous read done +> [ 44.519999] synchonous write done +> [ 45.853333] synchonous read done +> [ 47.186666] synchonous read done +> [ 47.186666] XXXXXXXXXXXXXXX RAID 6 XXXXXXXXXXXXXXXX +> [ 47.186666] asynchronous write posted, wait for it +> [ 50.186666] asynchronous write done +> [ 51.686666] synchonous read done +> [ 54.686666] synchonous write done +> [ 54.686666] asynchronous read posted, wait for it +> [ 56.186666] asynchonous read done +> [ 59.186666] synchonous write done +> [ 60.686666] synchonous read done +> [ 62.186666] synchonous read done +> [ 62.186666] Simulated time: 62.1867 \ No newline at end of file diff --git a/examples/cpp/plugin-link-load/s4u-plugin-link-load.cpp b/examples/cpp/plugin-link-load/s4u-plugin-link-load.cpp index 37b0f82166..5f962a1854 100644 --- a/examples/cpp/plugin-link-load/s4u-plugin-link-load.cpp +++ b/examples/cpp/plugin-link-load/s4u-plugin-link-load.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,14 +11,14 @@ namespace sg4 = simgrid::s4u; static void sender(const std::string& mailbox, uint64_t msg_size) { - auto mbox = sg4::Mailbox::by_name(mailbox); + auto* mbox = sg4::Mailbox::by_name(mailbox); static int payload = 42; mbox->put(&payload, msg_size); } static void receiver(const std::string& mailbox) { - auto mbox = sg4::Mailbox::by_name(mailbox); + auto* mbox = sg4::Mailbox::by_name(mailbox); mbox->get(); } @@ -31,8 +31,8 @@ static void run_transfer(sg4::Host* src_host, sg4::Host* dst_host, const std::st static void execute_load_test() { - auto host0 = sg4::Host::by_name("node-0.simgrid.org"); - auto host1 = sg4::Host::by_name("node-1.simgrid.org"); + auto* host0 = sg4::Host::by_name("node-0.simgrid.org"); + auto* host1 = sg4::Host::by_name("node-1.simgrid.org"); sg4::this_actor::sleep_for(1); run_transfer(host0, host1, "1", 1000 * 1000 * 1000); @@ -52,9 +52,9 @@ static void show_link_load(const std::string& link_name, const sg4::Link* link) static void monitor() { - auto link_backbone = sg4::Link::by_name("cluster0_backbone"); - auto link_host0 = sg4::Link::by_name("cluster0_link_0_UP"); - auto link_host1 = sg4::Link::by_name("cluster0_link_1_DOWN"); + const auto* link_backbone = sg4::Link::by_name("cluster0_backbone"); + const auto* link_host0 = sg4::Link::by_name("cluster0_link_0_UP"); + const auto* link_host1 = sg4::Link::by_name("cluster0_link_1_DOWN"); XBT_INFO("Tracking desired links"); sg_link_load_track(link_backbone); diff --git a/examples/cpp/plugin-prodcons/s4u-plugin-prodcons.cpp b/examples/cpp/plugin-prodcons/s4u-plugin-prodcons.cpp index 6ef625f8aa..8d1ceeb12a 100644 --- a/examples/cpp/plugin-prodcons/s4u-plugin-prodcons.cpp +++ b/examples/cpp/plugin-prodcons/s4u-plugin-prodcons.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -58,19 +58,16 @@ int main(int argc, char* argv[]) // Platform creation auto* cluster = sg4::create_star_zone("cluster"); for (int i = 0; i < 8; i++) { - std::string hostname = std::string("node-") + std::to_string(i) + ".simgrid.org"; + std::string hostname = "node-" + std::to_string(i) + ".simgrid.org"; const auto* host = cluster->create_host(hostname, "1Gf"); - std::string linkname = std::string("cluster") + "_link_" + std::to_string(i); + std::string linkname = "cluster_link_" + std::to_string(i); const auto* link = cluster->create_split_duplex_link(linkname, "1Gbps"); - cluster->add_route(host->get_netpoint(), nullptr, nullptr, nullptr, {{link, sg4::LinkInRoute::Direction::UP}}, - true); + cluster->add_route(host, nullptr, {{link, sg4::LinkInRoute::Direction::UP}}, true); } - - auto* router = cluster->create_router("cluster_router"); - cluster->add_route(router, nullptr, nullptr, nullptr, {}); + cluster->seal(); simgrid::plugin::ProducerConsumerPtr pc = simgrid::plugin::ProducerConsumer::create(2); @@ -78,10 +75,10 @@ int main(int argc, char* argv[]) XBT_INFO("Transfers are done in %s mode", pc->get_transfer_mode().c_str()); for (int i = 0; i < 3; i++) { - std::string hostname = std::string("node-") + std::to_string(i) + ".simgrid.org"; + std::string hostname = "node-" + std::to_string(i) + ".simgrid.org"; sg4::Actor::create("ingester-" + std::to_string(i), e.host_by_name(hostname), &ingester, i, pc); - hostname = std::string("node-") + std::to_string(i + 3) + ".simgrid.org"; + hostname = "node-" + std::to_string(i + 3) + ".simgrid.org"; sg4::Actor::create("retriever-" + std::to_string(i), e.host_by_name(hostname), &retriever, pc); } diff --git a/examples/cpp/replay-comm/s4u-replay-comm.cpp b/examples/cpp/replay-comm/s4u-replay-comm.cpp index e53af5bb3b..d5c8436229 100644 --- a/examples/cpp/replay-comm/s4u-replay-comm.cpp +++ b/examples/cpp/replay-comm/s4u-replay-comm.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -71,7 +71,7 @@ public: static void recv(simgrid::xbt::ReplayAction& action) { double clock = sg4::Engine::get_clock(); - sg4::Mailbox* from = sg4::Mailbox::by_name(std::string(action[2]) + "_" + sg4::this_actor::get_name()); + sg4::Mailbox* from = sg4::Mailbox::by_name(action[2] + "_" + sg4::this_actor::get_name()); ACT_DEBUG("Receiving: %s -- Actor %s on mailbox %s", NAME.c_str(), sg4::this_actor::get_cname(), from->get_cname()); from->get_unique(); diff --git a/examples/cpp/replay-io/s4u-replay-io.cpp b/examples/cpp/replay-io/s4u-replay-io.cpp index 5b586fd012..c09f2ac7a1 100644 --- a/examples/cpp/replay-io/s4u-replay-io.cpp +++ b/examples/cpp/replay-io/s4u-replay-io.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/routing-get-clusters/s4u-routing-get-clusters.cpp b/examples/cpp/routing-get-clusters/s4u-routing-get-clusters.cpp index 751954b33a..636762da41 100644 --- a/examples/cpp/routing-get-clusters/s4u-routing-get-clusters.cpp +++ b/examples/cpp/routing-get-clusters/s4u-routing-get-clusters.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp b/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp new file mode 100644 index 0000000000..624d83ef52 --- /dev/null +++ b/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.cpp @@ -0,0 +1,46 @@ +/* Copyright (c) 2003-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/plugins/solar_panel.hpp" +#include "simgrid/s4u.hpp" +#include + +XBT_LOG_NEW_DEFAULT_CATEGORY(solar_panel_simple, "Messages specific for this s4u example"); + +static void manager() +{ + auto solar_panel = simgrid::plugins::SolarPanel::init("Solar Panel", 10, 0.9, 10, 0, 1e3); + simgrid::s4u::this_actor::sleep_for(1); + XBT_INFO("%s: area: %fm² efficiency: %f irradiance: %fW/m² power: %fW", solar_panel->get_cname(), + solar_panel->get_area(), solar_panel->get_conversion_efficiency(), solar_panel->get_solar_irradiance(), + solar_panel->get_power()); + + solar_panel->set_area(20); + simgrid::s4u::this_actor::sleep_for(1); + XBT_INFO("%s: area: %fm² efficiency: %f irradiance: %fW/m² power: %fW", solar_panel->get_cname(), + solar_panel->get_area(), solar_panel->get_conversion_efficiency(), solar_panel->get_solar_irradiance(), + solar_panel->get_power()); + + solar_panel->set_conversion_efficiency(0.8); + simgrid::s4u::this_actor::sleep_for(1); + XBT_INFO("%s: area: %fm² efficiency: %f irradiance: %fW/m² power: %fW", solar_panel->get_cname(), + solar_panel->get_area(), solar_panel->get_conversion_efficiency(), solar_panel->get_solar_irradiance(), + solar_panel->get_power()); + + solar_panel->set_solar_irradiance(20); + simgrid::s4u::this_actor::sleep_for(1); + XBT_INFO("%s: area: %fm² efficiency: %f irradiance: %fW/m² power: %fW", solar_panel->get_cname(), + solar_panel->get_area(), solar_panel->get_conversion_efficiency(), solar_panel->get_solar_irradiance(), + solar_panel->get_power()); +} + +int main(int argc, char* argv[]) +{ + simgrid::s4u::Engine e(&argc, argv); + e.load_platform(argv[1]); + simgrid::s4u::Actor::create("manager", e.host_by_name("Tremblay"), manager); + e.run(); + return 0; +} diff --git a/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh b/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh new file mode 100644 index 0000000000..53b64dc33f --- /dev/null +++ b/examples/cpp/solar-panel-simple/s4u-solar-panel-simple.tesh @@ -0,0 +1,7 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-solar-panel-simple ${platfdir}/small_platform.xml +> [Tremblay:manager:(1) 1.000000] [solar_panel_simple/INFO] Solar Panel: area: 10.000000m² efficiency: 0.900000 irradiance: 10.000000W/m² power: 90.000000W +> [Tremblay:manager:(1) 2.000000] [solar_panel_simple/INFO] Solar Panel: area: 20.000000m² efficiency: 0.900000 irradiance: 10.000000W/m² power: 180.000000W +> [Tremblay:manager:(1) 3.000000] [solar_panel_simple/INFO] Solar Panel: area: 20.000000m² efficiency: 0.800000 irradiance: 10.000000W/m² power: 160.000000W +> [Tremblay:manager:(1) 4.000000] [solar_panel_simple/INFO] Solar Panel: area: 20.000000m² efficiency: 0.800000 irradiance: 20.000000W/m² power: 320.000000W diff --git a/examples/cpp/synchro-barrier/s4u-mc-synchro-barrier.tesh b/examples/cpp/synchro-barrier/s4u-mc-synchro-barrier.tesh index 2e610e7410..a9ee7cea4d 100644 --- a/examples/cpp/synchro-barrier/s4u-mc-synchro-barrier.tesh +++ b/examples/cpp/synchro-barrier/s4u-mc-synchro-barrier.tesh @@ -1,66 +1,98 @@ #!/usr/bin/env tesh -$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 1 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 1 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" > [Checker] Start a DFS exploration. Reduction is: dpor. -> [Checker] Execute 1: BARRIER_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: BARRIER_WAIT(barrier: 0) (stack depth: 2, state: 2, 0 interleaves) -> [Checker] Execution came to an end at 1;1;0 (state: 3, depth: 3) -> [Checker] Backtracking from 1;1;0 -> [Checker] DFS exploration ended. 3 unique states visited; 1 backtracks (3 transition replays, 0 states visited overall) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: BARRIER_WAIT(barrier: 0) (stack depth: 2, state: 2, 0 interleaves) +> [Checker] 0 actors remain, but none of them need to be interleaved (depth 4). +> [Checker] Execution came to an end at 1;1 (state: 3, depth: 3) +> [Checker] Backtracking from 1;1 +> [Checker] DFS exploration ended. 3 unique states visited; 0 backtracks (0 transition replays, 3 states visited overall) -$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 2 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 2 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" > [Checker] Start a DFS exploration. Reduction is: dpor. -> [Checker] Execute 1: BARRIER_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 2: BARRIER_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves) -> [Checker] Execute 1: BARRIER_WAIT(barrier: 0) (stack depth: 3, state: 3, 0 interleaves) -> [Checker] Execute 2: BARRIER_WAIT(barrier: 0) (stack depth: 4, state: 4, 0 interleaves) -> [Checker] Execution came to an end at 1;2;1;2;0 (state: 5, depth: 5) -> [Checker] Backtracking from 1;2;1;2;0 +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] Sleep set actually containing: +> [Checker] Executed 2: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves) > [Checker] INDEPENDENT Transitions: -> [Checker] BARRIER_WAIT(barrier: 0) (state=3) -> [Checker] BARRIER_WAIT(barrier: 0) (state=4) +> [Checker] #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1) +> [Checker] #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: BARRIER_WAIT(barrier: 0) (stack depth: 3, state: 3, 0 interleaves) > [Checker] Dependent Transitions: -> [Checker] BARRIER_LOCK(barrier: 0) (state=2) -> [Checker] BARRIER_WAIT(barrier: 0) (state=3) +> [Checker] #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2) +> [Checker] #1 BARRIER_WAIT(barrier: 0) (state=3) +> [Checker] Sleep set actually containing: +> [Checker] Executed 2: BARRIER_WAIT(barrier: 0) (stack depth: 4, state: 4, 0 interleaves) > [Checker] INDEPENDENT Transitions: -> [Checker] BARRIER_LOCK(barrier: 0) (state=1) -> [Checker] BARRIER_LOCK(barrier: 0) (state=2) -> [Checker] Backtracking from 1;2 -> [Checker] DFS exploration ended. 5 unique states visited; 2 backtracks (7 transition replays, 1 states visited overall) +> [Checker] #1 BARRIER_WAIT(barrier: 0) (state=3) +> [Checker] #2 BARRIER_WAIT(barrier: 0) (state=4) +> [Checker] Dependent Transitions: +> [Checker] #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1) +> [Checker] #2 BARRIER_WAIT(barrier: 0) (state=4) +> [Checker] 0 actors remain, but none of them need to be interleaved (depth 6). +> [Checker] Execution came to an end at 1;2;1;2 (state: 5, depth: 5) +> [Checker] Backtracking from 1;2;1;2 +> [Checker] Sleep set actually containing: +> [Checker] <1,BARRIER_ASYNC_LOCK(barrier: 0)> +> [Checker] Executed 2: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] 2 actors remain, but none of them need to be interleaved (depth 3). +> [Checker] Backtracking from 2 +> [Checker] DFS exploration ended. 6 unique states visited; 1 backtracks (0 transition replays, 7 states visited overall) -$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 3 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 3 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" > [Checker] Start a DFS exploration. Reduction is: dpor. -> [Checker] Execute 1: BARRIER_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 2: BARRIER_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves) -> [Checker] Execute 3: BARRIER_LOCK(barrier: 0) (stack depth: 3, state: 3, 0 interleaves) -> [Checker] Execute 1: BARRIER_WAIT(barrier: 0) (stack depth: 4, state: 4, 0 interleaves) -> [Checker] Execute 2: BARRIER_WAIT(barrier: 0) (stack depth: 5, state: 5, 0 interleaves) -> [Checker] Execute 3: BARRIER_WAIT(barrier: 0) (stack depth: 6, state: 6, 0 interleaves) -> [Checker] Execution came to an end at 1;2;3;1;2;3;0 (state: 7, depth: 7) -> [Checker] Backtracking from 1;2;3;1;2;3;0 +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] Sleep set actually containing: +> [Checker] Executed 2: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves) > [Checker] INDEPENDENT Transitions: -> [Checker] BARRIER_WAIT(barrier: 0) (state=5) -> [Checker] BARRIER_WAIT(barrier: 0) (state=6) +> [Checker] #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1) +> [Checker] #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2) +> [Checker] Sleep set actually containing: +> [Checker] Executed 3: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 3, state: 3, 0 interleaves) > [Checker] INDEPENDENT Transitions: -> [Checker] BARRIER_WAIT(barrier: 0) (state=4) -> [Checker] BARRIER_WAIT(barrier: 0) (state=6) +> [Checker] #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2) +> [Checker] #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=3) > [Checker] INDEPENDENT Transitions: -> [Checker] BARRIER_WAIT(barrier: 0) (state=4) -> [Checker] BARRIER_WAIT(barrier: 0) (state=5) +> [Checker] #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1) +> [Checker] #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=3) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: BARRIER_WAIT(barrier: 0) (stack depth: 4, state: 4, 0 interleaves) > [Checker] Dependent Transitions: -> [Checker] BARRIER_LOCK(barrier: 0) (state=3) -> [Checker] BARRIER_WAIT(barrier: 0) (state=5) +> [Checker] #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=3) +> [Checker] #1 BARRIER_WAIT(barrier: 0) (state=4) +> [Checker] Sleep set actually containing: +> [Checker] Executed 2: BARRIER_WAIT(barrier: 0) (stack depth: 5, state: 5, 0 interleaves) +> [Checker] INDEPENDENT Transitions: +> [Checker] #1 BARRIER_WAIT(barrier: 0) (state=4) +> [Checker] #2 BARRIER_WAIT(barrier: 0) (state=5) > [Checker] Dependent Transitions: -> [Checker] BARRIER_LOCK(barrier: 0) (state=3) -> [Checker] BARRIER_WAIT(barrier: 0) (state=4) +> [Checker] #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=3) +> [Checker] #2 BARRIER_WAIT(barrier: 0) (state=5) +> [Checker] Sleep set actually containing: +> [Checker] Executed 3: BARRIER_WAIT(barrier: 0) (stack depth: 6, state: 6, 0 interleaves) > [Checker] INDEPENDENT Transitions: -> [Checker] BARRIER_LOCK(barrier: 0) (state=2) -> [Checker] BARRIER_LOCK(barrier: 0) (state=3) +> [Checker] #2 BARRIER_WAIT(barrier: 0) (state=5) +> [Checker] #3 BARRIER_WAIT(barrier: 0) (state=6) > [Checker] INDEPENDENT Transitions: -> [Checker] BARRIER_LOCK(barrier: 0) (state=1) -> [Checker] BARRIER_LOCK(barrier: 0) (state=3) -> [Checker] Backtracking from 1;2;3 +> [Checker] #1 BARRIER_WAIT(barrier: 0) (state=4) +> [Checker] #3 BARRIER_WAIT(barrier: 0) (state=6) +> [Checker] Dependent Transitions: +> [Checker] #2 BARRIER_ASYNC_LOCK(barrier: 0) (state=2) +> [Checker] #3 BARRIER_WAIT(barrier: 0) (state=6) +> [Checker] 0 actors remain, but none of them need to be interleaved (depth 8). +> [Checker] Execution came to an end at 1;2;3;1;2;3 (state: 7, depth: 7) +> [Checker] Backtracking from 1;2;3;1;2;3 +> [Checker] Sleep set actually containing: +> [Checker] <2,BARRIER_ASYNC_LOCK(barrier: 0)> +> [Checker] Executed 3: BARRIER_ASYNC_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves) > [Checker] INDEPENDENT Transitions: -> [Checker] BARRIER_LOCK(barrier: 0) (state=1) -> [Checker] BARRIER_LOCK(barrier: 0) (state=2) -> [Checker] DFS exploration ended. 7 unique states visited; 2 backtracks (10 transition replays, 2 states visited overall) +> [Checker] #1 BARRIER_ASYNC_LOCK(barrier: 0) (state=1) +> [Checker] #3 BARRIER_ASYNC_LOCK(barrier: 0) (state=2) +> [Checker] 3 actors remain, but none of them need to be interleaved (depth 4). +> [Checker] Backtracking from 1;3 +> [Checker] DFS exploration ended. 8 unique states visited; 1 backtracks (1 transition replays, 10 states visited overall) \ No newline at end of file diff --git a/examples/cpp/synchro-barrier/s4u-synchro-barrier.cpp b/examples/cpp/synchro-barrier/s4u-synchro-barrier.cpp index 7c61144c00..07b0b62fd0 100644 --- a/examples/cpp/synchro-barrier/s4u-synchro-barrier.cpp +++ b/examples/cpp/synchro-barrier/s4u-synchro-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,10 +11,10 @@ namespace sg4 = simgrid::s4u; /// Wait on the barrier then leave static void worker(sg4::BarrierPtr barrier) { - XBT_INFO("Waiting on the barrier"); - barrier->wait(); + XBT_INFO("Waiting on the barrier"); + barrier->wait(); - XBT_INFO("Bye"); + XBT_INFO("Bye"); } /// Spawn actor_count-1 workers and do a barrier with them @@ -27,10 +27,10 @@ static void master(int actor_count) sg4::Actor::create("worker", sg4::Host::by_name("Jupiter"), worker, barrier); } - XBT_INFO("Waiting on the barrier"); - barrier->wait(); + XBT_INFO("Waiting on the barrier"); + barrier->wait(); - XBT_INFO("Bye"); + XBT_INFO("Bye"); } int main(int argc, char **argv) diff --git a/examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.cpp b/examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.cpp index e64a76b429..b660bf39fe 100644 --- a/examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.cpp +++ b/examples/cpp/synchro-condition-variable-waituntil/s4u-synchro-condition-variable-waituntil.cpp @@ -1,53 +1,49 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include /* std::mutex and std::lock_guard */ +#include /* std::mutex and std::scoped_lock */ #include /* All of S4U */ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category"); namespace sg4 = simgrid::s4u; -sg4::MutexPtr mtx = nullptr; -sg4::ConditionVariablePtr cv = nullptr; -bool ready = false; - -static void competitor(int id) +static void competitor(int id, sg4::ConditionVariablePtr cv, sg4::MutexPtr mtx, std::shared_ptr ready) { XBT_INFO("Entering the race..."); - std::unique_lock lck(*mtx); - while (not ready) { + std::unique_lock lock(*mtx); + while (not *ready) { auto now = sg4::Engine::get_clock(); - if (cv->wait_until(lck, now + (id+1)*0.25) == std::cv_status::timeout) { + if (cv->wait_until(lock, now + (id + 1) * 0.25) == std::cv_status::timeout) { XBT_INFO("Out of wait_until (timeout)"); - } - else { + } else { XBT_INFO("Out of wait_until (YAY!)"); } } XBT_INFO("Running!"); } -static void go() +static void go(sg4::ConditionVariablePtr cv, sg4::MutexPtr mtx, std::shared_ptr ready) { XBT_INFO("Are you ready? ..."); sg4::this_actor::sleep_for(3); - std::unique_lock lck(*mtx); + const std::scoped_lock lock(*mtx); XBT_INFO("Go go go!"); - ready = true; + *ready = true; cv->notify_all(); } static void main_actor() { - mtx = sg4::Mutex::create(); - cv = sg4::ConditionVariable::create(); + auto mtx = sg4::Mutex::create(); + auto cv = sg4::ConditionVariable::create(); + auto ready = std::make_shared(false); - auto host = sg4::this_actor::get_host(); + auto* host = sg4::this_actor::get_host(); for (int i = 0; i < 10; ++i) - sg4::Actor::create("competitor", host, competitor, i); - sg4::Actor::create("go", host, go); + sg4::Actor::create("competitor", host, competitor, i, cv, mtx, ready); + sg4::Actor::create("go", host, go, cv, mtx, ready); } int main(int argc, char* argv[]) diff --git a/examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp b/examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp index 3602e1dd3c..b471b658d8 100644 --- a/examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp +++ b/examples/cpp/synchro-condition-variable/s4u-synchro-condition-variable.cpp @@ -1,23 +1,20 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include /* std::mutex and std::lock_guard */ +#include /* std::mutex and std::scoped_lock */ #include /* All of S4U */ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category"); namespace sg4 = simgrid::s4u; -std::string data; -bool done = false; - -static void worker_fun(sg4::ConditionVariablePtr cv, sg4::MutexPtr mutex) +static void worker_fun(sg4::ConditionVariablePtr cv, sg4::MutexPtr mutex, std::string& data, bool& done) { - std::unique_lock lock(*mutex); + const std::scoped_lock lock(*mutex); XBT_INFO("Start processing data which is '%s'.", data.c_str()); - data += std::string(" after processing"); + data += " after processing"; // Send data back to main() XBT_INFO("Signal to master that the data processing is completed, and exit."); @@ -30,11 +27,14 @@ static void master_fun() { auto mutex = sg4::Mutex::create(); auto cv = sg4::ConditionVariable::create(); - data = std::string("Example data"); - auto worker = sg4::Actor::create("worker", sg4::Host::by_name("Jupiter"), worker_fun, cv, mutex); + std::string data = "Example data"; + bool done = false; + + auto worker = sg4::Actor::create("worker", sg4::Host::by_name("Jupiter"), worker_fun, cv, mutex, std::ref(data), + std::ref(done)); // wait for the worker - cv->wait(std::unique_lock(*mutex), []() { return done; }); + cv->wait(std::unique_lock(*mutex), [&done]() { return done; }); XBT_INFO("data is now '%s'.", data.c_str()); worker->join(); diff --git a/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh b/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh index e7dedc4a2f..26f7e203c4 100644 --- a/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh +++ b/examples/cpp/synchro-mutex/s4u-mc-synchro-mutex.tesh @@ -2,225 +2,84 @@ p This file tests the dependencies between MUTEX transitions -$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:1 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" -> [Checker] Start a DFS exploration. Reduction is: dpor. +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:1 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" > [App ] Configuration change: Set 'actors' to '1' -> [Checker] Execute 1: MUTEX_LOCK(mutex: 0, owner:1) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner:1) (stack depth: 2, state: 2, 0 interleaves) -> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 3, state: 3, 0 interleaves) -> [Checker] Execute 2: MUTEX_LOCK(mutex: 0, owner:2) (stack depth: 4, state: 4, 0 interleaves) -> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner:2) (stack depth: 5, state: 5, 0 interleaves) -> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 6, state: 6, 0 interleaves) -> [Checker] Execution came to an end at 1;1;1;2;2;2;0 (state: 7, depth: 7) -> [Checker] Backtracking from 1;1;1;2;2;2;0 -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=3) -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=4) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=2) -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=4) -> [Checker] Dependent Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:1) (state=1) -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=4) -> [Checker] Execute 2: MUTEX_LOCK(mutex: 0, owner:2) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: MUTEX_LOCK(mutex: 0, owner:2) (stack depth: 2, state: 8, 0 interleaves) -> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner:2) (stack depth: 3, state: 9, 0 interleaves) -> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner:1) (stack depth: 4, state: 10, 0 interleaves) -> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner:1) (stack depth: 5, state: 11, 0 interleaves) -> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 6, state: 12, 0 interleaves) -> [Checker] Execution came to an end at 2;1;2;2;1;1;0 (state: 13, depth: 7) -> [Checker] Backtracking from 2;1;2;2;1;1;0 -> [Checker] Dependent Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:1) (state=10) -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=11) -> [Checker] Backtracking from 2;1;2;2 -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=8) -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=9) -> [Checker] Dependent Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=1) -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=8) -> [Checker] DFS exploration ended. 13 unique states visited; 3 backtracks (18 transition replays, 3 states visited overall) - -$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:2 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" > [Checker] Start a DFS exploration. Reduction is: dpor. -> [App ] Configuration change: Set 'actors' to '2' -> [Checker] Execute 1: MUTEX_LOCK(mutex: 0, owner:1) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner:1) (stack depth: 2, state: 2, 0 interleaves) -> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 3, state: 3, 0 interleaves) -> [Checker] Execute 2: MUTEX_LOCK(mutex: 0, owner:2) (stack depth: 4, state: 4, 0 interleaves) -> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner:2) (stack depth: 5, state: 5, 0 interleaves) -> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 6, state: 6, 0 interleaves) -> [Checker] Execute 3: MUTEX_LOCK(mutex: 1, owner:3) (stack depth: 7, state: 7, 0 interleaves) -> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner:3) (stack depth: 8, state: 8, 0 interleaves) -> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 9, state: 9, 0 interleaves) -> [Checker] Execute 4: MUTEX_LOCK(mutex: 1, owner:4) (stack depth: 10, state: 10, 0 interleaves) -> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner:4) (stack depth: 11, state: 11, 0 interleaves) -> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 12, state: 12, 0 interleaves) -> [Checker] Execution came to an end at 1;1;1;2;2;2;3;3;3;4;4;4;0 (state: 13, depth: 13) -> [Checker] Backtracking from 1;1;1;2;2;2;3;3;3;4;4;4;0 -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 1, owner:-1) (state=9) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=10) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 1, owner:3) (state=8) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=10) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: MUTEX_WAIT(mutex: 0, owner: 1) (stack depth: 2, state: 2, 0 interleaves) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 3, state: 3, 0 interleaves) +> [Checker] Sleep set actually containing: +> [Checker] Executed 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 4, state: 4, 0 interleaves) +> [Checker] INDEPENDENT Transitions: +> [Checker] #1 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3) +> [Checker] #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4) +> [Checker] INDEPENDENT Transitions: +> [Checker] #1 MUTEX_WAIT(mutex: 0, owner: 1) (state=2) +> [Checker] #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4) > [Checker] Dependent Transitions: -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=7) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=10) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=6) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=5) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=4) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=3) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=2) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:1) (state=1) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=7) -> [Checker] Execute 4: MUTEX_LOCK(mutex: 1, owner:4) (stack depth: 7, state: 7, 0 interleaves) -> [Checker] Execute 3: MUTEX_LOCK(mutex: 1, owner:4) (stack depth: 8, state: 14, 0 interleaves) -> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner:4) (stack depth: 9, state: 15, 0 interleaves) -> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner:3) (stack depth: 10, state: 16, 0 interleaves) -> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner:3) (stack depth: 11, state: 17, 0 interleaves) -> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 12, state: 18, 0 interleaves) -> [Checker] Execution came to an end at 1;1;1;2;2;2;4;3;4;4;3;3;0 (state: 19, depth: 13) -> [Checker] Backtracking from 1;1;1;2;2;2;4;3;4;4;3;3;0 +> [Checker] #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1) +> [Checker] #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=4) +> [Checker] Sleep set actually containing: +> [Checker] Executed 2: MUTEX_WAIT(mutex: 0, owner: 2) (stack depth: 5, state: 5, 0 interleaves) > [Checker] Dependent Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 1, owner:3) (state=16) -> [Checker] MUTEX_WAIT(mutex: 1, owner:3) (state=17) -> [Checker] Backtracking from 1;1;1;2;2;2;4;3;4;4 -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=14) -> [Checker] MUTEX_WAIT(mutex: 1, owner:4) (state=15) +> [Checker] #1 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3) +> [Checker] #2 MUTEX_WAIT(mutex: 0, owner: 2) (state=5) +> [Checker] Sleep set actually containing: +> [Checker] Executed 2: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 6, state: 6, 0 interleaves) > [Checker] Dependent Transitions: -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=7) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=14) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=6) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=5) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=4) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=3) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=2) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:1) (state=1) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=7) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=3) -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=4) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=2) -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=4) +> [Checker] #1 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=3) +> [Checker] #2 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=6) +> [Checker] 0 actors remain, but none of them need to be interleaved (depth 8). +> [Checker] Execution came to an end at 1;1;1;2;2;2 (state: 7, depth: 7) +> [Checker] Backtracking from 1;1;1;2;2;2 +> [Checker] Sleep set actually containing: +> [Checker] <1,MUTEX_UNLOCK(mutex: 0, owner: -1)> +> [Checker] Executed 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (stack depth: 3, state: 3, 0 interleaves) +> [Checker] INDEPENDENT Transitions: +> [Checker] #1 MUTEX_WAIT(mutex: 0, owner: 1) (state=2) +> [Checker] #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=3) > [Checker] Dependent Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:1) (state=1) -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=4) -> [Checker] Execute 2: MUTEX_LOCK(mutex: 0, owner:2) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: MUTEX_LOCK(mutex: 0, owner:2) (stack depth: 2, state: 20, 0 interleaves) -> [Checker] Execute 2: MUTEX_WAIT(mutex: 0, owner:2) (stack depth: 3, state: 21, 0 interleaves) -> [Checker] Execute 2: MUTEX_UNLOCK(mutex: 0, owner:1) (stack depth: 4, state: 22, 0 interleaves) -> [Checker] Execute 1: MUTEX_WAIT(mutex: 0, owner:1) (stack depth: 5, state: 23, 0 interleaves) -> [Checker] Execute 1: MUTEX_UNLOCK(mutex: 0, owner:-1) (stack depth: 6, state: 24, 0 interleaves) -> [Checker] Execute 3: MUTEX_LOCK(mutex: 1, owner:3) (stack depth: 7, state: 25, 0 interleaves) -> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner:3) (stack depth: 8, state: 26, 0 interleaves) -> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 9, state: 27, 0 interleaves) -> [Checker] Execute 4: MUTEX_LOCK(mutex: 1, owner:4) (stack depth: 10, state: 28, 0 interleaves) -> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner:4) (stack depth: 11, state: 29, 0 interleaves) -> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 12, state: 30, 0 interleaves) -> [Checker] Execution came to an end at 2;1;2;2;1;1;3;3;3;4;4;4;0 (state: 31, depth: 13) -> [Checker] Backtracking from 2;1;2;2;1;1;3;3;3;4;4;4;0 -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 1, owner:-1) (state=27) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=28) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 1, owner:3) (state=26) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=28) +> [Checker] #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=1) +> [Checker] #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 1) (state=3) +> [Checker] 2 actors remain, but none of them need to be interleaved (depth 5). +> [Checker] Backtracking from 1;1;2 +> [Checker] Sleep set actually containing: +> [Checker] <1,MUTEX_ASYNC_LOCK(mutex: 0, owner: 1)> +> [Checker] Executed 2: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 1, state: 1, 0 interleaves) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (stack depth: 2, state: 9, 0 interleaves) > [Checker] Dependent Transitions: -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=25) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=28) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=24) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=23) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:1) (state=22) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=21) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=20) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=1) -> [Checker] MUTEX_LOCK(mutex: 1, owner:3) (state=25) -> [Checker] Execute 4: MUTEX_LOCK(mutex: 1, owner:4) (stack depth: 7, state: 25, 0 interleaves) -> [Checker] Execute 3: MUTEX_LOCK(mutex: 1, owner:4) (stack depth: 8, state: 32, 0 interleaves) -> [Checker] Execute 4: MUTEX_WAIT(mutex: 1, owner:4) (stack depth: 9, state: 33, 0 interleaves) -> [Checker] Execute 4: MUTEX_UNLOCK(mutex: 1, owner:3) (stack depth: 10, state: 34, 0 interleaves) -> [Checker] Execute 3: MUTEX_WAIT(mutex: 1, owner:3) (stack depth: 11, state: 35, 0 interleaves) -> [Checker] Execute 3: MUTEX_UNLOCK(mutex: 1, owner:-1) (stack depth: 12, state: 36, 0 interleaves) -> [Checker] Execution came to an end at 2;1;2;2;1;1;4;3;4;4;3;3;0 (state: 37, depth: 13) -> [Checker] Backtracking from 2;1;2;2;1;1;4;3;4;4;3;3;0 +> [Checker] #2 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=1) +> [Checker] #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=9) +> [Checker] Sleep set actually containing: +> [Checker] Executed 2: MUTEX_WAIT(mutex: 0, owner: 2) (stack depth: 3, state: 10, 0 interleaves) +> [Checker] INDEPENDENT Transitions: +> [Checker] #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=9) +> [Checker] #2 MUTEX_WAIT(mutex: 0, owner: 2) (state=10) +> [Checker] Sleep set actually containing: +> [Checker] Executed 2: MUTEX_UNLOCK(mutex: 0, owner: 1) (stack depth: 4, state: 11, 0 interleaves) +> [Checker] INDEPENDENT Transitions: +> [Checker] #1 MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) (state=9) +> [Checker] #2 MUTEX_UNLOCK(mutex: 0, owner: 1) (state=11) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: MUTEX_WAIT(mutex: 0, owner: 1) (stack depth: 5, state: 12, 0 interleaves) > [Checker] Dependent Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 1, owner:3) (state=34) -> [Checker] MUTEX_WAIT(mutex: 1, owner:3) (state=35) -> [Checker] Backtracking from 2;1;2;2;1;1;4;3;4;4 -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=32) -> [Checker] MUTEX_WAIT(mutex: 1, owner:4) (state=33) -> [Checker] Dependent Transitions: -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=25) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=32) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:-1) (state=24) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=23) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:1) (state=22) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=21) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=20) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=25) -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=1) -> [Checker] MUTEX_LOCK(mutex: 1, owner:4) (state=25) -> [Checker] Dependent Transitions: -> [Checker] MUTEX_UNLOCK(mutex: 0, owner:1) (state=22) -> [Checker] MUTEX_WAIT(mutex: 0, owner:1) (state=23) -> [Checker] Backtracking from 2;1;2;2 -> [Checker] INDEPENDENT Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=20) -> [Checker] MUTEX_WAIT(mutex: 0, owner:2) (state=21) +> [Checker] #2 MUTEX_UNLOCK(mutex: 0, owner: 1) (state=11) +> [Checker] #1 MUTEX_WAIT(mutex: 0, owner: 1) (state=12) +> [Checker] Sleep set actually containing: +> [Checker] Executed 1: MUTEX_UNLOCK(mutex: 0, owner: -1) (stack depth: 6, state: 13, 0 interleaves) > [Checker] Dependent Transitions: -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=1) -> [Checker] MUTEX_LOCK(mutex: 0, owner:2) (state=20) -> [Checker] DFS exploration ended. 37 unique states visited; 7 backtracks (76 transition replays, 33 states visited overall) +> [Checker] #2 MUTEX_UNLOCK(mutex: 0, owner: 1) (state=11) +> [Checker] #1 MUTEX_UNLOCK(mutex: 0, owner: -1) (state=13) +> [Checker] 0 actors remain, but none of them need to be interleaved (depth 8). +> [Checker] Execution came to an end at 2;1;2;2;1;1 (state: 14, depth: 7) +> [Checker] Backtracking from 2;1;2;2;1;1 +> [Checker] DFS exploration ended. 14 unique states visited; 2 backtracks (2 transition replays, 18 states visited overall) -$ ${bindir:=.}/../../../bin/simgrid-mc -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:3 --log=s4u_test.thres:critical +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:2 --log=s4u_test.thres:critical +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'actors' to '2' > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. -> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'actors' to '3' -> [0.000000] [mc_dfs/INFO] DFS exploration ended. 85 unique states visited; 15 backtracks (240 transition replays, 141 states visited overall) +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 66 unique states visited; 11 backtracks (49 transition replays, 126 states visited overall) diff --git a/examples/cpp/synchro-mutex/s4u-synchro-mutex.cpp b/examples/cpp/synchro-mutex/s4u-synchro-mutex.cpp index a17d574533..241322650e 100644 --- a/examples/cpp/synchro-mutex/s4u-synchro-mutex.cpp +++ b/examples/cpp/synchro-mutex/s4u-synchro-mutex.cpp @@ -1,11 +1,11 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "simgrid/s4u.hpp" /* All of S4U */ #include "xbt/config.hpp" -#include /* std::mutex and std::lock_guard */ +#include /* std::mutex and std::scoped_lock */ namespace sg4 = simgrid::s4u; @@ -29,14 +29,14 @@ static void worker(sg4::MutexPtr mutex, int& result) mutex->unlock(); } -static void workerLockGuard(sg4::MutexPtr mutex, int& result) +static void workerScopedLock(sg4::MutexPtr mutex, int& result) { - // Simply use the std::lock_guard like this + // Simply use the std::scoped_lock like this // It's like a lock() that would do the unlock() automatically when getting out of scope - std::lock_guard lock(*mutex); + const std::scoped_lock lock(*mutex); // then you are in a safe zone - XBT_INFO("Hello s4u, I'm ready to compute after a lock_guard"); + XBT_INFO("Hello s4u, I'm ready to compute after a scoped_lock"); // update the results result += 1; XBT_INFO("I'm done, good bye"); @@ -47,14 +47,14 @@ static void workerLockGuard(sg4::MutexPtr mutex, int& result) int main(int argc, char** argv) { sg4::Engine e(&argc, argv); - e.load_platform("../../platforms/two_hosts.xml"); + e.load_platform(argc > 1 ? argv[1] : "../../platforms/two_hosts.xml"); /* Create the requested amount of actors pairs. Each pair has a specific mutex and cell in `result`. */ std::vector result(cfg_actor_count.get()); for (int i = 0; i < cfg_actor_count; i++) { sg4::MutexPtr mutex = sg4::Mutex::create(); - sg4::Actor::create("worker", sg4::Host::by_name("Jupiter"), workerLockGuard, mutex, std::ref(result[i])); + sg4::Actor::create("worker", sg4::Host::by_name("Jupiter"), workerScopedLock, mutex, std::ref(result[i])); sg4::Actor::create("worker", sg4::Host::by_name("Tremblay"), worker, mutex, std::ref(result[i])); } diff --git a/examples/cpp/synchro-mutex/s4u-synchro-mutex.tesh b/examples/cpp/synchro-mutex/s4u-synchro-mutex.tesh index fbec803310..ca6b4894e8 100644 --- a/examples/cpp/synchro-mutex/s4u-synchro-mutex.tesh +++ b/examples/cpp/synchro-mutex/s4u-synchro-mutex.tesh @@ -1,17 +1,17 @@ #!/usr/bin/env tesh $ ${bindir:=.}/s4u-synchro-mutex -> [Jupiter:worker:(1) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a lock_guard +> [Jupiter:worker:(1) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a scoped_lock > [Jupiter:worker:(1) 0.000000] [s4u_test/INFO] I'm done, good bye -> [Jupiter:worker:(3) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a lock_guard +> [Jupiter:worker:(3) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a scoped_lock > [Jupiter:worker:(3) 0.000000] [s4u_test/INFO] I'm done, good bye -> [Jupiter:worker:(5) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a lock_guard +> [Jupiter:worker:(5) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a scoped_lock > [Jupiter:worker:(5) 0.000000] [s4u_test/INFO] I'm done, good bye -> [Jupiter:worker:(7) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a lock_guard +> [Jupiter:worker:(7) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a scoped_lock > [Jupiter:worker:(7) 0.000000] [s4u_test/INFO] I'm done, good bye -> [Jupiter:worker:(9) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a lock_guard +> [Jupiter:worker:(9) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a scoped_lock > [Jupiter:worker:(9) 0.000000] [s4u_test/INFO] I'm done, good bye -> [Jupiter:worker:(11) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a lock_guard +> [Jupiter:worker:(11) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a scoped_lock > [Jupiter:worker:(11) 0.000000] [s4u_test/INFO] I'm done, good bye > [Tremblay:worker:(2) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a regular lock > [Tremblay:worker:(2) 0.000000] [s4u_test/INFO] I'm done, good bye diff --git a/examples/cpp/synchro-semaphore/s4u-mc-synchro-semaphore.tesh b/examples/cpp/synchro-semaphore/s4u-mc-synchro-semaphore.tesh index d63b175385..65836b113d 100644 --- a/examples/cpp/synchro-semaphore/s4u-mc-synchro-semaphore.tesh +++ b/examples/cpp/synchro-semaphore/s4u-mc-synchro-semaphore.tesh @@ -1,79 +1,5 @@ #!/usr/bin/env tesh -$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-semaphore --log=sem_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:info --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-semaphore --log=sem_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n" > [Checker] Start a DFS exploration. Reduction is: dpor. -> [Checker] Execute 1: SEM_LOCK(semaphore: 0) (stack depth: 1, state: 1, 0 interleaves) -> [Checker] Execute 1: SEM_WAIT(semaphore: 0, granted: yes) (stack depth: 2, state: 2, 0 interleaves) -> [Checker] Execute 1: SEM_UNLOCK(semaphore: 1) (stack depth: 3, state: 3, 0 interleaves) -> [Checker] Execute 1: SEM_LOCK(semaphore: 0) (stack depth: 4, state: 4, 0 interleaves) -> [Checker] Execute 2: SEM_LOCK(semaphore: 1) (stack depth: 5, state: 5, 0 interleaves) -> [Checker] Execute 2: SEM_WAIT(semaphore: 1, granted: yes) (stack depth: 6, state: 6, 0 interleaves) -> [Checker] Execute 2: SEM_UNLOCK(semaphore: 0) (stack depth: 7, state: 7, 0 interleaves) -> [Checker] Execute 1: SEM_WAIT(semaphore: 0, granted: yes) (stack depth: 8, state: 8, 0 interleaves) -> [Checker] Execute 1: SEM_UNLOCK(semaphore: 1) (stack depth: 9, state: 9, 0 interleaves) -> [Checker] Execute 1: SEM_LOCK(semaphore: 0) (stack depth: 10, state: 10, 0 interleaves) -> [Checker] Execute 2: SEM_LOCK(semaphore: 1) (stack depth: 11, state: 11, 0 interleaves) -> [Checker] Execute 2: SEM_WAIT(semaphore: 1, granted: yes) (stack depth: 12, state: 12, 0 interleaves) -> [Checker] Execute 2: SEM_UNLOCK(semaphore: 0) (stack depth: 13, state: 13, 0 interleaves) -> [Checker] Execute 1: SEM_WAIT(semaphore: 0, granted: yes) (stack depth: 14, state: 14, 0 interleaves) -> [Checker] Execute 1: SEM_UNLOCK(semaphore: 1) (stack depth: 15, state: 15, 0 interleaves) -> [Checker] Execute 1: SEM_LOCK(semaphore: 0) (stack depth: 16, state: 16, 0 interleaves) -> [Checker] Execute 2: SEM_LOCK(semaphore: 1) (stack depth: 17, state: 17, 0 interleaves) -> [Checker] Execute 2: SEM_WAIT(semaphore: 1, granted: yes) (stack depth: 18, state: 18, 0 interleaves) -> [Checker] Execute 2: SEM_UNLOCK(semaphore: 0) (stack depth: 19, state: 19, 0 interleaves) -> [Checker] Execute 1: SEM_WAIT(semaphore: 0, granted: yes) (stack depth: 20, state: 20, 0 interleaves) -> [Checker] Execute 1: SEM_UNLOCK(semaphore: 1) (stack depth: 21, state: 21, 0 interleaves) -> [Checker] Execute 2: SEM_LOCK(semaphore: 1) (stack depth: 22, state: 22, 0 interleaves) -> [Checker] Execute 2: SEM_WAIT(semaphore: 1, granted: yes) (stack depth: 23, state: 23, 0 interleaves) -> [Checker] Execute 2: SEM_UNLOCK(semaphore: 0) (stack depth: 24, state: 24, 0 interleaves) -> [Checker] Execution came to an end at 1;1;1;1;2;2;2;1;1;1;2;2;2;1;1;1;2;2;2;1;1;2;2;2;0 (state: 25, depth: 25) -> [Checker] Backtracking from 1;1;1;1;2;2;2;1;1;1;2;2;2;1;1;1;2;2;2;1;1;2;2;2;0 -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_UNLOCK(semaphore: 1) (state=21) -> [Checker] SEM_LOCK(semaphore: 1) (state=22) -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_WAIT(semaphore: 0, granted: yes) (state=20) -> [Checker] SEM_LOCK(semaphore: 1) (state=22) -> [Checker] Dependent Transitions: -> [Checker] SEM_UNLOCK(semaphore: 0) (state=19) -> [Checker] SEM_WAIT(semaphore: 0, granted: yes) (state=20) -> [Checker] Backtracking from 1;1;1;1;2;2;2;1;1;1;2;2;2;1;1;1;2;2;2 -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_LOCK(semaphore: 0) (state=16) -> [Checker] SEM_LOCK(semaphore: 1) (state=17) -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_UNLOCK(semaphore: 1) (state=15) -> [Checker] SEM_LOCK(semaphore: 1) (state=17) -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_WAIT(semaphore: 0, granted: yes) (state=14) -> [Checker] SEM_LOCK(semaphore: 1) (state=17) -> [Checker] Dependent Transitions: -> [Checker] SEM_UNLOCK(semaphore: 0) (state=13) -> [Checker] SEM_WAIT(semaphore: 0, granted: yes) (state=14) -> [Checker] Backtracking from 1;1;1;1;2;2;2;1;1;1;2;2;2 -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_LOCK(semaphore: 0) (state=10) -> [Checker] SEM_LOCK(semaphore: 1) (state=11) -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_UNLOCK(semaphore: 1) (state=9) -> [Checker] SEM_LOCK(semaphore: 1) (state=11) -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_WAIT(semaphore: 0, granted: yes) (state=8) -> [Checker] SEM_LOCK(semaphore: 1) (state=11) -> [Checker] Dependent Transitions: -> [Checker] SEM_UNLOCK(semaphore: 0) (state=7) -> [Checker] SEM_WAIT(semaphore: 0, granted: yes) (state=8) -> [Checker] Backtracking from 1;1;1;1;2;2;2 -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_LOCK(semaphore: 0) (state=4) -> [Checker] SEM_LOCK(semaphore: 1) (state=5) -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_UNLOCK(semaphore: 1) (state=3) -> [Checker] SEM_LOCK(semaphore: 1) (state=5) -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_WAIT(semaphore: 0, granted: yes) (state=2) -> [Checker] SEM_LOCK(semaphore: 1) (state=5) -> [Checker] INDEPENDENT Transitions: -> [Checker] SEM_LOCK(semaphore: 0) (state=1) -> [Checker] SEM_LOCK(semaphore: 1) (state=5) -> [Checker] DFS exploration ended. 25 unique states visited; 4 backtracks (64 transition replays, 36 states visited overall) +> [Checker] DFS exploration ended. 33 unique states visited; 8 backtracks (84 transition replays, 125 states visited overall) diff --git a/examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp b/examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp index 0e708deac4..b9b5e77297 100644 --- a/examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp +++ b/examples/cpp/synchro-semaphore/s4u-synchro-semaphore.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,27 +14,24 @@ namespace sg4 = simgrid::s4u; XBT_LOG_NEW_DEFAULT_CATEGORY(sem_test, "Simple test of the semaphore"); -const char* buffer; /* Where the data is exchanged */ -sg4::SemaphorePtr sem_empty = sg4::Semaphore::create(1); /* indicates whether the buffer is empty */ -sg4::SemaphorePtr sem_full = sg4::Semaphore::create(0); /* indicates whether the buffer is full */ - -static void producer(const std::vector& args) +static void producer(std::string* buffer, sg4::SemaphorePtr sem_empty, sg4::SemaphorePtr sem_full, + const std::vector& args) { for (auto const& str : args) { sem_empty->acquire(); XBT_INFO("Pushing '%s'", str.c_str()); - buffer = str.c_str(); + *buffer = str; sem_full->release(); } XBT_INFO("Bye!"); } -static void consumer() +static void consumer(const std::string* buffer, sg4::SemaphorePtr sem_empty, sg4::SemaphorePtr sem_full) { std::string str; do { sem_full->acquire(); - str = buffer; + str = *buffer; XBT_INFO("Receiving '%s'", str.c_str()); sem_empty->release(); } while (str != ""); @@ -47,8 +44,13 @@ int main(int argc, char **argv) std::vector args({"one", "two", "three", ""}); sg4::Engine e(&argc, argv); e.load_platform(argc > 1 ? argv[1] : "../../platforms/two_hosts.xml"); - sg4::Actor::create("producer", e.host_by_name("Tremblay"), producer, std::cref(args)); - sg4::Actor::create("consumer", e.host_by_name("Jupiter"), consumer); + + std::string buffer; /* Where the data is exchanged */ + auto sem_empty = sg4::Semaphore::create(1); /* indicates whether the buffer is empty */ + auto sem_full = sg4::Semaphore::create(0); /* indicates whether the buffer is full */ + + sg4::Actor::create("producer", e.host_by_name("Tremblay"), producer, &buffer, sem_empty, sem_full, std::cref(args)); + sg4::Actor::create("consumer", e.host_by_name("Jupiter"), consumer, &buffer, sem_empty, sem_full); e.run(); return 0; diff --git a/examples/cpp/task-dispatch/s4u-task-dispatch.cpp b/examples/cpp/task-dispatch/s4u-task-dispatch.cpp new file mode 100644 index 0000000000..10bd0d2364 --- /dev/null +++ b/examples/cpp/task-dispatch/s4u-task-dispatch.cpp @@ -0,0 +1,103 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(task_dispatch, "Messages specific for this s4u example"); +namespace sg4 = simgrid::s4u; + +static void manager(sg4::ExecTaskPtr t) +{ + auto PM0 = sg4::Engine::get_instance()->host_by_name("PM0"); + auto PM1 = sg4::Engine::get_instance()->host_by_name("PM1"); + + XBT_INFO("Test set_flops"); + t->enqueue_firings(2); + sg4::this_actor::sleep_for(50); + XBT_INFO("Set instance_0 flops to 50."); + t->set_flops(50 * PM0->get_speed()); + sg4::this_actor::sleep_for(250); + t->set_flops(100 * PM0->get_speed()); + + XBT_INFO("Test set_parallelism degree"); + t->enqueue_firings(3); + sg4::this_actor::sleep_for(50); + XBT_INFO("Set Task parallelism degree to 2."); + t->set_parallelism_degree(2); + sg4::this_actor::sleep_for(250); + t->set_parallelism_degree(1); + + XBT_INFO("Test set_host dispatcher"); + t->enqueue_firings(2); + sg4::this_actor::sleep_for(50); + XBT_INFO("Move dispatcher to PM1"); + t->set_host(PM1, "dispatcher"); + t->set_internal_bytes(1e6, "dispatcher"); + sg4::this_actor::sleep_for(250); + t->set_host(PM0, "dispatcher"); + + XBT_INFO("Test set_host instance_0"); + t->enqueue_firings(2); + sg4::this_actor::sleep_for(50); + XBT_INFO("Move instance_0 to PM1"); + t->set_host(PM1, "instance_0"); + t->set_flops(100 * PM1->get_speed()); + t->set_internal_bytes(1e6, "instance_0"); + sg4::this_actor::sleep_for(250); + t->set_host(PM0, "instance_0"); + t->set_flops(100 * PM0->get_speed()); + + XBT_INFO("Test set_host collector"); + t->enqueue_firings(2); + sg4::this_actor::sleep_for(50); + XBT_INFO("Move collector to PM1"); + t->set_host(PM1, "collector"); + sg4::this_actor::sleep_for(250); + t->set_host(PM0, "collector"); + + XBT_INFO("Test add_instances"); + t->enqueue_firings(1); + sg4::this_actor::sleep_for(50); + XBT_INFO("Add 1 instance and update load balancing function"); + t->add_instances(1); + t->set_load_balancing_function([]() { + static int round_robin_counter = 0; + int ret = round_robin_counter; + round_robin_counter = round_robin_counter == 1 ? 0 : round_robin_counter + 1; + return "instance_" + std::to_string(ret); + }); + t->enqueue_firings(2); + sg4::this_actor::sleep_for(250); + + XBT_INFO("Test remove_instances"); + XBT_INFO("Remove 1 instance and update load balancing function"); + t->remove_instances(1); + t->set_load_balancing_function([]() { return "instance_0"; }); + t->enqueue_firings(2); + sg4::this_actor::sleep_for(300); +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + auto PM0 = e.host_by_name("PM0"); + auto PM1 = sg4::Engine::get_instance()->host_by_name("PM1"); + + auto a = sg4::ExecTask::init("A", 100 * PM0->get_speed(), PM0); + auto b = sg4::ExecTask::init("B", 50 * PM0->get_speed(), PM0); + auto c = sg4::CommTask::init("C", 1e6, PM1, PM0); + + a->add_successor(b); + + sg4::Task::on_completion_cb( + [](const sg4::Task* t) { XBT_INFO("Task %s finished (%d)", t->get_name().c_str(), t->get_count()); }); + sg4::Task::on_start_cb([](const sg4::Task* t) { XBT_INFO("Task %s start", t->get_name().c_str()); }); + + sg4::Actor::create("manager", PM0, manager, a); + + e.run(); + return 0; +} diff --git a/examples/cpp/task-dispatch/s4u-task-dispatch.tesh b/examples/cpp/task-dispatch/s4u-task-dispatch.tesh new file mode 100644 index 0000000000..a4ace5478a --- /dev/null +++ b/examples/cpp/task-dispatch/s4u-task-dispatch.tesh @@ -0,0 +1,82 @@ +#!/usr/bin/env tesh + +> > $ ${bindir:=.}/s4u-task-parallelism ${platfdir}/three_multicore_hosts.xml +> [PM0:manager:(1) 0.000000] [task_dispatch/INFO] Test set_flops +> [0.000000] [task_dispatch/INFO] Task A start +> [0.000000] [task_dispatch/INFO] Task A start +> [PM0:manager:(1) 50.000000] [task_dispatch/INFO] Set instance_0 flops to 50. +> [100.000000] [task_dispatch/INFO] Task A finished (1) +> [100.000000] [task_dispatch/INFO] Task B start +> [150.000000] [task_dispatch/INFO] Task A finished (2) +> [150.000000] [task_dispatch/INFO] Task B start +> [150.000000] [task_dispatch/INFO] Task B finished (1) +> [200.000000] [task_dispatch/INFO] Task B finished (2) +> [PM0:manager:(1) 300.000000] [task_dispatch/INFO] Test set_parallelism degree +> [300.000000] [task_dispatch/INFO] Task A start +> [300.000000] [task_dispatch/INFO] Task A start +> [300.000000] [task_dispatch/INFO] Task A start +> [PM0:manager:(1) 350.000000] [task_dispatch/INFO] Set Task parallelism degree to 2. +> [400.000000] [task_dispatch/INFO] Task A finished (3) +> [400.000000] [task_dispatch/INFO] Task B start +> [450.000000] [task_dispatch/INFO] Task A finished (4) +> [450.000000] [task_dispatch/INFO] Task B start +> [450.000000] [task_dispatch/INFO] Task B finished (3) +> [500.000000] [task_dispatch/INFO] Task A finished (5) +> [500.000000] [task_dispatch/INFO] Task B start +> [500.000000] [task_dispatch/INFO] Task B finished (4) +> [550.000000] [task_dispatch/INFO] Task B finished (5) +> [PM0:manager:(1) 600.000000] [task_dispatch/INFO] Test set_host dispatcher +> [600.000000] [task_dispatch/INFO] Task A start +> [600.000000] [task_dispatch/INFO] Task A start +> [PM0:manager:(1) 650.000000] [task_dispatch/INFO] Move dispatcher to PM1 +> [700.000000] [task_dispatch/INFO] Task A finished (6) +> [700.000000] [task_dispatch/INFO] Task B start +> [750.000000] [task_dispatch/INFO] Task B finished (6) +> [800.009961] [task_dispatch/INFO] Task A finished (7) +> [800.009961] [task_dispatch/INFO] Task B start +> [850.009961] [task_dispatch/INFO] Task B finished (7) +> [PM0:manager:(1) 900.000000] [task_dispatch/INFO] Test set_host instance_0 +> [900.000000] [task_dispatch/INFO] Task A start +> [900.000000] [task_dispatch/INFO] Task A start +> [PM0:manager:(1) 950.000000] [task_dispatch/INFO] Move instance_0 to PM1 +> [1000.000000] [task_dispatch/INFO] Task A finished (8) +> [1000.000000] [task_dispatch/INFO] Task B start +> [1050.000000] [task_dispatch/INFO] Task B finished (8) +> [1100.019922] [task_dispatch/INFO] Task A finished (9) +> [1100.019922] [task_dispatch/INFO] Task B start +> [1150.019922] [task_dispatch/INFO] Task B finished (9) +> [PM0:manager:(1) 1200.000000] [task_dispatch/INFO] Test set_host collector +> [1200.000000] [task_dispatch/INFO] Task A start +> [1200.000000] [task_dispatch/INFO] Task A start +> [PM0:manager:(1) 1250.000000] [task_dispatch/INFO] Move collector to PM1 +> [1300.000000] [task_dispatch/INFO] Task A finished (10) +> [1300.000000] [task_dispatch/INFO] Task B start +> [1350.000000] [task_dispatch/INFO] Task B finished (10) +> [1400.009961] [task_dispatch/INFO] Task A finished (11) +> [1400.009961] [task_dispatch/INFO] Task B start +> [1450.009961] [task_dispatch/INFO] Task B finished (11) +> [PM0:manager:(1) 1500.000000] [task_dispatch/INFO] Test add_instances +> [1500.000000] [task_dispatch/INFO] Task A start +> [PM0:manager:(1) 1550.000000] [task_dispatch/INFO] Add 1 instance and update load balancing function +> [1550.000000] [task_dispatch/INFO] Task A start +> [1550.000000] [task_dispatch/INFO] Task A start +> [1600.000000] [task_dispatch/INFO] Task A finished (12) +> [1600.000000] [task_dispatch/INFO] Task B start +> [1650.000000] [task_dispatch/INFO] Task A finished (13) +> [1650.000000] [task_dispatch/INFO] Task B start +> [1650.000000] [task_dispatch/INFO] Task B finished (12) +> [1700.000000] [task_dispatch/INFO] Task A finished (14) +> [1700.000000] [task_dispatch/INFO] Task B start +> [1700.000000] [task_dispatch/INFO] Task B finished (13) +> [1750.000000] [task_dispatch/INFO] Task B finished (14) +> [PM0:manager:(1) 1800.000000] [task_dispatch/INFO] Test remove_instances +> [PM0:manager:(1) 1800.000000] [task_dispatch/INFO] Remove 1 instance and update load balancing function +> [1800.000000] [task_dispatch/INFO] Task A start +> [1800.000000] [task_dispatch/INFO] Task A start +> [1900.000000] [task_dispatch/INFO] Task A finished (15) +> [1900.000000] [task_dispatch/INFO] Task B start +> [1950.000000] [task_dispatch/INFO] Task B finished (15) +> [2000.000000] [task_dispatch/INFO] Task A finished (16) +> [2000.000000] [task_dispatch/INFO] Task B start +> [2050.000000] [task_dispatch/INFO] Task B finished (16) +> \ No newline at end of file diff --git a/examples/cpp/task-io/s4u-task-io.cpp b/examples/cpp/task-io/s4u-task-io.cpp new file mode 100644 index 0000000000..c0f6eb0a3b --- /dev/null +++ b/examples/cpp/task-io/s4u-task-io.cpp @@ -0,0 +1,53 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example demonstrate basic use of tasks. + * + * We model the following graph: + * + * exec1 -> comm -> exec2 + * + * exec1 and exec2 are execution tasks. + * comm is a communication task. + */ + +#include "simgrid/s4u.hpp" +#include "simgrid/s4u/Task.hpp" +#include + +XBT_LOG_NEW_DEFAULT_CATEGORY(task_simple, "Messages specific for this task example"); +namespace sg4 = simgrid::s4u; + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + + // Retrieve hosts + auto* bob = e.host_by_name("bob"); + auto* carl = e.host_by_name("carl"); + + // Create tasks + auto exec1 = sg4::ExecTask::init("exec1", 1e9, bob); + auto exec2 = sg4::ExecTask::init("exec2", 1e9, carl); + auto write = sg4::IoTask::init("write", 1e7, bob->get_disks().front(), sg4::Io::OpType::WRITE); + auto read = sg4::IoTask::init("read", 1e7, carl->get_disks().front(), sg4::Io::OpType::READ); + + // Create the graph by defining dependencies between tasks + exec1->add_successor(write); + write->add_successor(read); + read->add_successor(exec2); + + // Add a function to be called when tasks end for log purpose + sg4::Task::on_completion_cb( + [](const sg4::Task* t) { XBT_INFO("Task %s finished (%d)", t->get_name().c_str(), t->get_count()); }); + + // Enqueue two firings for task exec1 + exec1->enqueue_firings(2); + + // Start the simulation + e.run(); + return 0; +} diff --git a/examples/cpp/task-io/s4u-task-io.tesh b/examples/cpp/task-io/s4u-task-io.tesh new file mode 100644 index 0000000000..b1b5cdb1be --- /dev/null +++ b/examples/cpp/task-io/s4u-task-io.tesh @@ -0,0 +1,11 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-task-io ${platfdir}/hosts_with_disks.xml +> [1.000000] [task_simple/INFO] Task exec1 finished (1) +> [1.250000] [task_simple/INFO] Task write finished (1) +> [1.350000] [task_simple/INFO] Task read finished (1) +> [2.000000] [task_simple/INFO] Task exec1 finished (2) +> [2.250000] [task_simple/INFO] Task write finished (2) +> [2.350000] [task_simple/INFO] Task exec2 finished (1) +> [2.350000] [task_simple/INFO] Task read finished (2) +> [3.350000] [task_simple/INFO] Task exec2 finished (2) diff --git a/examples/cpp/task-microservice/s4u-task-microservice.cpp b/examples/cpp/task-microservice/s4u-task-microservice.cpp new file mode 100644 index 0000000000..5c449e8d78 --- /dev/null +++ b/examples/cpp/task-microservice/s4u-task-microservice.cpp @@ -0,0 +1,145 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example illustrates how to use Simgrid Tasks to reproduce the workflow 2.a of the article + * "Automated performance prediction of microservice applications using simulation" by Clément Courageux-Sudan et al. + * + * To build this workflow we create; + * - each Execution Task + * - each Communication Task + * - the links between the Tasks, i.e. the graph + * + * We also increase the parallelism degree of each Task to 10. + * + * In this scenario we send 500 requests per second (RPS) to the entry point of the graph for 7 seconds, + * and we count the number of processed requests between 2 and 7 seconds to evaluate the number of requests processed + * per second. + */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(task_microservice, "Messages specific for this s4u example"); +namespace sg4 = simgrid::s4u; + +static void request_sender(sg4::TaskPtr t, int requests_per_second) +{ + for (int i = 0; i < requests_per_second * 7; i++) { + t->enqueue_firings(1); + sg4::this_actor::sleep_for(1.0 / requests_per_second); + } +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + + // Retrieve Hosts + auto pm0 = e.host_by_name("PM0"); + auto pm1 = e.host_by_name("PM1"); + + // Set concurrency limit + pm0->set_concurrency_limit(10); + pm1->set_concurrency_limit(10); + + // Create Exec Tasks + auto nginx_web_server = sg4::ExecTask::init("nginx_web_server", 783 * pm0->get_speed() / 1e6, pm0); + auto compose_post_service_0 = sg4::ExecTask::init("compose_post_service_0", 682 * pm0->get_speed() / 1e6, pm0); + auto unique_id_service = sg4::ExecTask::init("unique_id_service", 12 * pm0->get_speed() / 1e6, pm0); + auto compose_post_service_1 = sg4::ExecTask::init("compose_post_service_1", 140 * pm0->get_speed() / 1e6, pm0); + auto media_service = sg4::ExecTask::init("media_service", 6 * pm1->get_speed() / 1e6, pm1); + auto compose_post_service_2 = sg4::ExecTask::init("compose_post_service_2", 135 * pm0->get_speed() / 1e6, pm0); + auto user_service = sg4::ExecTask::init("user_service", 5 * pm0->get_speed() / 1e6, pm0); + auto compose_post_service_3 = sg4::ExecTask::init("compose_post_service_3", 147 * pm0->get_speed() / 1e6, pm0); + auto text_service_0 = sg4::ExecTask::init("text_service_0", 296 * pm0->get_speed() / 1e6, pm0); + auto text_service_1 = sg4::ExecTask::init("text_service_1", 350 * pm0->get_speed() / 1e6, pm0); + auto text_service_2 = sg4::ExecTask::init("text_service_2", 146 * pm0->get_speed() / 1e6, pm0); + auto user_mention_service = sg4::ExecTask::init("user_mention_service", 934 * pm0->get_speed() / 1e6, pm0); + auto url_shorten_service = sg4::ExecTask::init("url_shorten_service", 555 * pm0->get_speed() / 1e6, pm0); + auto compose_post_service_4 = sg4::ExecTask::init("compose_post_service_4", 138 * pm0->get_speed() / 1e6, pm0); + auto home_timeline_service_0 = sg4::ExecTask::init("home_timeline_service_0", 243 * pm0->get_speed() / 1e6, pm0); + auto social_graph_service = sg4::ExecTask::init("home_timeline_service_0", 707 * pm0->get_speed() / 1e6, pm0); + auto home_timeline_service_1 = sg4::ExecTask::init("home_timeline_service_0", 7 * pm0->get_speed() / 1e6, pm0); + auto compose_post_service_5 = sg4::ExecTask::init("compose_post_service_5", 192 * pm0->get_speed() / 1e6, pm0); + auto user_timeline_service = sg4::ExecTask::init("user_timeline_service", 913 * pm0->get_speed() / 1e6, pm0); + auto compose_post_service_6 = sg4::ExecTask::init("compose_post_service_6", 508 * pm0->get_speed() / 1e6, pm0); + auto post_storage_service = sg4::ExecTask::init("post_storage_service", 391 * pm1->get_speed() / 1e6, pm1); + + // Create Comm Tasks + auto compose_post_service_1_to_media_service = + sg4::CommTask::init("compose_post_service_1_to_media_service", 100, pm0, pm1); + auto media_service_to_compose_post_service_2 = + sg4::CommTask::init("media_service_to_compose_post_service_2", 100, pm1, pm0); + auto compose_post_service_6_to_post_storage_service = + sg4::CommTask::init("media_service_to_compose_post_service_2", 100, pm1, pm0); + + // Create the graph + nginx_web_server->add_successor(compose_post_service_0); + compose_post_service_0->add_successor(unique_id_service); + unique_id_service->add_successor(compose_post_service_1); + compose_post_service_1->add_successor(compose_post_service_1_to_media_service); + compose_post_service_1_to_media_service->add_successor(media_service); + media_service->add_successor(media_service_to_compose_post_service_2); + media_service_to_compose_post_service_2->add_successor(compose_post_service_2); + compose_post_service_2->add_successor(user_service); + user_service->add_successor(compose_post_service_3); + compose_post_service_3->add_successor(text_service_0); + text_service_0->add_successor(text_service_1); + text_service_0->add_successor(text_service_2); + text_service_1->add_successor(user_mention_service); + text_service_2->add_successor(url_shorten_service); + user_mention_service->add_successor(compose_post_service_4); + compose_post_service_4->add_successor(home_timeline_service_0); + home_timeline_service_0->add_successor(social_graph_service); + social_graph_service->add_successor(home_timeline_service_1); + home_timeline_service_1->add_successor(compose_post_service_5); + compose_post_service_5->add_successor(user_timeline_service); + user_timeline_service->add_successor(compose_post_service_6); + compose_post_service_6->add_successor(compose_post_service_6_to_post_storage_service); + compose_post_service_6_to_post_storage_service->add_successor(post_storage_service); + + // Dispatch Exec Tasks + std::vector exec_tasks = {nginx_web_server, + compose_post_service_0, + unique_id_service, + compose_post_service_1, + compose_post_service_1_to_media_service, + media_service, + media_service_to_compose_post_service_2, + compose_post_service_2, + user_service, + compose_post_service_3, + text_service_0, + text_service_1, + text_service_2, + user_mention_service, + url_shorten_service, + compose_post_service_4, + home_timeline_service_0, + social_graph_service, + home_timeline_service_1, + compose_post_service_5, + user_timeline_service, + compose_post_service_6, + compose_post_service_6_to_post_storage_service, + post_storage_service}; + for (auto t : exec_tasks) + t->set_parallelism_degree(10); + + // Create the actor that will inject requests during the simulation + sg4::Actor::create("request_sender", pm0, request_sender, nginx_web_server, 500); + + // Add a function to be called when tasks end for log purpose + int requests_processed = 0; + sg4::Task::on_completion_cb([&e, &requests_processed](const sg4::Task* t) { + if (t->get_name() == "post_storage_service" and e.get_clock() < 7 and e.get_clock() > 2) + requests_processed++; + }); + + // Start the simulation + e.run(); + XBT_INFO("Requests processed per second: %f", requests_processed / 5.0); + return 0; +} diff --git a/examples/cpp/task-microservice/s4u-task-microservice.tesh b/examples/cpp/task-microservice/s4u-task-microservice.tesh new file mode 100644 index 0000000000..9a95e4433e --- /dev/null +++ b/examples/cpp/task-microservice/s4u-task-microservice.tesh @@ -0,0 +1,4 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-task-microservice ${platfdir}/three_multicore_hosts.xml +> [7.008495] [task_microservice/INFO] Requests processed per second: 500.000000 \ No newline at end of file diff --git a/examples/cpp/task-parallelism/s4u-task-parallelism.cpp b/examples/cpp/task-parallelism/s4u-task-parallelism.cpp new file mode 100644 index 0000000000..c9f70dafb8 --- /dev/null +++ b/examples/cpp/task-parallelism/s4u-task-parallelism.cpp @@ -0,0 +1,51 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example tests increasing and decreasing parallelism degree of Tasks. + * First we increase and decrease parallelism degree while the Task is idle, + * then we increase and decrease parallelism degree while the Task has queued firings. + */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(task_parallelism, "Messages specific for this s4u example"); +namespace sg4 = simgrid::s4u; + +static void manager(sg4::ExecTaskPtr t) +{ + t->set_parallelism_degree(1); + t->enqueue_firings(2); + sg4::this_actor::sleep_for(300); + + t->set_parallelism_degree(2); + t->enqueue_firings(4); + sg4::this_actor::sleep_for(300); + + t->set_parallelism_degree(1); + t->enqueue_firings(2); + sg4::this_actor::sleep_for(300); + + t->enqueue_firings(11); + t->set_parallelism_degree(2); + sg4::this_actor::sleep_for(150); + t->set_parallelism_degree(1); + sg4::this_actor::sleep_for(200); + t->set_parallelism_degree(3); +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + auto pm0 = e.host_by_name("PM0"); + auto t = sg4::ExecTask::init("exec_A", 100 * pm0->get_speed(), pm0); + sg4::Task::on_completion_cb( + [](const sg4::Task* t) { XBT_INFO("Task %s finished (%d)", t->get_cname(), t->get_count()); }); + sg4::Task::on_start_cb([](const sg4::Task* t) { XBT_INFO("Task %s start", t->get_cname()); }); + sg4::Actor::create("sender", pm0, manager, t); + + e.run(); + return 0; +} diff --git a/examples/cpp/task-parallelism/s4u-task-parallelism.tesh b/examples/cpp/task-parallelism/s4u-task-parallelism.tesh new file mode 100644 index 0000000000..492d015adb --- /dev/null +++ b/examples/cpp/task-parallelism/s4u-task-parallelism.tesh @@ -0,0 +1,41 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-task-parallelism ${platfdir}/three_multicore_hosts.xml +> [0.000000] [task_parallelism/INFO] Task exec_A start +> [100.000000] [task_parallelism/INFO] Task exec_A start +> [100.000000] [task_parallelism/INFO] Task exec_A finished (1) +> [200.000000] [task_parallelism/INFO] Task exec_A finished (2) +> [300.000000] [task_parallelism/INFO] Task exec_A start +> [300.000000] [task_parallelism/INFO] Task exec_A start +> [400.000000] [task_parallelism/INFO] Task exec_A start +> [400.000000] [task_parallelism/INFO] Task exec_A start +> [400.000000] [task_parallelism/INFO] Task exec_A finished (3) +> [400.000000] [task_parallelism/INFO] Task exec_A finished (4) +> [500.000000] [task_parallelism/INFO] Task exec_A finished (5) +> [500.000000] [task_parallelism/INFO] Task exec_A finished (6) +> [600.000000] [task_parallelism/INFO] Task exec_A start +> [700.000000] [task_parallelism/INFO] Task exec_A start +> [700.000000] [task_parallelism/INFO] Task exec_A finished (7) +> [800.000000] [task_parallelism/INFO] Task exec_A finished (8) +> [900.000000] [task_parallelism/INFO] Task exec_A start +> [900.000000] [task_parallelism/INFO] Task exec_A start +> [1000.000000] [task_parallelism/INFO] Task exec_A start +> [1000.000000] [task_parallelism/INFO] Task exec_A start +> [1000.000000] [task_parallelism/INFO] Task exec_A finished (9) +> [1000.000000] [task_parallelism/INFO] Task exec_A finished (10) +> [1100.000000] [task_parallelism/INFO] Task exec_A start +> [1100.000000] [task_parallelism/INFO] Task exec_A finished (11) +> [1100.000000] [task_parallelism/INFO] Task exec_A finished (12) +> [1200.000000] [task_parallelism/INFO] Task exec_A start +> [1200.000000] [task_parallelism/INFO] Task exec_A finished (13) +> [1250.000000] [task_parallelism/INFO] Task exec_A start +> [1250.000000] [task_parallelism/INFO] Task exec_A start +> [1300.000000] [task_parallelism/INFO] Task exec_A start +> [1300.000000] [task_parallelism/INFO] Task exec_A finished (14) +> [1350.000000] [task_parallelism/INFO] Task exec_A start +> [1350.000000] [task_parallelism/INFO] Task exec_A start +> [1350.000000] [task_parallelism/INFO] Task exec_A finished (15) +> [1350.000000] [task_parallelism/INFO] Task exec_A finished (16) +> [1400.000000] [task_parallelism/INFO] Task exec_A finished (17) +> [1450.000000] [task_parallelism/INFO] Task exec_A finished (18) +> [1450.000000] [task_parallelism/INFO] Task exec_A finished (19) \ No newline at end of file diff --git a/examples/cpp/task-simple/s4u-task-simple.cpp b/examples/cpp/task-simple/s4u-task-simple.cpp new file mode 100644 index 0000000000..2d7224fc85 --- /dev/null +++ b/examples/cpp/task-simple/s4u-task-simple.cpp @@ -0,0 +1,50 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example demonstrate basic use of tasks. + * + * We model the following graph: + * + * exec1 -> comm -> exec2 + * + * exec1 and exec2 are execution tasks. + * comm is a communication task. + */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(task_simple, "Messages specific for this task example"); + +namespace sg4 = simgrid::s4u; + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + + // Retrieve hosts + auto* tremblay = e.host_by_name("Tremblay"); + auto* jupiter = e.host_by_name("Jupiter"); + + // Create tasks + auto exec1 = sg4::ExecTask::init("exec1", 1e9, tremblay); + auto exec2 = sg4::ExecTask::init("exec2", 1e9, jupiter); + auto comm = sg4::CommTask::init("comm", 1e7, tremblay, jupiter); + + // Create the graph by defining dependencies between tasks + exec1->add_successor(comm); + comm->add_successor(exec2); + + // Add a function to be called when tasks end for log purpose + sg4::Task::on_completion_cb( + [](const sg4::Task* t) { XBT_INFO("Task %s finished (%d)", t->get_name().c_str(), t->get_count()); }); + + // Enqueue two firings for task exec1 + exec1->enqueue_firings(2); + + // Start the simulation + e.run(); + return 0; +} diff --git a/examples/cpp/task-simple/s4u-task-simple.tesh b/examples/cpp/task-simple/s4u-task-simple.tesh new file mode 100644 index 0000000000..b07d406d4d --- /dev/null +++ b/examples/cpp/task-simple/s4u-task-simple.tesh @@ -0,0 +1,9 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-task-simple ${platfdir}/small_platform.xml +> [10.194200] [task_simple/INFO] Task exec1 finished (1) +> [11.714617] [task_simple/INFO] Task comm finished (1) +> [20.388399] [task_simple/INFO] Task exec1 finished (2) +> [21.908817] [task_simple/INFO] Task comm finished (2) +> [24.821464] [task_simple/INFO] Task exec2 finished (1) +> [37.928311] [task_simple/INFO] Task exec2 finished (2) diff --git a/examples/cpp/task-storm/s4u-task-storm.cpp b/examples/cpp/task-storm/s4u-task-storm.cpp new file mode 100644 index 0000000000..ca0f61ea5c --- /dev/null +++ b/examples/cpp/task-storm/s4u-task-storm.cpp @@ -0,0 +1,134 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example takes the main concepts of Apache Storm presented here + https://storm.apache.org/releases/2.4.0/Concepts.html and use them to build a simulation of a stream processing + application + + Spout SA produces data every 100ms. The volume produced is alternatively 1e3, 1e6 and 1e9 bytes. + Spout SB produces 1e6 bytes every 200ms. + + Bolt B1 and B2 processes data from Spout SA alternatively. The quantity of work to process this data is 10 flops per + bytes Bolt B3 processes data from Spout SB. Bolt B4 processes data from Bolt B3. + + Fafard + ┌────┐ + ┌──►│ B1 │ + Tremblay │ └────┘ + ┌────┐ │ + │ SA ├────┤ Ginette + └────┘ │ ┌────┐ + └──►│ B2 │ + └────┘ + + + Bourassa + Jupiter ┌──────────┐ + ┌────┐ │ │ + │ SB ├─────┤ B3 ──► B4│ + └────┘ │ │ + └──────────┘ + */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(task_storm, "Messages specific for this s4u example"); +namespace sg4 = simgrid::s4u; + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + + // Retrieve hosts + auto tremblay = e.host_by_name("Tremblay"); + auto jupiter = e.host_by_name("Jupiter"); + auto fafard = e.host_by_name("Fafard"); + auto ginette = e.host_by_name("Ginette"); + auto bourassa = e.host_by_name("Bourassa"); + + // Create execution tasks + auto SA = sg4::ExecTask::init("SA", tremblay->get_speed() * 0.1, tremblay); + auto SB = sg4::ExecTask::init("SB", jupiter->get_speed() * 0.2, jupiter); + auto B1 = sg4::ExecTask::init("B1", 1e8, fafard); + auto B2 = sg4::ExecTask::init("B2", 1e8, ginette); + auto B3 = sg4::ExecTask::init("B3", 1e8, bourassa); + auto B4 = sg4::ExecTask::init("B4", 2e8, bourassa); + + // Create communication tasks + auto SA_to_B1 = sg4::CommTask::init("SA_to_B1", 0, tremblay, fafard); + auto SA_to_B2 = sg4::CommTask::init("SA_to_B2", 0, tremblay, ginette); + auto SB_to_B3 = sg4::CommTask::init("SB_to_B3", 1e6, jupiter, bourassa); + + // Create the graph by defining dependencies between tasks + // Some dependencies are defined dynamically + SA_to_B1->add_successor(B1); + SA_to_B2->add_successor(B2); + SB->add_successor(SB_to_B3); + SB_to_B3->add_successor(B3); + B3->add_successor(B4); + + /* Dynamic modification of the graph and bytes sent + Alternatively we: remove/add the link between SA and SA_to_B2 + add/remove the link between SA and SA_to_B1 + */ + SA->on_this_completion_cb([&SA_to_B1, &SA_to_B2](sg4::Task* t) { + int count = t->get_count(); + sg4::CommTaskPtr comm; + if (count % 2 == 1) { + t->remove_successor(SA_to_B2); + t->add_successor(SA_to_B1); + comm = SA_to_B1; + } else { + t->remove_successor(SA_to_B1); + t->add_successor(SA_to_B2); + comm = SA_to_B2; + } + std::vector amount = {1e9, 1e3, 1e6}; + // XBT_INFO("Comm %f", amount[count % 3]); + comm->set_amount(amount[count % 3]); + auto token = std::make_shared(); + token->set_data(new double(amount[count % 3])); + t->set_token(token); + }); + + // The token sent by SA is forwarded by both communication tasks + SA_to_B1->on_this_completion_cb([&SA](sg4::Task* t) { + t->set_token(t->get_token_from(SA)); + t->deque_token_from(SA); + }); + SA_to_B2->on_this_completion_cb([&SA](sg4::Task* t) { + t->set_token(t->get_token_from(SA)); + t->deque_token_from(SA); + }); + + /* B1 and B2 read the value of the token received by their predecessors + and use it to adapt their amount of work to do. + */ + B1->on_this_start_cb([&SA_to_B1](sg4::Task* t) { + auto data = t->get_token_from(SA_to_B1)->get_data(); + t->deque_token_from(SA_to_B1); + t->set_amount(*data * 10); + delete data; + }); + B2->on_this_start_cb([&SA_to_B2](sg4::Task* t) { + auto data = t->get_token_from(SA_to_B2)->get_data(); + t->deque_token_from(SA_to_B2); + t->set_amount(*data * 10); + delete data; + }); + + // Enqueue firings for tasks without predecessors + SA->enqueue_firings(5); + SB->enqueue_firings(5); + + // Add a function to be called when tasks end for log purpose + sg4::Task::on_completion_cb( + [](const sg4::Task* t) { XBT_INFO("Task %s finished (%d)", t->get_name().c_str(), t->get_count()); }); + + // Start the simulation + e.run(); + return 0; +} diff --git a/examples/cpp/task-storm/s4u-task-storm.tesh b/examples/cpp/task-storm/s4u-task-storm.tesh new file mode 100644 index 0000000000..376dc31a47 --- /dev/null +++ b/examples/cpp/task-storm/s4u-task-storm.tesh @@ -0,0 +1,38 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-task-storm ${platfdir}/small_platform.xml +> [0.100000] [task_storm/INFO] Task SA finished (1) +> [0.125841] [task_storm/INFO] Task SA_to_B1 finished (1) +> [0.125972] [task_storm/INFO] Task B1 finished (1) +> [0.200000] [task_storm/INFO] Task SB finished (1) +> [0.200000] [task_storm/INFO] Task SA finished (2) +> [0.300000] [task_storm/INFO] Task SA finished (3) +> [0.364429] [task_storm/INFO] Task SA_to_B2 finished (1) +> [0.400000] [task_storm/INFO] Task SB finished (2) +> [0.400000] [task_storm/INFO] Task SA finished (4) +> [0.416759] [task_storm/INFO] Task SA_to_B2 finished (2) +> [0.500000] [task_storm/INFO] Task SA finished (5) +> [0.557036] [task_storm/INFO] Task SB_to_B3 finished (1) +> [0.570648] [task_storm/INFO] Task B2 finished (1) +> [0.570855] [task_storm/INFO] Task B2 finished (2) +> [0.600000] [task_storm/INFO] Task SB finished (3) +> [0.800000] [task_storm/INFO] Task SB finished (4) +> [0.867388] [task_storm/INFO] Task SB_to_B3 finished (2) +> [1.000000] [task_storm/INFO] Task SB finished (5) +> [1.177739] [task_storm/INFO] Task SB_to_B3 finished (3) +> [1.488090] [task_storm/INFO] Task SB_to_B3 finished (4) +> [1.798442] [task_storm/INFO] Task SB_to_B3 finished (5) +> [2.619232] [task_storm/INFO] Task B3 finished (1) +> [6.743624] [task_storm/INFO] Task B3 finished (2) +> [10.868015] [task_storm/INFO] Task B4 finished (1) +> [10.868015] [task_storm/INFO] Task B3 finished (3) +> [14.992407] [task_storm/INFO] Task B3 finished (4) +> [19.116799] [task_storm/INFO] Task B4 finished (2) +> [19.116799] [task_storm/INFO] Task B3 finished (5) +> [23.241190] [task_storm/INFO] Task B4 finished (3) +> [27.365582] [task_storm/INFO] Task B4 finished (4) +> [31.489974] [task_storm/INFO] Task B4 finished (5) +> [133.367321] [task_storm/INFO] Task SA_to_B1 finished (2) +> [133.525717] [task_storm/INFO] Task SA_to_B1 finished (3) +> [264.435791] [task_storm/INFO] Task B1 finished (2) +> [264.566859] [task_storm/INFO] Task B1 finished (3) diff --git a/examples/cpp/task-switch-host/s4u-task-switch-host.cpp b/examples/cpp/task-switch-host/s4u-task-switch-host.cpp new file mode 100644 index 0000000000..c236bdbdb9 --- /dev/null +++ b/examples/cpp/task-switch-host/s4u-task-switch-host.cpp @@ -0,0 +1,82 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example demonstrates how to dynamically modify a graph of tasks. + * + * Assuming we have two instances of a service placed on different hosts, + * we want to send data alternatively to thoses instances. + * + * We consider the following graph: + * + * comm0 -> exec1 -> comm1 + * ↳-> exec2 ->comm2 + * + * With exec1 and exec2 on different hosts. + */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(task_switch_host, "Messages specific for this task example"); +namespace sg4 = simgrid::s4u; + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + + // Retrieve hosts + auto* tremblay = e.host_by_name("Tremblay"); + auto* jupiter = e.host_by_name("Jupiter"); + auto* fafard = e.host_by_name("Fafard"); + + // Create tasks + auto comm0 = sg4::CommTask::init("comm0"); + comm0->set_bytes(1e7); + comm0->set_source(tremblay); + auto exec1 = sg4::ExecTask::init("exec1", 1e9, jupiter); + auto exec2 = sg4::ExecTask::init("exec2", 1e9, fafard); + auto comm1 = sg4::CommTask::init("comm1", 1e7, jupiter, tremblay); + auto comm2 = sg4::CommTask::init("comm2", 1e7, fafard, tremblay); + + // Create the initial graph by defining dependencies between tasks + comm0->add_successor(exec2); + exec1->add_successor(comm1); + exec2->add_successor(comm2); + + // Add a function to be called when tasks end for log purpose + sg4::Task::on_completion_cb( + [](const sg4::Task* t) { XBT_INFO("Task %s finished (%d)", t->get_name().c_str(), t->get_count()); }); + + // Add a function to be called before each firing of comm0 + // This function modifies the graph of tasks by adding or removing + // successors to comm0 + comm0->on_this_start_cb([&comm0, exec1, exec2, jupiter, fafard](const sg4::Task*) { + static int count = 0; + if (count % 2 == 0) + comm0->set_destination(jupiter); + else + comm0->set_destination(fafard); + count++; + }); + + comm0->on_this_completion_cb([&comm0, exec1, exec2](const sg4::Task*) { + static int count = 0; + if (count % 2 == 0) { + comm0->add_successor(exec1); + comm0->remove_successor(exec2); + } else { + comm0->add_successor(exec2); + comm0->remove_successor(exec1); + } + count++; + }); + + // Enqueue four firings for task comm0 + comm0->enqueue_firings(4); + + // Start the simulation + e.run(); + return 0; +} diff --git a/examples/cpp/task-switch-host/s4u-task-switch-host.tesh b/examples/cpp/task-switch-host/s4u-task-switch-host.tesh new file mode 100644 index 0000000000..b3146ff29c --- /dev/null +++ b/examples/cpp/task-switch-host/s4u-task-switch-host.tesh @@ -0,0 +1,15 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-task-switch-host ${platfdir}/small_platform.xml +> [1.520418] [task_switch_host/INFO] Task comm0 finished (1) +> [2.873012] [task_switch_host/INFO] Task comm0 finished (2) +> [4.393430] [task_switch_host/INFO] Task comm0 finished (3) +> [5.746025] [task_switch_host/INFO] Task comm0 finished (4) +> [14.627265] [task_switch_host/INFO] Task exec1 finished (1) +> [15.979859] [task_switch_host/INFO] Task exec2 finished (1) +> [16.147682] [task_switch_host/INFO] Task comm1 finished (1) +> [17.332454] [task_switch_host/INFO] Task comm2 finished (1) +> [27.734112] [task_switch_host/INFO] Task exec1 finished (2) +> [29.086707] [task_switch_host/INFO] Task exec2 finished (2) +> [29.254529] [task_switch_host/INFO] Task comm1 finished (2) +> [30.439301] [task_switch_host/INFO] Task comm2 finished (2) \ No newline at end of file diff --git a/examples/cpp/task-variable-load/s4u-task-variable-load.cpp b/examples/cpp/task-variable-load/s4u-task-variable-load.cpp new file mode 100644 index 0000000000..fff790dc68 --- /dev/null +++ b/examples/cpp/task-variable-load/s4u-task-variable-load.cpp @@ -0,0 +1,62 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* This example demonstrates how to create a variable load for tasks. + * + * We consider the following graph: + * + * comm -> exec + * + * With a small load each comm task is followed by an exec task. + * With a heavy load there is a burst of comm before the exec task can even finish once. + */ + +#include "simgrid/s4u.hpp" + +XBT_LOG_NEW_DEFAULT_CATEGORY(task_variable_load, "Messages specific for this s4u example"); +namespace sg4 = simgrid::s4u; + +static void variable_load(sg4::TaskPtr t) +{ + XBT_INFO("--- Small load ---"); + for (int i = 0; i < 3; i++) { + t->enqueue_firings(1); + sg4::this_actor::sleep_for(100); + } + sg4::this_actor::sleep_until(1000); + XBT_INFO("--- Heavy load ---"); + for (int i = 0; i < 3; i++) { + t->enqueue_firings(1); + sg4::this_actor::sleep_for(1); + } +} + +int main(int argc, char* argv[]) +{ + sg4::Engine e(&argc, argv); + e.load_platform(argv[1]); + + // Retreive hosts + auto* tremblay = e.host_by_name("Tremblay"); + auto* jupiter = e.host_by_name("Jupiter"); + + // Create tasks + auto comm = sg4::CommTask::init("comm", 1e7, tremblay, jupiter); + auto exec = sg4::ExecTask::init("exec", 1e9, jupiter); + + // Create the graph by defining dependencies between tasks + comm->add_successor(exec); + + // Add a function to be called when tasks end for log purpose + sg4::Task::on_completion_cb( + [](const sg4::Task* t) { XBT_INFO("Task %s finished (%d)", t->get_name().c_str(), t->get_count()); }); + + // Create the actor that will inject load during the simulation + sg4::Actor::create("input", tremblay, variable_load, comm); + + // Start the simulation + e.run(); + return 0; +} diff --git a/examples/cpp/task-variable-load/s4u-task-variable-load.tesh b/examples/cpp/task-variable-load/s4u-task-variable-load.tesh new file mode 100644 index 0000000000..2f2ab9bd1b --- /dev/null +++ b/examples/cpp/task-variable-load/s4u-task-variable-load.tesh @@ -0,0 +1,17 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/s4u-task-variable-load ${platfdir}/small_platform.xml +> [Tremblay:input:(1) 0.000000] [task_variable_load/INFO] --- Small load --- +> [1.520418] [task_variable_load/INFO] Task comm finished (1) +> [14.627265] [task_variable_load/INFO] Task exec finished (1) +> [101.520418] [task_variable_load/INFO] Task comm finished (2) +> [114.627265] [task_variable_load/INFO] Task exec finished (2) +> [201.520418] [task_variable_load/INFO] Task comm finished (3) +> [214.627265] [task_variable_load/INFO] Task exec finished (3) +> [Tremblay:input:(1) 1000.000000] [task_variable_load/INFO] --- Heavy load --- +> [1001.520418] [task_variable_load/INFO] Task comm finished (4) +> [1003.040835] [task_variable_load/INFO] Task comm finished (5) +> [1004.561253] [task_variable_load/INFO] Task comm finished (6) +> [1014.627265] [task_variable_load/INFO] Task exec finished (4) +> [1027.734112] [task_variable_load/INFO] Task exec finished (5) +> [1040.840959] [task_variable_load/INFO] Task exec finished (6) diff --git a/examples/cpp/trace-categories/s4u-trace-categories.cpp b/examples/cpp/trace-categories/s4u-trace-categories.cpp index 29eb21f673..adf6f3d3db 100644 --- a/examples/cpp/trace-categories/s4u-trace-categories.cpp +++ b/examples/cpp/trace-categories/s4u-trace-categories.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,7 +22,7 @@ struct Task { static void master() { - auto mbox = sg4::Mailbox::by_name("master_mailbox"); + auto* mbox = sg4::Mailbox::by_name("master_mailbox"); for (int i = 0; i < 10; i++) { Task task; if (i % 2) @@ -39,7 +39,7 @@ static void master() static void worker() { - auto mbox = sg4::Mailbox::by_name("master_mailbox"); + auto* mbox = sg4::Mailbox::by_name("master_mailbox"); while (true) { auto task = mbox->get_unique(); if (task->name == "finalize") { diff --git a/examples/cpp/trace-host-user-variables/s4u-trace-host-user-variables.cpp b/examples/cpp/trace-host-user-variables/s4u-trace-host-user-variables.cpp index 6b587adeb9..8dc6247432 100644 --- a/examples/cpp/trace-host-user-variables/s4u-trace-host-user-variables.cpp +++ b/examples/cpp/trace-host-user-variables/s4u-trace-host-user-variables.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/trace-link-user-variables/s4u-trace-link-user-variables.cpp b/examples/cpp/trace-link-user-variables/s4u-trace-link-user-variables.cpp index edca62c2ce..e46b3bdf37 100644 --- a/examples/cpp/trace-link-user-variables/s4u-trace-link-user-variables.cpp +++ b/examples/cpp/trace-link-user-variables/s4u-trace-link-user-variables.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/trace-masterworkers/s4u-trace-masterworkers.cpp b/examples/cpp/trace-masterworkers/s4u-trace-masterworkers.cpp index 76175f5406..d63d4a1354 100644 --- a/examples/cpp/trace-masterworkers/s4u-trace-masterworkers.cpp +++ b/examples/cpp/trace-masterworkers/s4u-trace-masterworkers.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -24,7 +24,7 @@ static void master(std::vector args) long communication_cost = std::stol(args[3]); size_t workers_count = args.size() - 4; const auto& my_host = sg4::this_actor::get_host()->get_name(); - auto mailbox = sg4::Mailbox::by_name("master_mailbox"); + auto* mailbox = sg4::Mailbox::by_name("master_mailbox"); XBT_DEBUG("Got %zu workers and %ld tasks to process", workers_count, tasks_count); @@ -54,7 +54,7 @@ static void worker(std::vector args) xbt_assert(args.size() == 1, "The worker expects no argument"); const auto& my_host = sg4::this_actor::get_host()->get_name(); - auto mailbox = sg4::Mailbox::by_name("master_mailbox"); + auto* mailbox = sg4::Mailbox::by_name("master_mailbox"); simgrid::instr::set_host_variable(my_host, "is_worker", 1); simgrid::instr::set_host_variable(my_host, "task_computation", 0); diff --git a/examples/cpp/trace-platform/s4u-trace-platform.cpp b/examples/cpp/trace-platform/s4u-trace-platform.cpp index 82109ca701..1666910d96 100644 --- a/examples/cpp/trace-platform/s4u-trace-platform.cpp +++ b/examples/cpp/trace-platform/s4u-trace-platform.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/cpp/trace-process-migration/s4u-trace-process-migration.cpp b/examples/cpp/trace-process-migration/s4u-trace-process-migration.cpp index 0f4506ff07..a09afe82e6 100644 --- a/examples/cpp/trace-process-migration/s4u-trace-process-migration.cpp +++ b/examples/cpp/trace-process-migration/s4u-trace-process-migration.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -17,7 +17,7 @@ namespace sg4 = simgrid::s4u; /* The guy we will move from host to host. It move alone and then is moved by policeman back */ static void emigrant() { - auto mailbox = sg4::Mailbox::by_name("master_mailbox"); + auto* mailbox = sg4::Mailbox::by_name("master_mailbox"); sg4::this_actor::sleep_for(2); @@ -35,7 +35,7 @@ static void policeman() // I am the master of emigrant actor, // I tell it where it must emigrate to. auto destinations = {"Tremblay", "Jupiter", "Fafard", "Ginette", "Bourassa", "Fafard", "Tremblay", "Ginette", ""}; - auto mailbox = sg4::Mailbox::by_name("master_mailbox"); + auto* mailbox = sg4::Mailbox::by_name("master_mailbox"); for (auto const& destination : destinations) { mailbox->put_init(new std::string(destination), 0)->set_tracing_category("migration_order")->wait(); diff --git a/examples/cpp/trace-process-migration/s4u-trace-process-migration.tesh b/examples/cpp/trace-process-migration/s4u-trace-process-migration.tesh index b6dafe2905..99d68659a6 100644 --- a/examples/cpp/trace-process-migration/s4u-trace-process-migration.tesh +++ b/examples/cpp/trace-process-migration/s4u-trace-process-migration.tesh @@ -117,253 +117,257 @@ $ tail -n +3 procmig.trace > %EndEventDef > 0 1 0 HOST > 6 0.000000 1 1 0 "Tremblay" +> 2 2 1 HOST_STATE +> 5 3 2 receive "1 0 0" +> 5 4 2 send "0 0 1" +> 5 5 2 execute "0 1 1" > 6 0.000000 2 1 0 "Jupiter" > 6 0.000000 3 1 0 "Fafard" > 6 0.000000 4 1 0 "Ginette" > 6 0.000000 5 1 0 "Bourassa" > 6 0.000000 6 1 0 "Jacquelin" > 6 0.000000 7 1 0 "Boivin" -> 0 2 0 LINK -> 6 0.000000 8 2 0 "6" -> 6 0.000000 9 2 0 "3" -> 6 0.000000 10 2 0 "7" -> 6 0.000000 11 2 0 "9" -> 6 0.000000 12 2 0 "2" -> 6 0.000000 13 2 0 "8" -> 6 0.000000 14 2 0 "1" -> 6 0.000000 15 2 0 "4" -> 6 0.000000 16 2 0 "0" -> 6 0.000000 17 2 0 "5" -> 6 0.000000 18 2 0 "145" -> 6 0.000000 19 2 0 "10" -> 6 0.000000 20 2 0 "11" -> 6 0.000000 21 2 0 "16" -> 6 0.000000 22 2 0 "17" -> 6 0.000000 23 2 0 "44" -> 6 0.000000 24 2 0 "47" -> 6 0.000000 25 2 0 "54" -> 6 0.000000 26 2 0 "56" -> 6 0.000000 27 2 0 "59" -> 6 0.000000 28 2 0 "78" -> 6 0.000000 29 2 0 "79" -> 6 0.000000 30 2 0 "80" -> 6 0.000000 31 2 0 "loopback" -> 4 3 0 2 2 0-LINK2-LINK2 -> 4 4 0 1 2 0-HOST1-LINK2 -> 4 5 0 2 1 0-LINK2-HOST1 -> 15 0.000000 3 0 topology 12 0 -> 16 0.000000 3 0 topology 16 0 -> 15 0.000000 3 0 topology 9 1 -> 16 0.000000 3 0 topology 16 1 -> 15 0.000000 3 0 topology 16 2 -> 16 0.000000 3 0 topology 14 2 -> 15 0.000000 3 0 topology 21 3 -> 16 0.000000 3 0 topology 19 3 -> 15 0.000000 3 0 topology 8 4 -> 16 0.000000 3 0 topology 19 4 -> 15 0.000000 3 0 topology 19 5 -> 16 0.000000 3 0 topology 20 5 -> 15 0.000000 3 0 topology 8 6 -> 16 0.000000 3 0 topology 20 6 -> 15 0.000000 3 0 topology 27 7 -> 16 0.000000 3 0 topology 18 7 -> 15 0.000000 4 0 topology 5 8 -> 16 0.000000 4 0 topology 18 8 -> 15 0.000000 4 0 topology 4 9 -> 16 0.000000 4 0 topology 18 9 -> 15 0.000000 4 0 topology 2 10 -> 16 0.000000 4 0 topology 18 10 -> 15 0.000000 3 0 topology 16 11 -> 16 0.000000 3 0 topology 21 11 -> 15 0.000000 3 0 topology 21 12 -> 16 0.000000 3 0 topology 22 12 -> 15 0.000000 3 0 topology 9 13 -> 16 0.000000 3 0 topology 12 13 -> 15 0.000000 3 0 topology 15 14 -> 16 0.000000 3 0 topology 9 14 -> 15 0.000000 4 0 topology 1 15 -> 16 0.000000 4 0 topology 9 15 -> 15 0.000000 3 0 topology 20 16 -> 16 0.000000 3 0 topology 23 16 -> 15 0.000000 3 0 topology 23 17 -> 16 0.000000 3 0 topology 24 17 -> 15 0.000000 4 0 topology 5 18 -> 16 0.000000 4 0 topology 24 18 -> 15 0.000000 4 0 topology 4 19 -> 16 0.000000 4 0 topology 24 19 -> 15 0.000000 4 0 topology 2 20 -> 16 0.000000 4 0 topology 24 20 -> 15 0.000000 3 0 topology 11 21 -> 16 0.000000 3 0 topology 15 21 -> 15 0.000000 4 0 topology 1 22 -> 16 0.000000 4 0 topology 15 22 -> 15 0.000000 3 0 topology 12 23 -> 16 0.000000 3 0 topology 17 23 -> 15 0.000000 3 0 topology 9 24 -> 16 0.000000 3 0 topology 17 24 -> 15 0.000000 3 0 topology 22 25 -> 16 0.000000 3 0 topology 25 25 -> 15 0.000000 3 0 topology 12 26 -> 16 0.000000 3 0 topology 25 26 -> 15 0.000000 3 0 topology 25 27 -> 16 0.000000 3 0 topology 26 27 -> 15 0.000000 3 0 topology 26 28 -> 16 0.000000 3 0 topology 27 28 -> 15 0.000000 3 0 topology 14 29 -> 16 0.000000 3 0 topology 8 29 -> 15 0.000000 3 0 topology 13 30 -> 16 0.000000 3 0 topology 8 30 -> 15 0.000000 3 0 topology 11 31 -> 16 0.000000 3 0 topology 8 31 -> 15 0.000000 3 0 topology 8 32 -> 16 0.000000 3 0 topology 10 32 -> 15 0.000000 3 0 topology 30 33 -> 16 0.000000 3 0 topology 28 33 -> 15 0.000000 4 0 topology 3 34 -> 16 0.000000 4 0 topology 28 34 -> 15 0.000000 3 0 topology 28 35 -> 16 0.000000 3 0 topology 29 35 -> 15 0.000000 4 0 topology 3 36 -> 16 0.000000 4 0 topology 30 36 -> 15 0.000000 3 0 topology 14 37 -> 16 0.000000 3 0 topology 13 37 -> 15 0.000000 3 0 topology 29 38 -> 16 0.000000 3 0 topology 11 38 -> 15 0.000000 4 0 topology 1 39 -> 16 0.000000 4 0 topology 11 39 -> 15 0.000000 5 0 topology 24 40 -> 16 0.000000 5 0 topology 7 40 -> 15 0.000000 5 0 topology 10 41 -> 16 0.000000 5 0 topology 5 41 -> 15 0.000000 5 0 topology 13 42 -> 16 0.000000 5 0 topology 3 42 -> 15 0.000000 5 0 topology 17 43 -> 16 0.000000 5 0 topology 4 43 -> 15 0.000000 5 0 topology 18 44 -> 16 0.000000 5 0 topology 6 44 -> 15 0.000000 5 0 topology 11 45 -> 16 0.000000 5 0 topology 2 45 -> 0 6 1 ACTOR -> 6 0.000000 32 6 3 "emigrant-1" -> 2 7 6 ACTOR_STATE -> 5 8 7 suspend "1 0 1" -> 5 9 7 sleep "1 1 0" -> 5 10 7 receive "1 0 0" -> 5 11 7 send "0 0 1" -> 5 12 7 execute "0 1 1" -> 4 13 0 6 6 ACTOR_LINK -> 6 0.000000 33 6 1 "policeman-2" -> 12 0.000000 7 32 9 -> 12 0.000000 7 33 11 -> 13 2.000000 7 32 -> 12 2.000000 7 32 10 -> 13 2.025708 7 33 -> 12 2.025708 7 33 11 -> 13 2.025708 7 32 -> 15 2.025708 13 0 M 32 0 -> 7 2.025708 6 32 -> 6 2.025708 34 6 1 "emigrant-1" -> 16 2.025708 13 0 M 34 0 -> 12 2.025708 7 34 9 -> 13 4.025708 7 34 -> 12 4.025708 7 34 10 -> 13 4.025903 7 33 -> 12 4.025903 7 33 11 -> 13 4.025903 7 34 -> 15 4.025903 13 0 M 34 1 -> 7 4.025903 6 34 -> 6 4.025903 35 6 2 "emigrant-1" -> 16 4.025903 13 0 M 35 1 -> 12 4.025903 7 35 9 -> 13 6.025903 7 35 -> 12 6.025903 7 35 10 -> 13 6.044918 7 33 -> 12 6.044918 7 33 11 -> 13 6.044918 7 35 -> 15 6.044918 13 0 M 35 2 -> 7 6.044918 6 35 -> 6 6.044918 36 6 3 "emigrant-1" -> 16 6.044918 13 0 M 36 2 -> 12 6.044918 7 36 9 -> 13 8.044918 7 36 -> 12 8.044918 7 36 10 -> 13 8.070626 7 33 -> 12 8.070626 7 33 11 -> 13 8.070626 7 36 -> 15 8.070626 13 0 M 36 3 -> 7 8.070626 6 36 -> 6 8.070626 37 6 4 "emigrant-1" -> 16 8.070626 13 0 M 37 3 -> 12 8.070626 7 37 9 -> 13 10.070626 7 37 -> 12 10.070626 7 37 10 -> 13 10.087178 7 33 -> 12 10.087178 7 33 11 -> 13 10.087178 7 37 -> 15 10.087178 13 0 M 37 4 -> 7 10.087178 6 37 -> 6 10.087178 38 6 5 "emigrant-1" -> 16 10.087178 13 0 M 38 4 -> 12 10.087178 7 38 9 -> 13 12.087178 7 38 -> 12 12.087178 7 38 10 -> 13 12.112617 7 33 -> 12 12.112617 7 33 11 -> 13 12.112617 7 38 -> 15 12.112617 13 0 M 38 5 -> 7 12.112617 6 38 -> 6 12.112617 39 6 3 "emigrant-1" -> 16 12.112617 13 0 M 39 5 -> 12 12.112617 7 39 9 -> 13 14.112617 7 39 -> 12 14.112617 7 39 10 -> 13 14.138325 7 33 -> 12 14.138325 7 33 11 -> 13 14.138325 7 39 -> 15 14.138325 13 0 M 39 6 -> 7 14.138325 6 39 -> 6 14.138325 40 6 1 "emigrant-1" -> 16 14.138325 13 0 M 40 6 -> 12 14.138325 7 40 9 -> 13 16.138325 7 40 -> 12 16.138325 7 40 10 -> 13 16.138521 7 33 -> 12 16.138521 7 33 11 -> 13 16.138521 7 40 -> 15 16.138521 13 0 M 40 7 -> 7 16.138521 6 40 -> 6 16.138521 41 6 4 "emigrant-1" -> 16 16.138521 13 0 M 41 7 -> 12 16.138521 7 41 9 -> 13 18.138521 7 41 -> 12 18.138521 7 41 10 -> 13 18.155073 7 33 -> 13 18.155073 7 41 -> 7 18.155073 6 33 -> 7 18.155073 6 41 -> 7 18.155073 2 16 -> 7 18.155073 2 14 -> 7 18.155073 2 19 -> 7 18.155073 2 20 -> 7 18.155073 2 18 -> 7 18.155073 2 21 -> 7 18.155073 2 22 -> 7 18.155073 2 12 -> 7 18.155073 2 9 -> 7 18.155073 2 15 -> 7 18.155073 2 23 -> 7 18.155073 2 24 -> 7 18.155073 2 17 -> 7 18.155073 2 25 -> 7 18.155073 2 26 -> 7 18.155073 2 27 -> 7 18.155073 2 8 -> 7 18.155073 2 10 -> 7 18.155073 2 28 -> 7 18.155073 2 29 -> 7 18.155073 2 13 -> 7 18.155073 2 30 -> 7 18.155073 2 11 +> 0 6 0 LINK +> 6 0.000000 8 6 0 "6" +> 6 0.000000 9 6 0 "3" +> 6 0.000000 10 6 0 "7" +> 6 0.000000 11 6 0 "9" +> 6 0.000000 12 6 0 "2" +> 6 0.000000 13 6 0 "8" +> 6 0.000000 14 6 0 "1" +> 6 0.000000 15 6 0 "4" +> 6 0.000000 16 6 0 "0" +> 6 0.000000 17 6 0 "5" +> 6 0.000000 18 6 0 "145" +> 6 0.000000 19 6 0 "10" +> 6 0.000000 20 6 0 "11" +> 6 0.000000 21 6 0 "16" +> 6 0.000000 22 6 0 "17" +> 6 0.000000 23 6 0 "44" +> 6 0.000000 24 6 0 "47" +> 6 0.000000 25 6 0 "54" +> 6 0.000000 26 6 0 "56" +> 6 0.000000 27 6 0 "59" +> 6 0.000000 28 6 0 "78" +> 6 0.000000 29 6 0 "79" +> 6 0.000000 30 6 0 "80" +> 6 0.000000 31 6 0 "loopback" +> 4 7 0 6 6 0-LINK6-LINK6 +> 4 8 0 1 6 0-HOST1-LINK6 +> 4 9 0 6 1 0-LINK6-HOST1 +> 15 0.000000 7 0 topology 12 0 +> 16 0.000000 7 0 topology 16 0 +> 15 0.000000 7 0 topology 9 1 +> 16 0.000000 7 0 topology 16 1 +> 15 0.000000 7 0 topology 16 2 +> 16 0.000000 7 0 topology 14 2 +> 15 0.000000 7 0 topology 21 3 +> 16 0.000000 7 0 topology 19 3 +> 15 0.000000 7 0 topology 8 4 +> 16 0.000000 7 0 topology 19 4 +> 15 0.000000 7 0 topology 19 5 +> 16 0.000000 7 0 topology 20 5 +> 15 0.000000 7 0 topology 8 6 +> 16 0.000000 7 0 topology 20 6 +> 15 0.000000 7 0 topology 27 7 +> 16 0.000000 7 0 topology 18 7 +> 15 0.000000 8 0 topology 5 8 +> 16 0.000000 8 0 topology 18 8 +> 15 0.000000 8 0 topology 4 9 +> 16 0.000000 8 0 topology 18 9 +> 15 0.000000 8 0 topology 2 10 +> 16 0.000000 8 0 topology 18 10 +> 15 0.000000 7 0 topology 16 11 +> 16 0.000000 7 0 topology 21 11 +> 15 0.000000 7 0 topology 21 12 +> 16 0.000000 7 0 topology 22 12 +> 15 0.000000 7 0 topology 9 13 +> 16 0.000000 7 0 topology 12 13 +> 15 0.000000 7 0 topology 15 14 +> 16 0.000000 7 0 topology 9 14 +> 15 0.000000 8 0 topology 1 15 +> 16 0.000000 8 0 topology 9 15 +> 15 0.000000 7 0 topology 20 16 +> 16 0.000000 7 0 topology 23 16 +> 15 0.000000 7 0 topology 23 17 +> 16 0.000000 7 0 topology 24 17 +> 15 0.000000 8 0 topology 5 18 +> 16 0.000000 8 0 topology 24 18 +> 15 0.000000 8 0 topology 4 19 +> 16 0.000000 8 0 topology 24 19 +> 15 0.000000 8 0 topology 2 20 +> 16 0.000000 8 0 topology 24 20 +> 15 0.000000 7 0 topology 11 21 +> 16 0.000000 7 0 topology 15 21 +> 15 0.000000 8 0 topology 1 22 +> 16 0.000000 8 0 topology 15 22 +> 15 0.000000 7 0 topology 12 23 +> 16 0.000000 7 0 topology 17 23 +> 15 0.000000 7 0 topology 9 24 +> 16 0.000000 7 0 topology 17 24 +> 15 0.000000 7 0 topology 22 25 +> 16 0.000000 7 0 topology 25 25 +> 15 0.000000 7 0 topology 12 26 +> 16 0.000000 7 0 topology 25 26 +> 15 0.000000 7 0 topology 25 27 +> 16 0.000000 7 0 topology 26 27 +> 15 0.000000 7 0 topology 26 28 +> 16 0.000000 7 0 topology 27 28 +> 15 0.000000 7 0 topology 14 29 +> 16 0.000000 7 0 topology 8 29 +> 15 0.000000 7 0 topology 13 30 +> 16 0.000000 7 0 topology 8 30 +> 15 0.000000 7 0 topology 11 31 +> 16 0.000000 7 0 topology 8 31 +> 15 0.000000 7 0 topology 8 32 +> 16 0.000000 7 0 topology 10 32 +> 15 0.000000 7 0 topology 30 33 +> 16 0.000000 7 0 topology 28 33 +> 15 0.000000 8 0 topology 3 34 +> 16 0.000000 8 0 topology 28 34 +> 15 0.000000 7 0 topology 28 35 +> 16 0.000000 7 0 topology 29 35 +> 15 0.000000 8 0 topology 3 36 +> 16 0.000000 8 0 topology 30 36 +> 15 0.000000 7 0 topology 14 37 +> 16 0.000000 7 0 topology 13 37 +> 15 0.000000 7 0 topology 29 38 +> 16 0.000000 7 0 topology 11 38 +> 15 0.000000 8 0 topology 1 39 +> 16 0.000000 8 0 topology 11 39 +> 15 0.000000 9 0 topology 24 40 +> 16 0.000000 9 0 topology 7 40 +> 15 0.000000 9 0 topology 10 41 +> 16 0.000000 9 0 topology 5 41 +> 15 0.000000 9 0 topology 13 42 +> 16 0.000000 9 0 topology 3 42 +> 15 0.000000 9 0 topology 17 43 +> 16 0.000000 9 0 topology 4 43 +> 15 0.000000 9 0 topology 18 44 +> 16 0.000000 9 0 topology 6 44 +> 15 0.000000 9 0 topology 11 45 +> 16 0.000000 9 0 topology 2 45 +> 0 10 1 ACTOR +> 6 0.000000 32 10 3 "emigrant-1" +> 2 11 10 ACTOR_STATE +> 5 12 11 suspend "1 0 1" +> 5 13 11 sleep "1 1 0" +> 5 14 11 receive "1 0 0" +> 5 15 11 send "0 0 1" +> 5 16 11 execute "0 1 1" +> 4 17 0 10 10 ACTOR_LINK +> 6 0.000000 33 10 1 "policeman-2" +> 12 0.000000 11 32 13 +> 12 0.000000 11 33 15 +> 13 2.000000 11 32 +> 12 2.000000 11 32 14 +> 13 2.025708 11 33 +> 13 2.025708 11 32 +> 12 2.025708 11 33 15 +> 15 2.025708 17 0 M 32 0 +> 7 2.025708 10 32 +> 6 2.025708 34 10 1 "emigrant-1" +> 16 2.025708 17 0 M 34 0 +> 12 2.025708 11 34 13 +> 13 4.025708 11 34 +> 12 4.025708 11 34 14 +> 13 4.025903 11 33 +> 13 4.025903 11 34 +> 12 4.025903 11 33 15 +> 15 4.025903 17 0 M 34 1 +> 7 4.025903 10 34 +> 6 4.025903 35 10 2 "emigrant-1" +> 16 4.025903 17 0 M 35 1 +> 12 4.025903 11 35 13 +> 13 6.025903 11 35 +> 12 6.025903 11 35 14 +> 13 6.044918 11 33 +> 13 6.044918 11 35 +> 12 6.044918 11 33 15 +> 15 6.044918 17 0 M 35 2 +> 7 6.044918 10 35 +> 6 6.044918 36 10 3 "emigrant-1" +> 16 6.044918 17 0 M 36 2 +> 12 6.044918 11 36 13 +> 13 8.044918 11 36 +> 12 8.044918 11 36 14 +> 13 8.070626 11 33 +> 13 8.070626 11 36 +> 12 8.070626 11 33 15 +> 15 8.070626 17 0 M 36 3 +> 7 8.070626 10 36 +> 6 8.070626 37 10 4 "emigrant-1" +> 16 8.070626 17 0 M 37 3 +> 12 8.070626 11 37 13 +> 13 10.070626 11 37 +> 12 10.070626 11 37 14 +> 13 10.087178 11 33 +> 13 10.087178 11 37 +> 12 10.087178 11 33 15 +> 15 10.087178 17 0 M 37 4 +> 7 10.087178 10 37 +> 6 10.087178 38 10 5 "emigrant-1" +> 16 10.087178 17 0 M 38 4 +> 12 10.087178 11 38 13 +> 13 12.087178 11 38 +> 12 12.087178 11 38 14 +> 13 12.112617 11 33 +> 13 12.112617 11 38 +> 12 12.112617 11 33 15 +> 15 12.112617 17 0 M 38 5 +> 7 12.112617 10 38 +> 6 12.112617 39 10 3 "emigrant-1" +> 16 12.112617 17 0 M 39 5 +> 12 12.112617 11 39 13 +> 13 14.112617 11 39 +> 12 14.112617 11 39 14 +> 13 14.138325 11 33 +> 13 14.138325 11 39 +> 12 14.138325 11 33 15 +> 15 14.138325 17 0 M 39 6 +> 7 14.138325 10 39 +> 6 14.138325 40 10 1 "emigrant-1" +> 16 14.138325 17 0 M 40 6 +> 12 14.138325 11 40 13 +> 13 16.138325 11 40 +> 12 16.138325 11 40 14 +> 13 16.138521 11 33 +> 13 16.138521 11 40 +> 12 16.138521 11 33 15 +> 15 16.138521 17 0 M 40 7 +> 7 16.138521 10 40 +> 6 16.138521 41 10 4 "emigrant-1" +> 16 16.138521 17 0 M 41 7 +> 12 16.138521 11 41 13 +> 13 18.138521 11 41 +> 12 18.138521 11 41 14 +> 13 18.155073 11 33 +> 13 18.155073 11 41 +> 7 18.155073 10 33 +> 7 18.155073 10 41 +> 7 18.155073 6 16 +> 7 18.155073 6 14 +> 7 18.155073 6 19 +> 7 18.155073 6 20 +> 7 18.155073 6 18 +> 7 18.155073 6 21 +> 7 18.155073 6 22 +> 7 18.155073 6 12 +> 7 18.155073 6 9 +> 7 18.155073 6 15 +> 7 18.155073 6 23 +> 7 18.155073 6 24 +> 7 18.155073 6 17 +> 7 18.155073 6 25 +> 7 18.155073 6 26 +> 7 18.155073 6 27 +> 7 18.155073 6 8 +> 7 18.155073 6 10 +> 7 18.155073 6 28 +> 7 18.155073 6 29 +> 7 18.155073 6 13 +> 7 18.155073 6 30 +> 7 18.155073 6 11 > 7 18.155073 1 7 > 7 18.155073 1 5 > 7 18.155073 1 3 @@ -371,6 +375,6 @@ $ tail -n +3 procmig.trace > 7 18.155073 1 6 > 7 18.155073 1 2 > 7 18.155073 1 1 -> 7 18.155073 2 31 +> 7 18.155073 6 31 $ rm -f procmig.trace diff --git a/examples/cpp/trace-route-user-variables/s4u-trace-route-user-variables.cpp b/examples/cpp/trace-route-user-variables/s4u-trace-route-user-variables.cpp index 39a9eff10e..d00b9c7b2b 100644 --- a/examples/cpp/trace-route-user-variables/s4u-trace-route-user-variables.cpp +++ b/examples/cpp/trace-route-user-variables/s4u-trace-route-user-variables.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/deprecated/java/CMakeLists.txt b/examples/deprecated/java/CMakeLists.txt deleted file mode 100644 index 82c20ede05..0000000000 --- a/examples/deprecated/java/CMakeLists.txt +++ /dev/null @@ -1,66 +0,0 @@ -set(app-bittorrent_files Main Common Connection MessageTask Peer Tracker TrackerTask) -set(app-centralizedmutex_files Main Coordinator GrantTask Node ReleaseTask RequestTask) -set(app-masterworker_files Main Master Worker) -set(app-pingpong_files Main PingPongTask Receiver Sender) -set(app-tokenring_files Main RelayRunner) -set(async-waitall_files Main Receiver Sender) -set(async-yield_files Main Yielder) -set(async-dsend_files Main Receiver Sender) -set(cloud-masterworker_files Main Master Worker) -set(cloud-migration_files Main Daemon Test XVM) -set(dht-chord_files Main ChordTask Common FindSuccessorAnswerTask FindSuccessorTask - GetPredecessorAnswerTask GetPredecessorTask Node NotifyTask) -set(dht-kademlia_files Main Answer Bucket Common Contact FindNodeAnswerTask FindNodeTask - KademliaTask Node RoutingTable) -set(trace-pingpong_files Main PingPongTask Receiver Sender) -set(energy-consumption_files Main EnergyConsumer) -set(energy-pstate_files Main PstateRunner) -set(energy-vm_files Main EnergyVMRunner) -set(process-kill_files Main Killer Victim) -set(process-migration_files Main Emigrant Policeman) -set(process-startkilltime_files Main Sleeper) -set(process-suspend_files Main DreamMaster LazyGuy) -set(task-priority_files Main Test) -set(hostload_files Main LoadRunner) - -if(enable_java) - add_custom_target(java-all COMMENT "Building all Java examples...") - add_dependencies(tests java-all) - add_dependencies(java-all simgrid-java) # useful when the libs are not included in the jar -endif() - -foreach (example app-bittorrent app-centralizedmutex app-masterworker app-pingpong app-tokenring async-yield async-waitall async-dsend - cloud-migration cloud-masterworker dht-chord dht-kademlia energy-consumption energy-pstate energy-vm hostload - process-kill process-migration process-startkilltime process-suspend task-priority trace-pingpong) - string (REPLACE "-" "/" example_dir ${example}) - set (srcdir ${CMAKE_CURRENT_SOURCE_DIR}/${example_dir}) - foreach (filename ${${example}_files} ) - set( ${example}_sources "${${example}_sources}" "${srcdir}/${filename}.java") - endforeach() - - if(enable_java) - add_jar(java-${example} SOURCES ${${example}_sources} - INCLUDE_JARS simgrid-java_jar - OUTPUT_NAME ${example} - OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${example_dir}) - add_dependencies(java-all java-${example}) - - string (REPLACE "-" "/" example_dir ${example}) - ADD_TESH(java-${example} --setenv javacmd=${Java_JAVA_EXECUTABLE} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/deprecated/java --setenv LD_LIBRARY_PATH=${TESH_LIBRARY_PATH} --setenv classpath=""${TESH_CLASSPATH}${TESH_CLASSPATH_SEPARATOR}${example}.jar"" --cd ${CMAKE_BINARY_DIR}/examples/deprecated/java/${example_dir} ${CMAKE_HOME_DIRECTORY}/examples/deprecated/java/${example_dir}/${example}.tesh) - endif() - set(examples_src ${examples_src} ${${example}_sources}) - set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${example_dir}/${example}.tesh) -endforeach() - -set(examples_src ${examples_src} PARENT_SCOPE) -set(tesh_files ${tesh_files} PARENT_SCOPE) -set(bin_files ${bin_files} ${CMAKE_CURRENT_SOURCE_DIR}/app/bittorrent/generate.py PARENT_SCOPE) -set(txt_files ${txt_files} ${CMAKE_CURRENT_SOURCE_DIR}/app/masterworker/README - ${CMAKE_CURRENT_SOURCE_DIR}/cloud/migration/README PARENT_SCOPE) -set(xml_files ${xml_files} ${CMAKE_CURRENT_SOURCE_DIR}/app/bittorrent/bittorrent.xml - ${CMAKE_CURRENT_SOURCE_DIR}/app/centralizedmutex/centralizedmutex.xml - ${CMAKE_CURRENT_SOURCE_DIR}/app/masterworker/masterworker.xml - ${CMAKE_CURRENT_SOURCE_DIR}/dht/chord/chord.xml - ${CMAKE_CURRENT_SOURCE_DIR}/dht/kademlia/kademlia.xml - ${CMAKE_CURRENT_SOURCE_DIR}/process/startkilltime/startkilltime.xml - ${CMAKE_CURRENT_SOURCE_DIR}/task/priority/priority.xml PARENT_SCOPE) diff --git a/examples/deprecated/java/app/bittorrent/Common.java b/examples/deprecated/java/app/bittorrent/Common.java deleted file mode 100644 index 2e7f0c81f9..0000000000 --- a/examples/deprecated/java/app/bittorrent/Common.java +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.bittorrent; - -/* Common constants for use in the simulation */ -class Common { - public static final String TRACKER_MAILBOX = "tracker_mailbox"; - public static final int FILE_SIZE = 5120; - public static final int FILE_PIECE_SIZE = 512; - public static final int FILE_PIECES = 10; - public static final int PIECES_BLOCKS = 5; - public static final int BLOCKS_REQUESTED = 2; - public static final int PIECE_COMM_SIZE = 1; - public static final int MESSAGE_SIZE = 1; /* Information message size */ - public static final int MAXIMUM_PEERS = 50; /* Max number of peers sent by the tracker to clients */ - public static final int TRACKER_QUERY_INTERVAL = 1000; /* Interval of time where the peer should send a request to the tracker */ - public static final double TRACKER_COMM_SIZE = 1; /* Communication size for a task to the tracker */ - public static final int GET_PEERS_TIMEOUT = 10000; /* Timeout for the get peers data */ - public static final int TIMEOUT_MESSAGE = 10; - public static final int TRACKER_RECEIVE_TIMEOUT = 10; - public static final int MAX_UNCHOKED_PEERS = 4; /* Number of peers that can be unchocked at a given time */ - public static final int UPDATE_CHOKED_INTERVAL = 30; /* Interval between each update of the choked peers */ - public static final int MAX_PIECES = 1; /* Number of pieces the peer asks for simultaneously */ - private Common() { - throw new IllegalAccessError("Utility class"); - } -} diff --git a/examples/deprecated/java/app/bittorrent/Connection.java b/examples/deprecated/java/app/bittorrent/Connection.java deleted file mode 100644 index 34288f8137..0000000000 --- a/examples/deprecated/java/app/bittorrent/Connection.java +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.bittorrent; -import java.util.Arrays; - -public class Connection { - protected int id; - protected char[] bitfield; - protected String mailbox; - // Indicates if we are interested in something this peer has - protected boolean amInterested = false; - // Indicates if the peer is interested in one of our pieces - protected boolean interested = false; - // Indicates if the peer is choked for the current peer - protected boolean chokedUpload = true; - // Indicates if the peer has choked the current peer - protected boolean chokedDownload = true; - // Number of messages we have received from the peer - protected int messagesCount = 0; - protected double peerSpeed = 0; - protected double lastUnchoke = 0; - - public Connection(int id) { - this.id = id; - this.mailbox = Integer.toString(id); - } - - // Add a new value to the peer speed average - public void addSpeedValue(double speed) { - peerSpeed = peerSpeed * 0.55 + speed * 0.45; - } - - @Override - public String toString() { - return "Connection [id=" + id + ", bitfield=" + Arrays.toString(bitfield) + ", mailbox=" + mailbox - + ", amInterested=" + amInterested + ", interested=" + interested + ", chokedUpload=" + chokedUpload - + ", chokedDownload=" + chokedDownload + "]"; - } -} diff --git a/examples/deprecated/java/app/bittorrent/Main.java b/examples/deprecated/java/app/bittorrent/Main.java deleted file mode 100644 index e0a9d6761a..0000000000 --- a/examples/deprecated/java/app/bittorrent/Main.java +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.bittorrent; - -import org.simgrid.msg.Msg; - -class Main{ - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - if(args.length < 2) { - Msg.info("Usage : Bittorrent platform_file deployment_file"); - Msg.info("example : Bittorrent ../platforms/cluster_backbone.xml bittorrent.xml"); - System.exit(1); - } - - /* construct the platform and deploy the application */ - Msg.createEnvironment(args[0]); - Msg.deployApplication(args[1]); - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/app/bittorrent/MessageTask.java b/examples/deprecated/java/app/bittorrent/MessageTask.java deleted file mode 100644 index 141dc8bd94..0000000000 --- a/examples/deprecated/java/app/bittorrent/MessageTask.java +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.bittorrent; -import org.simgrid.msg.Task; - -public class MessageTask extends Task { - public enum Type { - HANDSHAKE, - CHOKE, - UNCHOKE, - INTERESTED, - NOTINTERESTED, - HAVE, - BITFIELD, - REQUEST, - PIECE - } - - protected Type type; - protected String issuerHostname; - protected String mailbox; - protected int peerId; - protected char[] bitfield; - protected int index; - protected int blockIndex; - protected int blockLength; - protected boolean stalled; - - public MessageTask(Type type, String issuerHostname, String mailbox, int peerId) { - this(type,issuerHostname,mailbox,peerId,-1,false,-1,-1); - } - - public MessageTask(Type type, String issuerHostname, String mailbox, int peerId, int index) { - this(type,issuerHostname,mailbox,peerId,index,false,-1,-1); - } - - // builds a new bitfield message - public MessageTask(Type type, String issuerHostname, String mailbox, int peerId, char[] bitfield) { - this(type,issuerHostname,mailbox,peerId,-1,false,-1,-1); - this.bitfield = bitfield; - } - - // build a new "request" message - public MessageTask(Type type, String issuerHostname, String mailbox, int peerId, int index, int blockIndex, - int blockLength) { - this(type,issuerHostname,mailbox,peerId,index,false,blockIndex,blockLength); - } - - // build a new "piece" message - public MessageTask(Type type, String issuerHostname, String mailbox, int peerId, int index, boolean stalled, - int blockIndex, int blockLength) { - this.type = type; - this.issuerHostname = issuerHostname; - this.mailbox = mailbox; - this.peerId = peerId; - this.index = index; - this.stalled = stalled; - this.blockIndex = blockIndex; - this.blockLength = blockLength; - } -} diff --git a/examples/deprecated/java/app/bittorrent/Peer.java b/examples/deprecated/java/app/bittorrent/Peer.java deleted file mode 100644 index eb9ab122ff..0000000000 --- a/examples/deprecated/java/app/bittorrent/Peer.java +++ /dev/null @@ -1,627 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.bittorrent; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map.Entry; -import java.util.Random; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Comm; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; - -public class Peer extends Process { - Random rand = new Random(); - protected int round = 0; - protected double beginReceiveTime; - protected double deadline; - protected int id; - protected String mailbox; - protected String mailboxTracker; - protected String hostname; - protected int pieces = 0; - protected char[] bitfield = new char[Common.FILE_PIECES]; - protected char[][] bitfieldBlocks = new char[Common.FILE_PIECES][Common.PIECES_BLOCKS]; - protected short[] piecesCount = new short[Common.FILE_PIECES]; - protected int piecesRequested = 0; - protected ArrayList currentPieces = new ArrayList<>(); - protected int currentPiece = -1; - protected HashMap activePeers = new HashMap<>(); - protected HashMap peers = new HashMap<>(); - protected Comm commReceived = null; - - public Peer(Host host, String name, String[]args) { - super(host,name,args); - } - - @Override - public void main(String[] args) throws MsgException { - //Check arguments - if (args.length != 3 && args.length != 2) { - Msg.info("Wrong number of arguments"); - } - init(Integer.parseInt(args[0]), (args.length == 3)); - - //Retrieve the deadline - deadline = Double.parseDouble(args[1]); - if (deadline < 0) { - Msg.info("Wrong deadline supplied"); - return; - } - Msg.info("Hi, I'm joining the network with id " + id); - //Getting peer data from the tracker - if (getPeersData()) { - Msg.debug("Got " + peers.size() + " peers from the tracker"); - Msg.debug("Here is my current status: " + getStatus()); - beginReceiveTime = Msg.getClock(); - if (hasFinished()) { - pieces = Common.FILE_PIECES; - sendHandshakeAll(); - seedLoop(); - } else { - leechLoop(); - seedLoop(); - } - } else { - Msg.info("Couldn't contact the tracker."); - } - Msg.info("Here is my current status: " + getStatus()); - } - - private void leechLoop() { - double nextChokedUpdate = Msg.getClock() + Common.UPDATE_CHOKED_INTERVAL; - Msg.debug("Start downloading."); - // Send a "handshake" message to all the peers it got(it couldn't have gotten more than 50 peers anyway) - sendHandshakeAll(); - //Wait for at least one "bitfield" message. - waitForPieces(); - Msg.debug("Starting main leech loop"); - while (Msg.getClock() < deadline && pieces < Common.FILE_PIECES) { - if (commReceived == null) { - commReceived = Task.irecv(mailbox); - } - try { - if (commReceived.test()) { - handleMessage(commReceived.getTask()); - commReceived = null; - } else { - //If the user has a pending interesting - if (currentPiece != -1) { - sendInterestedToPeers(); - } else { - if (currentPieces.size() < Common.MAX_PIECES) { - updateCurrentPiece(); - } - } - //We don't execute the choke algorithm if we don't already have a piece - if (Msg.getClock() >= nextChokedUpdate && pieces > 0) { - updateChokedPeers(); - nextChokedUpdate += Common.UPDATE_CHOKED_INTERVAL; - } else { - waitFor(1); - } - } - } - catch (MsgException e) { - e.printStackTrace(); - commReceived = null; - } - } - } - - private void seedLoop() { - double nextChokedUpdate = Msg.getClock() + Common.UPDATE_CHOKED_INTERVAL; - Msg.debug("Start seeding."); - //start the main seed loop - while (Msg.getClock() < deadline) { - if (commReceived == null) { - commReceived = Task.irecv(mailbox); - } - try { - if (commReceived.test()) { - handleMessage(commReceived.getTask()); - commReceived = null; - } else { - if (Msg.getClock() >= nextChokedUpdate) { - updateChokedPeers(); - //TODO: Change the choked peer algorithm when seeding - nextChokedUpdate += Common.UPDATE_CHOKED_INTERVAL; - } else { - waitFor(1); - } - } - } - catch (MsgException e) { - commReceived = null; - } - } - } - - /** - * @brief Initialize the various peer data - * @param id id of the peer to take in the network - * @param seed indicates if the peer is a seed - */ - private void init(int id, boolean seed) { - this.id = id; - this.mailbox = Integer.toString(id); - this.mailboxTracker = "tracker_" + Integer.toString(id); - if (seed) { - for (int i = 0; i < bitfield.length; i++) { - bitfield[i] = '1'; - for (int j = 0; j < bitfieldBlocks[i].length; j++) { - bitfieldBlocks[i][j] = '1'; - } - } - } else { - for (int i = 0; i < bitfield.length; i++) { - bitfield[i] = '0'; - for (int j = 0; j < bitfieldBlocks[i].length; j++) { - bitfieldBlocks[i][j] = '0' ; - } - } - } - this.hostname = getHost().getName(); - } - - private boolean getPeersData() { - boolean success = false; - double timeout = Msg.getClock() + Common.GET_PEERS_TIMEOUT; - //Build the task to send to the tracker - TrackerTask taskSend = new TrackerTask(hostname, mailboxTracker, id); - - while (Msg.getClock() < timeout) { - try { - Msg.debug("Sending a peer request to the tracker."); - taskSend.send(Common.TRACKER_MAILBOX,Common.GET_PEERS_TIMEOUT); - break; - } - catch (MsgException e) { - e.printStackTrace(); - } - } - while (!success && Msg.getClock() < timeout) { - commReceived = Task.irecv(this.mailboxTracker); - try { - commReceived.waitCompletion(Common.GET_PEERS_TIMEOUT); - if (commReceived.getTask() instanceof TrackerTask) { - TrackerTask task = (TrackerTask)commReceived.getTask(); - for (Integer peerId: task.peers) { - if (peerId != this.id) { - peers.put(peerId, new Connection(peerId)); - } - } - success = true; - } - } - catch (MsgException e) { - e.printStackTrace(); - } - commReceived = null; - } - return success; - } - - private void handleMessage(Task task) { - MessageTask message = (MessageTask)task; - Connection remotePeer = peers.get(message.peerId); - switch (message.type) { - case HANDSHAKE: - Msg.debug("Received a HANDSHAKE message from " + message.mailbox); - //Check if the peer is in our connection list - if (remotePeer == null) { - peers.put(message.peerId, new Connection(message.peerId)); - sendHandshake(message.mailbox); - } - //Send our bitfield to the pair - sendBitfield(message.mailbox); - break; - case BITFIELD: - Msg.debug("Received a BITFIELD message from " + message.peerId + " (" + message.issuerHostname + ")"); - //update the pieces list - updatePiecesCountFromBitfield(message.bitfield); - //Update the current piece - if (currentPiece == -1 && pieces < Common.FILE_PIECES && currentPieces.size() < Common.MAX_PIECES) { - updateCurrentPiece(); - } - remotePeer.bitfield = message.bitfield.clone(); - break; - case INTERESTED: - Msg.debug("Received an INTERESTED message from " + message.peerId + " (" + message.issuerHostname + ")"); - assert remotePeer != null; - remotePeer.interested = true; - break; - case NOTINTERESTED: - Msg.debug("Received a NOTINTERESTED message from " + message.peerId + " (" + message.issuerHostname + ")"); - assert remotePeer != null; - remotePeer.interested = false; - break; - case UNCHOKE: - Msg.debug("Received an UNCHOKE message from " + message.peerId + "(" + message.issuerHostname + ")"); - assert remotePeer != null; - remotePeer.chokedDownload = false; - activePeers.put(remotePeer.id,remotePeer); - sendRequestsToPeer(remotePeer); - break; - case CHOKE: - Msg.debug("Received a CHOKE message from " + message.peerId + " (" + message.issuerHostname + ")"); - assert remotePeer != null; - remotePeer.chokedDownload = true; - activePeers.remove(remotePeer.id); - break; - case HAVE: - if (remotePeer.bitfield == null) { - return; - } - Msg.debug("Received a HAVE message from " + message.peerId + " (" + message.issuerHostname + ")"); - assert message.index >= 0 && message.index < Common.FILE_PIECES; - assert remotePeer.bitfield != null; - remotePeer.bitfield[message.index] = '1'; - piecesCount[message.index]++; - //Send interested message to the peer if he has what we want - if (!remotePeer.amInterested && currentPieces.contains(message.index) ) { - remotePeer.amInterested = true; - sendInterested(remotePeer.mailbox); - } - - if (currentPieces.contains(message.index)) { - int blockIndex = getFirstBlock(message.index); - int blockLength = Common.PIECES_BLOCKS - blockIndex ; - blockLength = blockLength > Common.BLOCKS_REQUESTED ? Common.BLOCKS_REQUESTED : blockLength; - sendRequest(message.mailbox,message.index,blockIndex,blockLength); - } - break; - case REQUEST: - assert message.index >= 0 && message.index < Common.FILE_PIECES; - if (!remotePeer.chokedUpload) { - Msg.debug("Received a REQUEST from " + message.peerId + "(" + message.issuerHostname + ") for " - + message.peerId); - if (bitfield[message.index] == '1') { - sendPiece(message.mailbox,message.index,false,message.blockIndex,message.blockLength); - } else { - Msg.debug("Received a REQUEST from " + message.peerId + " (" + message.issuerHostname - + ") but he is choked" ); - } - } - break; - case PIECE: - if (message.stalled) { - Msg.debug("The received piece " + message.index + " from " + message.peerId + " (" + message.issuerHostname - + ") is stalled"); - } else { - Msg.debug("Received piece " + message.index + " from " + message.peerId + " (" - + message.issuerHostname + ")"); - if (bitfield[message.index] == '0') { - updateBitfieldBlocks(message.index,message.blockIndex,message.blockLength); - if (pieceComplete(message.index)) { - piecesRequested--; - //Removing the piece from our piece list. - currentPieces.remove((Object)Integer.valueOf(message.index)); - //Setting the fact that we have the piece - bitfield[message.index] = '1'; - pieces++; - Msg.debug("My status is now " + getStatus()); - //Sending the information to all the peers we are connected to - sendHave(message.index); - //sending UNINTERESTED to peers that doesn't have what we want. - updateInterestedAfterReceive(); - } - } else { - Msg.debug("However, we already have it."); - } - } - break; - default: - Msg.error("Unexpected message type: " + message.type); - break; - } - if (remotePeer != null) { - remotePeer.addSpeedValue(1 / (Msg.getClock() - beginReceiveTime)); - } - beginReceiveTime = Msg.getClock(); - } - - private void waitForPieces() { - boolean finished = false; - while (Msg.getClock() < deadline && !finished) { - if (commReceived == null) { - commReceived = Task.irecv(mailbox); - } - try { - commReceived.waitCompletion(Common.TIMEOUT_MESSAGE); - handleMessage(commReceived.getTask()); - if (currentPiece != -1) { - finished = true; - } - commReceived = null; - } - catch (MsgException e) { - commReceived = null; - } - } - } - - private boolean hasFinished() { - for (int i = 0; i < bitfield.length; i++) { - if (bitfield[i] == '1') { - return true; - } - } - return false; - } - - /** - * @brief Updates the list of who has a piece from a bitfield - * @param bitfield bitfield - */ - private void updatePiecesCountFromBitfield(char[] bitfield) { - for (int i = 0; i < Common.FILE_PIECES; i++) { - if (bitfield[i] == '1') { - piecesCount[i]++; - } - } - } - - /** - * Update the piece the peer is currently interested in. - * There is two cases (as described in "Bittorrent Architecture Protocol", Ryan Toole : - * If the peer has less than 3 pieces, he chooses a piece at random. - * If the peer has more than pieces, he downloads the pieces that are the less - * replicated - */ - private void updateCurrentPiece() { - if (currentPieces.size() >= (Common.FILE_PIECES - pieces)) { - return; - } - - //TODO: trivial min algorithm when pieces >= 3 - do { - currentPiece = rand.nextInt(Common.FILE_PIECES); - } while (!(bitfield[currentPiece] == '0' && !currentPieces.contains(currentPiece))); - - currentPieces.add(currentPiece); - Msg.debug("New interested piece: " + currentPiece); - assert currentPiece >= 0 && currentPiece < Common.FILE_PIECES; - } - - // Update the list of current choked and unchoked peers, using the choke algorithm - private void updateChokedPeers() { - round = (round + 1) % 3; - if (peers.isEmpty()) { - return; - } - //remove a peer from the list - Iterator> it = activePeers.entrySet().iterator(); - if (it.hasNext()) { - Entry e = it.next(); - Connection peerChoked = e.getValue(); - peerChoked.chokedUpload = true; - sendChoked(peerChoked.mailbox); - activePeers.remove(e.getKey()); - } - Connection peerChosen = null; - //Separate the case from when the peer is seeding. - if (pieces == Common.FILE_PIECES) { - //Find the last unchoked peer. - double unchokeTime = deadline + 1; - for (Connection connection : peers.values()) { - if (connection.lastUnchoke < unchokeTime && connection.interested) { - peerChosen = connection; - unchokeTime = connection.lastUnchoke; - } - } - } else { - //Random optimistic unchoking - if (round == 0) { - int j = 0; - do { - int i = 0; - int idChosen = rand.nextInt(peers.size()); - for (Connection connection : peers.values()) { - if (i == idChosen) { - peerChosen = connection; - break; - } - i++; - } //TODO: Not really the best way ever - if (peerChosen != null && !peerChosen.interested) { - peerChosen = null; - } - j++; - } while (peerChosen == null && j < Common.MAXIMUM_PEERS); - } else { - Connection fastest = null; - double fastestSpeed = 0; - for (Connection c : peers.values()) { - if (c.peerSpeed > fastestSpeed && c.interested && c.chokedUpload) { - fastest = c; - fastestSpeed = c.peerSpeed; - } - } - peerChosen = fastest; - } - } - if (peerChosen != null) { - activePeers.put(peerChosen.id,peerChosen); - peerChosen.chokedUpload = false; - peerChosen.lastUnchoke = Msg.getClock(); - sendUnchoked(peerChosen.mailbox); - } - } - - // Updates our "interested" state about peers: send "not interested" to peers that don't have any more pieces we want. - private void updateInterestedAfterReceive() { - boolean interested; - for (Connection connection : peers.values()) { - interested = false; - if (connection.amInterested) { - for (Integer piece : currentPieces) { - if (connection.bitfield[piece] == '1') { - interested = true; - break; - } - } - if (!interested) { - connection.amInterested = false; - sendNotInterested(connection.mailbox); - } - } - } - } - - private void updateBitfieldBlocks(int index, int blockIndex, int blockLength) { - for (int i = blockIndex; i < (blockIndex + blockLength); i++) { - bitfieldBlocks[index][i] = '1'; - } - } - - // Returns if a piece is complete in the peer's bitfield. - private boolean pieceComplete(int index) { - for (int i = 0; i < bitfieldBlocks[index].length; i++) { - if (bitfieldBlocks[index][i] == '0') { - return false; - } - } - return true; - } - - // Returns the first block of a piece that we don't have. - private int getFirstBlock(int piece) { - int blockIndex = -1; - for (int i = 0; i < Common.PIECES_BLOCKS; i++) { - if (bitfieldBlocks[piece][i] == '0') { - blockIndex = i; - break; - } - } - return blockIndex; - } - - /** - * @brief Send request messages to a peer that have unchoked us - * @param remotePeer peer data to the peer we want to send the request - */ - private void sendRequestsToPeer(Connection remotePeer) { - if (remotePeer.bitfield == null) { - return; - } - for (Integer piece : currentPieces) { - //Getting the block to send. - int blockIndex = getFirstBlock(piece); - int blockLength = Common.PIECES_BLOCKS - blockIndex ; - blockLength = blockLength > Common.BLOCKS_REQUESTED ? Common.BLOCKS_REQUESTED : blockLength; - if (remotePeer.bitfield[piece] == '1') { - sendRequest(remotePeer.mailbox, piece, blockIndex, blockLength); - } - } - } - - // Find the peers that have the current interested piece and send them the "interested" message - private void sendInterestedToPeers() { - if (currentPiece == -1) { - return; - } - for (Connection connection : peers.values()) { - if (connection.bitfield != null && connection.bitfield[currentPiece] == '1' && !connection.amInterested) { - connection.amInterested = true; - MessageTask task = new MessageTask(MessageTask.Type.INTERESTED, hostname, this.mailbox, this.id); - task.dsend(connection.mailbox); - } - } - currentPiece = -1; - piecesRequested++; - } - - // Send a "interested" message to a peer. - private void sendInterested(String mailbox) { - MessageTask task = new MessageTask(MessageTask.Type.INTERESTED, hostname, this.mailbox, this.id); - task.dsend(mailbox); - } - - /** - * @brief Send a "not interested" message to a peer - * @param mailbox mailbox destination mailbox - */ - private void sendNotInterested(String mailbox) { - MessageTask task = new MessageTask(MessageTask.Type.NOTINTERESTED, hostname, this.mailbox, this.id); - task.dsend(mailbox); - } - - // Send a handshake message to all the peers the peer has. - private void sendHandshakeAll() { - for (Connection remotePeer : peers.values()) { - MessageTask task = new MessageTask(MessageTask.Type.HANDSHAKE, hostname, mailbox, id); - task.dsend(remotePeer.mailbox); - } - } - - /** - * @brief Send a "handshake" message to an user - * @param mailbox mailbox where to we send the message - */ - private void sendHandshake(String mailbox) { - Msg.debug("Sending a HANDSHAKE to " + mailbox); - MessageTask task = new MessageTask(MessageTask.Type.HANDSHAKE, hostname, this.mailbox, this.id); - task.dsend(mailbox); - } - - // Send a "choked" message to a peer - private void sendChoked(String mailbox) { - Msg.debug("Sending a CHOKE to " + mailbox); - MessageTask task = new MessageTask(MessageTask.Type.CHOKE, hostname, this.mailbox, this.id); - task.dsend(mailbox); - } - - // Send a "unchoked" message to a peer - private void sendUnchoked(String mailbox) { - Msg.debug("Sending a UNCHOKE to " + mailbox); - MessageTask task = new MessageTask(MessageTask.Type.UNCHOKE, hostname, this.mailbox, this.id); - task.dsend(mailbox); - } - - // Send a "HAVE" message to all peers we are connected to - private void sendHave(int piece) { - Msg.debug("Sending HAVE message to all my peers"); - for (Connection remotePeer : peers.values()) { - MessageTask task = new MessageTask(MessageTask.Type.HAVE, hostname, this.mailbox, this.id, piece); - task.dsend(remotePeer.mailbox); - } - } - // Send a bitfield message to all the peers the peer has. - private void sendBitfield(String mailbox) { - Msg.debug("Sending a BITFIELD to " + mailbox); - MessageTask task = new MessageTask(MessageTask.Type.BITFIELD, hostname, this.mailbox, this.id, this.bitfield); - task.dsend(mailbox); - } - // Send a "request" message to a peer, containing a request for a piece - private void sendRequest(String mailbox, int piece, int blockIndex, int blockLength) { - Msg.debug("Sending a REQUEST to " + mailbox + " for piece " + piece + " and blocks " + blockIndex + "," - + (blockIndex + blockLength)); - MessageTask task = new MessageTask(MessageTask.Type.REQUEST, hostname, this.mailbox, this.id, piece, blockIndex, - blockLength); - task.dsend(mailbox); - } - - // Send a "piece" message to a peer, containing a piece of the file - private void sendPiece(String mailbox, int piece, boolean stalled, int blockIndex, int blockLength) { - Msg.debug("Sending the PIECE " + piece + " to " + mailbox); - MessageTask task = new MessageTask(MessageTask.Type.PIECE, hostname, this.mailbox, this.id, piece, stalled, - blockIndex, blockLength); - task.dsend(mailbox); - } - - private String getStatus() { - StringBuilder s = new StringBuilder(""); - for (int i = 0; i < Common.FILE_PIECES; i++) - s.append(bitfield[i]); - return s.toString(); - } -} diff --git a/examples/deprecated/java/app/bittorrent/Tracker.java b/examples/deprecated/java/app/bittorrent/Tracker.java deleted file mode 100644 index 58e11b6a5c..0000000000 --- a/examples/deprecated/java/app/bittorrent/Tracker.java +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.bittorrent; -import java.util.ArrayList; -import java.util.Random; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Comm; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; - -public class Tracker extends Process { - Random rand = new Random(); - protected ArrayList peersList; - protected double deadline; - protected Comm commReceived = null; - - public Tracker(Host host, String name, String[]args) { - super(host,name,args); - } - - @Override - public void main(String[] args) throws MsgException { - if (args.length != 1) { - Msg.info("Wrong number of arguments for the tracker."); - return; - } - //Retrieve the end time - deadline = Double.parseDouble(args[0]); - //Building peers array - peersList = new ArrayList<>(); - - Msg.info("Tracker launched."); - while (Msg.getClock() < deadline) { - if (commReceived == null) { - commReceived = Task.irecv(Common.TRACKER_MAILBOX); - } - try { - if (commReceived.test()) { - Task task = commReceived.getTask(); - if (task instanceof TrackerTask) { - TrackerTask tTask = (TrackerTask)task; - //Sending peers to the peer - int nbPeers = 0; - while (nbPeers < Common.MAXIMUM_PEERS && nbPeers < peersList.size()) { - int nextPeer; - do { - nextPeer = rand.nextInt(peersList.size()); - } while (tTask.peers.contains(peersList.get(nextPeer))); - tTask.peers.add(peersList.get(nextPeer)); - nbPeers++; - } - //Adding the peer to our list - peersList.add(tTask.peerId); - tTask.type = TrackerTask.Type.ANSWER; - //Setting the interval - tTask.interval = Common.TRACKER_QUERY_INTERVAL; - //Sending the task back to the peer - tTask.dsend(tTask.mailbox); - } - commReceived = null; - } else { - waitFor(1); - } - } - catch (MsgException e) { - commReceived = null; - } - } - Msg.info("Tracker is leaving"); - } -} diff --git a/examples/deprecated/java/app/bittorrent/TrackerTask.java b/examples/deprecated/java/app/bittorrent/TrackerTask.java deleted file mode 100644 index aec2ec95cc..0000000000 --- a/examples/deprecated/java/app/bittorrent/TrackerTask.java +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.bittorrent; -import java.util.ArrayList; - -import org.simgrid.msg.Task; - -/* Task exchanged between the tracker and the peers. */ -public class TrackerTask extends Task { - public enum Type { - REQUEST, - ANSWER - } - - protected Type type; - protected String hostname; - protected String mailbox; - protected int peerId; - protected int uploaded; - protected int downloaded; - protected int left; - protected double interval; - protected ArrayList peers; - - public TrackerTask(String hostname, String mailbox, int peerId) { - this(hostname, mailbox, peerId, 0, 0, Common.FILE_SIZE); - } - - public TrackerTask(String hostname, String mailbox, int peerId, int uploaded, int downloaded, int left) { - super("", 0, Common.TRACKER_COMM_SIZE); - this.type = Type.REQUEST; - this.hostname = hostname; - this.mailbox = mailbox; - this.peerId = peerId; - this.uploaded = uploaded; - this.downloaded = downloaded; - this.left = left; - this.peers = new ArrayList<>(); - } -} diff --git a/examples/deprecated/java/app/bittorrent/app-bittorrent.tesh b/examples/deprecated/java/app/bittorrent/app-bittorrent.tesh deleted file mode 100644 index ce00fa8e1c..0000000000 --- a/examples/deprecated/java/app/bittorrent/app-bittorrent.tesh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 -! timeout 15 - -$ ${javacmd:=java} -classpath ${classpath:=.} app/bittorrent/Main ${srcdir:=.}/../../platforms/cluster_backbone.xml ${srcdir:=.}/app/bittorrent/bittorrent.xml -> [0.000000] [java/INFO] Using regular java threads. -> [5000.039030] [java/INFO] Terminating the simulation... -> [node-0.simgrid.org:app.bittorrent.Tracker:(1) 0.000000] [java/INFO] Tracker launched. -> [node-0.simgrid.org:app.bittorrent.Tracker:(1) 3000.000000] [java/INFO] Tracker is leaving -> [node-1.simgrid.org:app.bittorrent.Peer:(2) 0.000000] [java/INFO] Hi, I'm joining the network with id 2 -> [node-1.simgrid.org:app.bittorrent.Peer:(2) 5000.007806] [java/INFO] Here is my current status: 1111111111 -> [node-2.simgrid.org:app.bittorrent.Peer:(3) 0.000000] [java/INFO] Hi, I'm joining the network with id 3 -> [node-2.simgrid.org:app.bittorrent.Peer:(3) 5000.031224] [java/INFO] Here is my current status: 1111111111 -> [node-3.simgrid.org:app.bittorrent.Peer:(4) 0.000000] [java/INFO] Hi, I'm joining the network with id 4 -> [node-3.simgrid.org:app.bittorrent.Peer:(4) 5000.039030] [java/INFO] Here is my current status: 1111111111 -> [node-4.simgrid.org:app.bittorrent.Peer:(5) 0.000000] [java/INFO] Hi, I'm joining the network with id 5 -> [node-4.simgrid.org:app.bittorrent.Peer:(5) 5000.007806] [java/INFO] Here is my current status: 1111111111 -> [node-5.simgrid.org:app.bittorrent.Peer:(6) 0.000000] [java/INFO] Hi, I'm joining the network with id 6 -> [node-5.simgrid.org:app.bittorrent.Peer:(6) 5000.023418] [java/INFO] Here is my current status: 1111111111 -> [node-6.simgrid.org:app.bittorrent.Peer:(7) 0.000000] [java/INFO] Hi, I'm joining the network with id 7 -> [node-6.simgrid.org:app.bittorrent.Peer:(7) 5000.039030] [java/INFO] Here is my current status: 1111111111 -> [node-7.simgrid.org:app.bittorrent.Peer:(8) 0.000000] [java/INFO] Hi, I'm joining the network with id 8 -> [node-7.simgrid.org:app.bittorrent.Peer:(8) 5000.031224] [java/INFO] Here is my current status: 1111111111 diff --git a/examples/deprecated/java/app/bittorrent/bittorrent.xml b/examples/deprecated/java/app/bittorrent/bittorrent.xml deleted file mode 100644 index a510cf0753..0000000000 --- a/examples/deprecated/java/app/bittorrent/bittorrent.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/deprecated/java/app/bittorrent/generate.py b/examples/deprecated/java/app/bittorrent/generate.py deleted file mode 100755 index a565dc1815..0000000000 --- a/examples/deprecated/java/app/bittorrent/generate.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2013-2022. The SimGrid Team. -# All rights reserved. - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the license (GNU LGPL) which comes with this package. - -""" -This script generates a specific deployment file for the Bittorrent example. -It assumes that the platform will be a cluster. -Usage: python generate.py nb_nodes nb_bits end_date percentage -Example: python generate.py 10000 5000 -""" - -import sys -import random - -if len(sys.argv) != 4: - print( - "Usage: python generate.py nb_nodes end_date seed_percentage > deployment_file.xml") - sys.exit(1) - -nb_nodes = int(sys.argv[1]) -end_date = int(sys.argv[2]) -seed_percentage = int(sys.argv[3]) - -nb_bits = 24 -max_id = 2 ** nb_bits - 1 -all_ids = [42] - -sys.stdout.write("\n" - "\n" - "\n" - " \n" % - end_date) - -for i in range(1, nb_nodes): - - ok = False - while not ok: - my_id = random.randint(0, max_id) - ok = my_id not in all_ids - start_date = i * 10 - line = " " \ - "" % (i, my_id, end_date) - if random.randint(0, 100) < seed_percentage: - line += "" - line += "\n" - sys.stdout.write(line) - all_ids.append(my_id) -sys.stdout.write("") diff --git a/examples/deprecated/java/app/centralizedmutex/Coordinator.java b/examples/deprecated/java/app/centralizedmutex/Coordinator.java deleted file mode 100644 index cdf0447d41..0000000000 --- a/examples/deprecated/java/app/centralizedmutex/Coordinator.java +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.centralizedmutex; -import java.util.LinkedList; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; - -public class Coordinator extends Process { - public Coordinator(Host host, String name, String[]args) { - super(host,name,args); - } - - public void main(String[] args) throws MsgException { - int csToServe = Integer.parseInt(args[0]); - LinkedList waitingQueue=new LinkedList<>(); - - while (csToServe >0) { - Task task = Task.receive("coordinator"); - if (task instanceof RequestTask) { - RequestTask t = (RequestTask) task; - if (waitingQueue.isEmpty()) { - Msg.info("Got a request from "+t.from+". Queue empty: grant it"); - GrantTask tosend = new GrantTask(); - tosend.send(t.from); - } else { - waitingQueue.addFirst(t); - } - } else if (task instanceof ReleaseTask) { - if (!waitingQueue.isEmpty()) { - RequestTask req = waitingQueue.removeLast(); - GrantTask tosend = new GrantTask(); - tosend.send(req.from); - } - csToServe--; - if (waitingQueue.isEmpty() && csToServe==0) { - Msg.info("we should shutdown the simulation now"); - } - } - } - } -} diff --git a/examples/deprecated/java/app/centralizedmutex/GrantTask.java b/examples/deprecated/java/app/centralizedmutex/GrantTask.java deleted file mode 100644 index b7afba319a..0000000000 --- a/examples/deprecated/java/app/centralizedmutex/GrantTask.java +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.centralizedmutex; -public class GrantTask extends org.simgrid.msg.Task {} diff --git a/examples/deprecated/java/app/centralizedmutex/Main.java b/examples/deprecated/java/app/centralizedmutex/Main.java deleted file mode 100644 index 24c439a4c2..0000000000 --- a/examples/deprecated/java/app/centralizedmutex/Main.java +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.centralizedmutex; - -import org.simgrid.msg.Msg; - -class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - - String platf = args.length > 1 ? args[0] : "../platforms/small_platform.xml"; - String deploy = args.length > 1 ? args[1] : "./centralizedmutex.xml"; - - /* construct the platform and deploy the application */ - Msg.createEnvironment(platf); - Msg.deployApplication(deploy); - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/app/centralizedmutex/Node.java b/examples/deprecated/java/app/centralizedmutex/Node.java deleted file mode 100644 index fbc385a9a4..0000000000 --- a/examples/deprecated/java/app/centralizedmutex/Node.java +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.centralizedmutex; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; - -public class Node extends Process { - public Node(Host host, String name, String[]args) { - super(host,name,args); - } - public void request(double csTime) throws MsgException { - RequestTask req = new RequestTask(getName()); - Msg.info("Send a request to the coordinator"); - req.send("coordinator"); - Msg.info("Wait for a grant from the coordinator"); - Task.receive(getName()); - Task compute = new Task("CS", csTime, 0); - compute.execute(); - ReleaseTask release = new ReleaseTask(); - release.send("coordinator"); - } - - public void main(String[] args) throws MsgException { - request(Double.parseDouble(args[1])); - } -} \ No newline at end of file diff --git a/examples/deprecated/java/app/centralizedmutex/ReleaseTask.java b/examples/deprecated/java/app/centralizedmutex/ReleaseTask.java deleted file mode 100644 index ba3ff3d9a5..0000000000 --- a/examples/deprecated/java/app/centralizedmutex/ReleaseTask.java +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.centralizedmutex; -public class ReleaseTask extends org.simgrid.msg.Task {} diff --git a/examples/deprecated/java/app/centralizedmutex/RequestTask.java b/examples/deprecated/java/app/centralizedmutex/RequestTask.java deleted file mode 100644 index 739db80a47..0000000000 --- a/examples/deprecated/java/app/centralizedmutex/RequestTask.java +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.centralizedmutex; -import org.simgrid.msg.Task; - -public class RequestTask extends Task { - protected String from; - public RequestTask(String name) { - super(); - from=name; - } -} diff --git a/examples/deprecated/java/app/centralizedmutex/app-centralizedmutex.tesh b/examples/deprecated/java/app/centralizedmutex/app-centralizedmutex.tesh deleted file mode 100644 index 74d30a1568..0000000000 --- a/examples/deprecated/java/app/centralizedmutex/app-centralizedmutex.tesh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 - -$ ${javacmd:=java} -classpath ${classpath:=.} app/centralizedmutex/Main ${srcdir:=.}/../../platforms/small_platform.xml ${srcdir:=.}/app/centralizedmutex/centralizedmutex.xml -> [0.000000] [java/INFO] Using regular java threads. -> [Jupiter:app.centralizedmutex.Node:(2) 0.000000] [java/INFO] Send a request to the coordinator -> [Fafard:app.centralizedmutex.Node:(3) 0.000000] [java/INFO] Send a request to the coordinator -> [Tremblay:app.centralizedmutex.Coordinator:(1) 0.019014] [java/INFO] Got a request from app.centralizedmutex.Node. Queue empty: grant it -> [Jupiter:app.centralizedmutex.Node:(2) 0.019014] [java/INFO] Wait for a grant from the coordinator -> [Fafard:app.centralizedmutex.Node:(3) 0.063737] [java/INFO] Wait for a grant from the coordinator -> [Tremblay:app.centralizedmutex.Coordinator:(1) 0.063737] [java/INFO] Got a request from app.centralizedmutex.Node. Queue empty: grant it -> [Tremblay:app.centralizedmutex.Coordinator:(1) 0.134167] [java/INFO] we should shutdown the simulation now -> [0.134167] [java/INFO] Terminating the simulation... diff --git a/examples/deprecated/java/app/centralizedmutex/centralizedmutex.xml b/examples/deprecated/java/app/centralizedmutex/centralizedmutex.xml deleted file mode 100644 index cffdc2eb05..0000000000 --- a/examples/deprecated/java/app/centralizedmutex/centralizedmutex.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/examples/deprecated/java/app/masterworker/Main.java b/examples/deprecated/java/app/masterworker/Main.java deleted file mode 100644 index 3679eb237f..0000000000 --- a/examples/deprecated/java/app/masterworker/Main.java +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.masterworker; - -import java.io.File; - -import org.simgrid.msg.Msg; - -class Main { - public static final int TASK_COMP_SIZE = 10000000; - public static final int TASK_COMM_SIZE = 10000000; - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - /* initialize the MSG simulation. Must be done before anything else (even logging). */ - Msg.init(args); - - String platf = args.length > 1 ? args[0] : "../platforms/small_platform.xml"; - String deploy = args.length > 1 ? args[1] : "app/masterworker/masterworker.xml"; - - Msg.verb("Platform: "+platf+"; Deployment:"+deploy+"; Current directory: "+new File(".").getAbsolutePath()); - - /* construct the platform and deploy the application */ - Msg.createEnvironment(platf); - Msg.deployApplication(deploy); - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/app/masterworker/Master.java b/examples/deprecated/java/app/masterworker/Master.java deleted file mode 100644 index 7546be28d5..0000000000 --- a/examples/deprecated/java/app/masterworker/Master.java +++ /dev/null @@ -1,49 +0,0 @@ -/* Master of a basic master/worker example in Java */ - -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.masterworker; -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; - -public class Master extends Process { - public Master(Host host, String name, String[]args) { - super(host,name,args); - } - public void main(String[] args) throws MsgException { - if (args.length < 4) { - Msg.info("Master needs 4 arguments"); - System.exit(1); - } - - int tasksCount = Integer.parseInt(args[0]); - double taskComputeSize = Double.parseDouble(args[1]); - double taskCommunicateSize = Double.parseDouble(args[2]); - - int workersCount = Integer.parseInt(args[3]); - - Msg.info("Hello! My PID is "+getPID()+". Got "+ workersCount + " workers and "+tasksCount+" tasks to process"); - - for (int i = 0; i < tasksCount; i++) { - Task task = new Task("Task_" + i, taskComputeSize, taskCommunicateSize); - Msg.debug("Sending \"" + task.getName()+ "\" to \"worker_" + i % workersCount + "\""); - task.send("worker_"+(i%workersCount)); - } - - Msg.info("All tasks have been dispatched. Let's tell everybody the computation is over."); - - for (int i = 0; i < workersCount; i++) { - Task task = new Task("finalize", 0, 0); - task.send("worker_"+(i%workersCount)); - } - - Msg.info("Goodbye now!"); - } -} diff --git a/examples/deprecated/java/app/masterworker/README b/examples/deprecated/java/app/masterworker/README deleted file mode 100644 index 56d2f2988f..0000000000 --- a/examples/deprecated/java/app/masterworker/README +++ /dev/null @@ -1,9 +0,0 @@ -This is a somehow basic master/workers example. - -There is 2 kind of processes: - * Master: creates some tasks, and dispatches them to its workers - * Worker: get tasks from the master and run them - -At the end of the execution: - - the master sends a Task whose name is "finalize" to every known worker to stop them - - On reception of such tasks workers stop. \ No newline at end of file diff --git a/examples/deprecated/java/app/masterworker/Worker.java b/examples/deprecated/java/app/masterworker/Worker.java deleted file mode 100644 index 55aaaebcad..0000000000 --- a/examples/deprecated/java/app/masterworker/Worker.java +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.masterworker; - -import org.simgrid.msg.Host; -import org.simgrid.msg.HostFailureException; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Task; -import org.simgrid.msg.TaskCancelledException; -import org.simgrid.msg.TimeoutException; -import org.simgrid.msg.TransferFailureException; -import org.simgrid.msg.Process; - -public class Worker extends Process { - public Worker(Host host, String name, String[]args) { - super(host,name,args); - } - public void main(String[] args) throws TransferFailureException, HostFailureException, TimeoutException { - if (args.length < 1) { - Msg.info("Worker needs 1 argument (its number)"); - System.exit(1); - } - - int num = Integer.parseInt(args[0]); - Msg.debug("Receiving on 'worker_"+num+"'"); - - while(true) { - Task task = Task.receive("worker_"+num); - - if ("finalize".equals(task.getName())) { - break; - } - Msg.info("Received \"" + task.getName() + "\". Processing it (my pid is "+getPID()+")."); - try { - task.execute(); - } catch (TaskCancelledException e) { - e.printStackTrace(); - } - } - - Msg.info("Received Finalize. I'm done. See you!"); - } -} diff --git a/examples/deprecated/java/app/masterworker/app-masterworker.tesh b/examples/deprecated/java/app/masterworker/app-masterworker.tesh deleted file mode 100644 index 9d451db043..0000000000 --- a/examples/deprecated/java/app/masterworker/app-masterworker.tesh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env tesh - -$ ${javacmd:=java} -classpath ${classpath:=.} app/masterworker/Main ${srcdir:=.}/../../platforms/small_platform.xml ${srcdir:=.}/app/masterworker/masterworker.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (1:app.masterworker.Master@Jacquelin) Hello! My PID is 1. Got 7 workers and 5 tasks to process -> [ 0.860026] (2:app.masterworker.Worker@Tremblay) Received "Task_0". Processing it (my pid is 2). -> [ 1.752187] (3:app.masterworker.Worker@Fafard) Received "Task_1". Processing it (my pid is 3). -> [ 1.757531] (4:app.masterworker.Worker@Bourassa) Received "Task_2". Processing it (my pid is 4). -> [ 2.806417] (5:app.masterworker.Worker@Boivin) Received "Task_3". Processing it (my pid is 5). -> [ 2.811761] (6:app.masterworker.Worker@Ginette) Received "Task_4". Processing it (my pid is 6). -> [ 2.811761] (1:app.masterworker.Master@Jacquelin) All tasks have been dispatched. Let's tell everybody the computation is over. -> [ 3.671783] (2:app.masterworker.Worker@Tremblay) Received Finalize. I'm done. See you! -> [ 4.563940] (3:app.masterworker.Worker@Fafard) Received Finalize. I'm done. See you! -> [ 4.569280] (4:app.masterworker.Worker@Bourassa) Received Finalize. I'm done. See you! -> [ 5.618161] (5:app.masterworker.Worker@Boivin) Received Finalize. I'm done. See you! -> [ 5.623501] (6:app.masterworker.Worker@Ginette) Received Finalize. I'm done. See you! -> [ 5.628842] (7:app.masterworker.Worker@Jupiter) Received Finalize. I'm done. See you! -> [ 5.628842] (8:app.masterworker.Worker@Jacquelin) Received Finalize. I'm done. See you! -> [ 5.628842] (1:app.masterworker.Master@Jacquelin) Goodbye now! -> [ 5.628842] (0:maestro@) Terminating the simulation... diff --git a/examples/deprecated/java/app/masterworker/masterworker.xml b/examples/deprecated/java/app/masterworker/masterworker.xml deleted file mode 100644 index a059ff108a..0000000000 --- a/examples/deprecated/java/app/masterworker/masterworker.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/deprecated/java/app/pingpong/Main.java b/examples/deprecated/java/app/pingpong/Main.java deleted file mode 100644 index 9ff673eced..0000000000 --- a/examples/deprecated/java/app/pingpong/Main.java +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.pingpong; -import java.io.File; - -import org.simgrid.msg.HostNotFoundException; -import org.simgrid.msg.Msg; - -class Main { - protected static final int TASK_COUNT = 3; - - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) throws HostNotFoundException { - Msg.init(args); - - String platfFile = "../../examples/platforms/small_platform.xml"; - if (args.length == 1) - platfFile = args[0]; - - File f = new File(platfFile); - if (!f.exists()) { - Msg.error("File " + platfFile + " does not exist in " + System.getProperty("user.dir")); - Msg.error("Usage : Main ../platforms/platform.xml"); - } - - Msg.createEnvironment(platfFile); - new Sender("Jacquelin", "Sender", new String[] {"Boivin"}).start(); - new Receiver ("Boivin", "Receiver", null).start(); - - Msg.run(); - } -} diff --git a/examples/deprecated/java/app/pingpong/PingPongTask.java b/examples/deprecated/java/app/pingpong/PingPongTask.java deleted file mode 100644 index 638caa841e..0000000000 --- a/examples/deprecated/java/app/pingpong/PingPongTask.java +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.pingpong; -import org.simgrid.msg.Task; - -public class PingPongTask extends Task { - private double timeVal; - - public PingPongTask() { - this.timeVal = 0; - } - - public PingPongTask(String name, double computeDuration, double messageSize, double timeVal) { - super(name,computeDuration,messageSize); - - this.timeVal = timeVal; - } - - public double getTime() { - return this.timeVal; - } -} diff --git a/examples/deprecated/java/app/pingpong/Receiver.java b/examples/deprecated/java/app/pingpong/Receiver.java deleted file mode 100644 index 77efab80d3..0000000000 --- a/examples/deprecated/java/app/pingpong/Receiver.java +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.pingpong; -import org.simgrid.msg.HostNotFoundException; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Process; -import org.simgrid.msg.Task; - -public class Receiver extends Process { - private static final double COMM_SIZE_BW = 100000000; - public Receiver(String hostname, String name, String[]args) throws HostNotFoundException { - super(hostname, name, args); - } - - public void main(String[] args) throws MsgException { - for (int i = 0 ; i < Main.TASK_COUNT; i++) { - Msg.info("Wait for a task"); - - PingPongTask task = (PingPongTask)Task.receive(getHost().getName()); - double timeGot = Msg.getClock(); - double timeSent = task.getTime(); - - Msg.info("Got one that was sent at time "+ timeSent); - - double communicationTime = timeGot - timeSent; - Msg.info("Communication time : " + communicationTime); - Msg.info(" --- bw "+ COMM_SIZE_BW/communicationTime + " ----"); - } - Msg.info("Done."); - } -} \ No newline at end of file diff --git a/examples/deprecated/java/app/pingpong/Sender.java b/examples/deprecated/java/app/pingpong/Sender.java deleted file mode 100644 index c52fbedd4f..0000000000 --- a/examples/deprecated/java/app/pingpong/Sender.java +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.pingpong; -import org.simgrid.msg.Host; -import org.simgrid.msg.HostNotFoundException; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Process; - -public class Sender extends Process { - private static final double COMM_SIZE_LAT = 1; - - public Sender(String hostname, String name, String[] args) throws HostNotFoundException { - super(hostname,name,args); - } - - public void main(String[] args) throws MsgException { - Msg.info("Host count: " + args.length); - - for (int i = 0 ; i [0.000000] [java/INFO] Using regular java threads. -> [Jacquelin:Sender:(1) 0.000000] [java/INFO] Host count: 1 -> [Jacquelin:Sender:(1) 0.000000] [java/INFO] sender time: 0.0 -> [Boivin:Receiver:(2) 0.000000] [java/INFO] Wait for a task -> [Boivin:Receiver:(2) 1.048882] [java/INFO] Got one that was sent at time 0.0 -> [Boivin:Receiver:(2) 1.048882] [java/INFO] Communication time : 1.0488818628325232 -> [Boivin:Receiver:(2) 1.048882] [java/INFO] --- bw 9.533962169004269E7 ---- -> [Boivin:Receiver:(2) 1.048882] [java/INFO] Wait for a task -> [Jacquelin:Sender:(1) 1.048882] [java/INFO] sender time: 1.0488818628325232 -> [Boivin:Receiver:(2) 2.097764] [java/INFO] Got one that was sent at time 1.0488818628325232 -> [Boivin:Receiver:(2) 2.097764] [java/INFO] Communication time : 1.0488818628325232 -> [Boivin:Receiver:(2) 2.097764] [java/INFO] --- bw 9.533962169004269E7 ---- -> [Boivin:Receiver:(2) 2.097764] [java/INFO] Wait for a task -> [Jacquelin:Sender:(1) 2.097764] [java/INFO] sender time: 2.0977637256650463 -> [Boivin:Receiver:(2) 3.146646] [java/INFO] Got one that was sent at time 2.0977637256650463 -> [Boivin:Receiver:(2) 3.146646] [java/INFO] Communication time : 1.0488818628325234 -> [Boivin:Receiver:(2) 3.146646] [java/INFO] --- bw 9.533962169004266E7 ---- -> [Boivin:Receiver:(2) 3.146646] [java/INFO] Done. -> [Jacquelin:Sender:(1) 3.146646] [java/INFO] Done. -> [3.146646] [java/INFO] Terminating the simulation... diff --git a/examples/deprecated/java/app/tokenring/Main.java b/examples/deprecated/java/app/tokenring/Main.java deleted file mode 100644 index bd57c9a3a0..0000000000 --- a/examples/deprecated/java/app/tokenring/Main.java +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.tokenring; -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Process; - -class Main { - private Main() { - /* This is just to prevent anyone from creating an instance of this singleton */ - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - - String platform = "../platforms/small_platform.xml"; - if(args.length >= 1) - platform = args[0]; - Msg.createEnvironment(platform); - - Host[] hosts = Host.all(); - for (int rank = 0; rank < hosts.length; rank++) { - Process proc = new RelayRunner(hosts[rank], Integer.toString(rank), null); - proc.start(); - } - Msg.info("Number of hosts '"+hosts.length+"'"); - Msg.run(); - - Msg.info("Simulation time " + Msg.getClock()); - } -} diff --git a/examples/deprecated/java/app/tokenring/RelayRunner.java b/examples/deprecated/java/app/tokenring/RelayRunner.java deleted file mode 100644 index b2bfa8dc13..0000000000 --- a/examples/deprecated/java/app/tokenring/RelayRunner.java +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package app.tokenring; -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Process; -import org.simgrid.msg.Task; - -public class RelayRunner extends Process { - - private static final int TASK_COMM_SIZE = 1000000; /* The token is 1MB long*/ - - public RelayRunner(Host host, String name, String[]args) { - super(host,name,args); - } - - /* This is the function executed by this kind of processes */ - @Override - public void main(String[] args) throws MsgException { - // In this example, the processes are given numerical names: "0", "1", "2", and so on - int rank = Integer.parseInt(this.getName()); - - if (rank == 0) { - /* The root (rank 0) first sends the token then waits to receive it back */ - - String mailbox = "1"; - Task token = new Task("Token", 0/* no computation associated*/ , TASK_COMM_SIZE ); - - Msg.info("Host '"+rank+"' send '"+token.getName()+"' to Host '"+mailbox+"'"); - token.send(mailbox); - - token = Task.receive(this.getName()); // Get a message from the mailbox having the same name as the current processor - - Msg.info("Host '"+rank+"' received '"+token.getName()+"'"); - - } else { - /* The others processes receive on their name (coming from their left neighbor -- rank-1) - * and send to their right neighbor (rank+1) */ - Task token = Task.receive(this.getName()); - - Msg.info("Host '"+rank+"' received '"+token.getName()+"'"); - - String mailbox = Integer.toString(rank+1); - if (rank+1 == Host.getCount()) { - /* The last process has no right neighbor, so it sends the token back to rank 0 */ - mailbox = "0"; - } - - Msg.info("Host '"+rank+"' send '"+token.getName()+"' to Host '"+mailbox+"'"); - token.send(mailbox); - } - } -} diff --git a/examples/deprecated/java/app/tokenring/app-tokenring.tesh b/examples/deprecated/java/app/tokenring/app-tokenring.tesh deleted file mode 100644 index 3972847aa3..0000000000 --- a/examples/deprecated/java/app/tokenring/app-tokenring.tesh +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env tesh - -$ ${javacmd:=java} -classpath ${classpath:=.} app/tokenring/Main ${srcdir:=.}/../../platforms/routing_cluster.xml '--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n' -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (0:maestro@) Number of hosts '6' -> [ 0.000000] (1:0@host1) Host '0' send 'Token' to Host '1' -> [ 0.017354] (2:1@host2) Host '1' received 'Token' -> [ 0.017354] (2:1@host2) Host '1' send 'Token' to Host '2' -> [ 0.035121] (3:2@host3) Host '2' received 'Token' -> [ 0.035121] (3:2@host3) Host '2' send 'Token' to Host '3' -> [ 0.065898] (4:3@host4) Host '3' received 'Token' -> [ 0.065898] (4:3@host4) Host '3' send 'Token' to Host '4' -> [ 0.083252] (5:4@host5) Host '4' received 'Token' -> [ 0.083252] (5:4@host5) Host '4' send 'Token' to Host '5' -> [ 0.101019] (6:5@host6) Host '5' received 'Token' -> [ 0.101019] (6:5@host6) Host '5' send 'Token' to Host '0' -> [ 0.131796] (1:0@host1) Host '0' received 'Token' -> [ 0.131796] (0:maestro@) Terminating the simulation... -> [ 0.131796] (0:maestro@) Simulation time 0.13179602061855672 - -$ ${javacmd:=java} -classpath ${classpath:=.} app/tokenring/Main ${srcdir:=.}/../../platforms/two_peers.xml '--log=root.fmt:[%12.6r]%e(%i:%a@%h)%e%m%n' -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (0:maestro@) Number of hosts '2' -> [ 0.000000] (1:0@100030591) Host '0' send 'Token' to Host '1' -> [ 0.625106] (2:1@100036570) Host '1' received 'Token' -> [ 0.625106] (2:1@100036570) Host '1' send 'Token' to Host '0' -> [ 1.250212] (1:0@100030591) Host '0' received 'Token' -> [ 1.250212] (0:maestro@) Terminating the simulation... -> [ 1.250212] (0:maestro@) Simulation time 1.250212042288475 - -$ ${javacmd:=java} -classpath ${classpath:=.} app/tokenring/Main ${srcdir:=.}/../../platforms/meta_cluster.xml '--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n' -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (0:maestro@) Number of hosts '60' -> [ 0.000000] (1:0@host-1.cluster1) Host '0' send 'Token' to Host '1' -> [ 0.030364] (2:1@host-1.cluster2) Host '1' received 'Token' -> [ 0.030364] (2:1@host-1.cluster2) Host '1' send 'Token' to Host '2' -> [ 0.060729] (3:2@host-10.cluster1) Host '2' received 'Token' -> [ 0.060729] (3:2@host-10.cluster1) Host '2' send 'Token' to Host '3' -> [ 0.091093] (4:3@host-10.cluster2) Host '3' received 'Token' -> [ 0.091093] (4:3@host-10.cluster2) Host '3' send 'Token' to Host '4' -> [ 0.121458] (5:4@host-11.cluster1) Host '4' received 'Token' -> [ 0.121458] (5:4@host-11.cluster1) Host '4' send 'Token' to Host '5' -> [ 0.151822] (6:5@host-11.cluster2) Host '5' received 'Token' -> [ 0.151822] (6:5@host-11.cluster2) Host '5' send 'Token' to Host '6' -> [ 0.182187] (7:6@host-12.cluster1) Host '6' received 'Token' -> [ 0.182187] (7:6@host-12.cluster1) Host '6' send 'Token' to Host '7' -> [ 0.212551] (8:7@host-12.cluster2) Host '7' received 'Token' -> [ 0.212551] (8:7@host-12.cluster2) Host '7' send 'Token' to Host '8' -> [ 0.242915] (9:8@host-13.cluster1) Host '8' received 'Token' -> [ 0.242915] (9:8@host-13.cluster1) Host '8' send 'Token' to Host '9' -> [ 0.273280] (10:9@host-13.cluster2) Host '9' received 'Token' -> [ 0.273280] (10:9@host-13.cluster2) Host '9' send 'Token' to Host '10' -> [ 0.303644] (11:10@host-14.cluster1) Host '10' received 'Token' -> [ 0.303644] (11:10@host-14.cluster1) Host '10' send 'Token' to Host '11' -> [ 0.334009] (12:11@host-14.cluster2) Host '11' received 'Token' -> [ 0.334009] (12:11@host-14.cluster2) Host '11' send 'Token' to Host '12' -> [ 0.364373] (13:12@host-15.cluster1) Host '12' received 'Token' -> [ 0.364373] (13:12@host-15.cluster1) Host '12' send 'Token' to Host '13' -> [ 0.394737] (14:13@host-15.cluster2) Host '13' received 'Token' -> [ 0.394737] (14:13@host-15.cluster2) Host '13' send 'Token' to Host '14' -> [ 0.425102] (15:14@host-16.cluster1) Host '14' received 'Token' -> [ 0.425102] (15:14@host-16.cluster1) Host '14' send 'Token' to Host '15' -> [ 0.455466] (16:15@host-16.cluster2) Host '15' received 'Token' -> [ 0.455466] (16:15@host-16.cluster2) Host '15' send 'Token' to Host '16' -> [ 0.485831] (17:16@host-17.cluster1) Host '16' received 'Token' -> [ 0.485831] (17:16@host-17.cluster1) Host '16' send 'Token' to Host '17' -> [ 0.516195] (18:17@host-17.cluster2) Host '17' received 'Token' -> [ 0.516195] (18:17@host-17.cluster2) Host '17' send 'Token' to Host '18' -> [ 0.546560] (19:18@host-18.cluster1) Host '18' received 'Token' -> [ 0.546560] (19:18@host-18.cluster1) Host '18' send 'Token' to Host '19' -> [ 0.576924] (20:19@host-18.cluster2) Host '19' received 'Token' -> [ 0.576924] (20:19@host-18.cluster2) Host '19' send 'Token' to Host '20' -> [ 0.607288] (21:20@host-19.cluster1) Host '20' received 'Token' -> [ 0.607288] (21:20@host-19.cluster1) Host '20' send 'Token' to Host '21' -> [ 0.637653] (22:21@host-19.cluster2) Host '21' received 'Token' -> [ 0.637653] (22:21@host-19.cluster2) Host '21' send 'Token' to Host '22' -> [ 0.668017] (23:22@host-2.cluster1) Host '22' received 'Token' -> [ 0.668017] (23:22@host-2.cluster1) Host '22' send 'Token' to Host '23' -> [ 0.698382] (24:23@host-2.cluster2) Host '23' received 'Token' -> [ 0.698382] (24:23@host-2.cluster2) Host '23' send 'Token' to Host '24' -> [ 0.728746] (25:24@host-20.cluster1) Host '24' received 'Token' -> [ 0.728746] (25:24@host-20.cluster1) Host '24' send 'Token' to Host '25' -> [ 0.759111] (26:25@host-20.cluster2) Host '25' received 'Token' -> [ 0.759111] (26:25@host-20.cluster2) Host '25' send 'Token' to Host '26' -> [ 0.789475] (27:26@host-21.cluster1) Host '26' received 'Token' -> [ 0.789475] (27:26@host-21.cluster1) Host '26' send 'Token' to Host '27' -> [ 0.819839] (28:27@host-21.cluster2) Host '27' received 'Token' -> [ 0.819839] (28:27@host-21.cluster2) Host '27' send 'Token' to Host '28' -> [ 0.850204] (29:28@host-22.cluster1) Host '28' received 'Token' -> [ 0.850204] (29:28@host-22.cluster1) Host '28' send 'Token' to Host '29' -> [ 0.880568] (30:29@host-22.cluster2) Host '29' received 'Token' -> [ 0.880568] (30:29@host-22.cluster2) Host '29' send 'Token' to Host '30' -> [ 0.910933] (31:30@host-23.cluster1) Host '30' received 'Token' -> [ 0.910933] (31:30@host-23.cluster1) Host '30' send 'Token' to Host '31' -> [ 0.941297] (32:31@host-23.cluster2) Host '31' received 'Token' -> [ 0.941297] (32:31@host-23.cluster2) Host '31' send 'Token' to Host '32' -> [ 0.971662] (33:32@host-24.cluster1) Host '32' received 'Token' -> [ 0.971662] (33:32@host-24.cluster1) Host '32' send 'Token' to Host '33' -> [ 1.002026] (34:33@host-24.cluster2) Host '33' received 'Token' -> [ 1.002026] (34:33@host-24.cluster2) Host '33' send 'Token' to Host '34' -> [ 1.032390] (35:34@host-25.cluster1) Host '34' received 'Token' -> [ 1.032390] (35:34@host-25.cluster1) Host '34' send 'Token' to Host '35' -> [ 1.062755] (36:35@host-25.cluster2) Host '35' received 'Token' -> [ 1.062755] (36:35@host-25.cluster2) Host '35' send 'Token' to Host '36' -> [ 1.093119] (37:36@host-26.cluster1) Host '36' received 'Token' -> [ 1.093119] (37:36@host-26.cluster1) Host '36' send 'Token' to Host '37' -> [ 1.123484] (38:37@host-26.cluster2) Host '37' received 'Token' -> [ 1.123484] (38:37@host-26.cluster2) Host '37' send 'Token' to Host '38' -> [ 1.153848] (39:38@host-27.cluster1) Host '38' received 'Token' -> [ 1.153848] (39:38@host-27.cluster1) Host '38' send 'Token' to Host '39' -> [ 1.184212] (40:39@host-27.cluster2) Host '39' received 'Token' -> [ 1.184212] (40:39@host-27.cluster2) Host '39' send 'Token' to Host '40' -> [ 1.214577] (41:40@host-28.cluster1) Host '40' received 'Token' -> [ 1.214577] (41:40@host-28.cluster1) Host '40' send 'Token' to Host '41' -> [ 1.244941] (42:41@host-28.cluster2) Host '41' received 'Token' -> [ 1.244941] (42:41@host-28.cluster2) Host '41' send 'Token' to Host '42' -> [ 1.275306] (43:42@host-29.cluster1) Host '42' received 'Token' -> [ 1.275306] (43:42@host-29.cluster1) Host '42' send 'Token' to Host '43' -> [ 1.305670] (44:43@host-29.cluster2) Host '43' received 'Token' -> [ 1.305670] (44:43@host-29.cluster2) Host '43' send 'Token' to Host '44' -> [ 1.336035] (45:44@host-3.cluster1) Host '44' received 'Token' -> [ 1.336035] (45:44@host-3.cluster1) Host '44' send 'Token' to Host '45' -> [ 1.366399] (46:45@host-3.cluster2) Host '45' received 'Token' -> [ 1.366399] (46:45@host-3.cluster2) Host '45' send 'Token' to Host '46' -> [ 1.396763] (47:46@host-30.cluster1) Host '46' received 'Token' -> [ 1.396763] (47:46@host-30.cluster1) Host '46' send 'Token' to Host '47' -> [ 1.427128] (48:47@host-30.cluster2) Host '47' received 'Token' -> [ 1.427128] (48:47@host-30.cluster2) Host '47' send 'Token' to Host '48' -> [ 1.457492] (49:48@host-4.cluster1) Host '48' received 'Token' -> [ 1.457492] (49:48@host-4.cluster1) Host '48' send 'Token' to Host '49' -> [ 1.487857] (50:49@host-4.cluster2) Host '49' received 'Token' -> [ 1.487857] (50:49@host-4.cluster2) Host '49' send 'Token' to Host '50' -> [ 1.518221] (51:50@host-5.cluster1) Host '50' received 'Token' -> [ 1.518221] (51:50@host-5.cluster1) Host '50' send 'Token' to Host '51' -> [ 1.548586] (52:51@host-5.cluster2) Host '51' received 'Token' -> [ 1.548586] (52:51@host-5.cluster2) Host '51' send 'Token' to Host '52' -> [ 1.578950] (53:52@host-6.cluster1) Host '52' received 'Token' -> [ 1.578950] (53:52@host-6.cluster1) Host '52' send 'Token' to Host '53' -> [ 1.609314] (54:53@host-6.cluster2) Host '53' received 'Token' -> [ 1.609314] (54:53@host-6.cluster2) Host '53' send 'Token' to Host '54' -> [ 1.639679] (55:54@host-7.cluster1) Host '54' received 'Token' -> [ 1.639679] (55:54@host-7.cluster1) Host '54' send 'Token' to Host '55' -> [ 1.670043] (56:55@host-7.cluster2) Host '55' received 'Token' -> [ 1.670043] (56:55@host-7.cluster2) Host '55' send 'Token' to Host '56' -> [ 1.700408] (57:56@host-8.cluster1) Host '56' received 'Token' -> [ 1.700408] (57:56@host-8.cluster1) Host '56' send 'Token' to Host '57' -> [ 1.730772] (58:57@host-8.cluster2) Host '57' received 'Token' -> [ 1.730772] (58:57@host-8.cluster2) Host '57' send 'Token' to Host '58' -> [ 1.761137] (59:58@host-9.cluster1) Host '58' received 'Token' -> [ 1.761137] (59:58@host-9.cluster1) Host '58' send 'Token' to Host '59' -> [ 1.791501] (60:59@host-9.cluster2) Host '59' received 'Token' -> [ 1.791501] (60:59@host-9.cluster2) Host '59' send 'Token' to Host '0' -> [ 1.821865] (1:0@host-1.cluster1) Host '0' received 'Token' -> [ 1.821865] (0:maestro@) Terminating the simulation... -> [ 1.821865] (0:maestro@) Simulation time 1.8218653608247406 diff --git a/examples/deprecated/java/async/dsend/Main.java b/examples/deprecated/java/async/dsend/Main.java deleted file mode 100644 index 95aa5a1a8d..0000000000 --- a/examples/deprecated/java/async/dsend/Main.java +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package async.dsend; - -/** This example demonstrates the use of the Task.dsend() method. - * - * This way, the sender can be detached from the communication: it is not blocked as with Task.send() - * and has nothing to do at the end as with Task.isend() where it must do a Comm.wait(). - */ - -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; - -class Main { - private Main() { - /* This is just to ensure that nobody creates an instance of this singleton */ - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - - String platform = "../platforms/small_platform.xml"; - if (args.length >= 1) { - platform = args[0]; // Override the default value if passed on the command line - } - - /* construct the platform and deploy the application */ - Msg.createEnvironment(platform); - Host[] hosts = Host.all(); - new Sender(hosts[0],"Sender").start(); - for (int i=1; i < hosts.length; i++){ - new Receiver(hosts[i], "Receiver").start(); - } - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/async/dsend/Receiver.java b/examples/deprecated/java/async/dsend/Receiver.java deleted file mode 100644 index d1d4a48e67..0000000000 --- a/examples/deprecated/java/async/dsend/Receiver.java +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package async.dsend; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.HostFailureException; -import org.simgrid.msg.TimeoutException; -import org.simgrid.msg.TransferFailureException; - -public class Receiver extends Process { - public Receiver (Host host, String name) { - super(host,name); - } - - @Override - public void main(String[] args) throws TransferFailureException, HostFailureException, TimeoutException { - Msg.info("Receiving on '"+ getHost().getName() + "'"); - Task.receive(getHost().getName()); - Msg.info("Received a task. I'm done. See you!"); - } -} \ No newline at end of file diff --git a/examples/deprecated/java/async/dsend/Sender.java b/examples/deprecated/java/async/dsend/Sender.java deleted file mode 100644 index a248b7c2a2..0000000000 --- a/examples/deprecated/java/async/dsend/Sender.java +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package async.dsend; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; - -public class Sender extends Process { - public Sender (Host host, String name){ - super(host,name); - } - - @Override - public void main(String[] args) throws MsgException { - double taskComputeSize =0; - double taskCommunicateSize = 5000000; - Host[] hosts = Host.all(); - int receiverCount = hosts.length - 1; - - Msg.info("Hello! Got "+ receiverCount + " receivers to contact"); - - for (int i = 1; i <= receiverCount; i++) { - Task task = new Task("Task_" + i, taskComputeSize, taskCommunicateSize); - Msg.info("Sending \"" + task.getName()+ "\" to \"" + hosts[i].getName() + "\""); - task.dsend(hosts[i].getName()); - } - - Msg.info("All tasks have been (asynchronously) dispatched."+ - " Let's sleep for 20s so that nobody gets a message from a terminated process."); - - waitFor(20); - - Msg.info("Done sleeping. Goodbye now!"); - } -} diff --git a/examples/deprecated/java/async/dsend/async-dsend.tesh b/examples/deprecated/java/async/dsend/async-dsend.tesh deleted file mode 100644 index fa926a1a51..0000000000 --- a/examples/deprecated/java/async/dsend/async-dsend.tesh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env tesh - -! timeout 30 -$ ${javacmd:=java} -classpath ${classpath:=.} async/dsend/Main ${srcdir:=.}/../../platforms/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (1:Sender@Boivin) Hello! Got 6 receivers to contact -> [ 0.000000] (1:Sender@Boivin) Sending "Task_1" to "Bourassa" -> [ 0.000000] (2:Receiver@Bourassa) Receiving on 'Bourassa' -> [ 0.000000] (3:Receiver@Fafard) Receiving on 'Fafard' -> [ 0.000000] (4:Receiver@Ginette) Receiving on 'Ginette' -> [ 0.000000] (5:Receiver@Jacquelin) Receiving on 'Jacquelin' -> [ 0.000000] (6:Receiver@Jupiter) Receiving on 'Jupiter' -> [ 0.000000] (7:Receiver@Tremblay) Receiving on 'Tremblay' -> [ 0.000000] (1:Sender@Boivin) Sending "Task_2" to "Fafard" -> [ 0.000000] (1:Sender@Boivin) Sending "Task_3" to "Ginette" -> [ 0.000000] (1:Sender@Boivin) Sending "Task_4" to "Jacquelin" -> [ 0.000000] (1:Sender@Boivin) Sending "Task_5" to "Jupiter" -> [ 0.000000] (1:Sender@Boivin) Sending "Task_6" to "Tremblay" -> [ 0.000000] (1:Sender@Boivin) All tasks have been (asynchronously) dispatched. Let's sleep for 20s so that nobody gets a message from a terminated process. -> [ 1.933362] (6:Receiver@Jupiter) Received a task. I'm done. See you! -> [ 1.933362] (4:Receiver@Ginette) Received a task. I'm done. See you! -> [ 1.933362] (2:Receiver@Bourassa) Received a task. I'm done. See you! -> [ 2.449247] (7:Receiver@Tremblay) Received a task. I'm done. See you! -> [ 2.964768] (3:Receiver@Fafard) Received a task. I'm done. See you! -> [ 4.162002] (5:Receiver@Jacquelin) Received a task. I'm done. See you! -> [ 20.000000] (1:Sender@Boivin) Done sleeping. Goodbye now! -> [ 20.000000] (0:maestro@) Terminating the simulation... diff --git a/examples/deprecated/java/async/waitall/Main.java b/examples/deprecated/java/async/waitall/Main.java deleted file mode 100644 index 10830f7927..0000000000 --- a/examples/deprecated/java/async/waitall/Main.java +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package async.waitall; - -/** This example demonstrates the use of the asynchronous communications - * - * Task.isend() and Task.irecv() are used to start the communications in non-blocking mode. - * - * The sends are then blocked onto with Comm.waitCompletion(), that locks until the given - * communication terminates. - * - * The receives are packed into an array, and the sender blocks until all of them terminate - * with Comm.waitAll(). - */ - - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; - -class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - - String platform = "../platforms/small_platform.xml"; - if (args.length >= 1) { - platform = args[0]; // Override the default value if passed on the command line - } - - /* construct the platform and deploy the application */ - Msg.createEnvironment(platform); - Host[] hosts = Host.all(); - new Sender(hosts[0],"Sender").start(); - for (int i=1; i < hosts.length; i++){ - new Receiver(hosts[i], "Receiver").start(); - } - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/async/waitall/Receiver.java b/examples/deprecated/java/async/waitall/Receiver.java deleted file mode 100644 index cd837e91e7..0000000000 --- a/examples/deprecated/java/async/waitall/Receiver.java +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package async.waitall; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Comm; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.HostFailureException; -import org.simgrid.msg.TimeoutException; -import org.simgrid.msg.TransferFailureException; - -public class Receiver extends Process { - public Receiver (Host host, String name) { - super(host,name); - } - - @Override - public void main(String[] args) throws TransferFailureException, HostFailureException, TimeoutException { - Comm comm = Task.irecv(getHost().getName()); - Msg.info("I started receiving on '"+ getHost().getName() +". Wait 0.1 second, and block on the communication."); - waitFor(0.1); - try { - comm.waitCompletion(); - } catch (TimeoutException e) { - Msg.info("Timeout while waiting for my task"); - throw e; // Stop this process - } - Msg.info("I got my task, good bye."); - } -} \ No newline at end of file diff --git a/examples/deprecated/java/async/waitall/Sender.java b/examples/deprecated/java/async/waitall/Sender.java deleted file mode 100644 index 4a7e4fc001..0000000000 --- a/examples/deprecated/java/async/waitall/Sender.java +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package async.waitall; - -import org.simgrid.msg.Comm; -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Process; -import org.simgrid.msg.Task; - -public class Sender extends Process { - public Sender (Host host, String name){ - super(host,name); - } - - @Override - public void main(String[] args) throws MsgException { - double taskComputeSize =0; - double taskCommunicateSize = 5000000; - Host[] hosts = Host.all(); - int receiverCount = hosts.length - 1; - - Msg.info("I have "+ receiverCount + " receivers to contact"); - - Comm[] communicators = new Comm[receiverCount]; - for (int i = 1; i <= receiverCount; i++) { - Task task = new Task("Task_" + i, taskComputeSize, taskCommunicateSize); - Msg.info("Start the Sending '" + task.getName()+ "' to '" + hosts[i].getName() + "'"); - communicators[i-1] = task.isend(hosts[i].getName()); - } - - Msg.info("All tasks have been (asynchronously) dispatched. Let's wait for their completion."); - Comm.waitAll(communicators); - - Msg.info("Goodbye now!"); - } -} diff --git a/examples/deprecated/java/async/waitall/async-waitall.tesh b/examples/deprecated/java/async/waitall/async-waitall.tesh deleted file mode 100644 index 8aeab7bdc3..0000000000 --- a/examples/deprecated/java/async/waitall/async-waitall.tesh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env tesh - -$ ${javacmd:=java} -classpath ${classpath:=.} async/waitall/Main ${srcdir:=.}/../../platforms/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (1:Sender@Boivin) I have 6 receivers to contact -> [ 0.000000] (1:Sender@Boivin) Start the Sending 'Task_1' to 'Bourassa' -> [ 0.000000] (1:Sender@Boivin) Start the Sending 'Task_2' to 'Fafard' -> [ 0.000000] (2:Receiver@Bourassa) I started receiving on 'Bourassa. Wait 0.1 second, and block on the communication. -> [ 0.000000] (3:Receiver@Fafard) I started receiving on 'Fafard. Wait 0.1 second, and block on the communication. -> [ 0.000000] (4:Receiver@Ginette) I started receiving on 'Ginette. Wait 0.1 second, and block on the communication. -> [ 0.000000] (5:Receiver@Jacquelin) I started receiving on 'Jacquelin. Wait 0.1 second, and block on the communication. -> [ 0.000000] (6:Receiver@Jupiter) I started receiving on 'Jupiter. Wait 0.1 second, and block on the communication. -> [ 0.000000] (7:Receiver@Tremblay) I started receiving on 'Tremblay. Wait 0.1 second, and block on the communication. -> [ 0.000000] (1:Sender@Boivin) Start the Sending 'Task_3' to 'Ginette' -> [ 0.000000] (1:Sender@Boivin) Start the Sending 'Task_4' to 'Jacquelin' -> [ 0.000000] (1:Sender@Boivin) Start the Sending 'Task_5' to 'Jupiter' -> [ 0.000000] (1:Sender@Boivin) Start the Sending 'Task_6' to 'Tremblay' -> [ 0.000000] (1:Sender@Boivin) All tasks have been (asynchronously) dispatched. Let's wait for their completion. -> [ 1.933362] (6:Receiver@Jupiter) I got my task, good bye. -> [ 1.933362] (4:Receiver@Ginette) I got my task, good bye. -> [ 1.933362] (2:Receiver@Bourassa) I got my task, good bye. -> [ 2.449247] (7:Receiver@Tremblay) I got my task, good bye. -> [ 2.964768] (3:Receiver@Fafard) I got my task, good bye. -> [ 4.162002] (5:Receiver@Jacquelin) I got my task, good bye. -> [ 4.162002] (1:Sender@Boivin) Goodbye now! -> [ 4.162002] (0:maestro@) Terminating the simulation... diff --git a/examples/deprecated/java/async/yield/Main.java b/examples/deprecated/java/async/yield/Main.java deleted file mode 100644 index 4b6822eb56..0000000000 --- a/examples/deprecated/java/async/yield/Main.java +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package async.yield; - -/** This example demonstrates the use of the Task.dsend() method. - * - * This way, the sender can be detached from the communication: it is not blocked as with Task.send() - * and has nothing to do at the end as with Task.isend() where it must do a Comm.wait(). - */ - -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; - -class Main { - private Main() { - /* This is just to ensure that nobody creates an instance of this singleton */ - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - - String platform = "../platforms/small_platform.xml"; - if (args.length >= 1) { - platform = args[0]; // Override the default value if passed on the command line - } - - /* construct the platform and deploy the application */ - Msg.createEnvironment(platform); - Host[] hosts = Host.all(); - new Yielder(hosts[0],"Yielder", new String[] {"10"}).start(); - new Yielder(hosts[1],"Yielder", new String[] {"15"}).start(); - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/async/yield/Yielder.java b/examples/deprecated/java/async/yield/Yielder.java deleted file mode 100644 index 5cfe63fae1..0000000000 --- a/examples/deprecated/java/async/yield/Yielder.java +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package async.yield; -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Process; - -public class Yielder extends Process { - public Yielder (Host host, String name, String[] args) { - super(host, name, args); - } - - @Override - public void main(String[] args) { - int yieldsCount = Integer.parseInt(args[0]); - for (int i=0; i [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (1:Yielder@Boivin) Yielded 10. Good bye now! -> [ 0.000000] (2:Yielder@Bourassa) Yielded 15. Good bye now! -> [ 0.000000] (0:maestro@) Terminating the simulation... diff --git a/examples/deprecated/java/cloud/masterworker/Main.java b/examples/deprecated/java/cloud/masterworker/Main.java deleted file mode 100644 index 1f149b0805..0000000000 --- a/examples/deprecated/java/cloud/masterworker/Main.java +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package cloud.masterworker; - -import java.io.File; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; - -class Main { - public static final double TASK_COMP_SIZE = 10; - public static final double TASK_COMM_SIZE = 10; - public static final int NHOSTS = 6; - public static final int NSTEPS = 50; - - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - - String platfFile = "../../examples/platforms/small_platform.xml"; - if (args.length >= 1) - platfFile = args[0]; - - File f = new File(platfFile); - if (!f.exists()) { - Msg.error("File " + platfFile + " does not exist in " + System.getProperty("user.dir")); - Msg.error("Usage : Main ../platforms/platform.xml"); - } - - Msg.createEnvironment(platfFile); - Host[] hosts = Host.all(); - if (hosts.length < NHOSTS+1) { - Msg.info("I need at least "+ (NHOSTS+1) +" hosts in the platform file, but " + args[0] + " contains only " - + hosts.length + " hosts"); - System.exit(42); - } - new Master(hosts[0],"Master",hosts).start(); - - /* Execute the simulation */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/cloud/masterworker/Master.java b/examples/deprecated/java/cloud/masterworker/Master.java deleted file mode 100644 index d6df24abda..0000000000 --- a/examples/deprecated/java/cloud/masterworker/Master.java +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package cloud.masterworker; - -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Process; -import org.simgrid.msg.Task; -import org.simgrid.msg.VM; - -public class Master extends Process { - private Host[] hosts; - - public Master(Host host, String name, Host[] hosts) { - super(host,name,null); - this.hosts = hosts; - } - - public void main(String[] args) throws MsgException { - int workersCount = Main.NHOSTS; - - for (int step = 1; step <= Main.NSTEPS ; step++) { - // Create one VM per host and bind a process inside each one. - for (int i = 0; i < workersCount; i++) { - Msg.verb("create VM0-s"+step+"-"+i); - VM vm = new VM(hosts[i+1],"VM0-s"+step+"-"+i); - vm.start(); - Worker worker= new Worker(vm,"WK:"+step+":"+ i); - Msg.verb("Put Worker "+worker.getName()+ " on "+vm.getName()); - worker.start(); - } - VM[] vms = VM.all(); - - Msg.info("Launched " + vms.length + " VMs"); - - Msg.info("Send some work to everyone"); - workBatch(workersCount,"WK:"+step+":"); - - Msg.info("Suspend all VMs, wait a while, resume them, migrate them and shut them down."); - for (VM vm : vms) { - Msg.verb("Suspend "+vm.getName()); - vm.suspend(); - } - - Msg.verb("Wait a while, and resume all VMs."); - waitFor(2); - for (VM vm : vms) - vm.resume(); - - - Msg.verb("Sleep long enough for everyone to be done with previous batch of work"); - waitFor(1000*step - Msg.getClock()); - - Msg.verb("Migrate everyone to "+hosts[3].getName()); - for (VM vm : vms) { - Msg.verb("Migrate "+vm.getName()+" to "+hosts[3].getName()); - vm.migrate(hosts[3]); - } - - Msg.verb("Let's kill everyone."); - - for (VM vm : vms) - vm.destroy(); - Msg.info("XXXXXXXXXXXXXXX Step "+step+" done."); - } - } - - public void workBatch(int workersCount, String nameRoot) throws MsgException { - for (int i = 0; i < workersCount; i++) { - Task task = new Task("Task "+nameRoot + i, Main.TASK_COMP_SIZE, Main.TASK_COMM_SIZE); - Msg.verb("Sending to "+ nameRoot + i); - task.send(nameRoot + i); - } - } -} diff --git a/examples/deprecated/java/cloud/masterworker/Worker.java b/examples/deprecated/java/cloud/masterworker/Worker.java deleted file mode 100644 index 54e9c3703a..0000000000 --- a/examples/deprecated/java/cloud/masterworker/Worker.java +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package cloud.masterworker; - -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Process; -import org.simgrid.msg.Task; - -public class Worker extends Process { - public Worker(Host host, String name) { - super(host, name); - } - - public void main(String[] args) throws MsgException { - Msg.verb(this.getName() +" is listening on "+ getName()); - while(true) { - Task task = null; - try { - task = Task.receive(getName()); - } catch (MsgException e) { - Msg.info("Received failed. I'm done. See you!"); - exit(); - } - Msg.verb("Received '" + task.getName() + "'. Processing it."); - task.execute(); - Msg.verb("Done executing task '" + task.getName() +"'"); - } - } -} diff --git a/examples/deprecated/java/cloud/masterworker/cloud-masterworker.tesh b/examples/deprecated/java/cloud/masterworker/cloud-masterworker.tesh deleted file mode 100644 index 2aef8c8003..0000000000 --- a/examples/deprecated/java/cloud/masterworker/cloud-masterworker.tesh +++ /dev/null @@ -1,205 +0,0 @@ -#!/usr/bin/env tesh - -$ ${javacmd:=java} -classpath ${classpath:=.} cloud/masterworker/Main ${srcdir:=.}/../../platforms/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (1:Master@Boivin) Launched 6 VMs -> [ 0.000000] (1:Master@Boivin) Send some work to everyone -> [ 2.186532] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [1971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 1 done. -> [1971.662691] (1:Master@Boivin) Launched 6 VMs -> [1971.662691] (1:Master@Boivin) Send some work to everyone -> [1973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [2971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 2 done. -> [2971.662691] (1:Master@Boivin) Launched 6 VMs -> [2971.662691] (1:Master@Boivin) Send some work to everyone -> [2973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [3971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 3 done. -> [3971.662691] (1:Master@Boivin) Launched 6 VMs -> [3971.662691] (1:Master@Boivin) Send some work to everyone -> [3973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [4971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 4 done. -> [4971.662691] (1:Master@Boivin) Launched 6 VMs -> [4971.662691] (1:Master@Boivin) Send some work to everyone -> [4973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [5971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 5 done. -> [5971.662691] (1:Master@Boivin) Launched 6 VMs -> [5971.662691] (1:Master@Boivin) Send some work to everyone -> [5973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [6971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 6 done. -> [6971.662691] (1:Master@Boivin) Launched 6 VMs -> [6971.662691] (1:Master@Boivin) Send some work to everyone -> [6973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [7971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 7 done. -> [7971.662691] (1:Master@Boivin) Launched 6 VMs -> [7971.662691] (1:Master@Boivin) Send some work to everyone -> [7973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [8971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 8 done. -> [8971.662691] (1:Master@Boivin) Launched 6 VMs -> [8971.662691] (1:Master@Boivin) Send some work to everyone -> [8973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [9971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 9 done. -> [9971.662691] (1:Master@Boivin) Launched 6 VMs -> [9971.662691] (1:Master@Boivin) Send some work to everyone -> [9973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [10971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 10 done. -> [10971.662691] (1:Master@Boivin) Launched 6 VMs -> [10971.662691] (1:Master@Boivin) Send some work to everyone -> [10973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [11971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 11 done. -> [11971.662691] (1:Master@Boivin) Launched 6 VMs -> [11971.662691] (1:Master@Boivin) Send some work to everyone -> [11973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [12971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 12 done. -> [12971.662691] (1:Master@Boivin) Launched 6 VMs -> [12971.662691] (1:Master@Boivin) Send some work to everyone -> [12973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [13971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 13 done. -> [13971.662691] (1:Master@Boivin) Launched 6 VMs -> [13971.662691] (1:Master@Boivin) Send some work to everyone -> [13973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [14971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 14 done. -> [14971.662691] (1:Master@Boivin) Launched 6 VMs -> [14971.662691] (1:Master@Boivin) Send some work to everyone -> [14973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [15971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 15 done. -> [15971.662691] (1:Master@Boivin) Launched 6 VMs -> [15971.662691] (1:Master@Boivin) Send some work to everyone -> [15973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [16971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 16 done. -> [16971.662691] (1:Master@Boivin) Launched 6 VMs -> [16971.662691] (1:Master@Boivin) Send some work to everyone -> [16973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [17971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 17 done. -> [17971.662691] (1:Master@Boivin) Launched 6 VMs -> [17971.662691] (1:Master@Boivin) Send some work to everyone -> [17973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [18971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 18 done. -> [18971.662691] (1:Master@Boivin) Launched 6 VMs -> [18971.662691] (1:Master@Boivin) Send some work to everyone -> [18973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [19971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 19 done. -> [19971.662691] (1:Master@Boivin) Launched 6 VMs -> [19971.662691] (1:Master@Boivin) Send some work to everyone -> [19973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [20971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 20 done. -> [20971.662691] (1:Master@Boivin) Launched 6 VMs -> [20971.662691] (1:Master@Boivin) Send some work to everyone -> [20973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [21971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 21 done. -> [21971.662691] (1:Master@Boivin) Launched 6 VMs -> [21971.662691] (1:Master@Boivin) Send some work to everyone -> [21973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [22971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 22 done. -> [22971.662691] (1:Master@Boivin) Launched 6 VMs -> [22971.662691] (1:Master@Boivin) Send some work to everyone -> [22973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [23971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 23 done. -> [23971.662691] (1:Master@Boivin) Launched 6 VMs -> [23971.662691] (1:Master@Boivin) Send some work to everyone -> [23973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [24971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 24 done. -> [24971.662691] (1:Master@Boivin) Launched 6 VMs -> [24971.662691] (1:Master@Boivin) Send some work to everyone -> [24973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [25971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 25 done. -> [25971.662691] (1:Master@Boivin) Launched 6 VMs -> [25971.662691] (1:Master@Boivin) Send some work to everyone -> [25973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [26971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 26 done. -> [26971.662691] (1:Master@Boivin) Launched 6 VMs -> [26971.662691] (1:Master@Boivin) Send some work to everyone -> [26973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [27971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 27 done. -> [27971.662691] (1:Master@Boivin) Launched 6 VMs -> [27971.662691] (1:Master@Boivin) Send some work to everyone -> [27973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [28971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 28 done. -> [28971.662691] (1:Master@Boivin) Launched 6 VMs -> [28971.662691] (1:Master@Boivin) Send some work to everyone -> [28973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [29971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 29 done. -> [29971.662691] (1:Master@Boivin) Launched 6 VMs -> [29971.662691] (1:Master@Boivin) Send some work to everyone -> [29973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [30971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 30 done. -> [30971.662691] (1:Master@Boivin) Launched 6 VMs -> [30971.662691] (1:Master@Boivin) Send some work to everyone -> [30973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [31971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 31 done. -> [31971.662691] (1:Master@Boivin) Launched 6 VMs -> [31971.662691] (1:Master@Boivin) Send some work to everyone -> [31973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [32971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 32 done. -> [32971.662691] (1:Master@Boivin) Launched 6 VMs -> [32971.662691] (1:Master@Boivin) Send some work to everyone -> [32973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [33971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 33 done. -> [33971.662691] (1:Master@Boivin) Launched 6 VMs -> [33971.662691] (1:Master@Boivin) Send some work to everyone -> [33973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [34971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 34 done. -> [34971.662691] (1:Master@Boivin) Launched 6 VMs -> [34971.662691] (1:Master@Boivin) Send some work to everyone -> [34973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [35971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 35 done. -> [35971.662691] (1:Master@Boivin) Launched 6 VMs -> [35971.662691] (1:Master@Boivin) Send some work to everyone -> [35973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [36971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 36 done. -> [36971.662691] (1:Master@Boivin) Launched 6 VMs -> [36971.662691] (1:Master@Boivin) Send some work to everyone -> [36973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [37971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 37 done. -> [37971.662691] (1:Master@Boivin) Launched 6 VMs -> [37971.662691] (1:Master@Boivin) Send some work to everyone -> [37973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [38971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 38 done. -> [38971.662691] (1:Master@Boivin) Launched 6 VMs -> [38971.662691] (1:Master@Boivin) Send some work to everyone -> [38973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [39971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 39 done. -> [39971.662691] (1:Master@Boivin) Launched 6 VMs -> [39971.662691] (1:Master@Boivin) Send some work to everyone -> [39973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [40971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 40 done. -> [40971.662691] (1:Master@Boivin) Launched 6 VMs -> [40971.662691] (1:Master@Boivin) Send some work to everyone -> [40973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [41971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 41 done. -> [41971.662691] (1:Master@Boivin) Launched 6 VMs -> [41971.662691] (1:Master@Boivin) Send some work to everyone -> [41973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [42971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 42 done. -> [42971.662691] (1:Master@Boivin) Launched 6 VMs -> [42971.662691] (1:Master@Boivin) Send some work to everyone -> [42973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [43971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 43 done. -> [43971.662691] (1:Master@Boivin) Launched 6 VMs -> [43971.662691] (1:Master@Boivin) Send some work to everyone -> [43973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [44971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 44 done. -> [44971.662691] (1:Master@Boivin) Launched 6 VMs -> [44971.662691] (1:Master@Boivin) Send some work to everyone -> [44973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [45971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 45 done. -> [45971.662691] (1:Master@Boivin) Launched 6 VMs -> [45971.662691] (1:Master@Boivin) Send some work to everyone -> [45973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [46971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 46 done. -> [46971.662691] (1:Master@Boivin) Launched 6 VMs -> [46971.662691] (1:Master@Boivin) Send some work to everyone -> [46973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [47971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 47 done. -> [47971.662691] (1:Master@Boivin) Launched 6 VMs -> [47971.662691] (1:Master@Boivin) Send some work to everyone -> [47973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [48971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 48 done. -> [48971.662691] (1:Master@Boivin) Launched 6 VMs -> [48971.662691] (1:Master@Boivin) Send some work to everyone -> [48973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [49971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 49 done. -> [49971.662691] (1:Master@Boivin) Launched 6 VMs -> [49971.662691] (1:Master@Boivin) Send some work to everyone -> [49973.849223] (1:Master@Boivin) Suspend all VMs, wait a while, resume them, migrate them and shut them down. -> [50971.662691] (1:Master@Boivin) XXXXXXXXXXXXXXX Step 50 done. -> [50971.662691] (0:maestro@) Terminating the simulation... diff --git a/examples/deprecated/java/cloud/migration/Daemon.java b/examples/deprecated/java/cloud/migration/Daemon.java deleted file mode 100644 index 7453166c5e..0000000000 --- a/examples/deprecated/java/cloud/migration/Daemon.java +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package cloud.migration; - -import org.simgrid.msg.*; -import org.simgrid.msg.Process; - -public class Daemon extends Process { - private Task currentTask; - public Daemon(VM vm) { - super((Host)vm,"Daemon"); - currentTask = new Task(this.getHost().getName()+"-daemon-0", this.getHost().getSpeed()*100, 0); - } - public void main(String[] args) throws MsgException { - int i = 1; - while(!Main.isEndOfTest()) { - try { - currentTask.execute(); - } catch (HostFailureException e) { - e.printStackTrace(); - } catch (TaskCancelledException e) { - Msg.info("task cancelled"); - suspend(); // Suspend the process - } - currentTask = new Task(this.getHost().getName()+"-daemon-"+(i++), this.getHost().getSpeed()*100, 0); - } -} - - public double getRemaining(){ - return this.currentTask.getFlopsAmount(); - } -} diff --git a/examples/deprecated/java/cloud/migration/Main.java b/examples/deprecated/java/cloud/migration/Main.java deleted file mode 100644 index 75d3e01d7b..0000000000 --- a/examples/deprecated/java/cloud/migration/Main.java +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package cloud.migration; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; - -public class Main { - private static boolean endOfTest = false; - - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void setEndOfTest(){ - endOfTest=true; - } - - public static boolean isEndOfTest(){ - return endOfTest; - } - - public static void main(String[] args) throws MsgException { - Msg.init(args); - if (args.length < 1) { - Msg.info("Usage : Main platform_file.xml"); - System.exit(1); - } - - /* construct the platform and deploy the application */ - Msg.createEnvironment(args[0]); - new cloud.migration.Test("PM0","Test").start(); - Msg.run(); - } -} diff --git a/examples/deprecated/java/cloud/migration/README b/examples/deprecated/java/cloud/migration/README deleted file mode 100644 index b346b59326..0000000000 --- a/examples/deprecated/java/cloud/migration/README +++ /dev/null @@ -1,8 +0,0 @@ -There are two tests: -- The first one aims at validating the migration in presence of consolidated VMs -- The second one aims at validating the robustness of the migration process (the SRC node or the DST node are turned off during the migration process) - -To switch between the first and the second tests, you should instrument Main.java (sorry for that :( ) -Adsein - Thu Oct 9 18:25:39 CEST 2014 - -UPDATE: the second test was never used (dit it ever work?), and was removed 4 years later diff --git a/examples/deprecated/java/cloud/migration/Test.java b/examples/deprecated/java/cloud/migration/Test.java deleted file mode 100644 index 6bed352cec..0000000000 --- a/examples/deprecated/java/cloud/migration/Test.java +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package cloud.migration; -import java.util.ArrayList; -import java.util.List; - -import org.simgrid.msg.Host; -import org.simgrid.msg.HostFailureException; -import org.simgrid.msg.HostNotFoundException; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Process; -import org.simgrid.msg.VM; - -public class Test extends Process{ - - Test(String hostname, String name) throws HostNotFoundException { - super(hostname, name); - } - - public void doMigration(VM vm, Host src, Host dst) throws HostFailureException{ - Msg.info(" - Launch migration from "+ src.getName() +" to " + dst.getName()); - double startTime = Msg.getClock(); - vm.migrate(dst); - double endTime = Msg.getClock(); - Msg.info(" - End of Migration from "+ src.getName() +" to " + dst.getName()+ " (duration:" + - String.format(java.util.Locale.ROOT, "%.9f", (endTime-startTime))+")"); - } - - public void main(String[] strings) throws MsgException { - Host host0 = Host.getByName("PM0"); - Host host1 = Host.getByName("PM1"); - - List vms = new ArrayList<>(); - - /* Create VM1 */ - int dpRate = 70; - int load1 = 90; - int load2 = 80; - - Msg.info("This example evaluates the migration time of a VM in presence of collocated VMs on the source and " - + "the dest nodes"); - Msg.info("The migrated VM has a memory intensity rate of 70% of the network BW and a cpu load of 90% \" " - +"(see cloudcom 2013 paper \"Adding a Live Migration Model Into SimGrid\" for further information)"); - - Msg.info("Load of collocated VMs fluctuate between 0 and 90% in order to create a starvation issue and see " - + "whether it impacts or not the migration time"); - XVM vm1 = new XVM(host0, "vm0", - 2048, // Ramsize, - 125, // Net bandwidth, - dpRate // Memory intensity - ); - vms.add(vm1); - vm1.start(); - - /* Collocated VMs */ - int[] vmSrcLoad = { - 80, - 0, - 90, - 40, - 30, - 90, - }; - - XVM tmp; - for (int i=1 ; i<= vmSrcLoad.length ; i++){ - tmp = new XVM(host0, "vm"+i, - 2048, // Ramsize, - 125, // Net bandwidth, - dpRate // Memory intensity - ); - vms.add(tmp); - tmp.start(); - tmp.setLoad(vmSrcLoad[i-1]); - } - - int[] vmDstLoad = { - 0, - 40, - 90, - 100, - 0, - 80, - }; - - for (int i=1 ; i <= vmDstLoad.length ; i++){ - tmp = new XVM(host1, "vm"+(i+vmSrcLoad.length), - 2048, // Ramsize, - 125, // Net bandwidth, - dpRate // Memory intensity - ); - vms.add(tmp); - tmp.start(); - tmp.setLoad(vmDstLoad[i-1]); - } - - Msg.info("Round trip of VM1 (load "+load1+"%)"); - vm1.setLoad(load1); - doMigration(vm1, host0, host1); - doMigration(vm1, host1, host0); - Msg.info("."); - Msg.info("Round trip of VM1 (load "+load2+"%)"); - vm1.setLoad(load2); - doMigration(vm1, host0, host1); - doMigration(vm1, host1, host0); - - Main.setEndOfTest(); - Msg.info("Forcefully destroy VMs"); - for (VM vm: vms) - vm.destroy(); - } -} diff --git a/examples/deprecated/java/cloud/migration/XVM.java b/examples/deprecated/java/cloud/migration/XVM.java deleted file mode 100644 index bba4cf4bd4..0000000000 --- a/examples/deprecated/java/cloud/migration/XVM.java +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package cloud.migration; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.VM; -import org.simgrid.msg.Host; -import org.simgrid.msg.HostFailureException; - -public class XVM extends VM { - private int dpIntensity; - private int ramsize; - private int currentLoad = 0; - - private Daemon daemon; - - public XVM(Host host, String name, int ramsize, int migNetBW, int dpIntensity){ - super(host, name, ramsize, (int)(migNetBW*0.9), dpIntensity); - this.dpIntensity = dpIntensity ; - this.ramsize= ramsize; - this.daemon = new Daemon(this); - } - - public void setLoad(int load){ - if (load >0) { - this.setBound(this.getSpeed()*load/100); - daemon.resume(); - } else{ - daemon.suspend(); - } - currentLoad = load ; - } - - @Override - public void start() { - super.start(); - daemon.start(); - this.setLoad(0); - } - - public Daemon getDaemon(){ - return this.daemon; - } - - @Override - public void migrate(Host host) throws HostFailureException { - Msg.info("Start migration of VM " + this.getName() + " to " + host.getName()); - Msg.info(" currentLoad:" + this.currentLoad + "/ramSize:" + this.ramsize + "/dpIntensity:" + this.dpIntensity - + "/remaining:" + String.format(java.util.Locale.ROOT, "%.2E",this.daemon.getRemaining())); - try{ - super.migrate(host); - } catch (Exception e){ - Msg.info("Something wrong during the live migration of VM "+this.getName()); - throw new HostFailureException(); - } - this.setLoad(this.currentLoad); //Fixed the fact that setBound is not propagated to the new node. - Msg.info("End of migration of VM " + this.getName() + " to node " + host.getName()); - } -} diff --git a/examples/deprecated/java/cloud/migration/cloud-migration.tesh b/examples/deprecated/java/cloud/migration/cloud-migration.tesh deleted file mode 100644 index 01feec914c..0000000000 --- a/examples/deprecated/java/cloud/migration/cloud-migration.tesh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env tesh - -$ ${javacmd:=java} -classpath ${classpath:=.} cloud/migration/Main ${srcdir:=.}/../../platforms/three_multicore_hosts.xml -> [0.000000] [java/INFO] Using regular java threads. -> [PM0:Test:(1) 0.000000] [java/INFO] This example evaluates the migration time of a VM in presence of collocated VMs on the source and the dest nodes -> [PM0:Test:(1) 0.000000] [java/INFO] The migrated VM has a memory intensity rate of 70% of the network BW and a cpu load of 90% " (see cloudcom 2013 paper "Adding a Live Migration Model Into SimGrid" for further information) -> [PM0:Test:(1) 0.000000] [java/INFO] Load of collocated VMs fluctuate between 0 and 90% in order to create a starvation issue and see whether it impacts or not the migration time -> [PM0:Test:(1) 0.000000] [java/INFO] Round trip of VM1 (load 90%) -> [PM0:Test:(1) 0.000000] [java/INFO] - Launch migration from PM0 to PM1 -> [PM0:Test:(1) 0.000000] [java/INFO] Start migration of VM vm0 to PM1 -> [PM0:Test:(1) 0.000000] [java/INFO] currentLoad:90/ramSize:2048/dpIntensity:70/remaining:8.10E+11 -> [PM0:Test:(1) 45.731913] [java/INFO] End of migration of VM vm0 to node PM1 -> [PM0:Test:(1) 45.731913] [java/INFO] - End of Migration from PM0 to PM1 (duration:45.731912657) -> [PM0:Test:(1) 45.731913] [java/INFO] - Launch migration from PM1 to PM0 -> [PM0:Test:(1) 45.731913] [java/INFO] Start migration of VM vm0 to PM0 -> [PM0:Test:(1) 45.731913] [java/INFO] currentLoad:90/ramSize:2048/dpIntensity:70/remaining:5.01E+11 -> [PM0:Test:(1) 97.502375] [java/INFO] End of migration of VM vm0 to node PM0 -> [PM0:Test:(1) 97.502375] [java/INFO] - End of Migration from PM1 to PM0 (duration:51.770462809) -> [PM0:Test:(1) 97.502375] [java/INFO] . -> [PM0:Test:(1) 97.502375] [java/INFO] Round trip of VM1 (load 80%) -> [PM0:Test:(1) 97.502375] [java/INFO] - Launch migration from PM0 to PM1 -> [PM0:Test:(1) 97.502375] [java/INFO] Start migration of VM vm0 to PM1 -> [PM0:Test:(1) 97.502375] [java/INFO] currentLoad:80/ramSize:2048/dpIntensity:70/remaining:1.24E+11 -> [PM0:Test:(1) 140.710983] [java/INFO] End of migration of VM vm0 to node PM1 -> [PM0:Test:(1) 140.710983] [java/INFO] - End of Migration from PM0 to PM1 (duration:43.208607114) -> [PM0:Test:(1) 140.710983] [java/INFO] - Launch migration from PM1 to PM0 -> [PM0:Test:(1) 140.710983] [java/INFO] Start migration of VM vm0 to PM0 -> [PM0:Test:(1) 140.710983] [java/INFO] currentLoad:80/ramSize:2048/dpIntensity:70/remaining:6.54E+11 -> [PM0:Test:(1) 183.918289] [java/INFO] End of migration of VM vm0 to node PM0 -> [PM0:Test:(1) 183.918289] [java/INFO] - End of Migration from PM1 to PM0 (duration:43.207306114) -> [PM0:Test:(1) 183.918289] [java/INFO] Forcefully destroy VMs -> [183.918289] [java/INFO] Terminating the simulation... diff --git a/examples/deprecated/java/dht/chord/ChordTask.java b/examples/deprecated/java/dht/chord/ChordTask.java deleted file mode 100644 index e6e3184509..0000000000 --- a/examples/deprecated/java/dht/chord/ChordTask.java +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.chord; - -import org.simgrid.msg.Task; - -public class ChordTask extends Task { - private String issuerHostName; - private String answerTo; - public ChordTask() { - this(null,null); - } - - public ChordTask(String issuerHostName, String answerTo) { - super(null, Common.COMP_SIZE, Common.COMM_SIZE); - this.issuerHostName = issuerHostName; - this.answerTo = answerTo; - } - - public String getIssuerHostName(){ - return this.issuerHostName; - } - - public String getAnswerTo(){ - return this.answerTo; - } -} diff --git a/examples/deprecated/java/dht/chord/Common.java b/examples/deprecated/java/dht/chord/Common.java deleted file mode 100644 index 2b7b2934e9..0000000000 --- a/examples/deprecated/java/dht/chord/Common.java +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.chord; - -public class Common { - public static final int COMM_SIZE = 10; - public static final int COMP_SIZE = 0; - - public static final int NB_BITS = 24; - public static final int NB_KEYS = 16777216; - public static final int TIMEOUT = 50; - public static final int MAX_SIMULATION_TIME = 1000; - public static final int PERIODIC_STABILIZE_DELAY = 20; - public static final int PERIODIC_FIX_FINGERS_DELAY = 120; - public static final int PERIODIC_CHECK_PREDECESSOR_DELAY = 120; - public static final int PERIODIC_LOOKUP_DELAY = 10; - private Common() { - throw new IllegalAccessError("Utility class"); - } -} diff --git a/examples/deprecated/java/dht/chord/FindSuccessorAnswerTask.java b/examples/deprecated/java/dht/chord/FindSuccessorAnswerTask.java deleted file mode 100644 index 7e4c4b6efc..0000000000 --- a/examples/deprecated/java/dht/chord/FindSuccessorAnswerTask.java +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.chord; - -public class FindSuccessorAnswerTask extends ChordTask { - private int answerId; - - public FindSuccessorAnswerTask(String issuerHostname, String answerTo, int answerId) { - super(issuerHostname,answerTo); - this.answerId = answerId; - } - - public int getAnswerId(){ - return this.answerId; - } -} diff --git a/examples/deprecated/java/dht/chord/FindSuccessorTask.java b/examples/deprecated/java/dht/chord/FindSuccessorTask.java deleted file mode 100644 index 92474eb36c..0000000000 --- a/examples/deprecated/java/dht/chord/FindSuccessorTask.java +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.chord; - -public class FindSuccessorTask extends ChordTask { - private int requestId; - - public FindSuccessorTask(String issuerHostname, String answerTo, int requestId) { - super(issuerHostname, answerTo); - this.requestId = requestId; - } - - public int getRequestId(){ - return this.requestId; - } -} diff --git a/examples/deprecated/java/dht/chord/GetPredecessorAnswerTask.java b/examples/deprecated/java/dht/chord/GetPredecessorAnswerTask.java deleted file mode 100644 index 39ebffbeed..0000000000 --- a/examples/deprecated/java/dht/chord/GetPredecessorAnswerTask.java +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.chord; - -public class GetPredecessorAnswerTask extends ChordTask { - private int answerId; - - public GetPredecessorAnswerTask(String issuerHostname, String answerTo, int answerId) { - super(issuerHostname,answerTo); - this.answerId = answerId; - } - - public int getAnswerId(){ - return this.answerId; - } -} diff --git a/examples/deprecated/java/dht/chord/GetPredecessorTask.java b/examples/deprecated/java/dht/chord/GetPredecessorTask.java deleted file mode 100644 index 82bd9cf4e6..0000000000 --- a/examples/deprecated/java/dht/chord/GetPredecessorTask.java +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.chord; - -public class GetPredecessorTask extends ChordTask { - public GetPredecessorTask(String issuerHostName, String answerTo) { - super(issuerHostName, answerTo); - } -} diff --git a/examples/deprecated/java/dht/chord/Main.java b/examples/deprecated/java/dht/chord/Main.java deleted file mode 100644 index 5b217a6a66..0000000000 --- a/examples/deprecated/java/dht/chord/Main.java +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.chord; - -import org.simgrid.msg.Msg; - -class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - if(args.length < 2) { - Msg.info("Usage : Chord platform_file deployment_file"); - Msg.info("example : Chord ../platforms/platform.xml chord.xml"); - System.exit(1); - } - /* construct the platform and deploy the application */ - Msg.createEnvironment(args[0]); - Msg.deployApplication(args[1]); - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/dht/chord/Node.java b/examples/deprecated/java/dht/chord/Node.java deleted file mode 100644 index e079a7f071..0000000000 --- a/examples/deprecated/java/dht/chord/Node.java +++ /dev/null @@ -1,394 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.chord; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Comm; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.TimeoutException; -public class Node extends Process { - protected int id; - protected String mailbox; - protected int predId; - protected String predMailbox; - protected int nextFingerToFix; - protected Comm commReceive; - ///Last time I changed a finger or my predecessor - protected double lastChangeDate; - private int[] fingers; - - public Node(Host host, String name, String[] args) { - super(host,name,args); - } - - @Override - public void main(String[] args) throws MsgException { - if (args.length != 2 && args.length != 4) { - Msg.info("You need to provide 2 or 4 arguments."); - return; - } - double initTime = Msg.getClock(); - int i; - boolean joinSuccess; - double deadline; - - double nextStabilizeDate = initTime + Common.PERIODIC_STABILIZE_DELAY; - double nextFixFingersDate = initTime + Common.PERIODIC_FIX_FINGERS_DELAY; - double nextCheckPredecessorDate = initTime + Common.PERIODIC_CHECK_PREDECESSOR_DELAY; - double nextLookupDate = initTime + Common.PERIODIC_LOOKUP_DELAY; - - mailbox = args[0]; - id = Integer.parseInt(args[0]); - - fingers = new int[Common.NB_BITS]; - for (i = 0; i < Common.NB_BITS; i++) { - fingers[i] = -1; - setFinger(i,this.id); - } - - //First node - if (args.length == 2) { - deadline = Integer.parseInt(args[1]); - create(); - joinSuccess = true; - } else { - int knownId = Integer.parseInt(args[1]); - deadline = Integer.parseInt(args[3]); - Msg.debug("Hey! Let's join the system with the id " + id + "."); - - joinSuccess = join(knownId); - } - - if (!joinSuccess) { - Msg.info("I couldn't join the ring"); - return; - } - - double currentClock = Msg.getClock(); - while (currentClock < (initTime + deadline) && currentClock < Common.MAX_SIMULATION_TIME) { - if (commReceive == null) { - commReceive = Task.irecv(this.mailbox); - } - try { - if (!commReceive.test()) { - if (currentClock >= nextStabilizeDate) { - stabilize(); - nextStabilizeDate = Msg.getClock() + Common.PERIODIC_STABILIZE_DELAY; - } else if (currentClock >= nextFixFingersDate) { - fixFingers(); - nextFixFingersDate = Msg.getClock() + Common.PERIODIC_FIX_FINGERS_DELAY; - } else if (currentClock >= nextCheckPredecessorDate) { - this.checkPredecessor(); - nextCheckPredecessorDate = Msg.getClock() + Common.PERIODIC_CHECK_PREDECESSOR_DELAY; - } else if (currentClock >= nextLookupDate) { - this.randomLookup(); - nextLookupDate = Msg.getClock() + Common.PERIODIC_LOOKUP_DELAY; - } else { - waitFor(5); - } - currentClock = Msg.getClock(); - } else { - handleTask(commReceive.getTask()); - currentClock = Msg.getClock(); - commReceive = null; - } - } - catch (Exception e) { - currentClock = Msg.getClock(); - commReceive = null; - } - } - leave(); - if (commReceive != null) { - commReceive = null; - } - } - - private void handleTask(Task task) { - if (task instanceof FindSuccessorTask) { - FindSuccessorTask fTask = (FindSuccessorTask)task; - Msg.debug("Receiving a 'Find Successor' request from " + fTask.getIssuerHostName() + " for id " + - fTask.getRequestId()); - // is my successor the successor? - if (isInInterval(fTask.getRequestId(), this.id + 1, fingers[0])) { - Msg.debug("Send the request to " + fTask.getAnswerTo() + " with answer " + fingers[0]); - FindSuccessorAnswerTask answer = new FindSuccessorAnswerTask(getHost().getName(), mailbox, fingers[0]); - answer.dsend(fTask.getAnswerTo()); - } else { - // otherwise, forward the request to the closest preceding finger in my table - int closest = closestPrecedingNode(fTask.getRequestId()); - Msg.debug("Forward the request to " + closest); - fTask.dsend(Integer.toString(closest)); - } - } else if (task instanceof GetPredecessorTask) { - GetPredecessorTask gTask = (GetPredecessorTask)(task); - Msg.debug("Receiving a 'Get Predecessor' request from " + gTask.getIssuerHostName()); - GetPredecessorAnswerTask answer = new GetPredecessorAnswerTask(getHost().getName(), mailbox, predId); - answer.dsend(gTask.getAnswerTo()); - } else if (task instanceof NotifyTask) { - NotifyTask nTask = (NotifyTask)task; - notify(nTask.getRequestId()); - } else { - Msg.debug("Ignoring unexpected task of type:" + task); - } - } - - private void leave() { - Msg.debug("Well Guys! I Think it's time for me to quit ;)"); - // TODO: Notify my successor and predecessor. - } - - /** @brief Initializes the current node as the first one of the system */ - private void create() { - Msg.debug("Create a new Chord ring..."); - setPredecessor(-1); - } - - // Makes the current node join the ring, knowing the id of a node already in the ring - private boolean join(int knownId) { - Msg.info("Joining the ring with id " + this.id + " knowing node " + knownId); - setPredecessor(-1); - int successorId = remoteFindSuccessor(knownId, this.id); - if (successorId == -1) { - Msg.info("Cannot join the ring."); - } else { - setFinger(0, successorId); - } - return successorId != -1; - } - - private void setPredecessor(int predecessorId) { - if (predecessorId != predId) { - predId = predecessorId; - if (predecessorId != -1) { - predMailbox = Integer.toString(predId); - } - lastChangeDate = Msg.getClock(); - } - } - - /** - * @brief Asks another node its predecessor. - * @param askTo the node to ask to - * @return the id of its predecessor node, or -1 if the request failed(or if the node does not know its predecessor) - */ - private int remoteGetPredecessor(int askTo) { - int predecessorId = -1; - boolean stop = false; - Msg.debug("Sending a 'Get Predecessor' request to " + askTo); - String mailboxTo = Integer.toString(askTo); - GetPredecessorTask sendTask = new GetPredecessorTask(getHost().getName(), this.mailbox); - try { - sendTask.send(mailboxTo, Common.TIMEOUT); - do { - if (commReceive == null) { - commReceive = Task.irecv(this.mailbox); - } - commReceive.waitCompletion(Common.TIMEOUT); - Task taskReceived = commReceive.getTask(); - if (taskReceived instanceof GetPredecessorAnswerTask) { - predecessorId = ((GetPredecessorAnswerTask) taskReceived).getAnswerId(); - stop = true; - } else { - handleTask(taskReceived); - } - commReceive = null; - } while (!stop); - } - catch (MsgException e) { - Msg.debug("Failed to send the Get Predecessor request"); - } - commReceive = null; - - return predecessorId; - } - - /** - * @brief Makes the current node find the successor node of an id. - * @param node the current node - * @param id the id to find - * @return the id of the successor node, or -1 if the request failed - */ - private int findSuccessor(int id) { - if (isInInterval(id, this.id + 1, fingers[0])) { - return fingers[0]; - } - - int closest = this.closestPrecedingNode(id); - return remoteFindSuccessor(closest, id); - } - - // Asks another node the successor node of an id. - private int remoteFindSuccessor(int askTo, int id) { - int successor = -1; - boolean stop = false; - String askToMailbox = Integer.toString(askTo); - Task sendTask = new FindSuccessorTask(getHost().getName(), this.mailbox, id); - Msg.debug("Sending a 'Find Successor' request to " + askToMailbox + " for id " + id); - try { - sendTask.send(askToMailbox, Common.TIMEOUT); - do { - if (commReceive == null) { - commReceive = Task.irecv(this.mailbox); - } - commReceive.waitCompletion(Common.TIMEOUT); - Task task = commReceive.getTask(); - if (task instanceof FindSuccessorAnswerTask) { - //TODO: Check if this this our answer. - FindSuccessorAnswerTask fTask = (FindSuccessorAnswerTask) task; - stop = true; - successor = fTask.getAnswerId(); - } else { - handleTask(task); - } - commReceive = null; - } while (!stop); - } - catch (TimeoutException e) { - Msg.debug("Failed to send the 'Find Successor' request"); - } - catch (MsgException e) { - Msg.debug("Failed to receive Find Successor"); - } - commReceive = null; - - return successor; - } - - // This function is called periodically. It checks the immediate successor of the current node. - private void stabilize() { - Msg.debug("Stabilizing node"); - int candidateId; - int successorId = fingers[0]; - if (successorId != this.id){ - candidateId = remoteGetPredecessor(successorId); - } else { - candidateId = predId; - } - //This node is a candidate to become my new successor - if (candidateId != -1 && isInInterval(candidateId, this.id + 1, successorId - 1)) { - setFinger(0, candidateId); - } - if (successorId != this.id) { - remoteNotify(successorId, this.id); - } - } - - /** - * @brief Notifies the current node that its predecessor may have changed. - * @param candidate_id the possible new predecessor - */ - private void notify(int predecessorCandidateId) { - if (predId == -1 || isInInterval(predecessorCandidateId, predId + 1, this.id - 1 )) { - setPredecessor(predecessorCandidateId); - } - } - - /** - * @brief Notifies a remote node that its predecessor may have changed. - * @param notify_id id of the node to notify - * @param candidate_id the possible new predecessor - */ - private void remoteNotify(int notifyId, int predecessorCandidateId) { - Msg.debug("Sending a 'Notify' request to " + notifyId); - Task sentTask = new NotifyTask(getHost().getName(), this.mailbox, predecessorCandidateId); - sentTask.dsend(Integer.toString(notifyId)); - } - - // This function is called periodically. - // It refreshes the finger table of the current node. - private void fixFingers() { - Msg.debug("Fixing fingers"); - int successorId = findSuccessor(id + (1 << nextFingerToFix)); - if (successorId != -1) { - if (successorId != fingers[nextFingerToFix]) { - setFinger(nextFingerToFix, successorId); - } - nextFingerToFix = (nextFingerToFix + 1) % Common.NB_BITS; - } - } - - // This function is called periodically. - // It checks whether the predecessor has failed - private void checkPredecessor() { - //TODO - } - - // Performs a find successor request to a random id. - private void randomLookup() { - int dest = 1337; - findSuccessor(dest); - } - - /** - * @brief Returns the closest preceding finger of an id with respect to the finger table of the current node. - * @param id the id to find - * @return the closest preceding finger of that id - */ - private int closestPrecedingNode(int id) { - for (int i = Common.NB_BITS - 1; i >= 0; i--) { - if (isInInterval(fingers[i], this.id + 1, id - 1)) { - return fingers[i]; - } - } - return this.id; - } - - /** - * @brief Returns whether an id belongs to the interval [start, end]. - * - * The parameters are noramlized to make sure they are between 0 and nb_keys - 1). - * 1 belongs to [62, 3] - * 1 does not belong to [3, 62] - * 63 belongs to [62, 3] - * 63 does not belong to [3, 62] - * 24 belongs to [21, 29] - * 24 does not belong to [29, 21] - * - * @param id id to check - * @param start lower bound - * @param end upper bound - * @return a non-zero value if id in in [start, end] - */ - private static boolean isInInterval(int id, int start, int end) { - int normId = normalize(id); - int normStart = normalize(start); - int normEnd = normalize(end); - - // make sure end >= start and id >= start - if (normEnd < normStart) { - normEnd += Common.NB_KEYS; - } - if (normId < normStart) { - normId += Common.NB_KEYS; - } - return (normId <= normEnd); - } - - /** - * @brief Turns an id into an equivalent id in [0, nb_keys). - * @param id an id - * @return the corresponding normalized id - */ - private static int normalize(int id) { - return id & (Common.NB_KEYS - 1); - } - - /** - * @brief Sets a finger of the current node. - * @param finger_index index of the finger to set (0 to nb_bits - 1) - * @param id the id to set for this finger - */ - private void setFinger(int fingerIndex, int id) { - if (id != fingers[fingerIndex]) { - fingers[fingerIndex] = id; - lastChangeDate = Msg.getClock(); - } - } -} diff --git a/examples/deprecated/java/dht/chord/NotifyTask.java b/examples/deprecated/java/dht/chord/NotifyTask.java deleted file mode 100644 index 2318f1edd8..0000000000 --- a/examples/deprecated/java/dht/chord/NotifyTask.java +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.chord; - -public class NotifyTask extends ChordTask { - private int requestId; - - public NotifyTask(String issuerHostname, String answerTo, int requestId) { - super(issuerHostname, answerTo); - this.requestId = requestId; - } - - public int getRequestId(){ - return this.requestId; - } -} diff --git a/examples/deprecated/java/dht/chord/chord.xml b/examples/deprecated/java/dht/chord/chord.xml deleted file mode 100644 index bd76a59259..0000000000 --- a/examples/deprecated/java/dht/chord/chord.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/deprecated/java/dht/chord/dht-chord.tesh b/examples/deprecated/java/dht/chord/dht-chord.tesh deleted file mode 100644 index e85a815648..0000000000 --- a/examples/deprecated/java/dht/chord/dht-chord.tesh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 - -$ ${javacmd:=java} -classpath ${classpath:=.} dht/chord/Main ${srcdir:=.}/../../platforms/cluster_backbone.xml ${srcdir:=.}/dht/chord/chord.xml -> [0.000000] [java/INFO] Using regular java threads. -> [1046.803210] [java/INFO] Terminating the simulation... -> [node-1.simgrid.org:dht.chord.Node:(2) 0.000000] [java/INFO] Joining the ring with id 366680 knowing node 42 -> [node-2.simgrid.org:dht.chord.Node:(3) 0.000000] [java/INFO] Joining the ring with id 533744 knowing node 366680 -> [node-3.simgrid.org:dht.chord.Node:(4) 0.000000] [java/INFO] Joining the ring with id 1319738 knowing node 42 -> [node-4.simgrid.org:dht.chord.Node:(5) 0.000000] [java/INFO] Joining the ring with id 16509405 knowing node 366680 -> [node-5.simgrid.org:dht.chord.Node:(6) 0.000000] [java/INFO] Joining the ring with id 10874876 knowing node 533744 -> [node-6.simgrid.org:dht.chord.Node:(7) 0.000000] [java/INFO] Joining the ring with id 16728096 knowing node 1319738 -> [node-7.simgrid.org:dht.chord.Node:(8) 0.000000] [java/INFO] Joining the ring with id 10004760 knowing node 16509405 -> [node-8.simgrid.org:dht.chord.Node:(9) 0.000000] [java/INFO] Joining the ring with id 6518808 knowing node 42 -> [node-9.simgrid.org:dht.chord.Node:(10) 0.000000] [java/INFO] Joining the ring with id 2015253 knowing node 1319738 diff --git a/examples/deprecated/java/dht/kademlia/Answer.java b/examples/deprecated/java/dht/kademlia/Answer.java deleted file mode 100644 index d2d5b5f555..0000000000 --- a/examples/deprecated/java/dht/kademlia/Answer.java +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; -import java.util.ArrayList; -import java.util.Collections; - -/* Answer to a "FIND_NODE" query. Contains the nodes closest to an id given */ -public class Answer { - private int destinationId; - /* Closest nodes in the answer. */ - private ArrayList nodes; - - public Answer(int destinationId) { - this.destinationId = destinationId; - nodes = new ArrayList<>(); - } - - protected int getDestinationId() { - return destinationId; - } - - protected ArrayList getNodes() { - return nodes; - } - - protected int size() { - return nodes.size(); - } - - public void trim() { - if (nodes.size() > Common.BUCKET_SIZE) - nodes.subList(nodes.size() - Common.BUCKET_SIZE, nodes.size()).clear(); - } - - public void add(Contact contact) { - nodes.add(contact); - } - - /* Merge the contents of this answer with another answer */ - public int merge(Answer answer) { - int nbAdded = 0; - - for (Contact c: answer.getNodes()) { - if (!nodes.contains(c)) { - nbAdded++; - nodes.add(c); - } - } - Collections.sort(nodes); - //Trim the list - answer.trim(); - - return nbAdded; - } - - /* Returns if the destination has been found */ - public boolean destinationFound() { - if (nodes.isEmpty()) { - return false; - } - Contact tail = nodes.get(0); - return tail.getDistance() == 0; - } - - @Override - public String toString() { - return "Answer [destinationId=" + destinationId + ", nodes=" + nodes + "]"; - } -} diff --git a/examples/deprecated/java/dht/kademlia/Bucket.java b/examples/deprecated/java/dht/kademlia/Bucket.java deleted file mode 100644 index 327c8f4b3d..0000000000 --- a/examples/deprecated/java/dht/kademlia/Bucket.java +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; -import java.util.ArrayList; - -public class Bucket { - private ArrayList nodes; - private int id; - - public Bucket(int id) { - this.nodes = new ArrayList<>(); - this.id = id; - } - - public int getId() { - return this.id; - } - - public int size() { - return nodes.size(); - } - - public boolean contains(int id) { - return nodes.contains(id); - } - - /* Add a node to the front of the bucket */ - public void add(int id) { - nodes.add(0,id); - } - - /* Push a node to the front of a bucket */ - public void pushToFront(int id) { - int i = nodes.indexOf(id); - nodes.remove(i); - nodes.add(0, id); - } - - public int getNode(int id) { - return nodes.get(id); - } - - /* Add the content of the bucket into an answer object. */ - public void addToAnswer(Answer answer, int destination) { - for (int nodeId : this.nodes) { - answer.getNodes().add(new Contact(nodeId,nodeId ^ destination)); - } - } - - @Override - public String toString() { - return "Bucket [id= " + id + " nodes=" + nodes + "]"; - } -} diff --git a/examples/deprecated/java/dht/kademlia/Common.java b/examples/deprecated/java/dht/kademlia/Common.java deleted file mode 100644 index 1c4034e38f..0000000000 --- a/examples/deprecated/java/dht/kademlia/Common.java +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; - -public class Common { - /* Common constants used all over the simulation */ - public static final int COMM_SIZE = 1; - public static final int COMP_SIZE = 0; - - public static final int RANDOM_LOOKUP_INTERVAL = 100; - - public static final int ALPHA = 3; - - public static final int IDENTIFIER_SIZE = 32; - /* Maximum size of the buckets */ - public static final int BUCKET_SIZE = 20; - /* Maximum number of trials for the "JOIN" request */ - public static final int MAX_JOIN_TRIALS = 4; - /* Timeout for a "FIND_NODE" request to a node */ - public static final int FIND_NODE_TIMEOUT = 10; - /* Global timeout for a FIND_NODE request */ - public static final int FIND_NODE_GLOBAL_TIMEOUT = 50; - - public static final int MAX_STEPS = 10; - public static final int JOIN_BUCKETS_QUERIES = 1; - private Common() { - throw new IllegalAccessError("Utility class"); - } -} diff --git a/examples/deprecated/java/dht/kademlia/Contact.java b/examples/deprecated/java/dht/kademlia/Contact.java deleted file mode 100644 index 9d189fc88f..0000000000 --- a/examples/deprecated/java/dht/kademlia/Contact.java +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; - -public class Contact implements Comparable { - private int id; - private int distance; - - public Contact(int id, int distance) { - this.id = id; - this.distance = distance; - } - - public int getId() { - return id; - } - - public int getDistance() { - return distance; - } - - @Override - public boolean equals(Object x) { - return x != null && x.equals(id); - } - - @Override - public int hashCode() { - int hash = 1; - hash = hash * 17 + id; - hash = hash * 31 + distance; - return hash; - } - - @Override - public int compareTo(Object o) { - Contact c = (Contact)o; - if (distance < c.distance) { - return -1; - } - else if (distance == c.distance) { - return 0; - } - else { - return 1; - } - } - - @Override - public String toString() { - return "Contact [id=" + id + ", distance=" + distance + "]"; - } - -} diff --git a/examples/deprecated/java/dht/kademlia/FindNodeAnswerTask.java b/examples/deprecated/java/dht/kademlia/FindNodeAnswerTask.java deleted file mode 100644 index 8f28ef5382..0000000000 --- a/examples/deprecated/java/dht/kademlia/FindNodeAnswerTask.java +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; - -public class FindNodeAnswerTask extends KademliaTask { - protected int destinationId; - protected Answer answer; - - public FindNodeAnswerTask(int senderId, int destinationId, Answer answer) { - super(senderId); - this.destinationId = destinationId; - this.answer = answer; - } - public int getDestinationId() { - return destinationId; - } - public Answer getAnswer() { - return answer; - } -} diff --git a/examples/deprecated/java/dht/kademlia/FindNodeTask.java b/examples/deprecated/java/dht/kademlia/FindNodeTask.java deleted file mode 100644 index fa8fcaf09c..0000000000 --- a/examples/deprecated/java/dht/kademlia/FindNodeTask.java +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; - -/** - * @brief Find node tasks sent by a node to another "Find Node" task sent by a node to another. Ask him for its closest - * nodes from a destination. - */ -public class FindNodeTask extends KademliaTask { - /* Id of the node we are trying to find: the destination */ - private int destination; - - public FindNodeTask(int senderId, int destination) { - super(senderId); - this.destination = destination; - } - - public int getDestination() { - return destination; - } -} diff --git a/examples/deprecated/java/dht/kademlia/KademliaTask.java b/examples/deprecated/java/dht/kademlia/KademliaTask.java deleted file mode 100644 index 8aac869554..0000000000 --- a/examples/deprecated/java/dht/kademlia/KademliaTask.java +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; - -import org.simgrid.msg.Task; - -public class KademliaTask extends Task { - protected int senderId; - - public KademliaTask(int senderId) { - super("kademliatask",Common.COMP_SIZE,Common.COMM_SIZE); - this.senderId = senderId; - } - - public int getSenderId() { - return senderId; - } -} diff --git a/examples/deprecated/java/dht/kademlia/Main.java b/examples/deprecated/java/dht/kademlia/Main.java deleted file mode 100644 index 5ba37ff619..0000000000 --- a/examples/deprecated/java/dht/kademlia/Main.java +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; -import org.simgrid.msg.Msg; - -class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - if(args.length < 2) { - Msg.info("Usage : Kademlia platform_file deployment_file"); - Msg.info("example : Kademlia ../platforms/platform.xml kademlia.xml"); - System.exit(1); - } - - /* construct the platform and deploy the application */ - Msg.createEnvironment(args[0]); - Msg.deployApplication(args[1]); - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/dht/kademlia/Node.java b/examples/deprecated/java/dht/kademlia/Node.java deleted file mode 100644 index 2c485538f7..0000000000 --- a/examples/deprecated/java/dht/kademlia/Node.java +++ /dev/null @@ -1,280 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; - -import org.simgrid.msg.Host; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Comm; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; - -public class Node extends Process { - protected int id; - protected RoutingTable table; - protected int deadline; - protected int findNodeSuccedded = 0; - protected int findNodeFailed = 0; - protected Comm comm; - - public Node(Host host, String name, String[]args) { - super(host,name,args); - } - - @Override - public void main(String[] args) throws MsgException { - //Check the number of arguments. - if (args.length != 2 && args.length != 3) { - Msg.info("Wrong argument count."); - return; - } - this.id = Integer.parseInt(args[0]); - this.table = new RoutingTable(this.id); - - if (args.length == 3) { - this.deadline = Integer.parseInt(args[2]); - Msg.info("Hi, I'm going to join the network with the id " + id + "!"); - if (joinNetwork(Integer.parseInt(args[1]))) { - this.mainLoop(); - } - else { - Msg.info("I couldn't join the network :("); - } - } - else { - this.deadline = Integer.parseInt(args[1]); - Msg.info("Hi, I'm going to create the network with the id " + id + "!"); - table.update(this.id); - this.mainLoop(); - } - Msg.debug("I'm leaving the network"); - Msg.debug("Here is my routing table:" + table); - } - - public void mainLoop() { - double nextLookupTime = Msg.getClock() + Common.RANDOM_LOOKUP_INTERVAL; - while (Msg.getClock() < this.deadline) { - try { - if (comm == null) { - comm = Task.irecv(Integer.toString(id)); - } - if (!comm.test()) { - if (Msg.getClock() >= nextLookupTime) { - randomLookup(); - nextLookupTime += Common.RANDOM_LOOKUP_INTERVAL; - } else { - waitFor(1); - } - } else { - Task task = comm.getTask(); - handleTask(task); - comm = null; - } - } - catch (Exception e) { - Msg.debug("Caught exception: " + e); - } - } - Msg.info(findNodeSuccedded + "/" + (findNodeSuccedded + findNodeFailed) + " FIND_NODE have succeeded."); - } - - /** - * @brief Try to make the node join the network - * @param idKnown Id of someone we know in the system - */ - public boolean joinNetwork(int idKnown) { - boolean answerGot = false; - double timeBegin = Msg.getClock(); - Msg.debug("Joining the network knowing " + idKnown); - //Add ourselves and the node we know to our routing table - table.update(this.id); - table.update(idKnown); - //Send a "FIND_NODE" to the node we know. - sendFindNode(idKnown,this.id); - //Wait for the answer. - int trials = 0; - - do { - try { - if (comm == null) { - comm = Task.irecv(Integer.toString(id)); - } - if (comm != null) { - if (!comm.test()) { - waitFor(1); - } else { - Task task = comm.getTask(); - if (task instanceof FindNodeAnswerTask) { - //Retrieve the node list and ping them - FindNodeAnswerTask answerTask = (FindNodeAnswerTask)task; - Answer answer = answerTask.getAnswer(); - answerGot = true; - if (answer.getDestinationId() == this.id) { - //Ping everyone in the list - for (Contact c : answer.getNodes()) { - table.update(c.getId()); - } - } - } else { - handleTask(task); - } - comm = null; - } - } - } - catch (Exception ex) { - trials++; - Msg.info("FIND_NODE failed"); - } - } while (!answerGot && trials < Common.MAX_JOIN_TRIALS); - /* Second step: Send a FIND_NODE in a node in each bucket */ - int bucketId = table.findBucket(idKnown).getId(); - for (int i = 0; ((bucketId - i) > 0 || - (bucketId + i) <= Common.IDENTIFIER_SIZE) && - i < Common.JOIN_BUCKETS_QUERIES; i++) { - if (bucketId - i > 0) { - int idInBucket = table.getIdInPrefix(this.id,bucketId - i); - this.findNode(idInBucket,false); - } - if (bucketId + i <= Common.IDENTIFIER_SIZE) { - int idInBucket = table.getIdInPrefix(this.id,bucketId + i); - findNode(idInBucket,false); - } - } - Msg.debug("Time spent:" + (Msg.getClock() - timeBegin)); - return answerGot; - } - - /* Send a request to find a node in the node's routing table. */ - public boolean findNode(int destination, boolean counts) { - int queries; - int answers; - int nodesAdded; - boolean destinationFound; - int steps = 0; - double timeBeginReceive; - double timeout; - double globalTimeout = Msg.getClock() + Common.FIND_NODE_GLOBAL_TIMEOUT; - //Build a list of the closest nodes we already know. - Answer nodeList = table.findClosest(destination); - Msg.verb("Doing a FIND_NODE on " + destination); - do { - timeBeginReceive = Msg.getClock(); - answers = 0; - queries = this.sendFindNodeToBest(nodeList); - nodesAdded = 0; - timeout = Msg.getClock() + Common.FIND_NODE_TIMEOUT; - steps++; - do { - try { - if (comm == null) { - comm = Task.irecv(Integer.toString(id)); - } - if (!comm.test()) { - waitFor(1); - } else { - Task task = comm.getTask(); - if (task instanceof FindNodeAnswerTask) { - FindNodeAnswerTask answerTask = (FindNodeAnswerTask)task; - //Check if we received what we are looking for. - if (answerTask.getDestinationId() == destination) { - table.update(answerTask.getSenderId()); - //Add the answer to our routing table - for (Contact c: answerTask.getAnswer().getNodes()) { - table.update(c.getId()); - } - answers++; - - nodesAdded = nodeList.merge(answerTask.getAnswer()); - } else { - /* If it's not our answer, we answer to the node that has queried us anyway */ - handleTask(task); - //Update the timeout if it's not our answer. - timeout += Msg.getClock() - timeBeginReceive; - timeBeginReceive = Msg.getClock(); - } - } else { - handleTask(task); - timeout += Msg.getClock() - timeBeginReceive; - timeBeginReceive = Msg.getClock(); - } - comm = null; - } - } - catch (Exception e) { - comm = null; - } - } while (answers < queries && Msg.getClock() < timeout); - destinationFound = nodeList.destinationFound(); - } while (!destinationFound && (nodesAdded > 0 || answers == 0) && Msg.getClock() < globalTimeout - && steps < Common.MAX_STEPS); - - if (destinationFound) { - if (counts) { - findNodeSuccedded++; - } - Msg.debug("Find node on " + destination + " succeeded"); - } else { - Msg.debug("Find node on " + destination + " failed"); - Msg.debug("Queried " + queries + " nodes to find " + destination); - Msg.debug(nodeList.toString()); - if (counts) { - findNodeFailed++; - } - } - return destinationFound; - } - - /** - * @brief Sends a "FIND_NODE" request (task) to a node we know. - * @param id Id of the node we are querying - * @param destination id of the node we are trying to find. - */ - public void sendFindNode(int id, int destination) { - Msg.debug("Sending a FIND_NODE to " + Integer.toString(id) + " to find " + destination ); - FindNodeTask task = new FindNodeTask(this.id,destination); - task.dsend(Integer.toString(id)); - } - - /** Sends a "FIND_NODE" request to the best "alpha" nodes in a node list */ - public int sendFindNodeToBest(Answer nodeList) { - int destination = nodeList.getDestinationId(); - int i; - for (i = 0; i < Common.ALPHA && i < nodeList.size(); i++) { - Contact node = nodeList.getNodes().get(i); - if (node.getId() != this.id) { - this.sendFindNode(node.getId(),destination); - } - } - return i; - } - - public void randomLookup() { - findNode(0,true); - } - - /** - * @brief Handles an incoming task - * @param task The task we need to handle - */ - public void handleTask(Task task) { - if (task instanceof KademliaTask) { - table.update(((KademliaTask) task).getSenderId()); - if (task instanceof FindNodeTask) { - handleFindNode((FindNodeTask)task); - } - } - } - - public void handleFindNode(FindNodeTask task) { - Msg.debug("Received a FIND_NODE from " + task.getSenderId()); - Answer answer = table.findClosest(task.getDestination()); - FindNodeAnswerTask taskToSend = new FindNodeAnswerTask(this.id,task.getDestination(),answer); - taskToSend.dsend(Integer.toString(task.getSenderId())); - } -} diff --git a/examples/deprecated/java/dht/kademlia/RoutingTable.java b/examples/deprecated/java/dht/kademlia/RoutingTable.java deleted file mode 100644 index c62545e423..0000000000 --- a/examples/deprecated/java/dht/kademlia/RoutingTable.java +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package dht.kademlia; -import java.util.ArrayList; -import java.util.Collections; - -import org.simgrid.msg.Msg; - -public class RoutingTable { - /* Bucket list */ - private ArrayList buckets; - /* Id of the routing table owner */ - private int id; - - public RoutingTable(int id) { - this.id = id; - buckets = new ArrayList<>(); - for (int i = 0; i < Common.IDENTIFIER_SIZE + 1; i++) { - buckets.add(new Bucket(i)); - } - } - - /** - * @brief Returns an identifier which is in a specific bucket of a routing table - * @param id id of the routing table owner - * @param prefix id of the bucket where we want that identifier to be - */ - public int getIdInPrefix(int id, int prefix) { - if (prefix == 0) { - return 0; - } - int identifier = 1; - identifier = identifier << (prefix - 1); - identifier = identifier ^ id; - return identifier; - } - - /* Returns the corresponding node prefix for a given id */ - public int getNodePrefix(int id) { - for (int j = 0; j < 32; j++) { - if ((id >> (32 - 1 - j) & 0x1) != 0) { - return 32 - j; - } - } - return 0; - } - - /* Finds the corresponding bucket in a routing table for a given identifier */ - public Bucket findBucket(int id) { - int xorNumber = id ^ this.id; - int prefix = this.getNodePrefix(xorNumber); - return buckets.get(prefix); - } - - /* Updates the routing table with a new value. */ - public void update(int id) { - Bucket bucket = this.findBucket(id); - if (bucket.contains(id)) { - Msg.debug("Updating " + Integer.toString(id) + " in my routing table"); - //If the element is already in the bucket, we update it. - bucket.pushToFront(id); - } else { - Msg.debug("Adding " + id + " to my routing table"); - bucket.add(id); - if (bucket.size() > Common.BUCKET_SIZE) { - // TODO - Msg.debug("Should ping the least seen guy and remove him if he is offline."); - } - } - } - - /* Returns the closest notes we know to a given id */ - public Answer findClosest(int destinationId) { - Answer answer = new Answer(destinationId); - Bucket bucket = this.findBucket(destinationId); - bucket.addToAnswer(answer,destinationId); - - for (int i = 1; answer.size() < Common.BUCKET_SIZE && ((bucket.getId() - i) >= 0 || - (bucket.getId() + i) <= Common.IDENTIFIER_SIZE); i++) { - //Check the previous buckets - if (bucket.getId() - i >= 0) { - Bucket bucketP = this.buckets.get(bucket.getId() - i); - bucketP.addToAnswer(answer,destinationId); - } - //Check the next buckets - if (bucket.getId() + i <= Common.IDENTIFIER_SIZE) { - Bucket bucketN = this.buckets.get(bucket.getId() + i); - bucketN.addToAnswer(answer, destinationId); - } - } - //We sort the list - Collections.sort(answer.getNodes()); - //We trim the list - answer.trim(); - - return answer; - } - - @Override - public String toString() { - StringBuilder string = new StringBuilder("RoutingTable [ id=" + id + " "); - for (int i = 0; i < buckets.size(); i++) { - if (buckets.get(i).size() > 0) { - string.append(buckets.get(i) + " "); - } - } - return string.toString(); - } -} diff --git a/examples/deprecated/java/dht/kademlia/dht-kademlia.tesh b/examples/deprecated/java/dht/kademlia/dht-kademlia.tesh deleted file mode 100644 index 8623d4b5ac..0000000000 --- a/examples/deprecated/java/dht/kademlia/dht-kademlia.tesh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 - -$ ${javacmd:=java} -classpath ${classpath:=.} dht/kademlia/Main ${srcdir:=.}/../../platforms/cluster_backbone.xml ${srcdir:=.}/dht/kademlia/kademlia.xml -> [0.000000] [java/INFO] Using regular java threads. -> [900.000000] [java/INFO] Terminating the simulation... -> [node-0.simgrid.org:dht.kademlia.Node:(1) 0.000000] [java/INFO] Hi, I'm going to create the network with the id 0! -> [node-0.simgrid.org:dht.kademlia.Node:(1) 900.000000] [java/INFO] 8/8 FIND_NODE have succeeded. -> [node-1.simgrid.org:dht.kademlia.Node:(2) 0.000000] [java/INFO] Hi, I'm going to join the network with the id 1! -> [node-1.simgrid.org:dht.kademlia.Node:(2) 900.000000] [java/INFO] 8/8 FIND_NODE have succeeded. -> [node-2.simgrid.org:dht.kademlia.Node:(3) 0.000000] [java/INFO] Hi, I'm going to join the network with the id 2! -> [node-2.simgrid.org:dht.kademlia.Node:(3) 900.000000] [java/INFO] 8/8 FIND_NODE have succeeded. -> [node-3.simgrid.org:dht.kademlia.Node:(4) 0.000000] [java/INFO] Hi, I'm going to join the network with the id 4! -> [node-3.simgrid.org:dht.kademlia.Node:(4) 900.000000] [java/INFO] 8/8 FIND_NODE have succeeded. diff --git a/examples/deprecated/java/dht/kademlia/kademlia.xml b/examples/deprecated/java/dht/kademlia/kademlia.xml deleted file mode 100644 index 537afcb49a..0000000000 --- a/examples/deprecated/java/dht/kademlia/kademlia.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/deprecated/java/energy/consumption/EnergyConsumer.java b/examples/deprecated/java/energy/consumption/EnergyConsumer.java deleted file mode 100644 index 9aa457c996..0000000000 --- a/examples/deprecated/java/energy/consumption/EnergyConsumer.java +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package energy.consumption; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.HostNotFoundException; - -public class EnergyConsumer extends Process { - public EnergyConsumer(String hostname, String name) throws HostNotFoundException { - super(hostname,name); - } - - public void main(String[] args) throws MsgException { - Msg.info("Energetic profile: " + getHost().getProperty("wattage_per_state")); - Msg.info("Initial peak speed= " + getHost().getSpeed() + " flop/s; Energy dissipated = " - + getHost().getConsumedEnergy() + " J"); - - this.waitFor(10); - Msg.info("Currently consumed energy after sleeping 10 sec: "+getHost().getConsumedEnergy()); - new Task(null, 1E9, 0).execute(); - Msg.info("Currently consumed energy after executing 1E9 flops: "+getHost().getConsumedEnergy()); - } -} diff --git a/examples/deprecated/java/energy/consumption/Main.java b/examples/deprecated/java/energy/consumption/Main.java deleted file mode 100644 index 9005253566..0000000000 --- a/examples/deprecated/java/energy/consumption/Main.java +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package energy.consumption; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; - -public class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) throws MsgException { - Msg.energyInit(); - Msg.init(args); - - if (args.length < 1) { - Msg.info("Usage : Energy platform_file"); - Msg.info("Usage : Energy ../platforms/energy_platform.xml"); - System.exit(1); - } - /* Construct the platform */ - Msg.createEnvironment(args[0]); - /* Instantiate a process */ - new EnergyConsumer("MyHost1","energyConsumer").start(); - /* Execute the simulation */ - Msg.run(); - Msg.info("Total simulation time: " + Msg.getClock()); - } -} diff --git a/examples/deprecated/java/energy/consumption/energy-consumption.tesh b/examples/deprecated/java/energy/consumption/energy-consumption.tesh deleted file mode 100644 index 8a28d5c394..0000000000 --- a/examples/deprecated/java/energy/consumption/energy-consumption.tesh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env tesh - -! timeout 15 - -$ ${javacmd:=java} -classpath ${classpath:=.} energy/consumption/Main ${srcdir:=.}/../../platforms/energy_platform.xml -> [0.000000] [java/INFO] Using regular java threads. -> [MyHost1:energyConsumer:(1) 0.000000] [java/INFO] Energetic profile: 100.0:93.33333333333333:200.0, 93.0:90.0:170.0, 90.0:90.0:150.0 -> [MyHost1:energyConsumer:(1) 0.000000] [java/INFO] Initial peak speed= 1.0E8 flop/s; Energy dissipated = 0.0 J -> [MyHost1:energyConsumer:(1) 10.000000] [java/INFO] Currently consumed energy after sleeping 10 sec: 1000.0 -> [MyHost1:energyConsumer:(1) 20.000000] [java/INFO] Currently consumed energy after executing 1E9 flops: 2200.0 -> [20.000000] [host_energy/INFO] Total energy consumption: 6200.000000 Joules (used hosts: 2200.000000 Joules; unused/idle hosts: 4000.000000) -> [20.000000] [java/INFO] Terminating the simulation... -> [20.000000] [java/INFO] Total simulation time: 20.0 -> [20.000000] [host_energy/INFO] Energy consumption of host MyHost1: 2200.000000 Joules -> [20.000000] [host_energy/INFO] Energy consumption of host MyHost2: 2000.000000 Joules -> [20.000000] [host_energy/INFO] Energy consumption of host MyHost3: 2000.000000 Joules - diff --git a/examples/deprecated/java/energy/pstate/Main.java b/examples/deprecated/java/energy/pstate/Main.java deleted file mode 100644 index 8deac23290..0000000000 --- a/examples/deprecated/java/energy/pstate/Main.java +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package energy.pstate; - -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; - -class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.energyInit(); - Msg.init(args); - - if (args.length < 1) { - Msg.info("Usage: Main ../platforms/energy_platform_file.xml"); - System.exit(1); - } - - /* construct the platform */ - Msg.createEnvironment(args[0]); - - /* Create and start a runner for the experiment */ - new PstateRunner(Host.all()[0],"pstate runner",null).start(); - - Msg.run(); - } -} diff --git a/examples/deprecated/java/energy/pstate/PstateRunner.java b/examples/deprecated/java/energy/pstate/PstateRunner.java deleted file mode 100644 index 141a3c5e83..0000000000 --- a/examples/deprecated/java/energy/pstate/PstateRunner.java +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package energy.pstate; - -import org.simgrid.msg.Host; -import org.simgrid.msg.HostFailureException; -import org.simgrid.msg.HostNotFoundException; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Process; -import org.simgrid.msg.Task; -import org.simgrid.msg.TaskCancelledException; - -/* This class is a process in charge of running the test. It creates and starts the VMs, and fork processes within VMs */ -public class PstateRunner extends Process { - - public class DVFS extends Process { - public DVFS (Host host, String name) { - super(host, name); - } - - @Override - public void main(String[] strings) throws HostNotFoundException, HostFailureException, TaskCancelledException { - double workload = 100E6; - int newPstate = 2; - Host host = getHost(); - - int nb = host.getPstatesCount(); - Msg.info("Count of Processor states="+ nb); - - double currentPeak = host.getCurrentPowerPeak(); - Msg.info("Current power peak=" + currentPeak); - - // Run a task - Task task1 = new Task("t1", workload, 0); - task1.execute(); - - double taskTime = Msg.getClock(); - Msg.info("Task1 simulation time: "+ taskTime); - - // Change power peak - if ((newPstate >= nb) || (newPstate < 0)){ - Msg.info("Cannot set pstate "+newPstate+"%d, host supports only "+nb+" pstates."); - return; - } - - double peakAt = host.getPowerPeakAt(newPstate); - Msg.info("Changing power peak value to "+peakAt+" (at index "+newPstate+")"); - - host.setPstate(newPstate); - - currentPeak = host.getCurrentPowerPeak(); - Msg.info("Current power peak="+ currentPeak); - - // Run a second task - new Task("t1", workload, 0).execute(); - - taskTime = Msg.getClock() - taskTime; - Msg.info("Task2 simulation time: "+ taskTime); - - // Verify the default pstate is set to 0 - host = Host.getByName("MyHost2"); - int nb2 = host.getPstatesCount(); - Msg.info("Count of Processor states="+ nb2); - - double currentPeak2 = host.getCurrentPowerPeak(); - Msg.info("Current power peak=" + currentPeak2); - } - } - - PstateRunner(Host host, String name, String[] args) { - super(host, name, args); - } - - @Override - public void main(String[] strings) throws HostNotFoundException, HostFailureException { - - new DVFS (Host.getByName("MyHost1"), "dvfs_test").start(); - new DVFS (Host.getByName("MyHost2"), "dvfs_test").start(); - - } -} diff --git a/examples/deprecated/java/energy/pstate/energy-pstate.tesh b/examples/deprecated/java/energy/pstate/energy-pstate.tesh deleted file mode 100644 index b5ea27461e..0000000000 --- a/examples/deprecated/java/energy/pstate/energy-pstate.tesh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env tesh - -$ ${javacmd:=java} -classpath ${classpath:=.} energy/pstate/Main ${srcdir:=.}/../../platforms/energy_platform.xml -> [0.000000] [java/INFO] Using regular java threads. -> [MyHost1:dvfs_test:(2) 0.000000] [java/INFO] Count of Processor states=3 -> [MyHost1:dvfs_test:(2) 0.000000] [java/INFO] Current power peak=1.0E8 -> [MyHost2:dvfs_test:(3) 0.000000] [java/INFO] Count of Processor states=3 -> [MyHost2:dvfs_test:(3) 0.000000] [java/INFO] Current power peak=1.0E8 -> [MyHost1:dvfs_test:(2) 1.000000] [java/INFO] Task1 simulation time: 1.0 -> [MyHost1:dvfs_test:(2) 1.000000] [java/INFO] Changing power peak value to 2.0E7 (at index 2) -> [MyHost2:dvfs_test:(3) 1.000000] [java/INFO] Task1 simulation time: 1.0 -> [MyHost2:dvfs_test:(3) 1.000000] [java/INFO] Changing power peak value to 2.0E7 (at index 2) -> [MyHost1:dvfs_test:(2) 1.000000] [java/INFO] Current power peak=2.0E7 -> [MyHost2:dvfs_test:(3) 1.000000] [java/INFO] Current power peak=2.0E7 -> [MyHost1:dvfs_test:(2) 6.000000] [java/INFO] Task2 simulation time: 5.0 -> [MyHost1:dvfs_test:(2) 6.000000] [java/INFO] Count of Processor states=3 -> [MyHost1:dvfs_test:(2) 6.000000] [java/INFO] Current power peak=2.0E7 -> [MyHost2:dvfs_test:(3) 6.000000] [java/INFO] Task2 simulation time: 5.0 -> [MyHost2:dvfs_test:(3) 6.000000] [java/INFO] Count of Processor states=3 -> [MyHost2:dvfs_test:(3) 6.000000] [java/INFO] Current power peak=2.0E7 -> [6.000000] [host_energy/INFO] Total energy consumption: 2195.000000 Joules (used hosts: 1595.000000 Joules; unused/idle hosts: 600.000000) -> [6.000000] [java/INFO] Terminating the simulation... -> [6.000000] [host_energy/INFO] Energy consumption of host MyHost1: 645.000000 Joules -> [6.000000] [host_energy/INFO] Energy consumption of host MyHost2: 950.000000 Joules -> [6.000000] [host_energy/INFO] Energy consumption of host MyHost3: 600.000000 Joules diff --git a/examples/deprecated/java/energy/vm/EnergyVMRunner.java b/examples/deprecated/java/energy/vm/EnergyVMRunner.java deleted file mode 100644 index 220f1764b0..0000000000 --- a/examples/deprecated/java/energy/vm/EnergyVMRunner.java +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package energy.vm; - -import org.simgrid.msg.Host; -import org.simgrid.msg.HostFailureException; -import org.simgrid.msg.HostNotFoundException; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Process; -import org.simgrid.msg.Task; -import org.simgrid.msg.TaskCancelledException; -import org.simgrid.msg.VM; - -/* This class is a process in charge of running the test. It creates and starts the VMs, and fork processes within VMs */ -public class EnergyVMRunner extends Process { - - public class DummyProcess extends Process { - public DummyProcess (Host host, String name) { - super(host, name); - } - - @Override - public void main(String[] strings) { - Task task = new Task(this.getHost().getName()+"-task", 300E6 , 0); - try { - task.execute(); - } catch (HostFailureException | TaskCancelledException e) { - Msg.error(e.getMessage()); - e.printStackTrace(); - } - Msg.info("This worker is done."); - } - } - - EnergyVMRunner(Host host, String name, String[] args) { - super(host, name, args); - } - - @Override - public void main(String[] strings) throws HostNotFoundException, HostFailureException { - /* get hosts */ - Host host1 = Host.getByName("MyHost1"); - Host host2 = Host.getByName("MyHost2"); - Host host3 = Host.getByName("MyHost3"); - - Msg.info("Creating and starting two VMs"); - VM vmHost1 = new VM(host1, "vmHost1"); - vmHost1.start(); - - VM vmHost2 = new VM(host2, "vmHost3"); - vmHost2.start(); - - Msg.info("Create two tasks on Host1: one inside a VM, the other directly on the host"); - new DummyProcess (vmHost1, "p11").start(); - new DummyProcess (vmHost1, "p12").start(); - - Msg.info("Create two tasks on Host2: both directly on the host"); - new DummyProcess (vmHost2, "p21").start(); - new DummyProcess (host2, "p22").start(); - - Msg.info("Create two tasks on Host3: both inside a VM"); - new DummyProcess (host3, "p31").start(); - new DummyProcess (host3, "p312").start(); - - Msg.info("Wait 5 seconds. The tasks are still running (they run for 3 seconds, but 2 tasks are co-located, " - + "so they run for 6 seconds)"); - waitFor(5); - Msg.info("Wait another 5 seconds. The tasks stop at some point in between"); - waitFor(5); - - vmHost1.destroy(); - vmHost2.destroy(); - } -} diff --git a/examples/deprecated/java/energy/vm/Main.java b/examples/deprecated/java/energy/vm/Main.java deleted file mode 100644 index 49471abb94..0000000000 --- a/examples/deprecated/java/energy/vm/Main.java +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package energy.vm; - -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; - -class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.energyInit(); - Msg.init(args); - - if (args.length < 1) { - Msg.info("Usage: Main ../platforms/energy_platform_file.xml"); - System.exit(1); - } - - /* construct the platform */ - Msg.createEnvironment(args[0]); - - /* Create and start a runner for the experiment */ - new EnergyVMRunner(Host.all()[0],"energy VM runner",null).start(); - - Msg.run(); - } -} diff --git a/examples/deprecated/java/energy/vm/energy-vm.tesh b/examples/deprecated/java/energy/vm/energy-vm.tesh deleted file mode 100644 index 205d380e86..0000000000 --- a/examples/deprecated/java/energy/vm/energy-vm.tesh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env tesh - -$ ${javacmd:=java} -classpath ${classpath:=.} energy/vm/Main ${srcdir:=.}/../../platforms/energy_platform.xml -> [0.000000] [java/INFO] Using regular java threads. -> [MyHost1:energy VM runner:(1) 0.000000] [java/INFO] Creating and starting two VMs -> [MyHost1:energy VM runner:(1) 0.000000] [java/INFO] Create two tasks on Host1: one inside a VM, the other directly on the host -> [MyHost1:energy VM runner:(1) 0.000000] [java/INFO] Create two tasks on Host2: both directly on the host -> [MyHost1:energy VM runner:(1) 0.000000] [java/INFO] Create two tasks on Host3: both inside a VM -> [MyHost1:energy VM runner:(1) 0.000000] [java/INFO] Wait 5 seconds. The tasks are still running (they run for 3 seconds, but 2 tasks are co-located, so they run for 6 seconds) -> [MyHost1:energy VM runner:(1) 5.000000] [java/INFO] Wait another 5 seconds. The tasks stop at some point in between -> [MyHost2:p22:(5) 6.000000] [java/INFO] This worker is done. -> [MyHost3:p312:(7) 6.000000] [java/INFO] This worker is done. -> [MyHost3:p31:(6) 6.000000] [java/INFO] This worker is done. -> [vmHost1:p12:(3) 6.000000] [java/INFO] This worker is done. -> [vmHost1:p11:(2) 6.000000] [java/INFO] This worker is done. -> [vmHost3:p21:(4) 6.000000] [java/INFO] This worker is done. -> [10.000000] [host_energy/INFO] Total energy consumption: 4320.000000 Joules (used hosts: 4320.000000 Joules; unused/idle hosts: 0.000000) -> [10.000000] [java/INFO] Terminating the simulation... -> [10.000000] [host_energy/INFO] Energy consumption of host MyHost1: 1120.000000 Joules -> [10.000000] [host_energy/INFO] Energy consumption of host MyHost2: 1600.000000 Joules -> [10.000000] [host_energy/INFO] Energy consumption of host MyHost3: 1600.000000 Joules diff --git a/examples/deprecated/java/hostload/LoadRunner.java b/examples/deprecated/java/hostload/LoadRunner.java deleted file mode 100644 index 780a5b080e..0000000000 --- a/examples/deprecated/java/hostload/LoadRunner.java +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package hostload; - -import org.simgrid.msg.*; -import org.simgrid.msg.Process; - - -public class LoadRunner extends Process { - - public LoadRunner(Host host, String s) { - super(host, s); - } - - public void display(){ - Msg.info("Speed="+getHost().getSpeed()+" flop/s"); - Msg.info("Computed Flops "+ getHost().getComputedFlops()); - Msg.info("AvgLoad "+ getHost().getAvgLoad()); - } - @Override - public void main(String[] strings) throws MsgException { - display(); - Msg.info("Sleep for 10 seconds"); - waitFor(10); - display(); - - // Run a task - Task task1 = new Task("t1", 200E6, 0); - task1.execute(); - display(); - double taskTime = Msg.getClock(); - Msg.info("Task1 simulation time: "+ taskTime); - - // Run a second task - new Task("t1", 200E6, 0).execute(); - - taskTime = Msg.getClock() - taskTime; - Msg.info("Task2 simulation time: "+ taskTime); - display(); - - } - - -} \ No newline at end of file diff --git a/examples/deprecated/java/hostload/Main.java b/examples/deprecated/java/hostload/Main.java deleted file mode 100644 index 8b30e487b1..0000000000 --- a/examples/deprecated/java/hostload/Main.java +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package hostload; - -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; - -public class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.loadInit(); - Msg.init(args); - - if (args.length < 1) { - Msg.info("Usage : Load platform_file"); - Msg.info("Usage : Load ../platforms/small_platform.xml"); - System.exit(1); - } - /* Construct the platform */ - Msg.createEnvironment(args[0]); - new LoadRunner(Host.all()[0], "").start(); - - Msg.run(); - - } -} diff --git a/examples/deprecated/java/hostload/hostload.tesh b/examples/deprecated/java/hostload/hostload.tesh deleted file mode 100644 index 35d98dc731..0000000000 --- a/examples/deprecated/java/hostload/hostload.tesh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env tesh - -$ ${javacmd:=java} -classpath ${classpath:=.} hostload/Main ${srcdir:=.}/../../platforms/small_platform.xml -> [0.000000] [java/INFO] Using regular java threads. -> [Boivin::(1) 0.000000] [java/INFO] Speed=9.8095E7 flop/s -> [Boivin::(1) 0.000000] [java/INFO] Computed Flops 0.0 -> [Boivin::(1) 0.000000] [java/INFO] AvgLoad 0.0 -> [Boivin::(1) 0.000000] [java/INFO] Sleep for 10 seconds -> [Boivin::(1) 10.000000] [java/INFO] Speed=9.8095E7 flop/s -> [Boivin::(1) 10.000000] [java/INFO] Computed Flops 0.0 -> [Boivin::(1) 10.000000] [java/INFO] AvgLoad 0.0 -> [Boivin::(1) 12.038840] [java/INFO] Speed=9.8095E7 flop/s -> [Boivin::(1) 12.038840] [java/INFO] Computed Flops 2.0E8 -> [Boivin::(1) 12.038840] [java/INFO] AvgLoad 0.1693551801515729 -> [Boivin::(1) 12.038840] [java/INFO] Task1 simulation time: 12.038839900096844 -> [Boivin::(1) 14.077680] [java/INFO] Task2 simulation time: 2.0388399000968445 -> [Boivin::(1) 14.077680] [java/INFO] Speed=9.8095E7 flop/s -> [Boivin::(1) 14.077680] [java/INFO] Computed Flops 4.0E8 -> [Boivin::(1) 14.077680] [java/INFO] AvgLoad 0.2896556718201238 -> [14.077680] [java/INFO] Terminating the simulation... \ No newline at end of file diff --git a/examples/deprecated/java/process/kill/Killer.java b/examples/deprecated/java/process/kill/Killer.java deleted file mode 100644 index 8506569782..0000000000 --- a/examples/deprecated/java/process/kill/Killer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.kill; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.HostNotFoundException; - -public class Killer extends Process { - public Killer(String hostname, String name) throws HostNotFoundException { - super(hostname, name); - } - public void main(String[] args) throws MsgException { - Victim poorVictim = null; - Msg.info("Hello!"); - try { - poorVictim = new Victim("Boivin","victim"); - poorVictim.start(); - } catch (MsgException e){ - e.printStackTrace(); - Msg.error("Cannot create the victim process!"); - return; - } - sleep(10000); - Msg.info("Resume Process"); - poorVictim.resume(); - sleep(1000); - Msg.info("Kill Process"); - poorVictim.kill(); - - Msg.info("Ok, goodbye now."); - // The actor can also commit a suicide with the following command - exit(); // This will forcefully stop the current actor - // Of course, it's not useful here at the end of the main function, but that's for the example (and to check that this still works in the automated tests) - } -} diff --git a/examples/deprecated/java/process/kill/Main.java b/examples/deprecated/java/process/kill/Main.java deleted file mode 100644 index 34f1921c5e..0000000000 --- a/examples/deprecated/java/process/kill/Main.java +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.kill; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; - -public class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - /* initialize the MSG simulation. Must be done before anything else (even logging). */ - Msg.init(args); - Msg.createEnvironment(args[0]); - - /* bypass deploymemt */ - try { - Killer killer = new Killer("Jacquelin","killer"); - killer.start(); - } catch (MsgException e){ - Msg.error("Create processes failed!"); - } - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/process/kill/Victim.java b/examples/deprecated/java/process/kill/Victim.java deleted file mode 100644 index 5828708281..0000000000 --- a/examples/deprecated/java/process/kill/Victim.java +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.kill; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.HostNotFoundException; - -public class Victim extends Process { - public Victim(String hostname, String name) throws HostNotFoundException { - super(hostname, name); - } - public void main(String[] args) throws MsgException{ - Msg.info("Hello!"); - Msg.info("Suspending myself"); - suspend(); - Msg.info("OK, OK. Let's work"); - Task task = new Task("work", 1e9, 0); - task.execute(); - Msg.info("Bye"); - } -} \ No newline at end of file diff --git a/examples/deprecated/java/process/kill/process-kill.tesh b/examples/deprecated/java/process/kill/process-kill.tesh deleted file mode 100644 index 3dfabcc0c7..0000000000 --- a/examples/deprecated/java/process/kill/process-kill.tesh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env tesh - -$ ${javacmd:=java} -classpath ${classpath:=.} process/kill/Main ${srcdir:=.}/../../platforms/small_platform.xml --lof=no_loc -> [0.000000] [java/INFO] Using regular java threads. -> [Jacquelin:killer:(1) 0.000000] [java/INFO] Hello! -> [Boivin:victim:(2) 0.000000] [java/INFO] Hello! -> [Boivin:victim:(2) 0.000000] [java/INFO] Suspending myself -> [Jacquelin:killer:(1) 10.000000] [java/INFO] Resume Process -> [Boivin:victim:(2) 10.000000] [java/INFO] OK, OK. Let's work -> [Jacquelin:killer:(1) 11.000000] [java/INFO] Kill Process -> [Jacquelin:killer:(1) 11.000000] [java/INFO] Ok, goodbye now. -> [11.000000] [java/INFO] Terminating the simulation... diff --git a/examples/deprecated/java/process/migration/Emigrant.java b/examples/deprecated/java/process/migration/Emigrant.java deleted file mode 100644 index 133fe362ba..0000000000 --- a/examples/deprecated/java/process/migration/Emigrant.java +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.migration; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.HostNotFoundException; - -public class Emigrant extends Process { - public Emigrant(String hostname, String name) throws HostNotFoundException { - super(hostname, name); - } - - public void main(String[] args) throws MsgException { - Main.mutex.acquire(); - - Msg.info("I'll look for a new job on another machine where the grass is greener."); - migrate(Host.getByName("Boivin")); - - Msg.info("Yeah, found something to do"); - Task task = new Task("job", 98095000, 0); - task.execute(); - waitFor(2); - - Msg.info("Moving back to home after work"); - migrate(Host.getByName("Jacquelin")); - migrate(Host.getByName("Boivin")); - waitFor(4); - - Main.mutex.release(); - suspend(); - - Msg.info("I've been moved on this new host:" + getHost().getName()); - Msg.info("Uh, nothing to do here. Stopping now"); - } -} diff --git a/examples/deprecated/java/process/migration/Main.java b/examples/deprecated/java/process/migration/Main.java deleted file mode 100644 index c30ae07fdf..0000000000 --- a/examples/deprecated/java/process/migration/Main.java +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.migration; -import org.simgrid.msg.HostNotFoundException; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Mutex; -import org.simgrid.msg.Process; - -class Main { - protected static Mutex mutex; - protected static Process processToMigrate = null; - - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - if(args.length < 1) { - Msg.info("Usage : Migration platform_file"); - Msg.info("example : Migration ../platforms/platform.xml"); - System.exit(1); - } - /* Create the mutex */ - mutex = new Mutex(); - - /* construct the platform*/ - Msg.createEnvironment(args[0]); - /* bypass deploymemt */ - try { - Policeman policeman = new Policeman("Boivin","policeman"); - policeman.start(); - Emigrant emigrant = new Emigrant("Jacquelin","emigrant"); - emigrant.start(); - processToMigrate = emigrant; - } catch (HostNotFoundException e){ - Msg.error("Create processes failed!"); - e.printStackTrace(); - } - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/process/migration/Policeman.java b/examples/deprecated/java/process/migration/Policeman.java deleted file mode 100644 index 94e0fd80a6..0000000000 --- a/examples/deprecated/java/process/migration/Policeman.java +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.migration; - -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.HostNotFoundException; - -public class Policeman extends Process { - public Policeman(String hostname, String name) throws HostNotFoundException { - super(hostname, name); - } - - public void main(String[] args) throws MsgException { - waitFor(1); - - Msg.info("Wait a bit before migrating the emigrant."); - - Main.mutex.acquire(); - - Main.processToMigrate.migrate(Host.getByName("Jacquelin")); - Msg.info("I moved the emigrant"); - Main.processToMigrate.resume(); - } -} \ No newline at end of file diff --git a/examples/deprecated/java/process/migration/process-migration.tesh b/examples/deprecated/java/process/migration/process-migration.tesh deleted file mode 100644 index 849ea97f95..0000000000 --- a/examples/deprecated/java/process/migration/process-migration.tesh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 - -$ ${javacmd:=java} -classpath ${classpath:=.} process/migration/Main ${srcdir:=.}/../../platforms/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (2:emigrant@Jacquelin) I'll look for a new job on another machine where the grass is greener. -> [ 0.000000] (2:emigrant@Boivin) Yeah, found something to do -> [ 1.000000] (1:policeman@Boivin) Wait a bit before migrating the emigrant. -> [ 3.000000] (2:emigrant@Boivin) Moving back to home after work -> [ 7.000000] (0:maestro@) Terminating the simulation... -> [ 7.000000] (2:emigrant@Jacquelin) I've been moved on this new host:Jacquelin -> [ 7.000000] (2:emigrant@Jacquelin) Uh, nothing to do here. Stopping now -> [ 7.000000] (1:policeman@Boivin) I moved the emigrant diff --git a/examples/deprecated/java/process/startkilltime/Main.java b/examples/deprecated/java/process/startkilltime/Main.java deleted file mode 100644 index 7de10822e3..0000000000 --- a/examples/deprecated/java/process/startkilltime/Main.java +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.startkilltime; -import org.simgrid.msg.Msg; - -public class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - if(args.length < 2) { - Msg.info("Usage : StartKilltime platform_file deployment_file"); - Msg.info("example : StartKilltime ../platforms/platform.xml deployment_start_kill.xml"); - System.exit(1); - } - /* construct the platform and deploy the application */ - Msg.createEnvironment(args[0]); - Msg.deployApplication(args[1]); - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/process/startkilltime/Sleeper.java b/examples/deprecated/java/process/startkilltime/Sleeper.java deleted file mode 100644 index 4886c510a1..0000000000 --- a/examples/deprecated/java/process/startkilltime/Sleeper.java +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.startkilltime; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; - -public class Sleeper extends Process { - public Sleeper(Host host, String name, String[]args) { - super(host,name,args); - } - - public void main(String[] args) throws MsgException { - Msg.info("Hello! I go to sleep."); - try { - waitFor(Integer.parseInt(args[0])); - Msg.info("Done sleeping"); - } catch (MsgException e) { - Msg.debug("Wait cancelled."); - } - } -} diff --git a/examples/deprecated/java/process/startkilltime/process-startkilltime.tesh b/examples/deprecated/java/process/startkilltime/process-startkilltime.tesh deleted file mode 100644 index d2fd7df6c4..0000000000 --- a/examples/deprecated/java/process/startkilltime/process-startkilltime.tesh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env tesh -$ ${javacmd:=java} -classpath ${classpath:=.} process/startkilltime/Main ${srcdir:=.}/../../platforms/cluster_backbone.xml ${srcdir:=.}/process/startkilltime/startkilltime.xml -> [0.000000] [java/INFO] Using regular java threads. -> [node-0.simgrid.org:process.startkilltime.Sleeper:(1) 0.000000] [java/INFO] Hello! I go to sleep. -> [node-1.simgrid.org:process.startkilltime.Sleeper:(2) 1.000000] [java/INFO] Hello! I go to sleep. -> [node-2.simgrid.org:process.startkilltime.Sleeper:(3) 2.000000] [java/INFO] Hello! I go to sleep. -> [node-3.simgrid.org:process.startkilltime.Sleeper:(4) 3.000000] [java/INFO] Hello! I go to sleep. -> [node-4.simgrid.org:process.startkilltime.Sleeper:(5) 4.000000] [java/INFO] Hello! I go to sleep. -> [node-5.simgrid.org:process.startkilltime.Sleeper:(6) 5.000000] [java/INFO] Hello! I go to sleep. -> [node-2.simgrid.org:process.startkilltime.Sleeper:(3) 6.000000] [java/INFO] Done sleeping -> [node-3.simgrid.org:process.startkilltime.Sleeper:(4) 7.000000] [java/INFO] Done sleeping -> [10.000000] [java/INFO] Terminating the simulation... diff --git a/examples/deprecated/java/process/startkilltime/startkilltime.xml b/examples/deprecated/java/process/startkilltime/startkilltime.xml deleted file mode 100644 index 4c0e589e06..0000000000 --- a/examples/deprecated/java/process/startkilltime/startkilltime.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/deprecated/java/process/suspend/DreamMaster.java b/examples/deprecated/java/process/suspend/DreamMaster.java deleted file mode 100644 index 14a21236aa..0000000000 --- a/examples/deprecated/java/process/suspend/DreamMaster.java +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.suspend; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.HostNotFoundException; - -public class DreamMaster extends Process { - public DreamMaster(String hostname, String name) throws HostNotFoundException{ - super(hostname,name); - } - - public void main(String[] args) throws MsgException { - Msg.info("Let's create a lazy guy."); - Process lazyGuy = new LazyGuy(getHost(),"Lazy",null); - lazyGuy.start(); - Msg.info("Let's wait a little bit..."); - waitFor(10); - Msg.info("Let's wake the lazy guy up! >:) BOOOOOUUUHHH!!!!"); - lazyGuy.resume(); - Msg.info("OK, goodbye now."); - } -} \ No newline at end of file diff --git a/examples/deprecated/java/process/suspend/LazyGuy.java b/examples/deprecated/java/process/suspend/LazyGuy.java deleted file mode 100644 index c13a5adedc..0000000000 --- a/examples/deprecated/java/process/suspend/LazyGuy.java +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.suspend; -import org.simgrid.msg.Host; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; - -public class LazyGuy extends Process { - public LazyGuy(Host host, String name, String[]args) { - super(host,name,args); - } - - public void main(String[] args) throws MsgException { - Msg.info("Nobody's watching me ? Let's go to sleep."); - suspend(); - Msg.info("Uuuh ? Did somebody call me ?"); - Msg.info("Mmmh, goodbye now."); - } -} \ No newline at end of file diff --git a/examples/deprecated/java/process/suspend/Main.java b/examples/deprecated/java/process/suspend/Main.java deleted file mode 100644 index 6b3b5ae4ab..0000000000 --- a/examples/deprecated/java/process/suspend/Main.java +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package process.suspend; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; - -public class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - if(args.length < 1) { - Msg.info("Usage : Suspend platform_file"); - Msg.info("example : Suspend ../platforms/platform.xml"); - System.exit(1); - } - /* construct the platform and deploy the application */ - Msg.createEnvironment(args[0]); - try { - DreamMaster process1 = new DreamMaster("Jacquelin","DreamMaster"); - process1.start(); - } catch (MsgException e){ - Msg.error("Create processes failed!"); - } - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/process/suspend/process-suspend.tesh b/examples/deprecated/java/process/suspend/process-suspend.tesh deleted file mode 100644 index e24890a007..0000000000 --- a/examples/deprecated/java/process/suspend/process-suspend.tesh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 -$ ${javacmd:=java} -classpath ${classpath:=.} process/suspend/Main ${srcdir:=.}/../../platforms/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (1:DreamMaster@Jacquelin) Let's create a lazy guy. -> [ 0.000000] (1:DreamMaster@Jacquelin) Let's wait a little bit... -> [ 0.000000] (2:Lazy@Jacquelin) Nobody's watching me ? Let's go to sleep. -> [ 10.000000] (0:maestro@) Terminating the simulation... -> [ 10.000000] (1:DreamMaster@Jacquelin) Let's wake the lazy guy up! >:) BOOOOOUUUHHH!!!! -> [ 10.000000] (1:DreamMaster@Jacquelin) OK, goodbye now. -> [ 10.000000] (2:Lazy@Jacquelin) Uuuh ? Did somebody call me ? -> [ 10.000000] (2:Lazy@Jacquelin) Mmmh, goodbye now. diff --git a/examples/deprecated/java/task/priority/Main.java b/examples/deprecated/java/task/priority/Main.java deleted file mode 100644 index 763425eaa6..0000000000 --- a/examples/deprecated/java/task/priority/Main.java +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package task.priority; -import org.simgrid.msg.Msg; - -/* Demonstrates the use of Task.setPriority to change the computation priority of a task */ -public class Main { - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) { - Msg.init(args); - if(args.length < 2) { - Msg.info("Usage : Priority platform_file deployment_file"); - Msg.info("example : Priority ../platforms/small_platform.xml priority.xml"); - System.exit(1); - } - - /* construct the platform and deploy the application */ - Msg.createEnvironment(args[0]); - Msg.deployApplication(args[1]); - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/task/priority/Test.java b/examples/deprecated/java/task/priority/Test.java deleted file mode 100644 index b2997392aa..0000000000 --- a/examples/deprecated/java/task/priority/Test.java +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package task.priority; -import org.simgrid.msg.Msg; -import org.simgrid.msg.Host; -import org.simgrid.msg.Task; -import org.simgrid.msg.Process; -import org.simgrid.msg.MsgException; - -public class Test extends Process { - public Test(Host host, String name, String[]args) { - super(host,name,args); - } - - public void main(String[] args) throws MsgException { - double computationAmount = Double.parseDouble(args[0]); - double priority = Double.parseDouble(args[1]); - - Msg.info("Hello! Running a task of size " + computationAmount + " with priority " + priority); - - Task task = new Task("Task", computationAmount, 0); - task.setPriority(priority); - - task.execute(); - - Msg.info("Goodbye now!"); - } -} diff --git a/examples/deprecated/java/task/priority/priority.xml b/examples/deprecated/java/task/priority/priority.xml deleted file mode 100644 index 3349a60298..0000000000 --- a/examples/deprecated/java/task/priority/priority.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/examples/deprecated/java/task/priority/task-priority.tesh b/examples/deprecated/java/task/priority/task-priority.tesh deleted file mode 100644 index a457ff753e..0000000000 --- a/examples/deprecated/java/task/priority/task-priority.tesh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 - -$ ${javacmd:=java} -classpath ${classpath:=.} task/priority/Main ${srcdir:=.}/../../platforms/small_platform.xml ${srcdir:=.}/task/priority/priority.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Using regular java threads. -> [ 0.000000] (1:task.priority.Test@Fafard) Hello! Running a task of size 7.6296E7 with priority 1.0 -> [ 0.000000] (2:task.priority.Test@Fafard) Hello! Running a task of size 7.6296E7 with priority 2.0 -> [ 1.500000] (2:task.priority.Test@Fafard) Goodbye now! -> [ 2.000000] (0:maestro@) Terminating the simulation... -> [ 2.000000] (1:task.priority.Test@Fafard) Goodbye now! diff --git a/examples/deprecated/java/trace/pingpong/Main.java b/examples/deprecated/java/trace/pingpong/Main.java deleted file mode 100644 index 22e4c94199..0000000000 --- a/examples/deprecated/java/trace/pingpong/Main.java +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package trace.pingpong; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.trace.Trace; - -public class Main { - public static final String PM_STATE = "PM_STATE"; - - private Main() { - throw new IllegalAccessError("Utility class"); - } - - public static void main(String[] args) throws MsgException { - Msg.init(args); - if(args.length < 1) { - Msg.info("Usage : Main platform_file"); - Msg.info("example : Main ../platforms/platform.xml"); - System.exit(1); - } - - /* construct the platform and deploy the application */ - Msg.createEnvironment(args[0]); - new Sender("Jacquelin", "Sender", new String[] {"Boivin", "Tremblay"}).start(); - new Receiver ("Boivin", "Receiver", null).start(); - new Receiver ("Tremblay", "Receiver", null).start(); - - /* Initialize some state for the hosts */ - Trace.hostStateDeclare (PM_STATE); - Trace.hostStateDeclareValue (PM_STATE, "waitingPing", "0 0 1"); - Trace.hostStateDeclareValue (PM_STATE, "sendingPong", "0 1 0"); - Trace.hostStateDeclareValue (PM_STATE, "sendingPing", "0 1 1"); - Trace.hostStateDeclareValue (PM_STATE, "waitingPong", "1 0 0"); - - /* execute the simulation. */ - Msg.run(); - } -} diff --git a/examples/deprecated/java/trace/pingpong/PingPongTask.java b/examples/deprecated/java/trace/pingpong/PingPongTask.java deleted file mode 100644 index 8f2b8b3870..0000000000 --- a/examples/deprecated/java/trace/pingpong/PingPongTask.java +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package trace.pingpong; -import org.simgrid.msg.Task; - -public class PingPongTask extends Task { - private double timeVal; - - public PingPongTask() { - this.timeVal = 0; - } - - public PingPongTask(String name, double computeDuration, double messageSize) { - super(name,computeDuration,messageSize); - } - - public void setTime(double timeVal){ - this.timeVal = timeVal; - } - - public double getTime() { - return this.timeVal; - } -} - diff --git a/examples/deprecated/java/trace/pingpong/Receiver.java b/examples/deprecated/java/trace/pingpong/Receiver.java deleted file mode 100644 index 9b68c66360..0000000000 --- a/examples/deprecated/java/trace/pingpong/Receiver.java +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package trace.pingpong; -import org.simgrid.msg.HostNotFoundException; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Process; -import org.simgrid.msg.Task; -import org.simgrid.trace.Trace; - -public class Receiver extends Process { - private static final double COMM_SIZE_LAT = 1; - private static final double COMM_SIZE_BW = 100000000; - private static final String PM_STATE = Main.PM_STATE; - - public Receiver(String hostname, String name, String[]args) throws HostNotFoundException { - super(hostname,name,args); - } - - public void main(String[] args) throws MsgException { - Msg.info("hello!"); - Trace.hostPushState (getHost().getName(), PM_STATE, "waitingPing"); - - /* Wait for the ping */ - Msg.info("try to get a task"); - - PingPongTask ping = (PingPongTask)Task.receive(getHost().getName()); - double timeGot = Msg.getClock(); - double timeSent = ping.getTime(); - - Msg.info("Got at time "+ timeGot); - Msg.info("Was sent at time "+timeSent); - double time=timeSent; - - double communicationTime=timeGot - time; - Msg.info("Communication time : " + communicationTime); - - Msg.info(" --- bw "+ COMM_SIZE_BW/communicationTime + " ----"); - - /* Send the pong */ - Trace.hostPushState (getHost().getName(), PM_STATE, "sendingPong"); - double computeDuration = 0; - PingPongTask pong = new PingPongTask("no name",computeDuration,COMM_SIZE_LAT); - pong.setTime(time); - pong.send(ping.getSource().getName()); - - /* Pop the two states */ - Trace.hostPopState (getHost().getName(), PM_STATE); - Trace.hostPopState (getHost().getName(), PM_STATE); - - Msg.info("goodbye!"); - } -} diff --git a/examples/deprecated/java/trace/pingpong/Sender.java b/examples/deprecated/java/trace/pingpong/Sender.java deleted file mode 100644 index cf871a510b..0000000000 --- a/examples/deprecated/java/trace/pingpong/Sender.java +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package trace.pingpong; -import org.simgrid.msg.Host; -import org.simgrid.msg.HostNotFoundException; -import org.simgrid.msg.Msg; -import org.simgrid.msg.MsgException; -import org.simgrid.msg.Process; -import org.simgrid.msg.Task; -import org.simgrid.trace.Trace; - -public class Sender extends Process { - private static final double COMM_SIZE_LAT = 1; - private static final double COMM_SIZE_BW = 100000000; - private static final String PM_STATE = Main.PM_STATE; - - public Sender(String hostname, String name, String[] args) throws HostNotFoundException { - super(hostname,name,args); - } - - public void main(String[] args) throws MsgException { - Msg.info("hello !"); - Trace.hostPushState (getHost().getName(), PM_STATE, "sendingPing"); - - int hostCount = args.length; - Msg.info("host count: " + hostCount); - String[] mailboxes = new String[hostCount]; - double time; - double computeDuration = 0; - PingPongTask ping; - - for(int pos = 0; pos < args.length ; pos++) { - mailboxes[pos] = Host.getByName(args[pos]).getName(); - } - - for (int pos = 0; pos < hostCount; pos++) { - time = Msg.getClock(); - Msg.info("sender time: " + time); - ping = new PingPongTask("no name",computeDuration,COMM_SIZE_LAT); - ping.setTime(time); - ping.send(mailboxes[pos]); - - Trace.hostPushState (getHost().getName(), PM_STATE, "waitingPong"); - Task.receive(getHost().getName()); - double timeGot = Msg.getClock(); - double timeSent = ping.getTime(); - double communicationTime; - - Msg.info("Got at time "+ timeGot); - Msg.info("Was sent at time "+timeSent); - time = timeSent; - - communicationTime=timeGot - time; - Msg.info("Communication time : " + communicationTime); - - Msg.info(" --- bw "+ COMM_SIZE_BW/communicationTime + " ----"); - - /* Pop the last state (going back to sending ping) */ - Trace.hostPopState (getHost().getName(), PM_STATE); - } - - /* Pop the sendingPong state */ - Trace.hostPopState (getHost().getName(), PM_STATE); - Msg.info("goodbye!"); - } -} diff --git a/examples/deprecated/java/trace/pingpong/trace-pingpong.tesh b/examples/deprecated/java/trace/pingpong/trace-pingpong.tesh deleted file mode 100644 index 62c1e0f4c7..0000000000 --- a/examples/deprecated/java/trace/pingpong/trace-pingpong.tesh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env tesh - -! output sort 19 - -$ ${javacmd:=java} -classpath ${classpath:=.} trace/pingpong/Main ${srcdir:=.}/../../platforms/small_platform.xml --cfg=tracing:yes --cfg=tracing/filename:simulation.trace --cfg=tracing/platform:yes -> [0.000000] [java/INFO] Using regular java threads. -> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes' -> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'simulation.trace' -> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/platform' to 'yes' -> [3.817809] [java/INFO] Terminating the simulation... -> [Boivin:Receiver:(2) 0.000000] [java/INFO] hello! -> [Boivin:Receiver:(2) 0.000000] [java/INFO] try to get a task -> [Boivin:Receiver:(2) 1.048882] [java/INFO] Got at time 1.0488818628325232 -> [Boivin:Receiver:(2) 1.048882] [java/INFO] Was sent at time 0.0 -> [Boivin:Receiver:(2) 1.048882] [java/INFO] Communication time : 1.0488818628325232 -> [Boivin:Receiver:(2) 1.048882] [java/INFO] --- bw 9.533962169004269E7 ---- -> [Boivin:Receiver:(2) 2.097764] [java/INFO] goodbye! -> [Jacquelin:Sender:(1) 0.000000] [java/INFO] hello ! -> [Jacquelin:Sender:(1) 0.000000] [java/INFO] host count: 2 -> [Jacquelin:Sender:(1) 0.000000] [java/INFO] sender time: 0.0 -> [Jacquelin:Sender:(1) 2.097764] [java/INFO] Got at time 2.0977637256650463 -> [Jacquelin:Sender:(1) 2.097764] [java/INFO] Was sent at time 0.0 -> [Jacquelin:Sender:(1) 2.097764] [java/INFO] Communication time : 2.0977637256650463 -> [Jacquelin:Sender:(1) 2.097764] [java/INFO] --- bw 4.7669810845021345E7 ---- -> [Jacquelin:Sender:(1) 2.097764] [java/INFO] sender time: 2.0977637256650463 -> [Jacquelin:Sender:(1) 3.817809] [java/INFO] Got at time 3.8178087458100927 -> [Jacquelin:Sender:(1) 3.817809] [java/INFO] Was sent at time 2.0977637256650463 -> [Jacquelin:Sender:(1) 3.817809] [java/INFO] Communication time : 1.7200450201450463 -> [Jacquelin:Sender:(1) 3.817809] [java/INFO] --- bw 5.813801315012516E7 ---- -> [Jacquelin:Sender:(1) 3.817809] [java/INFO] goodbye! -> [Tremblay:Receiver:(3) 0.000000] [java/INFO] hello! -> [Tremblay:Receiver:(3) 0.000000] [java/INFO] try to get a task -> [Tremblay:Receiver:(3) 2.957786] [java/INFO] Got at time 2.9577862357375695 -> [Tremblay:Receiver:(3) 2.957786] [java/INFO] Was sent at time 2.0977637256650463 -> [Tremblay:Receiver:(3) 2.957786] [java/INFO] Communication time : 0.8600225100725232 -> [Tremblay:Receiver:(3) 2.957786] [java/INFO] --- bw 1.1627602630025032E8 ---- -> [Tremblay:Receiver:(3) 3.817809] [java/INFO] goodbye! - -$ rm -rf simulation.trace diff --git a/examples/platforms/config.xml b/examples/platforms/config.xml index 20da60cff0..6ab64321ad 100644 --- a/examples/platforms/config.xml +++ b/examples/platforms/config.xml @@ -2,12 +2,11 @@ - + - - + diff --git a/examples/platforms/griffon.cpp b/examples/platforms/griffon.cpp index ff1efdbdac..04a83e6fcf 100644 --- a/examples/platforms/griffon.cpp +++ b/examples/platforms/griffon.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -16,18 +16,17 @@ namespace sg4 = simgrid::s4u; * @param root Root netzone * @param name Cabinet name * @param radicals IDs of nodes inside the cabinet - * @return netzone,router the created netzone and its router + * @return netzone the created netzone */ -static std::pair +static sg4::NetZone* create_cabinet(const sg4::NetZone* root, const std::string& name, const std::vector& radicals) { - auto* cluster = sg4::create_star_zone(name); + auto* cluster = sg4::create_star_zone(name)->set_parent(root); std::string prefix = "griffon-"; std::string suffix = ".nancy.grid5000.fr"; - cluster->set_parent(root); /* create the backbone link */ - const sg4::Link* l_bb = cluster->create_link("backbone-" + name, "1.25GBps")->seal(); + const sg4::Link* l_bb = cluster->create_link("backbone-" + name, "1.25GBps"); sg4::LinkInRoute backbone(l_bb); /* create all hosts and connect them to outside world */ @@ -36,18 +35,17 @@ create_cabinet(const sg4::NetZone* root, const std::string& name, const std::vec /* create host */ const sg4::Host* host = cluster->create_host(hostname, "286.087kf"); /* create UP/DOWN link */ - const sg4::Link* link = cluster->create_split_duplex_link(hostname, "125MBps")->set_latency("24us")->seal(); + const sg4::Link* link = cluster->create_split_duplex_link(hostname, "125MBps")->set_latency("24us"); /* add link and backbone for communications from the host */ - cluster->add_route(host->get_netpoint(), nullptr, nullptr, nullptr, - {{link, sg4::LinkInRoute::Direction::UP}, backbone}, true); + cluster->add_route(host, nullptr, {{link, sg4::LinkInRoute::Direction::UP}, backbone}, true); } - /* create router */ - auto* router = cluster->create_router(prefix + name + "-router" + suffix); + /* create gateway */ + cluster->set_gateway(cluster->create_router(prefix + name + "-router" + suffix)); cluster->seal(); - return std::make_pair(cluster, router); + return cluster; } /** @brief Programmatic version of griffon.xml */ @@ -75,7 +73,6 @@ void load_platform(const sg4::Engine& /*e*/) auto* root = sg4::create_star_zone("AS_griffon"); sg4::NetZone* cab_zone; - simgrid::kernel::routing::NetPoint* router; /* create top link */ const sg4::Link* l_bb = root->create_link("backbone", "1.25GBps")->set_latency("24us")->seal(); @@ -84,23 +81,23 @@ void load_platform(const sg4::Engine& /*e*/) /* create cabinet1 */ std::vector rad(32); std::iota(rad.begin(), rad.end(), 1); // 1-29,58,59,60 - rad[rad.size() - 1] = 60; - rad[rad.size() - 2] = 59; - rad[rad.size() - 3] = 58; - std::tie(cab_zone, router) = create_cabinet(root, "cabinet1", rad); - root->add_route(cab_zone->get_netpoint(), nullptr, router, nullptr, {backbone}); + rad[rad.size() - 1] = 60; + rad[rad.size() - 2] = 59; + rad[rad.size() - 3] = 58; + cab_zone = create_cabinet(root, "cabinet1", rad); + root->add_route(cab_zone, nullptr, {backbone}); /* create cabinet2 */ rad.resize(28); std::iota(rad.begin(), rad.end(), 30); // 30-57 - std::tie(cab_zone, router) = create_cabinet(root, "cabinet2", rad); - root->add_route(cab_zone->get_netpoint(), nullptr, router, nullptr, {backbone}); + cab_zone = create_cabinet(root, "cabinet2", rad); + root->add_route(cab_zone, nullptr, {backbone}); /* create cabinet3 */ rad.resize(32); std::iota(rad.begin(), rad.end(), 61); // 61-92 - std::tie(cab_zone, router) = create_cabinet(root, "cabinet3", rad); - root->add_route(cab_zone->get_netpoint(), nullptr, router, nullptr, {backbone}); + cab_zone = create_cabinet(root, "cabinet3", rad); + root->add_route(cab_zone, nullptr, {backbone}); root->seal(); } diff --git a/examples/platforms/optorsim/transform_optorsim_platform.pl b/examples/platforms/optorsim/transform_optorsim_platform.pl index 75c2d6d4cb..d7f11bce0f 100644 --- a/examples/platforms/optorsim/transform_optorsim_platform.pl +++ b/examples/platforms/optorsim/transform_optorsim_platform.pl @@ -1,6 +1,6 @@ #!/usr/bin/env perl -# Copyright (c) 2011-2022. The SimGrid Team. +# Copyright (c) 2011-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/examples/platforms/routing_cluster.cpp b/examples/platforms/routing_cluster.cpp index 0cef8eee58..b7b218f58d 100644 --- a/examples/platforms/routing_cluster.cpp +++ b/examples/platforms/routing_cluster.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -16,40 +16,40 @@ namespace sg4 = simgrid::s4u; * @param host List of hostname inside the cluster * @param single_link_host Hostname of "special" node */ -static void create_cluster(const sg4::NetZone* root, const std::string& cluster_suffix, +static sg4::NetZone* create_cluster(const sg4::NetZone* root, const std::string& cluster_suffix, const std::vector& hosts, const std::string& single_link_host) { - auto* cluster = sg4::create_star_zone("cluster" + cluster_suffix); - cluster->set_parent(root); + auto* cluster = sg4::create_star_zone("cluster" + cluster_suffix)->set_parent(root); /* create the backbone link */ - const sg4::Link* l_bb = cluster->create_link("backbone" + cluster_suffix, 2.25e9)->set_latency(5e-4)->seal(); + const sg4::Link* l_bb = cluster->create_link("backbone" + cluster_suffix, "20Gbps")->set_latency("500us"); /* create all hosts and connect them to outside world */ for (const auto& hostname : hosts) { /* create host */ - const sg4::Host* host = cluster->create_host(hostname, 1e9); + const sg4::Host* host = cluster->create_host(hostname, "1Gf"); /* create UP link */ - const sg4::Link* l_up = cluster->create_link(hostname + "_up", 1.25e8)->set_latency(0.0001)->seal(); + const sg4::Link* l_up = cluster->create_link(hostname + "_up", "1Gbps")->set_latency("100us"); /* create DOWN link, if needed */ const sg4::Link* l_down = l_up; if (hostname != single_link_host) { - l_down = cluster->create_link(hostname + "_down", 1.25e8)->set_latency(0.0001)->seal(); + l_down = cluster->create_link(hostname + "_down", "1Gbps")->set_latency("100us"); } sg4::LinkInRoute backbone{l_bb}; sg4::LinkInRoute link_up{l_up}; sg4::LinkInRoute link_down{l_down}; /* add link UP and backbone for communications from the host */ - cluster->add_route(host->get_netpoint(), nullptr, nullptr, nullptr, {link_up, backbone}, false); + cluster->add_route(host, nullptr, {link_up, backbone}, false); /* add backbone and link DOWN for communications to the host */ - cluster->add_route(nullptr, host->get_netpoint(), nullptr, nullptr, {backbone, link_down}, false); + cluster->add_route(nullptr, host, {backbone, link_down}, false); } - /* create router */ - cluster->create_router("router" + cluster_suffix); + /* create gateway*/ + cluster->set_gateway(cluster->create_router("router" + cluster_suffix)); cluster->seal(); + return cluster; } /** @brief Programmatic version of routing_cluster.xml */ @@ -76,15 +76,14 @@ void load_platform(const sg4::Engine& e) auto* root = sg4::create_full_zone("AS0"); /* create left cluster */ - create_cluster(root, "1", {"host1", "host2", "host3"}, "host3"); + auto* left_cluster = create_cluster(root, "1", {"host1", "host2", "host3"}, "host3"); /* create right cluster */ - create_cluster(root, "2", {"host4", "host5", "host6"}, "host6"); + auto* right_cluster = create_cluster(root, "2", {"host4", "host5", "host6"}, "host6"); - /* connect both cluster through their respective routers */ - const sg4::Link* l = root->create_link("link1-2", 2.25e9)->set_latency(5e-4)->seal(); + /* connect both clusters */ + const sg4::Link* l = root->create_link("link1-2", "20Gbps")->set_latency("500us"); sg4::LinkInRoute link{l}; - root->add_route(e.netpoint_by_name_or_null("cluster1"), e.netpoint_by_name_or_null("cluster2"), - e.netpoint_by_name_or_null("router1"), e.netpoint_by_name_or_null("router2"), {link}); + root->add_route(left_cluster, right_cluster, {link}); root->seal(); } diff --git a/examples/platforms/storage/content/small_content.txt b/examples/platforms/storage/content/small_content.txt index 80d00dd8a6..f638bcc862 100644 --- a/examples/platforms/storage/content/small_content.txt +++ b/examples/platforms/storage/content/small_content.txt @@ -21,7 +21,7 @@ /include/xbt/fifo.h 3626 /include/msg/datatypes.h 4635 /include/mc/modelchecker.h 96 -/include/surf/simgrid_dtd.h 23583 +/include/simgrid_dtd.h 23583 /include/instr/instr.h 5750 /include/simdag/simdag.h 10325 /include/simix/simix.h 13003 diff --git a/examples/platforms/storage/content/storage_content.txt b/examples/platforms/storage/content/storage_content.txt index 6744799dff..a8e02680cd 100644 --- a/examples/platforms/storage/content/storage_content.txt +++ b/examples/platforms/storage/content/storage_content.txt @@ -292,11 +292,11 @@ /doc/simgrid/html/MSG_ex_master_slave_lua_bypass.html 4803 /doc/simgrid/html/simgrid_modules2.png 11932 /doc/simgrid/html/classsimgrid_1_1msg_1_1Msg.html 1519 -/doc/simgrid/html/group__SURF__actions.html 13562 +/doc/simgrid/html/group__SIMGRID__actions.html 13562 /doc/simgrid/html/publis_intra.html 435 /doc/simgrid/html/simgrid_logo_small.png 8326 -/doc/simgrid/html/group__SURF__resources.html 4203 -/doc/simgrid/html/structsurf__cpu__model__extension__public.html 2751 +/doc/simgrid/html/group__SIMGRID__resources.html 4203 +/doc/simgrid/html/structsimgrid__cpu__model__extension__public.html 2751 /doc/simgrid/html/tabs.css 1095 /doc/simgrid/html/group__XBT__set.html 6991 /doc/simgrid/html/group__XBT__set__curs.html 9653 @@ -309,11 +309,11 @@ /doc/simgrid/html/nav_f.png 159 /doc/simgrid/html/group__XBT__queue.html 23050 /doc/simgrid/html/group__XBT__fifo__cons.html 9876 -/doc/simgrid/html/structsurf__model.html 17707 +/doc/simgrid/html/structsimgrid__model.html 17707 /doc/simgrid/html/MSG_ex_asynchronous_communications.html 43212 /doc/simgrid/html/Paje_MSG_screenshot_thn.jpg 30326 -/doc/simgrid/html/structsurf__network__model__extension__public.html 2783 -/doc/simgrid/html/structsurf__model__description.html 2621 +/doc/simgrid/html/structsimgrid__network__model__extension__public.html 2783 +/doc/simgrid/html/structsimgrid__model__description.html 2621 /doc/simgrid/html/group__m__host__management.html 19042 /doc/simgrid/html/group__XBT__fifo__perl.html 14045 /doc/simgrid/html/modules.html 12734 @@ -321,7 +321,6 @@ /doc/simgrid/html/group__XBT__fifo.html 6191 /doc/simgrid/html/group__XBT__parmap.html 3765 /doc/simgrid/html/tracing.html 58483 -/doc/simgrid/html/structs__surf__metric__t.html 2523 /doc/simgrid/html/classsimgrid_1_1msg_1_1Task.html 1519 /doc/simgrid/html/group__XBT__swag.html 5923 /doc/simgrid/html/functions_vars.html 11436 @@ -351,7 +350,7 @@ /doc/simgrid/html/index.html 9659 /doc/simgrid/html/group__SD__link__management.html 17867 /doc/simgrid/html/group__MSG__JAVA.html 5443 -/doc/simgrid/html/group__SURF__simulation.html 10385 +/doc/simgrid/html/group__SIMGRID__simulation.html 10385 /doc/simgrid/html/structm__host.html 4188 /doc/simgrid/html/group__XBT__dynar__array.html 22436 /doc/simgrid/html/simgrid.css 386 @@ -380,7 +379,7 @@ /doc/simgrid/html/group__XBT__dict__basic.html 20935 /doc/simgrid/html/group__XBT__graph.html 23682 /doc/simgrid/html/group__XBT__mallocator.html 6444 -/doc/simgrid/html/structsurf__workstation__model__extension__public.html 11076 +/doc/simgrid/html/structsimgrid__workstation__model__extension__public.html 11076 /doc/simgrid/html/publis.html 435 /doc/simgrid/html/group__XBT__misc.html 4663 /doc/simgrid/html/simdag.html 226 @@ -409,12 +408,12 @@ /doc/simgrid/html/options.html 7629 /doc/simgrid/html/group__XBT__dict__nnul.html 18891 /doc/simgrid/html/win_install_04.png 52033 -/doc/simgrid/html/structsurf__action.html 8353 +/doc/simgrid/html/structsimgrid__action.html 8353 /doc/simgrid/html/group__XBT__ex.html 32537 -/doc/simgrid/html/group__SURF__API.html 6659 +/doc/simgrid/html/group__SIMGRID__API.html 6659 /doc/simgrid/html/doxygen.css 12350 /doc/simgrid/html/group__XBT__set__cons.html 7965 -/doc/simgrid/html/group__SURF__build__api.html 7821 +/doc/simgrid/html/group__SIMGRID__build__api.html 7821 /doc/simgrid/html/group__m__process__management.html 47169 /doc/simgrid/html/group__XBT__dict__curs.html 19747 /doc/simgrid/html/group__SD__datatypes__management.html 20816 @@ -430,7 +429,7 @@ /doc/simgrid/html/group__SD__task__management.html 60347 /doc/simgrid/html/group__XBT__syscall.html 10095 /doc/simgrid/html/group__XBT__heap.html 18482 -/doc/simgrid/html/structsurf__action__state.html 7301 +/doc/simgrid/html/structsimgrid__action__state.html 7301 /doc/simgrid/html/tab_s.png 189 /doc/simgrid/html/tab_h.png 192 /doc/simgrid/html/nav_h.png 97 @@ -476,9 +475,7 @@ /include/msg/msg.h 12038 /include/simgrid_config.h 3641 /include/mc/modelchecker.h 96 -/include/surf/simgrid_dtd.h 23583 -/include/surf/surf_routing.h 1167 -/include/surf/surfxml_parse.h 5343 +/include/simgrid_dtd.h 23583 /include/instr/instr.h 5750 /include/simdag/simdag.h 10325 /include/simdag/datatypes.h 3715 diff --git a/examples/platforms/supernode.cpp b/examples/platforms/supernode.cpp index 2b4afb8a9d..033abe9331 100644 --- a/examples/platforms/supernode.cpp +++ b/examples/platforms/supernode.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -26,8 +26,7 @@ static std::string int_string(int n) */ static sg4::NetZone* create_node(const sg4::NetZone* root, const std::string& node_name, const int nb_cpu) { - auto* node = sg4::create_star_zone(node_name); - node->set_parent(root); + auto* node = sg4::create_star_zone(node_name)->set_parent(root); /* create all hosts and connect them to outside world */ for (int i = 0; i < nb_cpu; i++) { @@ -35,9 +34,8 @@ static sg4::NetZone* create_node(const sg4::NetZone* root, const std::string& no const auto& linkname = "link_" + cpuname; const sg4::Host* host = node->create_host(cpuname, 1e9); - const sg4::Link* l = node->create_split_duplex_link(linkname, BW_CPU)->set_latency(LAT_CPU)->seal(); - - node->add_route(host->get_netpoint(), nullptr, nullptr, nullptr, {{l, sg4::LinkInRoute::Direction::UP}}, true); + const sg4::Link* l = node->create_split_duplex_link(linkname, BW_CPU)->set_latency(LAT_CPU); + node->add_route(host, nullptr, {{l, sg4::LinkInRoute::Direction::UP}}, true); } return node; @@ -50,8 +48,7 @@ static sg4::NetZone* create_node(const sg4::NetZone* root, const std::string& no static sg4::NetZone* create_supernode(const sg4::NetZone* root, const std::string& supernode_name, const int nb_nodes, const int nb_cpu) { - auto* supernode = sg4::create_star_zone(supernode_name); - supernode->set_parent(root); + auto* supernode = sg4::create_star_zone(supernode_name)->set_parent(root); /* create all nodes and connect them to outside world */ for (int i = 0; i < nb_nodes; i++) { @@ -59,11 +56,11 @@ static sg4::NetZone* create_supernode(const sg4::NetZone* root, const std::strin const auto& linkname = "link_" + node_name; sg4::NetZone* node = create_node(supernode, node_name, nb_cpu); - const auto router = node->create_router("router_" + node_name); + node->set_gateway(node->create_router("router_" + node_name)); node->seal(); - const sg4::Link* l = supernode->create_split_duplex_link(linkname, BW_NODE)->set_latency(LAT_NODE)->seal(); - supernode->add_route(node->get_netpoint(), nullptr, router, nullptr, {{l, sg4::LinkInRoute::Direction::UP}}, true); + const sg4::Link* l = supernode->create_split_duplex_link(linkname, BW_NODE)->set_latency(LAT_NODE); + supernode->add_route(node, nullptr, {{l, sg4::LinkInRoute::Direction::UP}}, true); } return supernode; } @@ -83,12 +80,11 @@ static sg4::NetZone* create_cluster(const std::string& cluster_name, const int n const auto& linkname = "link_" + supernode_name; sg4::NetZone* supernode = create_supernode(cluster, supernode_name, nb_nodes, nb_cpu); - const auto router = supernode->create_router("router_" + supernode_name); + supernode->set_gateway(supernode->create_router("router_" + supernode_name)); supernode->seal(); - const sg4::Link* l = cluster->create_split_duplex_link(linkname, BW_NETWORK)->set_latency(LAT_NETWORK)->seal(); - cluster->add_route(supernode->get_netpoint(), nullptr, router, nullptr, {{l, sg4::LinkInRoute::Direction::UP}}, - true); + const sg4::Link* l = cluster->create_split_duplex_link(linkname, BW_NETWORK)->set_latency(LAT_NETWORK); + cluster->add_route(supernode, nullptr, {{l, sg4::LinkInRoute::Direction::UP}}, true); } return cluster; } diff --git a/examples/platforms/supernode.py b/examples/platforms/supernode.py index 7270da85ee..f445fe54ef 100755 --- a/examples/platforms/supernode.py +++ b/examples/platforms/supernode.py @@ -1,6 +1,6 @@ #! /usr/bin/env python3 -# Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/platforms/syscoord/generate_peer_platform.pl b/examples/platforms/syscoord/generate_peer_platform.pl index 77a6029b0d..d5eccd1866 100755 --- a/examples/platforms/syscoord/generate_peer_platform.pl +++ b/examples/platforms/syscoord/generate_peer_platform.pl @@ -1,6 +1,6 @@ #!/usr/bin/env perl -# Copyright (c) 2011-2022. The SimGrid Team. +# Copyright (c) 2011-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/examples/platforms/wifi_large_cell.xml b/examples/platforms/wifi_large_cell.xml new file mode 100755 index 0000000000..bd53e78f6e --- /dev/null +++ b/examples/platforms/wifi_large_cell.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/python/CMakeLists.txt b/examples/python/CMakeLists.txt index 1efe8e23b6..3705f4739e 100644 --- a/examples/python/CMakeLists.txt +++ b/examples/python/CMakeLists.txt @@ -1,9 +1,12 @@ foreach(example actor-create actor-daemon actor-join actor-kill actor-migrate actor-suspend actor-yield actor-lifetime + activityset-testany activityset-waitall activityset-waitallfor activityset-waitany app-masterworkers - comm-wait comm-waitall comm-waitallfor comm-waitany comm-waitfor comm-failure comm-host2host comm-pingpong - comm-ready comm-serialize comm-suspend comm-testany comm-throttling comm-waitallfor comm-waituntil + comm-wait comm-failure comm-host2host comm-pingpong + comm-ready comm-suspend comm-throttling comm-waituntil exec-async exec-basic exec-dvfs exec-remote exec-ptask - platform-profile platform-failures + task-io task-simple task-switch-host task-variable-load + platform-comm-serialize platform-profile platform-failures + plugin-host-load network-nonlinear clusters-multicpu io-degradation exec-cpu-nonlinear synchro-barrier synchro-mutex synchro-semaphore) set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh) diff --git a/examples/python/activityset-testany/activityset-testany.py b/examples/python/activityset-testany/activityset-testany.py new file mode 100644 index 0000000000..6a8901ff70 --- /dev/null +++ b/examples/python/activityset-testany/activityset-testany.py @@ -0,0 +1,57 @@ +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. +# +# This program is free software you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +""" +Usage: activityset-testany.py platform_file [other parameters] +""" + +import sys +from simgrid import Actor, ActivitySet, Engine, Comm, Exec, Io, Host, Mailbox, this_actor + +def bob(): + mbox = Mailbox.by_name("mbox") + disk = Host.current().get_disks()[0] + + this_actor.info("Create my asynchronous activities") + exec = this_actor.exec_async(5e9) + comm = mbox.get_async() + io = disk.read_async(300000000) + + pending_activities = ActivitySet([exec, comm]) + pending_activities.push(io) # Activities can be pushed after creation, too + + this_actor.info("Sleep_for a while") + this_actor.sleep_for(1) + + this_actor.info("Test for completed activities") + while not pending_activities.empty(): + completed_one = pending_activities.test_any() + if completed_one == None: + this_actor.info("Nothing matches, test again in 0.5s") + this_actor.sleep_for(.5) + elif isinstance(completed_one, Comm): + this_actor.info("Completed a Comm") + elif isinstance(completed_one, Exec): + this_actor.info("Completed an Exec") + elif isinstance(completed_one, Io): + this_actor.info("Completed an I/O") + + this_actor.info("Last activity is complete") + +def alice(): + this_actor.info("Send 'Message'") + Mailbox.by_name("mbox").put("Message", 600000000) + +if __name__ == '__main__': + e = Engine(sys.argv) + e.set_log_control("root.fmt:[%4.2r]%e[%5a]%e%m%n") + + # Load the platform description + e.load_platform(sys.argv[1]) + + Actor.create("bob", Host.by_name("bob"), bob) + Actor.create("alice", Host.by_name("alice"), alice) + + e.run() diff --git a/examples/cpp/activity-testany/s4u-activity-testany.tesh b/examples/python/activityset-testany/activityset-testany.tesh similarity index 87% rename from examples/cpp/activity-testany/s4u-activity-testany.tesh rename to examples/python/activityset-testany/activityset-testany.tesh index ab4d8208b0..5177a166b1 100644 --- a/examples/cpp/activity-testany/s4u-activity-testany.tesh +++ b/examples/python/activityset-testany/activityset-testany.tesh @@ -1,6 +1,6 @@ #!/usr/bin/env tesh -$ ${bindir:=.}/s4u-activity-testany ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%4.2r]%e[%5a]%e%m%n" +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/activityset-testany.py ${platfdir}/hosts_with_disks.xml > [0.00] [alice] Send 'Message' > [0.00] [ bob] Create my asynchronous activities > [0.00] [ bob] Sleep_for a while diff --git a/examples/python/activityset-waitall/activityset-waitall.py b/examples/python/activityset-waitall/activityset-waitall.py new file mode 100644 index 0000000000..4e4d1eede5 --- /dev/null +++ b/examples/python/activityset-waitall/activityset-waitall.py @@ -0,0 +1,44 @@ +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. +# +# This program is free software you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +""" +Usage: activityset-waitall.py platform_file [other parameters] +""" + +import sys +from simgrid import Actor, ActivitySet, Engine, Comm, Exec, Io, Host, Mailbox, this_actor + +def bob(): + mbox = Mailbox.by_name("mbox") + disk = Host.current().get_disks()[0] + + this_actor.info("Create my asynchronous activities") + exec = this_actor.exec_async(5e9) + comm = mbox.get_async() + io = disk.read_async(300000000) + + pending_activities = ActivitySet([exec, comm]) + pending_activities.push(io) # Activities can be pushed after creation, too + + this_actor.info("Wait for asynchronous activities to complete, all in one shot.") + pending_activities.wait_all() + + this_actor.info("All activities are completed.") + +def alice(): + this_actor.info("Send 'Message'") + Mailbox.by_name("mbox").put("Message", 600000000) + +if __name__ == '__main__': + e = Engine(sys.argv) + e.set_log_control("root.fmt:[%4.6r]%e[%5a]%e%m%n") + + # Load the platform description + e.load_platform(sys.argv[1]) + + Actor.create("bob", Host.by_name("bob"), bob) + Actor.create("alice", Host.by_name("alice"), alice) + + e.run() diff --git a/examples/python/activityset-waitall/activityset-waitall.tesh b/examples/python/activityset-waitall/activityset-waitall.tesh new file mode 100644 index 0000000000..ab4b17590a --- /dev/null +++ b/examples/python/activityset-waitall/activityset-waitall.tesh @@ -0,0 +1,7 @@ +#!/usr/bin/env tesh + +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/activityset-waitall.py ${platfdir}/hosts_with_disks.xml +> [0.000000] [alice] Send 'Message' +> [0.000000] [ bob] Create my asynchronous activities +> [0.000000] [ bob] Wait for asynchronous activities to complete, all in one shot. +> [5.197828] [ bob] All activities are completed. diff --git a/examples/python/activityset-waitallfor/activityset-waitallfor.py b/examples/python/activityset-waitallfor/activityset-waitallfor.py new file mode 100644 index 0000000000..44b3c6f5b2 --- /dev/null +++ b/examples/python/activityset-waitallfor/activityset-waitallfor.py @@ -0,0 +1,58 @@ +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. +# +# This program is free software you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +""" +Usage: activityset-waitallfor.py platform_file [other parameters] +""" + +import sys +from simgrid import Actor, ActivitySet, Engine, Comm, Exec, Io, Host, Mailbox, this_actor, TimeoutException + +def bob(): + mbox = Mailbox.by_name("mbox") + disk = Host.current().get_disks()[0] + + this_actor.info("Create my asynchronous activities") + exec = this_actor.exec_async(5e9) + comm = mbox.get_async() + io = disk.read_async(300000000) + + pending_activities = ActivitySet([exec, comm]) + pending_activities.push(io) # Activities can be pushed after creation, too + + this_actor.info("Wait for asynchronous activities to complete") + while not pending_activities.empty(): + try: + pending_activities.wait_all_for(1) + except TimeoutException: + this_actor.info("Not all activities are terminated yet.") + + completed_one = pending_activities.test_any() + while completed_one != None: + if isinstance(completed_one, Comm): + this_actor.info("Completed a Comm") + elif isinstance(completed_one, Exec): + this_actor.info("Completed an Exec") + elif isinstance(completed_one, Io): + this_actor.info("Completed an I/O") + completed_one = pending_activities.test_any() + + this_actor.info("Last activity is complete") + +def alice(): + this_actor.info("Send 'Message'") + Mailbox.by_name("mbox").put("Message", 600000000) + +if __name__ == '__main__': + e = Engine(sys.argv) + e.set_log_control("root.fmt:[%4.6r]%e[%5a]%e%m%n") + + # Load the platform description + e.load_platform(sys.argv[1]) + + Actor.create("bob", Host.by_name("bob"), bob) + Actor.create("alice", Host.by_name("alice"), alice) + + e.run() diff --git a/examples/python/activityset-waitallfor/activityset-waitallfor.tesh b/examples/python/activityset-waitallfor/activityset-waitallfor.tesh new file mode 100644 index 0000000000..cf08947e37 --- /dev/null +++ b/examples/python/activityset-waitallfor/activityset-waitallfor.tesh @@ -0,0 +1,15 @@ +#!/usr/bin/env tesh + +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/activityset-waitallfor.py ${platfdir}/hosts_with_disks.xml +> [0.000000] [alice] Send 'Message' +> [0.000000] [ bob] Create my asynchronous activities +> [0.000000] [ bob] Wait for asynchronous activities to complete +> [1.000000] [ bob] Not all activities are terminated yet. +> [2.000000] [ bob] Not all activities are terminated yet. +> [3.000000] [ bob] Not all activities are terminated yet. +> [3.000000] [ bob] Completed an I/O +> [4.000000] [ bob] Not all activities are terminated yet. +> [5.000000] [ bob] Not all activities are terminated yet. +> [5.000000] [ bob] Completed an Exec +> [5.197828] [ bob] Completed a Comm +> [5.197828] [ bob] Last activity is complete diff --git a/examples/python/activityset-waitany/activityset-waitany.py b/examples/python/activityset-waitany/activityset-waitany.py new file mode 100644 index 0000000000..88ac531128 --- /dev/null +++ b/examples/python/activityset-waitany/activityset-waitany.py @@ -0,0 +1,52 @@ +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. +# +# This program is free software you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +""" +Usage: activityset-waitany.py platform_file [other parameters] +""" + +import sys +from simgrid import Actor, ActivitySet, Engine, Comm, Exec, Io, Host, Mailbox, this_actor + +def bob(): + mbox = Mailbox.by_name("mbox") + disk = Host.current().get_disks()[0] + + this_actor.info("Create my asynchronous activities") + exec = this_actor.exec_async(5e9) + comm = mbox.get_async() + io = disk.read_async(300000000) + + pending_activities = ActivitySet([exec, comm]) + pending_activities.push(io) # Activities can be pushed after creation, too + + this_actor.info("Wait for asynchronous activities to complete") + while not pending_activities.empty(): + completed_one = pending_activities.wait_any() + + if isinstance(completed_one, Comm): + this_actor.info("Completed a Comm") + elif isinstance(completed_one, Exec): + this_actor.info("Completed an Exec") + elif isinstance(completed_one, Io): + this_actor.info("Completed an I/O") + + this_actor.info("Last activity is complete") + +def alice(): + this_actor.info("Send 'Message'") + Mailbox.by_name("mbox").put("Message", 600000000) + +if __name__ == '__main__': + e = Engine(sys.argv) + e.set_log_control("root.fmt:[%4.6r]%e[%5a]%e%m%n") + + # Load the platform description + e.load_platform(sys.argv[1]) + + Actor.create("bob", Host.by_name("bob"), bob) + Actor.create("alice", Host.by_name("alice"), alice) + + e.run() diff --git a/examples/cpp/activity-waitany/s4u-activity-waitany.tesh b/examples/python/activityset-waitany/activityset-waitany.tesh similarity index 59% rename from examples/cpp/activity-waitany/s4u-activity-waitany.tesh rename to examples/python/activityset-waitany/activityset-waitany.tesh index 7b15aa64cd..70b707b41e 100644 --- a/examples/cpp/activity-waitany/s4u-activity-waitany.tesh +++ b/examples/python/activityset-waitany/activityset-waitany.tesh @@ -1,9 +1,9 @@ #!/usr/bin/env tesh -$ ${bindir:=.}/s4u-activity-waitany ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%7.6r]%e[%5a]%e%m%n" +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/activityset-waitany.py ${platfdir}/hosts_with_disks.xml > [0.000000] [alice] Send 'Message' > [0.000000] [ bob] Create my asynchronous activities -> [0.000000] [ bob] Wait for asynchrounous activities to complete +> [0.000000] [ bob] Wait for asynchronous activities to complete > [3.000000] [ bob] Completed an I/O > [5.000000] [ bob] Completed an Exec > [5.197828] [ bob] Completed a Comm diff --git a/examples/python/actor-create/actor-create.py b/examples/python/actor-create/actor-create.py index 0f4e01e3c0..2c7f623f81 100644 --- a/examples/python/actor-create/actor-create.py +++ b/examples/python/actor-create/actor-create.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/actor-daemon/actor-daemon.py b/examples/python/actor-daemon/actor-daemon.py index a6f1b83aee..f999178cd9 100644 --- a/examples/python/actor-daemon/actor-daemon.py +++ b/examples/python/actor-daemon/actor-daemon.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. # # This program is free software you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/actor-join/actor-join.py b/examples/python/actor-join/actor-join.py index d64118d366..770ec7662e 100644 --- a/examples/python/actor-join/actor-join.py +++ b/examples/python/actor-join/actor-join.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. # # This program is free software you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/actor-kill/actor-kill.py b/examples/python/actor-kill/actor-kill.py index fa2871723d..43960b9e9d 100644 --- a/examples/python/actor-kill/actor-kill.py +++ b/examples/python/actor-kill/actor-kill.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/actor-lifetime/actor-lifetime.py b/examples/python/actor-lifetime/actor-lifetime.py index 7cd8867d11..5e4bb4c0b0 100644 --- a/examples/python/actor-lifetime/actor-lifetime.py +++ b/examples/python/actor-lifetime/actor-lifetime.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/actor-migrate/actor-migrate.py b/examples/python/actor-migrate/actor-migrate.py index 9cac4bbf01..77873ca5cf 100644 --- a/examples/python/actor-migrate/actor-migrate.py +++ b/examples/python/actor-migrate/actor-migrate.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/actor-suspend/actor-suspend.py b/examples/python/actor-suspend/actor-suspend.py index af021b6cfd..1aa545dc94 100644 --- a/examples/python/actor-suspend/actor-suspend.py +++ b/examples/python/actor-suspend/actor-suspend.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. # # This program is free software you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/actor-yield/actor-yield.py b/examples/python/actor-yield/actor-yield.py index d82b20fcbb..36f20bd4dc 100644 --- a/examples/python/actor-yield/actor-yield.py +++ b/examples/python/actor-yield/actor-yield.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/app-masterworkers/app-masterworkers.py b/examples/python/app-masterworkers/app-masterworkers.py index 9ae26538e7..856d9e387e 100644 --- a/examples/python/app-masterworkers/app-masterworkers.py +++ b/examples/python/app-masterworkers/app-masterworkers.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -56,7 +56,7 @@ def worker(*args): # main-begin if __name__ == '__main__': - assert len(sys.argv) > 2, f"Usage: python app-masterworkers.py platform_file deployment_file" + assert len(sys.argv) > 2, "Usage: python app-masterworkers.py platform_file deployment_file" e = Engine(sys.argv) diff --git a/examples/python/clusters-multicpu/clusters-multicpu.py b/examples/python/clusters-multicpu/clusters-multicpu.py index 637eab55b9..6a4d783a12 100644 --- a/examples/python/clusters-multicpu/clusters-multicpu.py +++ b/examples/python/clusters-multicpu/clusters-multicpu.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -28,19 +28,19 @@ class Sender: # Actors that are created as object will execute their __call__ method. # So, the following constitutes the main function of the Sender actor. def __call__(self): - pending_comms = [] + pending_comms = simgrid.ActivitySet() mboxes = [] for host in self.hosts: msg = "Hello, I'm alive and running on " + simgrid.this_actor.get_host().name mbox = simgrid.Mailbox.by_name(host.name) mboxes.append(mbox) - pending_comms.append(mbox.put_async(msg, self.msg_size)) + pending_comms.push(mbox.put_async(msg, self.msg_size)) simgrid.this_actor.info("Done dispatching all messages") # Now that all message exchanges were initiated, wait for their completion in one single call - simgrid.Comm.wait_all(pending_comms) + pending_comms.wait_all() simgrid.this_actor.info("Goodbye now!") @@ -58,8 +58,7 @@ class Receiver: ##################################################################################################### -def create_hostzone(zone: simgrid.NetZone, coord: typing.List[int], ident: int) -> typing.Tuple[simgrid.NetPoint, - simgrid.NetPoint]: +def create_hostzone(zone: simgrid.NetZone, coord: typing.List[int], ident: int) -> simgrid.NetZone: r""" Callback to set a cluster leaf/element @@ -94,24 +93,22 @@ def create_hostzone(zone: simgrid.NetZone, coord: typing.List[int], ident: int) # setting my Torus parent zone host_zone.set_parent(zone) - gateway = None # create CPUs for i in range(num_cpus): cpu_name = hostname + "-cpu" + str(i) host = host_zone.create_host(cpu_name, speed).seal() # the first CPU is the gateway if i == 0: - gateway = host + host_zone.set_gateway(host.netpoint) # create split-duplex link link = host_zone.create_split_duplex_link("link-" + cpu_name, link_bw) link.set_latency(link_lat).seal() # connecting CPU to outer world - host_zone.add_route(host.netpoint, None, None, None, - [simgrid.LinkInRoute(link, simgrid.LinkInRoute.Direction.UP)], True) + host_zone.add_route(host, None, [simgrid.LinkInRoute(link, simgrid.LinkInRoute.Direction.UP)], True) # seal newly created netzone host_zone.seal() - return host_zone.netpoint, gateway.netpoint + return host_zone ##################################################################################################### diff --git a/examples/python/comm-failure/comm-failure.py b/examples/python/comm-failure/comm-failure.py index b251f781a1..02cd701377 100644 --- a/examples/python/comm-failure/comm-failure.py +++ b/examples/python/comm-failure/comm-failure.py @@ -1,11 +1,11 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. import sys -from simgrid import Engine, Actor, Comm, NetZone, Link, LinkInRoute, Mailbox, this_actor, NetworkFailureException +from simgrid import Engine, Actor, ActivitySet, Comm, NetZone, Link, LinkInRoute, Mailbox, this_actor, NetworkFailureException def sender(mailbox1_name: str, mailbox2_name: str) -> None: @@ -18,27 +18,26 @@ def sender(mailbox1_name: str, mailbox2_name: str) -> None: this_actor.info(f"Initiating asynchronous send to {mailbox2.name}") comm2: Comm = mailbox2.put_async(666, 2) - this_actor.info(f"Calling wait_any..") - pending_comms = [comm1, comm2] + this_actor.info("Calling wait_any..") + pending_comms = ActivitySet([comm1, comm2]) try: - index = Comm.wait_any([comm1, comm2]) - this_actor.info(f"Wait any returned index {index} (comm to {pending_comms[index].mailbox.name})") + comm = pending_comms.wait_any() + this_actor.info(f"Wait any returned a comm to {comm.mailbox.name})") except NetworkFailureException: - this_actor.info(f"Sender has experienced a network failure exception, so it knows that something went wrong") - this_actor.info(f"Now it needs to figure out which of the two comms failed by looking at their state") + this_actor.info("Sender has experienced a network failure exception, so it knows that something went wrong") + this_actor.info("Now it needs to figure out which of the two comms failed by looking at their state:") - this_actor.info(f"Comm to {comm1.mailbox.name} has state: {comm1.state_str}") - this_actor.info(f"Comm to {comm2.mailbox.name} has state: {comm2.state_str}") + this_actor.info(f" Comm to {comm1.mailbox.name} has state: {comm1.state_str}") + this_actor.info(f" Comm to {comm2.mailbox.name} has state: {comm2.state_str}") try: comm1.wait() - except NetworkFailureException: - this_actor.info(f"Waiting on a FAILED comm raises an exception") + except NetworkFailureException as err: + this_actor.info(f"Waiting on a FAILED comm raises an exception: '{err}'") this_actor.info("Wait for remaining comm, just to be nice") - pending_comms.pop(0) try: - Comm.wait_any(pending_comms) + pending_comms.wait_all() except Exception as e: this_actor.warning(str(e)) @@ -55,12 +54,9 @@ def receiver(mailbox_name: str) -> None: def link_killer(link_name: str) -> None: link_to_kill = Link.by_name(link_name) - this_actor.info("sleeping 10 seconds...") this_actor.sleep_for(10.0) - this_actor.info(f"turning off link {link_to_kill.name}") + this_actor.info(f"Turning off link '{link_to_kill.name}'") link_to_kill.turn_off() - this_actor.info("link killed. exiting") - def main(): e = Engine(sys.argv) @@ -69,11 +65,11 @@ def main(): host2 = zone.create_host("Host2", "1f") host3 = zone.create_host("Host3", "1f") - link_to_2 = LinkInRoute(zone.create_link("link_to_2", "1bps").seal()) - link_to_3 = LinkInRoute(zone.create_link("link_to_3", "1bps").seal()) + link_to_2 = zone.create_link("link_to_2", "1bps").seal() + link_to_3 = zone.create_link("link_to_3", "1bps").seal() - zone.add_route(host1.netpoint, host2.netpoint, None, None, [link_to_2], False) - zone.add_route(host1.netpoint, host3.netpoint, None, None, [link_to_3], False) + zone.add_route(host1, host2, [link_to_2]) + zone.add_route(host1, host3, [link_to_3]) zone.seal() Actor.create("Sender", host1, sender, "mailbox2", "mailbox3") diff --git a/examples/python/comm-failure/comm-failure.tesh b/examples/python/comm-failure/comm-failure.tesh index cc78b708b8..8f4de0e380 100644 --- a/examples/python/comm-failure/comm-failure.tesh +++ b/examples/python/comm-failure/comm-failure.tesh @@ -1,19 +1,17 @@ #!/usr/bin/env tesh $ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-failure.py "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" ->[ 0.000000] (4:LinkKiller@Host2) sleeping 10 seconds... ->[ 0.000000] (2:Receiver-1@Host2) Receiver posting a receive (mailbox2)... ->[ 0.000000] (3:Receiver-2@Host3) Receiver posting a receive (mailbox3)... ->[ 0.000000] (1:Sender@Host1) Initiating asynchronous send to mailbox2 ->[ 0.000000] (1:Sender@Host1) Initiating asynchronous send to mailbox3 ->[ 0.000000] (1:Sender@Host1) Calling wait_any.. ->[ 10.000000] (4:LinkKiller@Host2) turning off link link_to_2 ->[ 10.000000] (4:LinkKiller@Host2) link killed. exiting ->[ 10.000000] (2:Receiver-1@Host2) Receiver has experience a network failure exception (mailbox2) ->[ 10.000000] (1:Sender@Host1) Sender has experienced a network failure exception, so it knows that something went wrong ->[ 10.000000] (1:Sender@Host1) Now it needs to figure out which of the two comms failed by looking at their state ->[ 10.000000] (1:Sender@Host1) Comm to mailbox2 has state: FAILED ->[ 10.000000] (1:Sender@Host1) Comm to mailbox3 has state: STARTED ->[ 10.000000] (1:Sender@Host1) Waiting on a FAILED comm raises an exception ->[ 10.000000] (1:Sender@Host1) Wait for remaining comm, just to be nice ->[ 16.494845] (3:Receiver-2@Host3) Receiver has received successfully (mailbox3)! +> [ 0.000000] (2:Receiver-1@Host2) Receiver posting a receive (mailbox2)... +> [ 0.000000] (3:Receiver-2@Host3) Receiver posting a receive (mailbox3)... +> [ 0.000000] (1:Sender@Host1) Initiating asynchronous send to mailbox2 +> [ 0.000000] (1:Sender@Host1) Initiating asynchronous send to mailbox3 +> [ 0.000000] (1:Sender@Host1) Calling wait_any.. +> [ 10.000000] (4:LinkKiller@Host2) Turning off link 'link_to_2' +> [ 10.000000] (2:Receiver-1@Host2) Receiver has experience a network failure exception (mailbox2) +> [ 10.000000] (1:Sender@Host1) Sender has experienced a network failure exception, so it knows that something went wrong +> [ 10.000000] (1:Sender@Host1) Now it needs to figure out which of the two comms failed by looking at their state: +> [ 10.000000] (1:Sender@Host1) Comm to mailbox2 has state: FAILED +> [ 10.000000] (1:Sender@Host1) Comm to mailbox3 has state: STARTED +> [ 10.000000] (1:Sender@Host1) Waiting on a FAILED comm raises an exception: 'Cannot wait for a failed communication' +> [ 10.000000] (1:Sender@Host1) Wait for remaining comm, just to be nice +> [ 17.319588] (3:Receiver-2@Host3) Receiver has received successfully (mailbox3)! diff --git a/examples/python/comm-host2host/comm-host2host.py b/examples/python/comm-host2host/comm-host2host.py index e352a96582..edbadb5faf 100644 --- a/examples/python/comm-host2host/comm-host2host.py +++ b/examples/python/comm-host2host/comm-host2host.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/comm-pingpong/comm-pingpong.py b/examples/python/comm-pingpong/comm-pingpong.py index d5c76f9dd3..f07a583872 100644 --- a/examples/python/comm-pingpong/comm-pingpong.py +++ b/examples/python/comm-pingpong/comm-pingpong.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/comm-ready/comm-ready.py b/examples/python/comm-ready/comm-ready.py index 646d4d1af1..20065327c5 100644 --- a/examples/python/comm-ready/comm-ready.py +++ b/examples/python/comm-ready/comm-ready.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -7,7 +7,7 @@ from argparse import ArgumentParser from typing import List import sys -from simgrid import Actor, Comm, Engine, Mailbox, this_actor +from simgrid import Actor, ActivitySet, Comm, Engine, Mailbox, this_actor FINALIZE_MESSAGE = "finalize" @@ -31,7 +31,7 @@ def get_peer_mailbox(peer_id: int) -> Mailbox: def peer(my_id: int, message_count: int, payload_size: int, peers_count: int): my_mailbox: Mailbox = get_peer_mailbox(my_id) my_mailbox.set_receiver(Actor.self()) - pending_comms: List[Comm] = [] + pending_comms = ActivitySet() # Start dispatching all messages to peers others that myself for i in range(message_count): for peer_id in range(peers_count): @@ -39,14 +39,14 @@ def peer(my_id: int, message_count: int, payload_size: int, peers_count: int): peer_mailbox = get_peer_mailbox(peer_id) message = f"Message {i} from peer {my_id}" this_actor.info(f"Send '{message}' to '{peer_mailbox.name}'") - pending_comms.append(peer_mailbox.put_async(message, payload_size)) + pending_comms.push(peer_mailbox.put_async(message, payload_size)) # Start sending messages to let peers know that they should stop for peer_id in range(peers_count): if peer_id != my_id: peer_mailbox = get_peer_mailbox(peer_id) payload = str(FINALIZE_MESSAGE) - pending_comms.append(peer_mailbox.put_async(payload, payload_size)) + pending_comms.push(peer_mailbox.put_async(payload, payload_size)) this_actor.info(f"Send '{payload}' to '{peer_mailbox.name}'") this_actor.info("Done dispatching all messages") @@ -58,7 +58,7 @@ def peer(my_id: int, message_count: int, payload_size: int, peers_count: int): start = Engine.clock received: str = my_mailbox.get() waiting_time = Engine.clock - start - if waiting_time != 0.0: + if waiting_time > 0.0: raise AssertionError(f"Expecting the waiting time to be 0.0 because the communication was supposedly " f"ready, but got {waiting_time} instead") this_actor.info(f"I got a '{received}'.") @@ -69,7 +69,7 @@ def peer(my_id: int, message_count: int, payload_size: int, peers_count: int): this_actor.sleep_for(0.01) this_actor.info("I'm done, just waiting for my peers to receive the messages before exiting") - Comm.wait_all(pending_comms) + pending_comms.wait_all() this_actor.info("Goodbye now!") diff --git a/examples/python/comm-suspend/comm-suspend.py b/examples/python/comm-suspend/comm-suspend.py index 126b7caeb6..85646ed4d6 100644 --- a/examples/python/comm-suspend/comm-suspend.py +++ b/examples/python/comm-suspend/comm-suspend.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -43,7 +43,7 @@ def sender(): comm.resume() comm.wait() this_actor.info(f"There is {comm.remaining:.0f} bytes to transfer after the communication completion.") - this_actor.info(f"Suspending a completed activity is a no-op.") + this_actor.info("Suspending a completed activity is a no-op.") comm.suspend() diff --git a/examples/python/comm-testany/comm-testany.py b/examples/python/comm-testany/comm-testany.py deleted file mode 100644 index 1b32047802..0000000000 --- a/examples/python/comm-testany/comm-testany.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the license (GNU LGPL) which comes with this package. - -from argparse import ArgumentParser -from typing import List -import sys - -from simgrid import Engine, Actor, Comm, Mailbox, this_actor - - -def create_parser() -> ArgumentParser: - parser = ArgumentParser() - parser.add_argument( - '--platform', - type=str, - required=True, - help='path to the platform description' - ) - return parser - - -def rank0(): - rank0_mailbox: Mailbox = Mailbox.by_name("rank0") - this_actor.info("Post my asynchronous receives") - comm1, a1 = rank0_mailbox.get_async() - comm2, a2 = rank0_mailbox.get_async() - comm3, a3 = rank0_mailbox.get_async() - pending_comms: List[Comm] = [comm1, comm2, comm3] - - this_actor.info("Send some data to rank-1") - rank1_mailbox: Mailbox = Mailbox.by_name("rank1") - for i in range(3): - rank1_mailbox.put(i, 1) - - this_actor.info("Test for completed comms") - while pending_comms: - flag = Comm.test_any(pending_comms) - if flag != -1: - pending_comms.pop(flag) - this_actor.info("Remove a pending comm.") - else: - # Nothing matches, wait for a little bit - this_actor.sleep_for(0.1) - this_actor.info("Last comm is complete") - - -def rank1(): - rank0_mailbox: Mailbox = Mailbox.by_name("rank0") - rank1_mailbox: Mailbox = Mailbox.by_name("rank1") - for i in range(3): - data: int = rank1_mailbox.get() - this_actor.info(f"Received {data}") - msg_content = f"Message {i}" - this_actor.info(f"Send '{msg_content}'") - rank0_mailbox.put(msg_content, int(1e6)) - - -def main(): - settings = create_parser().parse_known_args()[0] - e = Engine(sys.argv) - e.load_platform(settings.platform) - - Actor.create("rank0", e.host_by_name("Tremblay"), rank0) - Actor.create("rank1", e.host_by_name("Fafard"), rank1) - - e.run() - - -if __name__ == "__main__": - main() diff --git a/examples/python/comm-testany/comm-testany.tesh b/examples/python/comm-testany/comm-testany.tesh deleted file mode 100644 index 83d80f118b..0000000000 --- a/examples/python/comm-testany/comm-testany.tesh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env tesh - -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-testany.py --platform ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" ->[ 0.000000] (1:rank0@Tremblay) Post my asynchronous receives ->[ 0.000000] (1:rank0@Tremblay) Send some data to rank-1 ->[ 0.025708] (2:rank1@Fafard) Received 0 ->[ 0.025708] (2:rank1@Fafard) Send 'Message 0' ->[ 0.209813] (2:rank1@Fafard) Received 1 ->[ 0.209813] (2:rank1@Fafard) Send 'Message 1' ->[ 0.393918] (1:rank0@Tremblay) Test for completed comms ->[ 0.393918] (2:rank1@Fafard) Received 2 ->[ 0.393918] (2:rank1@Fafard) Send 'Message 2' ->[ 0.393918] (1:rank0@Tremblay) Remove a pending comm. ->[ 0.393918] (1:rank0@Tremblay) Remove a pending comm. ->[ 0.593918] (1:rank0@Tremblay) Remove a pending comm. ->[ 0.593918] (1:rank0@Tremblay) Last comm is complete diff --git a/examples/python/comm-throttling/comm-throttling.py b/examples/python/comm-throttling/comm-throttling.py index 3e7e140d98..8806777f00 100644 --- a/examples/python/comm-throttling/comm-throttling.py +++ b/examples/python/comm-throttling/comm-throttling.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/comm-wait/comm-wait.py b/examples/python/comm-wait/comm-wait.py index 95c1e9c3aa..b79b2a287f 100644 --- a/examples/python/comm-wait/comm-wait.py +++ b/examples/python/comm-wait/comm-wait.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it diff --git a/examples/python/comm-waitall/comm-waitall.py b/examples/python/comm-waitall/comm-waitall.py deleted file mode 100644 index 0ffa0d22f5..0000000000 --- a/examples/python/comm-waitall/comm-waitall.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the license (GNU LGPL) which comes with this package. - -""" -This example shows how to block on the completion of a set of communications. - -As for the other asynchronous examples, the sender initiate all the messages it wants to send and -pack the resulting simgrid.Comm objects in a list. All messages thus occur concurrently. - -The sender then blocks until all ongoing communication terminate, using simgrid.Comm.wait_all() -""" - -import sys -from simgrid import Actor, Comm, Engine, Host, Mailbox, this_actor - - -def sender(messages_count, msg_size, receivers_count): - # List in which we store all ongoing communications - pending_comms = [] - - # Vector of the used mailboxes - mboxes = [Mailbox.by_name("receiver-{:d}".format(i)) - for i in range(0, receivers_count)] - - # Start dispatching all messages to receivers, in a round robin fashion - for i in range(0, messages_count): - content = "Message {:d}".format(i) - mbox = mboxes[i % receivers_count] - - this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox))) - - # Create a communication representing the ongoing communication, and store it in pending_comms - comm = mbox.put_async(content, msg_size) - pending_comms.append(comm) - - # Start sending messages to let the workers know that they should stop - for i in range(0, receivers_count): - mbox = mboxes[i] - this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox))) - comm = mbox.put_async("finalize", 0) - pending_comms.append(comm) - - this_actor.info("Done dispatching all messages") - - # Now that all message exchanges were initiated, wait for their completion in one single call - Comm.wait_all(pending_comms) - - this_actor.info("Goodbye now!") - - -def receiver(my_id): - mbox = Mailbox.by_name("receiver-{:d}".format(my_id)) - - this_actor.info("Wait for my first message") - while True: - received = mbox.get() - this_actor.info("I got a '{:s}'.".format(received)) - if received == "finalize": - break # If it's a finalize message, we're done. - - -if __name__ == '__main__': - e = Engine(sys.argv) - - # Load the platform description - e.load_platform(sys.argv[1]) - - Actor.create("sender", Host.by_name("Tremblay"), sender, 5, 1000000, 2) - Actor.create("receiver", Host.by_name("Ruby"), receiver, 0) - Actor.create("receiver", Host.by_name("Perl"), receiver, 1) - - e.run() diff --git a/examples/python/comm-waitall/comm-waitall.tesh b/examples/python/comm-waitall/comm-waitall.tesh deleted file mode 100644 index 32ca46ce01..0000000000 --- a/examples/python/comm-waitall/comm-waitall.tesh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env tesh - -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-waitall.py ${platfdir}/small_platform_fatpipe.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (2:receiver@Ruby) Wait for my first message -> [ 0.000000] (3:receiver@Perl) Wait for my first message -> [ 0.000000] (1:sender@Tremblay) Send 'Message 0' to 'Mailbox(receiver-0)' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 1' to 'Mailbox(receiver-1)' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 2' to 'Mailbox(receiver-0)' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 3' to 'Mailbox(receiver-1)' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 4' to 'Mailbox(receiver-0)' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-0)' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-1)' -> [ 0.000000] (1:sender@Tremblay) Done dispatching all messages -> [ 0.004022] (2:receiver@Ruby) I got a 'Message 0'. -> [ 0.004022] (3:receiver@Perl) I got a 'Message 1'. -> [ 0.008043] (2:receiver@Ruby) I got a 'Message 2'. -> [ 0.008043] (3:receiver@Perl) I got a 'Message 3'. -> [ 0.009995] (3:receiver@Perl) I got a 'finalize'. -> [ 0.012065] (2:receiver@Ruby) I got a 'Message 4'. -> [ 0.014016] (2:receiver@Ruby) I got a 'finalize'. -> [ 0.014016] (1:sender@Tremblay) Goodbye now! diff --git a/examples/python/comm-waitallfor/comm-waitallfor.py b/examples/python/comm-waitallfor/comm-waitallfor.py deleted file mode 100644 index fd94bcdf75..0000000000 --- a/examples/python/comm-waitallfor/comm-waitallfor.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the license (GNU LGPL) which comes with this package. - -""" -This example implements the following scenario: -- Multiple workers consume jobs (Job) from a shared mailbox (worker) -- A client first dispatches several jobs (with a simulated 'cost' - i.e. time the worker will 'process' the job) -- The client then waits for all job results for a maximum time set by the 'wait timeout' (Comm.wait_all_for) -- The client then displays the status of individual jobs. -""" - - -from argparse import ArgumentParser -from dataclasses import dataclass -from typing import List -from uuid import uuid4 -import sys - -from simgrid import Actor, Comm, Engine, Host, Mailbox, PyGetAsync, this_actor - - -SIMULATED_JOB_SIZE_BYTES = 1024 -SIMULATED_RESULT_SIZE_BYTES = 1024 * 1024 - - -def parse_requests(requests_str: str) -> List[float]: - return [float(item.strip()) for item in requests_str.split(",")] - - -def create_parser() -> ArgumentParser: - parser = ArgumentParser() - parser.add_argument( - '--platform', - type=str, - required=True, - help='path to the platform description' - ) - parser.add_argument( - "--workers", - type=int, - default=1, - help="number of worker actors to start" - ) - parser.add_argument( - "--jobs", - type=parse_requests, - default="1,2,3,4,5", - help="duration of individual jobs sent to the workers by the client" - ) - parser.add_argument( - "--wait-timeout", - type=float, - default=5.0, - help="number of seconds before the client gives up waiting for results and aborts the simulation" - ) - return parser - - -@dataclass -class Job: - job_id: str - duration: float - result_mailbox: Mailbox - - -def worker(worker_id: str): - this_actor.info(f"{worker_id} started") - mailbox: Mailbox = Mailbox.by_name("worker") - while True: - job: Job = mailbox.get() - this_actor.info(f"{worker_id} working on {job.job_id} (will take {job.duration}s to complete)") - this_actor.sleep_for(job.duration) - job.result_mailbox.put(f"{worker_id}", SIMULATED_RESULT_SIZE_BYTES) - - -@dataclass -class AsyncJobResult: - job: Job - result_comm: Comm - async_data: PyGetAsync - - @property - def complete(self) -> bool: - return self.result_comm.test() - - @property - def status(self) -> str: - return "complete" if self.complete else "pending" - - -def client(client_id: str, jobs: List[float], wait_timeout: float): - worker_mailbox: Mailbox = Mailbox.by_name("worker") - this_actor.info(f"{client_id} started") - async_job_results: list[AsyncJobResult] = [] - for job_idx, job_duration in enumerate(jobs): - result_mailbox: Mailbox = Mailbox.by_name(str(uuid4())) - job = Job(job_id=f"job-{job_idx}", duration=job_duration, result_mailbox=result_mailbox) - out_comm = worker_mailbox.put_init(Job( - job_id=f"job-{job_idx}", - duration=job_duration, - result_mailbox=result_mailbox - ), SIMULATED_JOB_SIZE_BYTES) - out_comm.detach() - result_comm, async_data = result_mailbox.get_async() - async_job_results.append(AsyncJobResult( - job=job, - result_comm=result_comm, - async_data=async_data - )) - this_actor.info(f"awaiting results for all jobs (timeout={wait_timeout}s)") - completed_comms = Comm.wait_all_for([entry.result_comm for entry in async_job_results], wait_timeout) - logger = this_actor.warning if completed_comms < len(async_job_results) else this_actor.info - logger(f"received {completed_comms}/{len(async_job_results)} results") - for result in async_job_results: - this_actor.info(f"{result.job.job_id}" - f" status={result.status}" - f" result_payload={result.async_data.get() if result.complete else ''}") - - -def main(): - settings = create_parser().parse_known_args()[0] - e = Engine(sys.argv) - e.load_platform(settings.platform) - Actor.create("client", Host.by_name("Tremblay"), client, "client", settings.jobs, settings.wait_timeout) - for worker_idx in range(settings.workers): - Actor.create("worker", Host.by_name("Ruby"), worker, f"worker-{worker_idx}").daemonize() - e.run() - - -if __name__ == "__main__": - main() diff --git a/examples/python/comm-waitallfor/comm-waitallfor.tesh b/examples/python/comm-waitallfor/comm-waitallfor.tesh deleted file mode 100644 index 50cc88c625..0000000000 --- a/examples/python/comm-waitallfor/comm-waitallfor.tesh +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env tesh - -p Testing Comm.wait_all_for() - -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-waitallfor.py --platform ${platfdir}/small_platform_fatpipe.xml --workers 1 --wait-timeout 1 --jobs 1,2,3,4,5 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" ->[ 0.000000] (2:worker@Ruby) worker-0 started ->[ 0.000000] (1:client@Tremblay) client started ->[ 0.000000] (1:client@Tremblay) awaiting results for all jobs (timeout=1.0s) ->[ 0.001954] (2:worker@Ruby) worker-0 working on job-0 (will take 1.0s to complete) ->[ 1.000000] (1:client@Tremblay) received 0/5 results ->[ 1.000000] (1:client@Tremblay) job-0 status=pending result_payload= ->[ 1.000000] (1:client@Tremblay) job-1 status=pending result_payload= ->[ 1.000000] (1:client@Tremblay) job-2 status=pending result_payload= ->[ 1.000000] (1:client@Tremblay) job-3 status=pending result_payload= ->[ 1.000000] (1:client@Tremblay) job-4 status=pending result_payload= - -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-waitallfor.py --platform ${platfdir}/small_platform_fatpipe.xml --workers 1 --wait-timeout 5 --jobs 1,2,3,4,5 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" ->[ 0.000000] (2:worker@Ruby) worker-0 started ->[ 0.000000] (1:client@Tremblay) client started ->[ 0.000000] (1:client@Tremblay) awaiting results for all jobs (timeout=5.0s) ->[ 0.001954] (2:worker@Ruby) worker-0 working on job-0 (will take 1.0s to complete) ->[ 1.008029] (2:worker@Ruby) worker-0 working on job-1 (will take 2.0s to complete) ->[ 3.014105] (2:worker@Ruby) worker-0 working on job-2 (will take 3.0s to complete) ->[ 5.000000] (1:client@Tremblay) received 2/5 results ->[ 5.000000] (1:client@Tremblay) job-0 status=complete result_payload=worker-0 ->[ 5.000000] (1:client@Tremblay) job-1 status=complete result_payload=worker-0 ->[ 5.000000] (1:client@Tremblay) job-2 status=pending result_payload= ->[ 5.000000] (1:client@Tremblay) job-3 status=pending result_payload= ->[ 5.000000] (1:client@Tremblay) job-4 status=pending result_payload= - -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-waitallfor.py --platform ${platfdir}/small_platform_fatpipe.xml --workers 1 --wait-timeout -1 --jobs 1,2,3,4,5 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" ->[ 0.000000] (2:worker@Ruby) worker-0 started ->[ 0.000000] (1:client@Tremblay) client started ->[ 0.000000] (1:client@Tremblay) awaiting results for all jobs (timeout=-1.0s) ->[ 0.001954] (2:worker@Ruby) worker-0 working on job-0 (will take 1.0s to complete) ->[ 1.008029] (2:worker@Ruby) worker-0 working on job-1 (will take 2.0s to complete) ->[ 3.014105] (2:worker@Ruby) worker-0 working on job-2 (will take 3.0s to complete) ->[ 6.020181] (2:worker@Ruby) worker-0 working on job-3 (will take 4.0s to complete) ->[ 10.026257] (2:worker@Ruby) worker-0 working on job-4 (will take 5.0s to complete) ->[ 15.030379] (1:client@Tremblay) received 5/5 results ->[ 15.030379] (1:client@Tremblay) job-0 status=complete result_payload=worker-0 ->[ 15.030379] (1:client@Tremblay) job-1 status=complete result_payload=worker-0 ->[ 15.030379] (1:client@Tremblay) job-2 status=complete result_payload=worker-0 ->[ 15.030379] (1:client@Tremblay) job-3 status=complete result_payload=worker-0 ->[ 15.030379] (1:client@Tremblay) job-4 status=complete result_payload=worker-0 - -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-waitallfor.py --platform ${platfdir}/small_platform_fatpipe.xml --workers 5 --wait-timeout 3 --jobs 1,2,3,4,5 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" ->[ 0.000000] (2:worker@Ruby) worker-0 started ->[ 0.000000] (3:worker@Ruby) worker-1 started ->[ 0.000000] (4:worker@Ruby) worker-2 started ->[ 0.000000] (5:worker@Ruby) worker-3 started ->[ 0.000000] (6:worker@Ruby) worker-4 started ->[ 0.000000] (1:client@Tremblay) client started ->[ 0.000000] (1:client@Tremblay) awaiting results for all jobs (timeout=3.0s) ->[ 0.001954] (6:worker@Ruby) worker-4 working on job-4 (will take 5.0s to complete) ->[ 0.001954] (5:worker@Ruby) worker-3 working on job-3 (will take 4.0s to complete) ->[ 0.001954] (4:worker@Ruby) worker-2 working on job-2 (will take 3.0s to complete) ->[ 0.001954] (3:worker@Ruby) worker-1 working on job-1 (will take 2.0s to complete) ->[ 0.001954] (2:worker@Ruby) worker-0 working on job-0 (will take 1.0s to complete) ->[ 3.000000] (1:client@Tremblay) received 2/5 results ->[ 3.000000] (1:client@Tremblay) job-0 status=complete result_payload=worker-0 ->[ 3.000000] (1:client@Tremblay) job-1 status=complete result_payload=worker-1 ->[ 3.000000] (1:client@Tremblay) job-2 status=pending result_payload= ->[ 3.000000] (1:client@Tremblay) job-3 status=pending result_payload= ->[ 3.000000] (1:client@Tremblay) job-4 status=pending result_payload= - -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-waitallfor.py --platform ${platfdir}/small_platform_fatpipe.xml --workers 5 --wait-timeout -1 --jobs 5,10,5,20,5,40,5,80,5,160 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" ->[ 0.000000] (2:worker@Ruby) worker-0 started ->[ 0.000000] (3:worker@Ruby) worker-1 started ->[ 0.000000] (4:worker@Ruby) worker-2 started ->[ 0.000000] (5:worker@Ruby) worker-3 started ->[ 0.000000] (6:worker@Ruby) worker-4 started ->[ 0.000000] (1:client@Tremblay) client started ->[ 0.000000] (1:client@Tremblay) awaiting results for all jobs (timeout=-1.0s) ->[ 0.001954] (6:worker@Ruby) worker-4 working on job-4 (will take 5.0s to complete) ->[ 0.001954] (5:worker@Ruby) worker-3 working on job-3 (will take 20.0s to complete) ->[ 0.001954] (4:worker@Ruby) worker-2 working on job-2 (will take 5.0s to complete) ->[ 0.001954] (3:worker@Ruby) worker-1 working on job-1 (will take 10.0s to complete) ->[ 0.001954] (2:worker@Ruby) worker-0 working on job-0 (will take 5.0s to complete) ->[ 5.008029] (2:worker@Ruby) worker-0 working on job-7 (will take 80.0s to complete) ->[ 5.008029] (4:worker@Ruby) worker-2 working on job-6 (will take 5.0s to complete) ->[ 5.008029] (6:worker@Ruby) worker-4 working on job-5 (will take 40.0s to complete) ->[ 10.008029] (3:worker@Ruby) worker-1 working on job-8 (will take 5.0s to complete) ->[ 10.014105] (4:worker@Ruby) worker-2 working on job-9 (will take 160.0s to complete) ->[170.018227] (1:client@Tremblay) received 10/10 results ->[170.018227] (1:client@Tremblay) job-0 status=complete result_payload=worker-0 ->[170.018227] (1:client@Tremblay) job-1 status=complete result_payload=worker-1 ->[170.018227] (1:client@Tremblay) job-2 status=complete result_payload=worker-2 ->[170.018227] (1:client@Tremblay) job-3 status=complete result_payload=worker-3 ->[170.018227] (1:client@Tremblay) job-4 status=complete result_payload=worker-4 ->[170.018227] (1:client@Tremblay) job-5 status=complete result_payload=worker-4 ->[170.018227] (1:client@Tremblay) job-6 status=complete result_payload=worker-2 ->[170.018227] (1:client@Tremblay) job-7 status=complete result_payload=worker-0 ->[170.018227] (1:client@Tremblay) job-8 status=complete result_payload=worker-1 ->[170.018227] (1:client@Tremblay) job-9 status=complete result_payload=worker-2 diff --git a/examples/python/comm-waitany/comm-waitany.py b/examples/python/comm-waitany/comm-waitany.py deleted file mode 100644 index d19c590b05..0000000000 --- a/examples/python/comm-waitany/comm-waitany.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the license (GNU LGPL) which comes with this package. - -""" -This example shows how to block on the completion of a set of communications. - -As for the other asynchronous examples, the sender initiate all the messages it wants to send and -pack the resulting simgrid.Comm objects in a list. All messages thus occur concurrently. - -The sender then loops until there is no ongoing communication. Using wait_any() ensures that the sender -will notice events as soon as they occur even if it does not follow the order of the container. - -Here, finalize messages will terminate earlier because their size is 0, so they travel faster than the -other messages of this application. As expected, the trace shows that the finalize of worker 1 is -processed before 'Message 5' that is sent to worker 0. -""" - -import sys -from simgrid import Actor, Comm, Engine, Host, Mailbox, this_actor - - -def sender(messages_count, msg_size, receivers_count): - # List in which we store all ongoing communications - pending_comms = [] - - # Vector of the used mailboxes - mboxes = [Mailbox.by_name("receiver-{:d}".format(i)) - for i in range(0, receivers_count)] - - # Start dispatching all messages to receivers, in a round robin fashion - for i in range(0, messages_count): - content = "Message {:d}".format(i) - mbox = mboxes[i % receivers_count] - - this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox))) - - # Create a communication representing the ongoing communication, and store it in pending_comms - comm = mbox.put_async(content, msg_size) - pending_comms.append(comm) - - # Start sending messages to let the workers know that they should stop - for i in range(0, receivers_count): - mbox = mboxes[i] - this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox))) - comm = mbox.put_async("finalize", 0) - pending_comms.append(comm) - - this_actor.info("Done dispatching all messages") - - # Now that all message exchanges were initiated, wait for their completion, in order of completion. - # - # This loop waits for first terminating message with wait_any() and remove it with del, until all comms are - # terminated. - # Even in this simple example, the pending comms do not terminate in the exact same order of creation. - while pending_comms: - changed_pos = Comm.wait_any(pending_comms) - del pending_comms[changed_pos] - if changed_pos != 0: - this_actor.info( - "Remove the {:d}th pending comm: it terminated earlier than another comm that was initiated first." - .format(changed_pos)) - - this_actor.info("Goodbye now!") - - -def receiver(my_id): - mbox = Mailbox.by_name("receiver-{:d}".format(my_id)) - this_actor.info("Wait for my first message") - while True: - received = mbox.get() - this_actor.info("I got a '{:s}'.".format(received)) - if received == "finalize": - break # If it's a finalize message, we're done. - -if __name__ == '__main__': - e = Engine(sys.argv) - - # Load the platform description - e.load_platform(sys.argv[1]) - - Actor.create("sender", Host.by_name("Tremblay"), sender, 6, 1000000, 2) - Actor.create("receiver", Host.by_name("Fafard"), receiver, 0) - Actor.create("receiver", Host.by_name("Jupiter"), receiver, 1) - - e.run() diff --git a/examples/python/comm-waitany/comm-waitany.tesh b/examples/python/comm-waitany/comm-waitany.tesh deleted file mode 100644 index d4593c1ac0..0000000000 --- a/examples/python/comm-waitany/comm-waitany.tesh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env tesh - -p Testing Comm.wait_any() - -! output sort 19 -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-waitany.py ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (1:sender@Tremblay) Send 'Message 0' to 'Mailbox(receiver-0)' -> [ 0.000000] (2:receiver@Fafard) Wait for my first message -> [ 0.000000] (3:receiver@Jupiter) Wait for my first message -> [ 0.000000] (1:sender@Tremblay) Send 'Message 1' to 'Mailbox(receiver-1)' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 2' to 'Mailbox(receiver-0)' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 3' to 'Mailbox(receiver-1)' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 4' to 'Mailbox(receiver-0)' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 5' to 'Mailbox(receiver-1)' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-0)' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-1)' -> [ 0.000000] (1:sender@Tremblay) Done dispatching all messages -> [ 0.158397] (2:receiver@Fafard) I got a 'Message 0'. -> [ 0.169155] (3:receiver@Jupiter) I got a 'Message 1'. -> [ 0.316794] (2:receiver@Fafard) I got a 'Message 2'. -> [ 0.338309] (3:receiver@Jupiter) I got a 'Message 3'. -> [ 0.475190] (2:receiver@Fafard) I got a 'Message 4'. -> [ 0.500898] (2:receiver@Fafard) I got a 'finalize'. -> [ 0.500898] (1:sender@Tremblay) Remove the 1th pending comm: it terminated earlier than another comm that was initiated first. -> [ 0.507464] (3:receiver@Jupiter) I got a 'Message 5'. -> [ 0.526478] (3:receiver@Jupiter) I got a 'finalize'. -> [ 0.526478] (1:sender@Tremblay) Goodbye now! diff --git a/examples/python/comm-waitfor/comm-waitfor.py b/examples/python/comm-waitfor/comm-waitfor.py deleted file mode 100644 index 9624a75351..0000000000 --- a/examples/python/comm-waitfor/comm-waitfor.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the license (GNU LGPL) which comes with this package. - -""" -This example shows how to block on the completion of a set of communications. - -As for the other asynchronous examples, the sender initiate all the messages it wants to send and -pack the resulting simgrid.Comm objects in a list. All messages thus occur concurrently. - -The sender then loops until there is no ongoing communication. Using wait_any() ensures that the sender -will notice events as soon as they occur even if it does not follow the order of the container. - -Here, finalize messages will terminate earlier because their size is 0, so they travel faster than the -other messages of this application. As expected, the trace shows that the finalize of worker 1 is -processed before 'Message 5' that is sent to worker 0. -""" - -import sys -from simgrid import Actor, Comm, Engine, Host, Mailbox, this_actor - - -FINALIZE_TAG = "finalize" - - -def sender(receiver_id: str, messages_count: int, payload_size: int) -> None: - # List in which we store all ongoing communications - pending_comms = [] - mbox = Mailbox.by_name(receiver_id) - - # Asynchronously send `messages_count` message(s) to the receiver - for i in range(0, messages_count): - payload = "Message {:d}".format(i) - this_actor.info("Send '{:s}' to '{:s}'".format(payload, receiver_id)) - - # Create a communication representing the ongoing communication, and store it in pending_comms - comm = mbox.put_async(payload, payload_size) - pending_comms.append(comm) - - # Send the final message to the receiver - payload = FINALIZE_TAG - final_payload_size = 0 - final_comm = mbox.put_async(payload, final_payload_size) - pending_comms.append(final_comm) - this_actor.info("Send '{:s}' to '{:s}".format(payload, receiver_id)) - this_actor.info("Done dispatching all messages") - - this_actor.info("Waiting for all outstanding communications to complete") - while pending_comms: - current_comm: Comm = pending_comms[-1] - current_comm.wait_for(1.0) - pending_comms.pop() - this_actor.info("Goodbye now!") - - -def receiver(identifier: str) -> None: - mbox: Mailbox = Mailbox.by_name(identifier) - this_actor.info("Wait for my first message") - while True: - received = mbox.get() - this_actor.info("I got a '{:s}'.".format(received)) - if received == FINALIZE_TAG: - break - this_actor.info("Goodbye now!") - - -def main(): - e = Engine(sys.argv) - - # Load the platform description - e.load_platform(sys.argv[1]) - - receiver_id = "receiver-0" - Actor.create("sender", Host.by_name("Tremblay"), sender, receiver_id, 3, int(5e7)) - Actor.create("receiver", Host.by_name("Ruby"), receiver, receiver_id) - - e.run() - - -if __name__ == '__main__': - main() diff --git a/examples/python/comm-waitfor/comm-waitfor.tesh b/examples/python/comm-waitfor/comm-waitfor.tesh deleted file mode 100644 index b326fcb7db..0000000000 --- a/examples/python/comm-waitfor/comm-waitfor.tesh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env tesh - -p Testing Comm.wait_any() - -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-waitfor.py ${platfdir}/small_platform_fatpipe.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (1:sender@Tremblay) Send 'Message 0' to 'receiver-0' -> [ 0.000000] (2:receiver@Ruby) Wait for my first message -> [ 0.000000] (1:sender@Tremblay) Send 'Message 1' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'Message 2' to 'receiver-0' -> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-0 -> [ 0.000000] (1:sender@Tremblay) Done dispatching all messages -> [ 0.000000] (1:sender@Tremblay) Waiting for all outstanding communications to complete -> [ 0.105458] (2:receiver@Ruby) I got a 'Message 0'. -> [ 0.210917] (2:receiver@Ruby) I got a 'Message 1'. -> [ 0.316375] (2:receiver@Ruby) I got a 'Message 2'. -> [ 0.318326] (2:receiver@Ruby) I got a 'finalize'. -> [ 0.318326] (2:receiver@Ruby) Goodbye now! -> [ 0.318326] (1:sender@Tremblay) Goodbye now! diff --git a/examples/python/comm-waituntil/comm-waituntil.py b/examples/python/comm-waituntil/comm-waituntil.py index 0209dc86a1..0f2bdf8362 100644 --- a/examples/python/comm-waituntil/comm-waituntil.py +++ b/examples/python/comm-waituntil/comm-waituntil.py @@ -1,9 +1,9 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. -""" This example shows how to suspend and resume an asynchronous communication. +""" This example demonstrates Comm.wait_for() and Comm.wait_until to set timeouts on waits. """ from argparse import ArgumentParser @@ -47,7 +47,7 @@ def sender(receiver_mailbox: Mailbox, messages_count: int, payload_size: int): # Now that all message exchanges were initiated, wait for their completion, in order of creation while pending_comms: comm = pending_comms[-1] - comm.wait_until(Engine.clock + 1) + comm.wait_until(Engine.clock + 1) # same as: current_comm.wait_for(1.0) pending_comms.pop() # remove it from the list this_actor.info("Goodbye now!") diff --git a/examples/python/exec-async/exec-async.py b/examples/python/exec-async/exec-async.py index 707d03d100..5892dca6ea 100644 --- a/examples/python/exec-async/exec-async.py +++ b/examples/python/exec-async/exec-async.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. # # This program is free software you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/exec-basic/exec-basic.py b/examples/python/exec-basic/exec-basic.py index 754fe7168f..2f8d1dfc74 100644 --- a/examples/python/exec-basic/exec-basic.py +++ b/examples/python/exec-basic/exec-basic.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/exec-cpu-nonlinear/exec-cpu-nonlinear.py b/examples/python/exec-cpu-nonlinear/exec-cpu-nonlinear.py index d4d9498ec0..2fa4294fc4 100644 --- a/examples/python/exec-cpu-nonlinear/exec-cpu-nonlinear.py +++ b/examples/python/exec-cpu-nonlinear/exec-cpu-nonlinear.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/exec-dvfs/exec-dvfs.py b/examples/python/exec-dvfs/exec-dvfs.py index f8d8dffc73..fa5e4571fb 100644 --- a/examples/python/exec-dvfs/exec-dvfs.py +++ b/examples/python/exec-dvfs/exec-dvfs.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/exec-dvfs/exec-dvfs.tesh b/examples/python/exec-dvfs/exec-dvfs.tesh index 06bd1904af..7055274dbf 100644 --- a/examples/python/exec-dvfs/exec-dvfs.tesh +++ b/examples/python/exec-dvfs/exec-dvfs.tesh @@ -9,9 +9,9 @@ $ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/exec-dvfs.py ${pla > [ 0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000 > [ 1.000000] (1:dvfs_test@MyHost1) Task1 duration: 1.00 > [ 1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2) +> [ 1.000000] (1:dvfs_test@MyHost1) Changed power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Task1 duration: 1.00 > [ 1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2) -> [ 1.000000] (1:dvfs_test@MyHost1) Changed power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Changed power peak=20000000.000000 > [ 6.000000] (1:dvfs_test@MyHost1) Task2 duration: 5.00 > [ 6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3 @@ -27,9 +27,9 @@ $ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/exec-dvfs.py ${pla > [ 0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000 > [ 1.000000] (1:dvfs_test@MyHost1) Task1 duration: 1.00 > [ 1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2) +> [ 1.000000] (1:dvfs_test@MyHost1) Changed power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Task1 duration: 1.00 > [ 1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2) -> [ 1.000000] (1:dvfs_test@MyHost1) Changed power peak=20000000.000000 > [ 1.000000] (2:dvfs_test@MyHost2) Changed power peak=20000000.000000 > [ 6.000000] (1:dvfs_test@MyHost1) Task2 duration: 5.00 > [ 6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3 diff --git a/examples/python/exec-ptask/exec-ptask.py b/examples/python/exec-ptask/exec-ptask.py index 4b2da92feb..fa0a2c2154 100644 --- a/examples/python/exec-ptask/exec-ptask.py +++ b/examples/python/exec-ptask/exec-ptask.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/exec-remote/exec-remote.py b/examples/python/exec-remote/exec-remote.py index 2e4f2b93c1..e8625bfd7e 100644 --- a/examples/python/exec-remote/exec-remote.py +++ b/examples/python/exec-remote/exec-remote.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. # # This program is free software you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/io-degradation/io-degradation.py b/examples/python/io-degradation/io-degradation.py index f6b60429c5..ae5ff1e5c1 100644 --- a/examples/python/io-degradation/io-degradation.py +++ b/examples/python/io-degradation/io-degradation.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/network-nonlinear/network-nonlinear.py b/examples/python/network-nonlinear/network-nonlinear.py index 40cb0b7035..40df779d7a 100644 --- a/examples/python/network-nonlinear/network-nonlinear.py +++ b/examples/python/network-nonlinear/network-nonlinear.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -9,7 +9,7 @@ This example shows how to simulate a non-linear resource sharing for network lin import functools import sys -from simgrid import Actor, Engine, Comm, Mailbox, NetZone, Link, LinkInRoute, this_actor +from simgrid import Actor, ActivitySet, Engine, Comm, Mailbox, NetZone, Link, LinkInRoute, this_actor class Sender: """ @@ -22,7 +22,7 @@ class Sender: # Actors that are created as object will execute their __call__ method. # So, the following constitutes the main function of the Sender actor. def __call__(self): - pending_comms = [] + pending_comms = ActivitySet() mbox = Mailbox.by_name("receiver") for i in range(self.msg_count): @@ -30,12 +30,12 @@ class Sender: size = self.msg_size * (i + 1) this_actor.info("Send '%s' to '%s, msg size: %d'" % (msg, mbox.name, size)) comm = mbox.put_async(msg, size) - pending_comms.append(comm) + pending_comms.push(comm) this_actor.info("Done dispatching all messages") # Now that all message exchanges were initiated, wait for their completion in one single call - Comm.wait_all(pending_comms) + pending_comms.wait_all() this_actor.info("Goodbye now!") @@ -50,21 +50,16 @@ class Receiver: def __call__(self): mbox = Mailbox.by_name("receiver") - pending_msgs = [] - pending_comms = [] + pending_comms = ActivitySet() this_actor.info("Wait for %d messages asynchronously" % self.msg_count) for _ in range(self.msg_count): - comm, data = mbox.get_async() - pending_comms.append(comm) - pending_msgs.append(data) + comm = mbox.get_async() + pending_comms.push(comm) - while pending_comms: - index = Comm.wait_any(pending_comms) - msg = pending_msgs[index].get() - this_actor.info("I got '%s'." % msg) - del pending_comms[index] - del pending_msgs[index] + while not pending_comms.empty(): + comm = pending_comms.wait_any() + this_actor.info("I got '%s'." % comm.get_payload()) #################################################################################################### def link_nonlinear(link: Link, capacity: float, n: int) -> float: @@ -104,8 +99,7 @@ def load_platform(): link.set_latency(10e-6).seal() # create routes between nodes - zone.add_route(sender.netpoint, receiver.netpoint, None, None, - [LinkInRoute(link, LinkInRoute.Direction.UP)], True) + zone.add_route(sender, receiver, [link]) zone.seal() # create actors Sender/Receiver diff --git a/examples/python/comm-serialize/comm-serialize.py b/examples/python/platform-comm-serialize/platform-comm-serialize.py similarity index 73% rename from examples/python/comm-serialize/comm-serialize.py rename to examples/python/platform-comm-serialize/platform-comm-serialize.py index f3e8ef13db..f221f492ce 100644 --- a/examples/python/comm-serialize/comm-serialize.py +++ b/examples/python/platform-comm-serialize/platform-comm-serialize.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -6,7 +6,7 @@ from typing import List, Tuple import sys -from simgrid import Engine, Actor, Comm, Host, LinkInRoute, Mailbox, NetZone, this_actor, PyGetAsync +from simgrid import Engine, Actor, ActivitySet, Comm, Host, LinkInRoute, Mailbox, NetZone, this_actor RECEIVER_MAILBOX_NAME = "receiver" @@ -19,7 +19,7 @@ class Sender(object): def __call__(self) -> None: # List in which we store all ongoing communications - pending_comms: List[Comm] = [] + pending_comms = ActivitySet() # Make a vector of the mailboxes to use receiver_mailbox: Mailbox = Mailbox.by_name(RECEIVER_MAILBOX_NAME) @@ -27,12 +27,12 @@ class Sender(object): message_content = f"Message {i}" this_actor.info(f"Send '{message_content}' to '{receiver_mailbox.name}'") # Create a communication representing the ongoing communication, and store it in pending_comms - pending_comms.append(receiver_mailbox.put_async(message_content, self.message_size)) + pending_comms.push(receiver_mailbox.put_async(message_content, self.message_size)) this_actor.info("Done dispatching all messages") # Now that all message exchanges were initiated, wait for their completion in one single call - Comm.wait_all(pending_comms) + pending_comms.wait_all() this_actor.info("Goodbye now!") @@ -44,15 +44,13 @@ class Receiver(object): def __call__(self): # List in which we store all incoming msgs - pending_comms: List[Tuple[Comm, PyGetAsync]] = [] + pending_comms = ActivitySet() this_actor.info(f"Wait for {self.messages_count} messages asynchronously") for _ in range(self.messages_count): - pending_comms.append(self.mailbox.get_async()) - while pending_comms: - index = Comm.wait_any([comm for (comm, _) in pending_comms]) - _, async_data = pending_comms[index] - this_actor.info(f"I got '{async_data.get()}'.") - pending_comms.pop(index) + pending_comms.push(self.mailbox.get_async()) + while not pending_comms.empty(): + comm = pending_comms.wait_any() + this_actor.info(f"I got '{comm.get_payload()}'.") def main(): @@ -70,14 +68,7 @@ def main(): link = zone.create_split_duplex_link("link1", 10e9).set_latency(10e-6).set_concurrency_limit(2).seal() # create routes between nodes - zone.add_route( - sender_host.netpoint, - receiver_host.netpoint, - None, - None, - [LinkInRoute(link, LinkInRoute.UP)], - True - ) + zone.add_route(sender_host, receiver_host, [link]) zone.seal() # create actors Sender/Receiver diff --git a/examples/python/comm-serialize/comm-serialize.tesh b/examples/python/platform-comm-serialize/platform-comm-serialize.tesh similarity index 91% rename from examples/python/comm-serialize/comm-serialize.tesh rename to examples/python/platform-comm-serialize/platform-comm-serialize.tesh index 0a0174850e..f889c935e8 100644 --- a/examples/python/comm-serialize/comm-serialize.tesh +++ b/examples/python/platform-comm-serialize/platform-comm-serialize.tesh @@ -1,6 +1,6 @@ #!/usr/bin/env tesh -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/comm-serialize.py "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/platform-comm-serialize.py "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" >[ 0.000000] (1:receiver@receiver) Wait for 10 messages asynchronously >[ 0.000000] (2:sender@sender) Send 'Message 0' to 'receiver' >[ 0.000000] (2:sender@sender) Send 'Message 1' to 'receiver' diff --git a/examples/python/platform-failures/platform-failures.py b/examples/python/platform-failures/platform-failures.py index a94446642f..9850ab45c7 100644 --- a/examples/python/platform-failures/platform-failures.py +++ b/examples/python/platform-failures/platform-failures.py @@ -1,4 +1,4 @@ -## Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. +## Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -82,7 +82,7 @@ def sleeper(): this_actor.info("done sleeping.") if __name__ == '__main__': - assert len(sys.argv) > 2, f"Usage: python app-masterworkers.py platform_file deployment_file" + assert len(sys.argv) > 2, "Usage: python app-masterworkers.py platform_file deployment_file" e = Engine(sys.argv) diff --git a/examples/python/platform-failures/platform-failures.tesh b/examples/python/platform-failures/platform-failures.tesh index 54bfd27b7f..2ab163e63b 100644 --- a/examples/python/platform-failures/platform-failures.tesh +++ b/examples/python/platform-failures/platform-failures.tesh @@ -3,7 +3,7 @@ p Testing a simple master/workers example application handling failures ! output sort 19 -$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/platform-failures.py ${platfdir}/small_platform_failures.xml ${srcdir:=.}/platform-failures_d.xml --log=xbt_cfg.thres:critical --log=no_loc --cfg=path:${srcdir} --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/platform-failures.py ${platfdir}/small_platform_failures.xml ${srcdir:=.}/platform-failures_d.xml --log=xbt_cfg.thres:critical --log=no_loc --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose > [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard' > [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off. > [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process diff --git a/examples/python/platform-profile/platform-profile.py b/examples/python/platform-profile/platform-profile.py index 680d265457..6bf23d9079 100644 --- a/examples/python/platform-profile/platform-profile.py +++ b/examples/python/platform-profile/platform-profile.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/plugin-host-load/plugin-host-load.py b/examples/python/plugin-host-load/plugin-host-load.py new file mode 100644 index 0000000000..71d3ac8f4c --- /dev/null +++ b/examples/python/plugin-host-load/plugin-host-load.py @@ -0,0 +1,87 @@ +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + + +from argparse import ArgumentParser +import sys +from simgrid import Engine, Host, this_actor, Actor, sg_host_load_plugin_init + +def parse(): + parser = ArgumentParser() + parser.add_argument( + '--platform', + type=str, + required=True, + help='path to the platform description' + ) + return parser.parse_args() + +def execute_load_test(): + host = Host.by_name('MyHost1') + this_actor.info(f'Initial peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E} (should be 0) and current average load: {host.avg_load} (should be 0)') + + start = Engine.clock + this_actor.info('Sleep for 10 seconds') + this_actor.sleep_for(10) + + speed = host.speed + this_actor.info(f'Done sleeping {Engine.clock - start}s; peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E} (nothing should have changed)') + + # Run an activity + start = e.clock + this_actor.info(f'Run an activity of {200E6:.0E} flops at current speed of {host.speed:.0E} flop/s') + this_actor.execute(200E6) + + this_actor.info(f'Done working on my activity; this took {Engine.clock - start}s; current peak speed: {host.speed:.0E} flop/s (when I started the computation, \ +the speed was set to {speed:.0E} flop/s); number of flops computed so \ +far: {host.computed_flops:.0E}, average load as reported by the HostLoad plugin: {host.avg_load:.5f} (should be {200E6 / (10.5 * speed * host.core_count + (Engine.clock - start - 0.5) * host.speed * host.core_count):.5f})') + + # ========= Change power peak ========= + pstate = 1 + host.pstate = pstate + this_actor.info(f'========= Requesting pstate {pstate} (speed should be of {host.pstate_speed(pstate):.0E} flop/s and is of {host.speed:.0E} flop/s, average load is {host.avg_load:.5f})') + + # Run a second activity + start = Engine.clock + this_actor.info(f'Run an activity of {100E6:.0E} flops') + this_actor.execute(100E6) + this_actor.info(f'Done working on my activity; this took {Engine.clock - start}s; current peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E}') + + start = Engine.clock + this_actor.info("========= Requesting a reset of the computation and load counters") + host.reset_load() + this_actor.info(f'After reset: {host.computed_flops:.0E} flops computed; load is {host.avg_load}') + this_actor.info('Sleep for 4 seconds') + this_actor.sleep_for(4) + this_actor.info(f'Done sleeping {Engine.clock - start}s; peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E}') + + # =========== Turn the other host off ========== + host2 = Host.by_name('MyHost2') + this_actor.info(f'Turning MyHost2 off, and sleeping another 10 seconds. MyHost2 computed {host2.computed_flops:.0E} flops so far and has an average load of {host2.avg_load}') + host2.turn_off() + start = Engine.clock + this_actor.sleep_for(10) + this_actor.info(f'Done sleeping {Engine.clock - start}s; peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E}') + +def change_speed(): + host = Host.by_name('MyHost1') + this_actor.sleep_for(10.5) + this_actor.info("I slept until now, but now I'll change the speed of this host while the other actor is still computing! This should slow the computation down.") + host.pstate = 2 + +if __name__ == '__main__': + args = parse() + + sg_host_load_plugin_init() + e = Engine(sys.argv) + e.load_platform(args.platform) + + Actor.create('load_test', e.host_by_name('MyHost1'), execute_load_test) + Actor.create('change_speed', e.host_by_name('MyHost1'), change_speed) + + e.run() + + this_actor.info(f'Total simulation time: {Engine.clock}') + diff --git a/examples/python/plugin-host-load/plugin-host-load.tesh b/examples/python/plugin-host-load/plugin-host-load.tesh new file mode 100644 index 0000000000..ad14d1915e --- /dev/null +++ b/examples/python/plugin-host-load/plugin-host-load.tesh @@ -0,0 +1,21 @@ +#!/usr/bin/env tesh + +p This tests the Host Load plugin (that allows the user to get the current load of a host and the computed flops) + +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/plugin-host-load.py --platform ${platfdir}/energy_platform.xml +> [MyHost1:load_test:(1) 0.000000] [python/INFO] Initial peak speed: 1E+08 flop/s; number of flops computed so far: 0E+00 (should be 0) and current average load: 0.0 (should be 0) +> [MyHost1:load_test:(1) 0.000000] [python/INFO] Sleep for 10 seconds +> [MyHost1:load_test:(1) 10.000000] [python/INFO] Done sleeping 10.0s; peak speed: 1E+08 flop/s; number of flops computed so far: 0E+00 (nothing should have changed) +> [MyHost1:load_test:(1) 10.000000] [python/INFO] Run an activity of 2E+08 flops at current speed of 1E+08 flop/s +> [MyHost1:change_speed:(2) 10.500000] [python/INFO] I slept until now, but now I'll change the speed of this host while the other actor is still computing! This should slow the computation down. +> [MyHost1:load_test:(1) 18.000000] [python/INFO] Done working on my activity; this took 8.0s; current peak speed: 2E+07 flop/s (when I started the computation, the speed was set to 1E+08 flop/s); number of flops computed so far: 2E+08, average load as reported by the HostLoad plugin: 0.04167 (should be 0.04167) +> [MyHost1:load_test:(1) 18.000000] [python/INFO] ========= Requesting pstate 1 (speed should be of 5E+07 flop/s and is of 5E+07 flop/s, average load is 0.04167) +> [MyHost1:load_test:(1) 18.000000] [python/INFO] Run an activity of 1E+08 flops +> [MyHost1:load_test:(1) 20.000000] [python/INFO] Done working on my activity; this took 2.0s; current peak speed: 5E+07 flop/s; number of flops computed so far: 3E+08 +> [MyHost1:load_test:(1) 20.000000] [python/INFO] ========= Requesting a reset of the computation and load counters +> [MyHost1:load_test:(1) 20.000000] [python/INFO] After reset: 0E+00 flops computed; load is 0.0 +> [MyHost1:load_test:(1) 20.000000] [python/INFO] Sleep for 4 seconds +> [MyHost1:load_test:(1) 24.000000] [python/INFO] Done sleeping 4.0s; peak speed: 5E+07 flop/s; number of flops computed so far: 0E+00 +> [MyHost1:load_test:(1) 24.000000] [python/INFO] Turning MyHost2 off, and sleeping another 10 seconds. MyHost2 computed 0E+00 flops so far and has an average load of 0.0 +> [MyHost1:load_test:(1) 34.000000] [python/INFO] Done sleeping 10.0s; peak speed: 5E+07 flop/s; number of flops computed so far: 0E+00 +> [34.000000] [python/INFO] Total simulation time: 34.0 diff --git a/examples/python/synchro-barrier/synchro-barrier.py b/examples/python/synchro-barrier/synchro-barrier.py index b4cd4d90eb..6b81a1d7b0 100644 --- a/examples/python/synchro-barrier/synchro-barrier.py +++ b/examples/python/synchro-barrier/synchro-barrier.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -30,7 +30,7 @@ def worker(barrier: Barrier): """ Wait on the barrier and exits. :param barrier: Barrier to be awaited """ - this_actor.info(f"Waiting on the barrier") + this_actor.info("Waiting on the barrier") barrier.wait() this_actor.info("Bye") @@ -45,7 +45,7 @@ def master(actor_count: int): this_actor.info(f"Spawning {workers_count} workers") for i in range(workers_count): Actor.create(f"worker-{i}", Host.by_name("Jupiter"), worker, barrier) - this_actor.info(f"Waiting on the barrier") + this_actor.info("Waiting on the barrier") barrier.wait() this_actor.info("Bye") diff --git a/examples/python/synchro-mutex/synchro-mutex.py b/examples/python/synchro-mutex/synchro-mutex.py index fe84e47e80..1a202ba875 100644 --- a/examples/python/synchro-mutex/synchro-mutex.py +++ b/examples/python/synchro-mutex/synchro-mutex.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -35,9 +35,9 @@ class ResultHolder: def worker_context_manager(mutex: Mutex, result: ResultHolder): # When using a context manager, the lock and the unlock are automatic. This is the easiest approach with mutex: - this_actor.info(f"Hello simgrid, I'm ready to compute after acquiring the mutex from a context manager") + this_actor.info("Hello simgrid, I'm ready to compute after acquiring the mutex from a context manager") result.value += 1 - this_actor.info(f"I'm done, good bye") + this_actor.info("I'm done, good bye") def worker(mutex: Mutex, result: ResultHolder): diff --git a/examples/python/synchro-semaphore/synchro-semaphore.py b/examples/python/synchro-semaphore/synchro-semaphore.py index 58e5b162ea..3600af872b 100644 --- a/examples/python/synchro-semaphore/synchro-semaphore.py +++ b/examples/python/synchro-semaphore/synchro-semaphore.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/python/task-io/task-io.py b/examples/python/task-io/task-io.py new file mode 100644 index 0000000000..d3ab8c1b1d --- /dev/null +++ b/examples/python/task-io/task-io.py @@ -0,0 +1,50 @@ +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +from argparse import ArgumentParser +import sys +from simgrid import Engine, Task, ExecTask, IoTask, IoOpType + +def parse(): + parser = ArgumentParser() + parser.add_argument( + '--platform', + type=str, + required=True, + help='path to the platform description' + ) + return parser.parse_args() + +def callback(t): + print(f'[{Engine.clock}] {t} finished ({t.get_count()})') + +if __name__ == '__main__': + args = parse() + e = Engine(sys.argv) + e.load_platform(args.platform) + + # Retrieve hosts + bob = e.host_by_name('bob') + carl = e.host_by_name('carl') + + # Create tasks + exec1 = ExecTask.init("exec1", 1e9, bob) + exec2 = ExecTask.init("exec2", 1e9, carl) + write = IoTask.init("write", 1e7, bob.disks[0], IoOpType.WRITE) + read = IoTask.init("read", 1e7, carl.disks[0], IoOpType.READ) + + # Create the graph by defining dependencies between tasks + exec1.add_successor(write) + write.add_successor(read) + read.add_successor(exec2) + + # Add a function to be called when tasks end for log purpose + Task.on_completion_cb(callback) + + # Enqueue two firings for task exec1 + exec1.enqueue_firings(2) + + # runs the simulation + e.run() diff --git a/examples/python/task-io/task-io.tesh b/examples/python/task-io/task-io.tesh new file mode 100644 index 0000000000..c6e5691f3f --- /dev/null +++ b/examples/python/task-io/task-io.tesh @@ -0,0 +1,12 @@ +#!/usr/bin/env tesh + +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/task-io.py --platform ${platfdir}/hosts_with_disks.xml +> [1.0] ExecTask(exec1) finished (1) +> [1.25] IoTask(write) finished (1) +> [1.35] IoTask(read) finished (1) +> [2.0] ExecTask(exec1) finished (2) +> [2.25] IoTask(write) finished (2) +> [2.35] ExecTask(exec2) finished (1) +> [2.35] IoTask(read) finished (2) +> [3.35] ExecTask(exec2) finished (2) + diff --git a/examples/python/task-simple/task-simple.py b/examples/python/task-simple/task-simple.py new file mode 100644 index 0000000000..beca2b6a2c --- /dev/null +++ b/examples/python/task-simple/task-simple.py @@ -0,0 +1,58 @@ +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +""" +This example demonstrates basic use of the task plugin. +We model the following graph: + +exec1 -> comm -> exec2 + +exec1 and exec2 are execution tasks. +comm is a communication task. +""" + +from argparse import ArgumentParser +import sys +from simgrid import Engine, Task, CommTask, ExecTask + +def parse(): + parser = ArgumentParser() + parser.add_argument( + '--platform', + type=str, + required=True, + help='path to the platform description' + ) + return parser.parse_args() + +def callback(t): + print(f'[{Engine.clock}] {t} finished ({t.get_count()})') + +if __name__ == '__main__': + args = parse() + e = Engine(sys.argv) + e.load_platform(args.platform) + + # Retrieve hosts + tremblay = e.host_by_name('Tremblay') + jupiter = e.host_by_name('Jupiter') + + # Create tasks + exec1 = ExecTask.init("exec1", 1e9, tremblay) + exec2 = ExecTask.init("exec2", 1e9, jupiter) + comm = CommTask.init("comm", 1e7, tremblay, jupiter) + + # Create the graph by defining dependencies between tasks + exec1.add_successor(comm) + comm.add_successor(exec2) + + # Add a function to be called when tasks end for log purpose + Task.on_completion_cb(callback) + + # Enqueue two firings for task exec1 + exec1.enqueue_firings(2) + + # runs the simulation + e.run() diff --git a/examples/python/task-simple/task-simple.tesh b/examples/python/task-simple/task-simple.tesh new file mode 100644 index 0000000000..f9a828fe28 --- /dev/null +++ b/examples/python/task-simple/task-simple.tesh @@ -0,0 +1,9 @@ +#!/usr/bin/env tesh + +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/task-simple.py --platform ${platfdir}/small_platform.xml +> [10.194199500484224] ExecTask(exec1) finished (1) +> [11.714617112501687] CommTask(comm) finished (1) +> [20.388399000968448] ExecTask(exec1) finished (2) +> [21.90881661298591] CommTask(comm) finished (2) +> [24.821464129383305] ExecTask(exec2) finished (1) +> [37.928311146264925] ExecTask(exec2) finished (2) diff --git a/examples/python/task-switch-host/task-switch-host.py b/examples/python/task-switch-host/task-switch-host.py new file mode 100644 index 0000000000..03dce6a7fb --- /dev/null +++ b/examples/python/task-switch-host/task-switch-host.py @@ -0,0 +1,96 @@ +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +""" +This example demonstrates how to dynamically modify a graph of tasks. + +Assuming we have two instances of a service placed on different hosts, +we want to send data alternatively to thoses instances. + +We consider the following graph: + + comm1 + ┌────────────────────────┐ + │ │ + │ Fafard │ + │ ┌───────┐ │ + │ ┌──────►│ exec1 ├─┘ + ▼ │ └───────┘ + Tremblay ──┤comm0 + ▲ │ Jupiter + │ │ ┌───────┐ + │ └──────►│ exec2 ├─┐ + │ └───────┘ │ + │ │ + └────────────────────────┘ + comm2 + +""" + +from argparse import ArgumentParser +import sys +from simgrid import Engine, Task, CommTask, ExecTask + +def parse(): + parser = ArgumentParser() + parser.add_argument( + '--platform', + type=str, + required=True, + help='path to the platform description' + ) + return parser.parse_args() + +def callback(t): + print(f'[{Engine.clock}] {t} finished ({t.get_count()})') + +def switch_destination(t, hosts): + t.destination = hosts[switch_destination.count % 2] + switch_destination.count += 1 +switch_destination.count = 0 + +def switch_successor(t, execs): + t.remove_successor(execs[t.get_count() % 2]) + t.add_successor(execs[t.get_count() % 2 - 1]) + +if __name__ == '__main__': + args = parse() + e = Engine(sys.argv) + e.load_platform(args.platform) + + # Retrieve hosts + tremblay = e.host_by_name('Tremblay') + jupiter = e.host_by_name('Jupiter') + fafard = e.host_by_name('Fafard') + + # Create tasks + comm0 = CommTask.init("comm0") + comm0.bytes = 1e7 + comm0.source = tremblay + exec1 = ExecTask.init("exec1", 1e9, jupiter) + exec2 = ExecTask.init("exec2", 1e9, fafard) + comm1 = CommTask.init("comm1", 1e7, jupiter, tremblay) + comm2 = CommTask.init("comm2", 1e7, fafard, tremblay) + + # Create the initial graph by defining dependencies between tasks + exec1.add_successor(comm1) + exec2.add_successor(comm2) + + # Add a callback when tasks end for log purpose + Task.on_completion_cb(callback) + + # Add a callback before each firing of comm0 + # It switches the destination of comm0 + comm0.on_this_start_cb(lambda t: switch_destination(t, [jupiter, fafard])) + + # Add a callback before comm0 send tokens to successors + # It switches the successor of comm0 + comm0.on_this_completion_cb(lambda t: switch_successor(t, [exec1,exec2])) + + # Enqueue two firings for task exec1 + comm0.enqueue_firings(4) + + # runs the simulation + e.run() diff --git a/examples/python/task-switch-host/task-switch-host.tesh b/examples/python/task-switch-host/task-switch-host.tesh new file mode 100644 index 0000000000..e506de708b --- /dev/null +++ b/examples/python/task-switch-host/task-switch-host.tesh @@ -0,0 +1,15 @@ +#!/usr/bin/env tesh + +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/task-switch-host.py --platform ${platfdir}/small_platform.xml +> [1.5204176120174615] CommTask(comm0) finished (1) +> [2.873012467069035] CommTask(comm0) finished (2) +> [4.393430079086497] CommTask(comm0) finished (3) +> [5.74602493413807] CommTask(comm0) finished (4) +> [14.62726462889908] ExecTask(exec1) finished (1) +> [15.979859483950655] ExecTask(exec2) finished (1) +> [16.14768224091654] CommTask(comm1) finished (1) +> [17.33245433900223] CommTask(comm2) finished (1) +> [27.7341116457807] ExecTask(exec1) finished (2) +> [29.086706500832275] ExecTask(exec2) finished (2) +> [29.25452925779816] CommTask(comm1) finished (2) +> [30.43930135588385] CommTask(comm2) finished (2) diff --git a/examples/python/task-variable-load/task-variable-load.py b/examples/python/task-variable-load/task-variable-load.py new file mode 100644 index 0000000000..14fc2ec94e --- /dev/null +++ b/examples/python/task-variable-load/task-variable-load.py @@ -0,0 +1,67 @@ +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +""" +This example demonstrates how to create a variable load for tasks. +We consider the following graph: + +comm -> exec + +With a small load each comm task is followed by an exec task. +With a heavy load there is a burst of comm before the exec task can even finish once. +""" + +from argparse import ArgumentParser +import sys +from simgrid import Engine, Task, CommTask, ExecTask, Actor, this_actor + +def parse(): + parser = ArgumentParser() + parser.add_argument( + '--platform', + type=str, + required=True, + help='path to the platform description' + ) + return parser.parse_args() + +def callback(t): + print(f'[{Engine.clock}] {t} finished ({t.get_count()})') + +def variable_load(t): + print('--- Small load ---') + for _ in range(3): + t.enqueue_firings(1) + this_actor.sleep_for(100) + this_actor.sleep_for(1000) + print('--- Heavy load ---') + for _ in range(3): + t.enqueue_firings(1) + this_actor.sleep_for(1) + +if __name__ == '__main__': + args = parse() + e = Engine(sys.argv) + e.load_platform(args.platform) + + # Retrieve hosts + tremblay = e.host_by_name('Tremblay') + jupiter = e.host_by_name('Jupiter') + + # Create tasks + comm = CommTask.init("comm", 1e7, tremblay, jupiter) + exec = ExecTask.init("exec", 1e9, jupiter) + + # Create the graph by defining dependencies between tasks + comm.add_successor(exec) + + # Add a function to be called when tasks end for log purpose + Task.on_completion_cb(callback) + + # Create the actor that will inject load during the simulation + Actor.create("input", tremblay, variable_load, comm) + + # runs the simulation + e.run() diff --git a/examples/python/task-variable-load/task-variable-load.tesh b/examples/python/task-variable-load/task-variable-load.tesh new file mode 100644 index 0000000000..0aa185a3a7 --- /dev/null +++ b/examples/python/task-variable-load/task-variable-load.tesh @@ -0,0 +1,19 @@ +#!/usr/bin/env tesh + +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/task-variable-load.py --platform ${platfdir}/small_platform.xml +> --- Small load --- +> [1.5204176120174615] CommTask(comm) finished (1) +> [14.62726462889908] ExecTask(exec) finished (1) +> [101.52041761201747] CommTask(comm) finished (2) +> [114.62726462889908] ExecTask(exec) finished (2) +> [201.52041761201744] CommTask(comm) finished (3) +> [214.62726462889907] ExecTask(exec) finished (3) +> --- Heavy load --- +> [1301.5204176120174] CommTask(comm) finished (4) +> [1303.0408352240347] CommTask(comm) finished (5) +> [1304.561252836052] CommTask(comm) finished (6) +> [1314.627264628899] ExecTask(exec) finished (4) +> [1327.7341116457806] ExecTask(exec) finished (5) +> [1340.8409586626622] ExecTask(exec) finished (6) + + diff --git a/examples/smpi/CMakeLists.txt b/examples/smpi/CMakeLists.txt index 406554822f..e5901089c3 100644 --- a/examples/smpi/CMakeLists.txt +++ b/examples/smpi/CMakeLists.txt @@ -3,8 +3,7 @@ set(_replay_sources ${CMAKE_CURRENT_SOURCE_DIR}/replay/replay.cpp) set(_ampi_test_sources ${CMAKE_CURRENT_SOURCE_DIR}/ampi_test/ampi_test.cpp) # These tests are only used when MC is actived -set(MC_tests bugged1 bugged2 bugged1_liveness only_send_deterministic mutual_exclusion non_termination1 - non_termination2 non_termination3 non_termination4 sendsend) +set(MC_tests bugged1 bugged2 only_send_deterministic mutual_exclusion sendsend) foreach(x ${MC_tests}) if(NOT SIMGRID_HAVE_MC) set(_${x}_disable 1) @@ -65,13 +64,10 @@ set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/energy/energy.tes ${CMAKE_CURRENT_SOURCE_DIR}/replay/replay.tesh PARENT_SCOPE) set(bin_files ${bin_files} ${CMAKE_CURRENT_SOURCE_DIR}/hostfile ${CMAKE_CURRENT_SOURCE_DIR}/energy/hostfile - ${CMAKE_CURRENT_SOURCE_DIR}/mc/promela_bugged1_liveness - ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_bugged1_liveness ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_bugged1 ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_bugged2 ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_only_send_deterministic ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_mutual_exclusion - ${CMAKE_CURRENT_SOURCE_DIR}/mc/hostfile_non_termination ${CMAKE_CURRENT_SOURCE_DIR}/simple-execute/hostfile_griffon PARENT_SCOPE) set(txt_files ${txt_files} ${CMAKE_CURRENT_SOURCE_DIR}/replay/actions0.txt ${CMAKE_CURRENT_SOURCE_DIR}/replay/actions1.txt diff --git a/examples/smpi/NAS/CMakeLists.txt b/examples/smpi/NAS/CMakeLists.txt index bec59f117d..c654e01c74 100644 --- a/examples/smpi/NAS/CMakeLists.txt +++ b/examples/smpi/NAS/CMakeLists.txt @@ -1,9 +1,5 @@ if(enable_smpi) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - endif() + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") add_executable (is EXCLUDE_FROM_ALL is.c nas_common.c) diff --git a/examples/smpi/NAS/DGraph.c b/examples/smpi/NAS/DGraph.c index ad4f682106..452abc674d 100644 --- a/examples/smpi/NAS/DGraph.c +++ b/examples/smpi/NAS/DGraph.c @@ -54,7 +54,8 @@ DGraph* newDGraph(char* nm){ } int AttachNode(DGraph* dg, DGNode* nd) { - int i=0,j,len=0; + int i = 0, j; + unsigned len = 0; DGNode **nds =NULL, *tmpnd=NULL; DGArc **ar=NULL; diff --git a/examples/smpi/NAS/nas_common.c b/examples/smpi/NAS/nas_common.c index 04c435ef6f..d70f552cd0 100644 --- a/examples/smpi/NAS/nas_common.c +++ b/examples/smpi/NAS/nas_common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. +/* Copyright (c) 2016-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/smpi/NAS/nas_common.h b/examples/smpi/NAS/nas_common.h index 15b2e1e30c..a234be5b25 100644 --- a/examples/smpi/NAS/nas_common.h +++ b/examples/smpi/NAS/nas_common.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. +/* Copyright (c) 2016-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/smpi/ampi_test/ampi_test.cpp b/examples/smpi/ampi_test/ampi_test.cpp index 5e8d430504..53308b1b67 100644 --- a/examples/smpi/ampi_test/ampi_test.cpp +++ b/examples/smpi/ampi_test/ampi_test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/smpi/comm_dynamic_costs/comm-dynamic-cost.cpp b/examples/smpi/comm_dynamic_costs/comm-dynamic-cost.cpp index 14fad4f913..470836b3e9 100644 --- a/examples/smpi/comm_dynamic_costs/comm-dynamic-cost.cpp +++ b/examples/smpi/comm_dynamic_costs/comm-dynamic-cost.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,9 +15,9 @@ namespace sg4 = simgrid::s4u; * in collective operations. But it doesn't happen in this example * * @param op MPI Operation (set by user at cb registering below) - * @param size Message size (set by simgrid) - * @param src Source host (set by simgrid) - * @param dst Source host (set by simgrid) + * @param size Message size (set by SimGrid) + * @param src Source host (set by SimGrid) + * @param dst Source host (set by SimGrid) */ static double smpi_cost_cb(SmpiOperation op, size_t /*size*/, const sg4::Host* src, const sg4::Host* dst) { @@ -47,8 +47,7 @@ void load_platform(const sg4::Engine& /*e*/) const sg4::Link* link9 = root->create_split_duplex_link("9", "7.20975MBps")->set_latency("1.461517ms")->seal(); - root->add_route(tremblay->get_netpoint(), jupiter->get_netpoint(), nullptr, nullptr, - {{link9, sg4::LinkInRoute::Direction::UP}}, true); + root->add_route(tremblay, jupiter, {link9}); root->seal(); /* set cost callback for MPI_Send and MPI_Recv */ diff --git a/examples/smpi/energy/energy.c b/examples/smpi/energy/energy.c index 8525d50622..25318b7c7b 100644 --- a/examples/smpi/energy/energy.c +++ b/examples/smpi/energy/energy.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/smpi/gemm/gemm.c b/examples/smpi/gemm/gemm.c index 196b2fd90f..b9f0635d70 100644 --- a/examples/smpi/gemm/gemm.c +++ b/examples/smpi/gemm/gemm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,32 +12,32 @@ /*#*/ /*# ==================================================================================================*/ -#include "stdio.h" -#include "mpi.h" +#include +#include -void multiply(float* a, float* b, float* c, int istart, int iend, int size); -void multiply_sampled(float* a, float* b, float* c, int istart, int iend, int size); - - -void multiply(float* a, float* b, float* c, int istart, int iend, int size) +static void multiply(const float* a, const float* b, float* c, int istart, int iend, int size) { for (int i = istart; i <= iend; ++i) { for (int j = 0; j < size; ++j) { - for (int k = 0; k < size; ++k) { - c[i*size+j] += a[i*size+k] * b[k*size+j]; - } + float sum = 0.0; + for (int k = 0; k < size; ++k) { + sum += a[i * size + k] * b[k * size + j]; + } + c[i * size + j] += sum; } } } -void multiply_sampled(float* a, float* b, float* c, int istart, int iend, int size) +static void multiply_sampled(const float* a, const float* b, float* c, int istart, int iend, int size) { //for (int i = istart; i <= iend; ++i) { SMPI_SAMPLE_GLOBAL (int i = istart, i <= iend, ++i, 10, 0.005){ for (int j = 0; j < size; ++j) { - for (int k = 0; k < size; ++k) { - c[i*size+j] += a[i*size+k] * b[k*size+j]; - } + float sum = 0.0; + for (int k = 0; k < size; ++k) { + sum += a[i * size + k] * b[k * size + j]; + } + c[i * size + j] += sum; } } } diff --git a/examples/smpi/gemm/gemm.tesh b/examples/smpi/gemm/gemm.tesh index 280152aebd..a9c2bd62d5 100644 --- a/examples/smpi/gemm/gemm.tesh +++ b/examples/smpi/gemm/gemm.tesh @@ -4,13 +4,13 @@ p Test instrumentation of SMPI -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning --cfg=smpi/host-speed:1f -np 8 ${bindir:=.}/smpi_gemm 1000 native +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning --cfg=smpi/host-speed:1f -np 8 ${bindir:=.}/smpi_gemm 1000 native > [0.000000] [smpi/INFO] You requested to use 8 ranks, but there is only 5 processes in your hostfile... > Matrix Size : 1000x1000 > Native mode > Performance= 220.56 GFlop/s, Time= 9.068 sec, Size= 2000000000 Ops -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning --cfg=smpi/host-speed:1f -np 8 ${bindir:=.}/smpi_gemm 1000 sampling +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning --cfg=smpi/host-speed:1f -np 8 ${bindir:=.}/smpi_gemm 1000 sampling > [0.000000] [smpi/INFO] You requested to use 8 ranks, but there is only 5 processes in your hostfile... > Matrix Size : 1000x1000 > Sampling mode diff --git a/examples/smpi/mc/bugged1.c b/examples/smpi/mc/bugged1.c index 7c0aae8627..43a0f624f9 100644 --- a/examples/smpi/mc/bugged1.c +++ b/examples/smpi/mc/bugged1.c @@ -1,6 +1,6 @@ /* A simple bugged MPI_ISend and MPI_IRecv test */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/smpi/mc/bugged1_liveness.c b/examples/smpi/mc/bugged1_liveness.c deleted file mode 100644 index b7c12d60c3..0000000000 --- a/examples/smpi/mc/bugged1_liveness.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/***************** Centralized Mutual Exclusion Algorithm *********************/ -/* This example implements a centralized mutual exclusion algorithm. */ -/* Bug : CS requests of process 1 not satisfied */ -/* LTL property checked : G(r->F(cs)); (r=request of CS, cs=CS ok) */ -/******************************************************************************/ - -/* Run : - /usr/bin/time -f "clock:%e user:%U sys:%S swapped:%W exitval:%x max:%Mk" "$@" \ - ../../../smpi_script/bin/smpirun -hostfile hostfile_bugged1_liveness -platform ../../platforms/cluster_backbone.xml \ - --cfg=contexts/factory:ucontext --cfg=model-check/reduction:none \ - --cfg=model-check/property:promela_bugged1_liveness --cfg=smpi/send-is-detached-thresh:0 \ - --cfg=contexts/stack-size:128 --cfg=model-check/visited:100000 --cfg=model-check/max-depth:100000 ./bugged1_liveness -*/ - -#include -#include -#include -#include - -#define GRANT_TAG 0 -#define REQUEST_TAG 1 -#define RELEASE_TAG 2 - -int r; -int cs; - -int main(int argc, char **argv){ - int size; - int rank; - int recv_buff; - MPI_Status status; - xbt_dynar_t requests = xbt_dynar_new(sizeof(int), NULL); - - /* Initialize MPI */ - int err = MPI_Init(&argc, &argv); - if(err != MPI_SUCCESS){ - printf("MPI initialization failed !\n"); - exit(1); - } - - MC_automaton_new_propositional_symbol_pointer("r", &r); - MC_automaton_new_propositional_symbol_pointer("cs", &cs); - - MC_ignore(&status.count, sizeof status.count); - - /* Get number of processes */ - MPI_Comm_size(MPI_COMM_WORLD, &size); - /* Get id of this process */ - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - if(rank == 0){ /* Coordinator */ - int CS_used = 0; - while(1){ - MPI_Recv(&recv_buff, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); - if(status.MPI_TAG == REQUEST_TAG){ - if(CS_used){ - printf("CS already used.\n"); - xbt_dynar_push(requests, &recv_buff); - }else{ - if(recv_buff != size - 1){ - printf("CS idle. Grant immediately.\n"); - MPI_Send(&rank, 1, MPI_INT, recv_buff, GRANT_TAG, MPI_COMM_WORLD); - CS_used = 1; - } - } - }else{ - if(!xbt_dynar_is_empty(requests)){ - printf("CS release. Grant to queued requests (queue size: %lu)", xbt_dynar_length(requests)); - xbt_dynar_shift(requests, &recv_buff); - if(recv_buff != size - 1){ - MPI_Send(&rank, 1, MPI_INT, recv_buff, GRANT_TAG, MPI_COMM_WORLD); - CS_used = 1; - }else{ - xbt_dynar_push(requests, &recv_buff); - CS_used = 0; - } - }else{ - printf("CS release. Resource now idle.\n"); - CS_used = 0; - } - } - } - }else{ /* Client */ - while(1){ - printf("%d asks the request.\n", rank); - MPI_Send(&rank, 1, MPI_INT, 0, REQUEST_TAG, MPI_COMM_WORLD); - if(rank == size - 1){ - r = 1; - cs = 0; - } - MPI_Recv(&recv_buff, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); - if(status.MPI_TAG == GRANT_TAG && rank == size - 1){ - cs = 1; - r = 0; - } - printf("%d got the answer. Release it.\n", rank); - MPI_Send(&rank, 1, MPI_INT, 0, RELEASE_TAG, MPI_COMM_WORLD); - if(rank == size - 1){ - r = 0; - cs = 0; - } - } - } - - MPI_Finalize(); - - return 0; -} diff --git a/examples/smpi/mc/bugged2.c b/examples/smpi/mc/bugged2.c index 21a458c854..c7bf34b1b7 100644 --- a/examples/smpi/mc/bugged2.c +++ b/examples/smpi/mc/bugged2.c @@ -1,6 +1,6 @@ /* A simple bugged MPI_ISend and MPI_IRecv test */ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/smpi/mc/hostfile_bugged1_liveness b/examples/smpi/mc/hostfile_bugged1_liveness deleted file mode 100644 index edbbeb8312..0000000000 --- a/examples/smpi/mc/hostfile_bugged1_liveness +++ /dev/null @@ -1,3 +0,0 @@ -node-1.simgrid.org -node-2.simgrid.org -node-3.simgrid.org diff --git a/examples/smpi/mc/hostfile_non_termination b/examples/smpi/mc/hostfile_non_termination deleted file mode 100644 index c1627f2e47..0000000000 --- a/examples/smpi/mc/hostfile_non_termination +++ /dev/null @@ -1,2 +0,0 @@ -node-1.simgrid.org -node-2.simgrid.org \ No newline at end of file diff --git a/examples/smpi/mc/mutual_exclusion.c b/examples/smpi/mc/mutual_exclusion.c index 5dd36e8dc3..235860c24d 100644 --- a/examples/smpi/mc/mutual_exclusion.c +++ b/examples/smpi/mc/mutual_exclusion.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. +/* Copyright (c) 2014-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ int main(int argc, char **argv){ exit(1); } - MC_ignore(&status.count, sizeof status.count); - /* Get number of processes */ MPI_Comm_size(MPI_COMM_WORLD, &size); /* Get id of this process */ diff --git a/examples/smpi/mc/non_termination1.c b/examples/smpi/mc/non_termination1.c deleted file mode 100644 index a0cb471d08..0000000000 --- a/examples/smpi/mc/non_termination1.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include - -int x = 5; -int y = 8; - -int main(int argc, char **argv) { - int recv_buff; - int size; - int rank; - MPI_Status status; - - MPI_Init(&argc, &argv); - - MPI_Comm_size(MPI_COMM_WORLD, &size); /* Get nr of tasks */ - MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Get id of this process */ - - MC_ignore(&status.count, sizeof status.count); - - if (rank == 0) { - while (1) { - MPI_Recv(&recv_buff, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); - } - } else { - while (1) { - int old_x = x; - x = -y; - y = old_x; - printf("x = %d, y = %d\n", x, y); - MPI_Send(&rank, 1, MPI_INT, 0, 42, MPI_COMM_WORLD); - } - } - - MPI_Finalize(); - - return 0; -} diff --git a/examples/smpi/mc/non_termination2.c b/examples/smpi/mc/non_termination2.c deleted file mode 100644 index 7bae9086bc..0000000000 --- a/examples/smpi/mc/non_termination2.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include - -int x; - -int main(int argc, char **argv) { - int recv_buff; - int size; - int rank; - MPI_Status status; - - MPI_Init(&argc, &argv); - - MPI_Comm_size(MPI_COMM_WORLD, &size); /* Get nr of tasks */ - MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Get id of this process */ - - MC_ignore(&status.count, sizeof status.count); - - if (rank == 0) { - while (1) { - MPI_Recv(&recv_buff, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); - } - } else { - while (1) { - x = 2; - MPI_Send(&rank, 1, MPI_INT, 0, 42, MPI_COMM_WORLD); - } - } - - MPI_Finalize(); - - return 0; -} diff --git a/examples/smpi/mc/non_termination3.c b/examples/smpi/mc/non_termination3.c deleted file mode 100644 index 0a2c7e3b02..0000000000 --- a/examples/smpi/mc/non_termination3.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include - -int x = 0; -int y = 0; - -int main(int argc, char **argv) { - int recv_x; - int recv_y; - int size; - int rank; - MPI_Status status; - - MPI_Init(&argc, &argv); - - MPI_Comm_size(MPI_COMM_WORLD, &size); /* Get nr of tasks */ - MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Get id of this process */ - - MC_ignore(&status.count, sizeof status.count); - - if (rank == 0) { - while (x<5) { - MPI_Recv(&recv_x, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); - MPI_Recv(&recv_y, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); - } - } else { - while (x<5) { - int old_x = x; - x = old_x - y; - MPI_Send(&x, 1, MPI_INT, 0, 42, MPI_COMM_WORLD); - y = old_x + y; - MPI_Send(&y, 1, MPI_INT, 0, 42, MPI_COMM_WORLD); - } - } - - MPI_Finalize(); - - return 0; -} diff --git a/examples/smpi/mc/non_termination4.c b/examples/smpi/mc/non_termination4.c deleted file mode 100644 index 88a207de3e..0000000000 --- a/examples/smpi/mc/non_termination4.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include - -int x = 20; - -int main(int argc, char **argv) { - int recv_x = 1; - int size; - int rank; - MPI_Status status; - - MPI_Init(&argc, &argv); - - MPI_Comm_size(MPI_COMM_WORLD, &size); /* Get nr of tasks */ - MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Get id of this process */ - - MC_ignore(&status.count, sizeof status.count); - - if(rank==0){ - while (recv_x>=0) { - MPI_Recv(&recv_x, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); - } - }else{ - while (x >= 0) { - if (MC_random(0,1) == 0) { - x -= 1; - } else { - x += 1; - } - printf("x=%d\n", x); - MPI_Send(&x, 1, MPI_INT, 0, 42, MPI_COMM_WORLD); - } - } - - MPI_Finalize(); - - return 0; -} diff --git a/examples/smpi/mc/only_send_deterministic.c b/examples/smpi/mc/only_send_deterministic.c index fcb11e1b79..9275859b8d 100644 --- a/examples/smpi/mc/only_send_deterministic.c +++ b/examples/smpi/mc/only_send_deterministic.c @@ -1,6 +1,6 @@ /* ../../../smpi_script/bin/smpirun -hostfile hostfile_send_deterministic -platform ../../platforms/cluster_backbone.xml -np 3 --cfg=smpi/send-is-detached-thresh:0 gdb\ --args\ ./send_deterministic */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/examples/smpi/mc/only_send_deterministic.tesh b/examples/smpi/mc/only_send_deterministic.tesh index 957f042544..4f070ab9b7 100644 --- a/examples/smpi/mc/only_send_deterministic.tesh +++ b/examples/smpi/mc/only_send_deterministic.tesh @@ -1,7 +1,7 @@ #!/usr/bin/env tesh ! timeout 60 -$ ../../../smpi_script/bin/smpirun -wrapper "${bindir:=.}/../../../bin/simgrid-mc" --log=xbt_cfg.thresh:warning -hostfile ${srcdir:=.}/hostfile_only_send_deterministic -platform ${srcdir:=.}/../../platforms/cluster_backbone.xml --cfg=model-check/communications-determinism:1 --cfg=smpi/buffering:zero --cfg=smpi/host-speed:1Gf ./smpi_only_send_deterministic +$ $VALGRIND_NO_LEAK_CHECK ../../../smpi_script/bin/smpirun -wrapper "${bindir:=.}/../../../bin/simgrid-mc" --log=xbt_cfg.thresh:warning -hostfile ${srcdir:=.}/hostfile_only_send_deterministic -platform ${srcdir:=.}/../../platforms/cluster_backbone.xml --cfg=model-check/communications-determinism:1 --cfg=smpi/buffering:zero --cfg=smpi/host-speed:1Gf ./smpi_only_send_deterministic > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. > [0.000000] [mc_comm_determinism/INFO] Check communication determinism > [0.000000] [mc_comm_determinism/INFO] ******************************************************* @@ -10,4 +10,4 @@ $ ../../../smpi_script/bin/smpirun -wrapper "${bindir:=.}/../../../bin/simgrid-m > [0.000000] [mc_comm_determinism/INFO] The recv communications pattern of the actor 0 is different! Different source for communication #1 > [0.000000] [mc_comm_determinism/INFO] Send-deterministic : Yes > [0.000000] [mc_comm_determinism/INFO] Recv-deterministic : No -> [0.000000] [mc_dfs/INFO] DFS exploration ended. 36 unique states visited; 13 backtracks (97 transition replays, 49 states visited overall) \ No newline at end of file +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 25 unique states visited; 6 backtracks (11 transition replays, 42 states visited overall) diff --git a/examples/smpi/mc/promela_bugged1_liveness b/examples/smpi/mc/promela_bugged1_liveness deleted file mode 100644 index 96b491d6af..0000000000 --- a/examples/smpi/mc/promela_bugged1_liveness +++ /dev/null @@ -1,11 +0,0 @@ -never { /* !G(r->Fcs) */ -T0_init : /* init */ - if - :: (1) -> goto T0_init - :: (!cs && r) -> goto accept_S2 - fi; -accept_S2 : /* 1 */ - if - :: (!cs) -> goto accept_S2 - fi; -} diff --git a/examples/smpi/mc/sendsend.c b/examples/smpi/mc/sendsend.c index ad557dc543..2491a4f5d9 100644 --- a/examples/smpi/mc/sendsend.c +++ b/examples/smpi/mc/sendsend.c @@ -1,6 +1,6 @@ /* A simple bugged MPI_Send and MPI_Recv test: it deadlocks when MPI_Send are blocking */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -23,7 +23,7 @@ int main(int argc, char** argv) MPI_Comm_size(MPI_COMM_WORLD, &size); /* Get nr of tasks */ MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Get id of this process */ - if (size < 2) { + if (size != 2) { printf("run this program with exactly 2 processes (-np 2)\n"); MPI_Finalize(); exit(0); diff --git a/examples/smpi/mc/sendsend.tesh b/examples/smpi/mc/sendsend.tesh index c1ca35ff21..3a628573f9 100644 --- a/examples/smpi/mc/sendsend.tesh +++ b/examples/smpi/mc/sendsend.tesh @@ -2,26 +2,30 @@ p Testing the permissive model ! timeout 60 -$ ../../../smpi_script/bin/smpirun -quiet -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -np 2 -platform ${platfdir:=.}/cluster_backbone.xml --cfg=smpi/buffering:infty --log=xbt_cfg.thresh:warning ./smpi_sendsend +$ $VALGRIND_NO_LEAK_CHECK ../../../smpi_script/bin/smpirun -quiet -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -np 2 -platform ${platfdir:=.}/cluster_backbone.xml --cfg=smpi/buffering:infty --log=xbt_cfg.thresh:warning ./smpi_sendsend > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. > Sent 0 to rank 1 > Sent 1 to rank 0 > rank 0 recv the data > rank 1 recv the data -> Sent 0 to rank 1 -> [0.000000] [mc_dfs/INFO] DFS exploration ended. 7 unique states visited; 2 backtracks (10 transition replays, 2 states visited overall) +> Sent 1 to rank 0 +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 9 unique states visited; 1 backtracks (0 transition replays, 10 states visited overall) p Testing the paranoid model ! timeout 60 ! expect return 3 -$ ../../../smpi_script/bin/smpirun -quiet -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -np 2 -platform ${platfdir:=.}/cluster_backbone.xml --cfg=smpi/buffering:zero --log=xbt_cfg.thresh:warning ./smpi_sendsend +$ $VALGRIND_NO_LEAK_CHECK ../../../smpi_script/bin/smpirun -quiet -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -np 2 -platform ${platfdir:=.}/cluster_backbone.xml --cfg=smpi/buffering:zero --log=xbt_cfg.thresh:warning ./smpi_sendsend > [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. > [0.000000] [mc_global/INFO] ************************** > [0.000000] [mc_global/INFO] *** DEADLOCK DETECTED *** > [0.000000] [mc_global/INFO] ************************** +> [0.000000] [ker_engine/INFO] 2 actors are still running, waiting for something. +> [0.000000] [ker_engine/INFO] Legend of the following listing: "Actor (@): " +> [0.000000] [ker_engine/INFO] Actor 1 (0@node-0.simgrid.org) simcall CommWait(comm_id:1 src:1 dst:-1 mbox:SMPI-2(id:2)) +> [0.000000] [ker_engine/INFO] Actor 2 (1@node-1.simgrid.org) simcall CommWait(comm_id:2 src:2 dst:-1 mbox:SMPI-1(id:3)) > [0.000000] [mc_global/INFO] Counter-example execution trace: -> [0.000000] [mc_global/INFO] 1: iSend(mbox=2) -> [0.000000] [mc_global/INFO] 2: iSend(mbox=0) -> [0.000000] [mc_global/INFO] Path = 1;2 -> [0.000000] [mc_dfs/INFO] DFS exploration ended. 3 unique states visited; 1 backtracks (3 transition replays, 0 states visited overall) +> [0.000000] [mc_global/INFO] Actor 1 in :0:() ==> simcall: iSend(mbox=2) +> [0.000000] [mc_global/INFO] Actor 2 in :0:() ==> simcall: iSend(mbox=3) +> [0.000000] [mc_Session/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'1;2' +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 3 unique states visited; 0 backtracks (0 transition replays, 3 states visited overall) > Execution failed with code 3. diff --git a/examples/smpi/replay/replay.cpp b/examples/smpi/replay/replay.cpp index 4fdc7232c0..216f7f35a3 100644 --- a/examples/smpi/replay/replay.cpp +++ b/examples/smpi/replay/replay.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -20,15 +20,9 @@ static void action_blah(const simgrid::xbt::ReplayAction& /*args*/) args is a strings array containing the blank-separated parameters found in the trace for this event instance. */ } -action_fun previous_send; -static void overriding_send(simgrid::xbt::ReplayAction& args) -{ - previous_send(args); // Just call the overridden symbol. That's a toy example. -} - int main(int argc, char* argv[]) { - auto properties = simgrid::s4u::Actor::self()->get_properties(); + const auto* properties = simgrid::s4u::Actor::self()->get_properties(); const char* instance_id = properties->at("instance_id").c_str(); const int rank = static_cast(xbt_str_parse_int(properties->at("rank").c_str(), "Cannot parse rank")); @@ -47,14 +41,17 @@ int main(int argc, char* argv[]) /* Connect your callback function to the "blah" event in the trace files */ xbt_replay_action_register("blah", action_blah); - /* The send action is an override, so we have to first save its previous value in a global */ + /* The send action is an override, so we could have saved its previous value in a global, or use a lambda capture like + * in the following */ int new_rank; MPI_Comm_rank(MPI_COMM_WORLD, &new_rank); if (new_rank != rank) XBT_WARN("Rank inconsistency. Got %d, expected %d", new_rank, rank); if (rank == 0) { - previous_send = xbt_replay_action_get("send"); - xbt_replay_action_register("send", overriding_send); + auto previous_send = xbt_replay_action_get("send"); + xbt_replay_action_register("send", [previous_send](simgrid::xbt::ReplayAction& args) { + previous_send(args); // Just call the overridden symbol. That's a toy example. + }); } /* The regular run of the replayer */ if (shared_trace != nullptr) diff --git a/examples/smpi/replay_multiple/generate_multiple_deployment.sh b/examples/smpi/replay_multiple/generate_multiple_deployment.sh index ded0495928..56da4ad919 100755 --- a/examples/smpi/replay_multiple/generate_multiple_deployment.sh +++ b/examples/smpi/replay_multiple/generate_multiple_deployment.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/examples/smpi/replay_multiple/replay_multiple.cpp b/examples/smpi/replay_multiple/replay_multiple.cpp index 2bf3e03841..53ea26cd8d 100644 --- a/examples/smpi/replay_multiple/replay_multiple.cpp +++ b/examples/smpi/replay_multiple/replay_multiple.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/smpi/replay_multiple_manual_deploy/replay_multiple_manual.cpp b/examples/smpi/replay_multiple_manual_deploy/replay_multiple_manual.cpp index a45fe98d7f..7707303610 100644 --- a/examples/smpi/replay_multiple_manual_deploy/replay_multiple_manual.cpp +++ b/examples/smpi/replay_multiple_manual_deploy/replay_multiple_manual.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -44,10 +44,6 @@ struct Job { int unique_job_number; //!< The job unique number in [0, n[. }; -// ugly globals to avoid creating structures for giving args to processes -static std::vector hosts; -static int noise_between_jobs; - static void smpi_replay_process(Job* job, simgrid::s4u::BarrierPtr barrier, int rank) { XBT_INFO("Replaying rank %d of job %d (smpi_app '%s')", rank, job->unique_job_number, job->smpi_app_name.c_str()); @@ -75,7 +71,7 @@ static void pop_some_processes(int nb_processes, simgrid::s4u::Host* host) } } -static int job_executor_process(Job* job) +static int job_executor_process(const std::vector& hosts, Job* job) { XBT_INFO("Executing job %d (smpi_app '%s')", job->unique_job_number, job->smpi_app_name.c_str()); @@ -96,7 +92,8 @@ static int job_executor_process(Job* job) } // Executes a workload of SMPI processes -static int workload_executor_process(const std::vector>& workload) +static int workload_executor_process(const std::vector& hosts, + const std::vector>& workload, int noise_between_jobs) { for (auto const& job : workload) { // Let's wait until the job's waiting time if needed @@ -117,7 +114,8 @@ static int workload_executor_process(const std::vector>& wo // Let's finally run the job executor char* str_pname = bprintf("job_%04d", job->unique_job_number); XBT_INFO("Launching the job executor of job %d (app '%s')", job->unique_job_number, job->smpi_app_name.c_str()); - simgrid::s4u::Actor::create(str_pname, hosts[job->allocation[0]], job_executor_process, job.get()); + simgrid::s4u::Actor::create(str_pname, hosts[job->allocation[0]], job_executor_process, std::cref(hosts), + job.get()); xbt_free(str_pname); } @@ -210,7 +208,7 @@ int main(int argc, char* argv[]) // Simulation setting simgrid::s4u::Engine e(&argc, argv); e.load_platform(argv[1]); - hosts = e.get_all_hosts(); + const auto hosts = e.get_all_hosts(); xbt_assert(hosts.size() >= 4, "The given platform should contain at least 4 hosts (found %zu).", hosts.size()); // Let's retrieve all SMPI jobs @@ -226,7 +224,7 @@ int main(int argc, char* argv[]) int initial_noise = std::stoi(argv[3]); xbt_assert(initial_noise >= 0, "Invalid initial_noise argument"); - noise_between_jobs = std::stoi(argv[4]); + int noise_between_jobs = std::stoi(argv[4]); xbt_assert(noise_between_jobs >= 0, "Invalid noise_between_jobs argument"); if (initial_noise > 0) { @@ -235,7 +233,8 @@ int main(int argc, char* argv[]) } // Let's execute the workload - simgrid::s4u::Actor::create("workload", hosts[0], workload_executor_process, std::cref(jobs)); + simgrid::s4u::Actor::create("workload", hosts[0], workload_executor_process, std::cref(hosts), std::cref(jobs), + noise_between_jobs); e.run(); XBT_INFO("Simulation finished! Final time: %g", simgrid::s4u::Engine::get_clock()); diff --git a/examples/smpi/simple-execute/simple-execute.c b/examples/smpi/simple-execute/simple-execute.c index 0f6834b836..f865162ae2 100644 --- a/examples/smpi/simple-execute/simple-execute.c +++ b/examples/smpi/simple-execute/simple-execute.c @@ -1,6 +1,6 @@ /* A simple example ping-pong program to test MPI_Send and MPI_Recv */ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -42,8 +42,10 @@ int main(int argc, char *argv[]) MPI_Send(&msg, 1, MPI_INT, dst, tag1, MPI_COMM_WORLD); /* Inject five seconds of fake computation time */ - /* We are in a public file, not internal to simgrid, so _benched flavour is preferred, as it protects against accidental skip */ - /* smpi_execute_benched here is mostly equivalent to sleep, which is intercepted by smpi and turned into smpi_sleep */ + /* We are in a public file, not internal to SimGrid, so _benched flavour is preferred, as it protects against + * accidental skip */ + /* smpi_execute_benched here is mostly equivalent to sleep, which is intercepted by smpi and turned into smpi_sleep + */ /* Difference with sleep is only for energy consumption */ smpi_execute_benched(5.0); @@ -56,7 +58,8 @@ int main(int argc, char *argv[]) msg++; /* Inject 762.96 Mflops of computation time - Host Jupiter is 76.296Mf per second, so this should amount to 10s */ - /* We are in a public file, not internal to simgrid, so _benched flavour is preferred, as it protects against accidental skip */ + /* We are in a public file, not internal to SimGrid, so _benched flavour is preferred, as it protects against + * accidental skip */ smpi_execute_flops_benched(762960000); printf("[%d] After a nap, increment message's value to '%d'\n", rank, msg); diff --git a/examples/smpi/smpi_s4u_masterworker/deployment_masterworker_mailbox_smpi.xml b/examples/smpi/smpi_s4u_masterworker/deployment_masterworker_mailbox_smpi.xml index 1c5fac6b2d..cfa702183d 100644 --- a/examples/smpi/smpi_s4u_masterworker/deployment_masterworker_mailbox_smpi.xml +++ b/examples/smpi/smpi_s4u_masterworker/deployment_masterworker_mailbox_smpi.xml @@ -21,20 +21,4 @@ - - - - - - - - - - - - - - - - diff --git a/examples/smpi/smpi_s4u_masterworker/masterworker_mailbox_smpi.cpp b/examples/smpi/smpi_s4u_masterworker/masterworker_mailbox_smpi.cpp index 2dab28fd09..d81d9fa2bd 100644 --- a/examples/smpi/smpi_s4u_masterworker/masterworker_mailbox_smpi.cpp +++ b/examples/smpi/smpi_s4u_masterworker/masterworker_mailbox_smpi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -80,9 +80,9 @@ static void master_mpi(int argc, char* argv[]) XBT_INFO("After finalize %d %d", rank, test[0]); } -static void alltoall_mpi(int argc, char* argv[]) +static void alltoall_mpi() { - MPI_Init(&argc, &argv); + MPI_Init(); int rank; int size; @@ -114,9 +114,22 @@ int main(int argc, char* argv[]) e.register_function("worker", worker); // launch two MPI applications as well, one using master_mpi function as main on 2 nodes SMPI_app_instance_register("master_mpi", master_mpi, 2); - // the second performing an alltoall on 4 nodes - SMPI_app_instance_register("alltoall_mpi", alltoall_mpi, 4); e.load_deployment(argv[2]); + // the second performing an alltoall on 4 nodes, started directly, not from the deployment file + SMPI_app_instance_start("alltoall_mpi", alltoall_mpi, + {e.host_by_name_or_null("Ginette"), e.host_by_name_or_null("Bourassa"), + e.host_by_name_or_null("Jupiter"), e.host_by_name_or_null("Fafard")}); + + // Start a third MPI application, from a S4U actor after a delay of 10 sec + simgrid::s4u::Actor::create("launcher", e.host_by_name_or_null("Ginette"), [&e]() { + simgrid::s4u::this_actor::sleep_for(10); + XBT_INFO("Start another alltoall_mpi instance"); + SMPI_app_instance_start("alltoall_mpi", alltoall_mpi, + {e.host_by_name_or_null("Ginette"), e.host_by_name_or_null("Bourassa"), + e.host_by_name_or_null("Jupiter"), e.host_by_name_or_null("Fafard")}); + SMPI_app_instance_join("alltoall_mpi"); + XBT_INFO("This other alltoall_mpi instance terminated."); + }); e.run(); diff --git a/examples/smpi/smpi_s4u_masterworker/s4u_smpi.tesh b/examples/smpi/smpi_s4u_masterworker/s4u_smpi.tesh index b6dccb4223..ba6efdd22f 100644 --- a/examples/smpi/smpi_s4u_masterworker/s4u_smpi.tesh +++ b/examples/smpi/smpi_s4u_masterworker/s4u_smpi.tesh @@ -1,24 +1,24 @@ -p Test the use of SMPI+MSG in the same file, as well as several different SMPI instances at the same time +p Test the use of SMPI+S4u in the same file, as well as several different SMPI instances at the same time ! output sort $ ./masterworker_mailbox_smpi ${srcdir:=.}/../../platforms/small_platform_with_routers.xml ${srcdir:=.}/deployment_masterworker_mailbox_smpi.xml --log=smpi.:info --cfg=smpi/simulate-computation:no > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/simulate-computation' to 'no' > [0.000000] [smpi_config/INFO] You did not set the power of the host running the simulation. The timings will certainly not be accurate. Use the option "--cfg=smpi/host-speed:" to set its value. Check https://simgrid.org/doc/latest/Configuring_SimGrid.html#automatic-benchmarking-of-smpi-code for more information. > [11.586581] [smpi_masterworkers/INFO] Simulation time 11.5866 -> [Bourassa:alltoall_mpi:(7) 0.000000] [smpi_masterworkers/INFO] alltoall for rank 1 -> [Bourassa:alltoall_mpi:(7) 0.047272] [smpi_masterworkers/INFO] after alltoall 1 +> [Bourassa:alltoall_mpi#1:(7) 0.000000] [smpi_masterworkers/INFO] alltoall for rank 1 +> [Bourassa:alltoall_mpi#1:(7) 0.047272] [smpi_masterworkers/INFO] after alltoall 1 > [Bourassa:master_mpi:(5) 0.000000] [smpi_masterworkers/INFO] here for rank 1 > [Bourassa:master_mpi:(5) 0.017245] [smpi_masterworkers/INFO] After comm 1 > [Bourassa:master_mpi:(5) 0.017245] [smpi_masterworkers/INFO] After finalize 1 0 -> [Fafard:alltoall_mpi:(9) 0.000000] [smpi_masterworkers/INFO] alltoall for rank 3 -> [Fafard:alltoall_mpi:(9) 0.047582] [smpi_masterworkers/INFO] after alltoall 3 -> [Ginette:alltoall_mpi:(6) 0.000000] [smpi_masterworkers/INFO] alltoall for rank 0 -> [Ginette:alltoall_mpi:(6) 0.037258] [smpi_masterworkers/INFO] after alltoall 0 +> [Fafard:alltoall_mpi#3:(9) 0.000000] [smpi_masterworkers/INFO] alltoall for rank 3 +> [Fafard:alltoall_mpi#3:(9) 0.047582] [smpi_masterworkers/INFO] after alltoall 3 +> [Ginette:alltoall_mpi#0:(6) 0.000000] [smpi_masterworkers/INFO] alltoall for rank 0 +> [Ginette:alltoall_mpi#0:(6) 0.037258] [smpi_masterworkers/INFO] after alltoall 0 > [Ginette:master_mpi:(4) 0.000000] [smpi_masterworkers/INFO] After comm 0 > [Ginette:master_mpi:(4) 0.000000] [smpi_masterworkers/INFO] After finalize 0 0 > [Ginette:master_mpi:(4) 0.000000] [smpi_masterworkers/INFO] here for rank 0 > [Ginette:worker:(2) 11.567566] [smpi_masterworkers/INFO] Exiting now. -> [Jupiter:alltoall_mpi:(8) 0.000000] [smpi_masterworkers/INFO] alltoall for rank 2 -> [Jupiter:alltoall_mpi:(8) 0.047582] [smpi_masterworkers/INFO] after alltoall 2 +> [Jupiter:alltoall_mpi#2:(8) 0.000000] [smpi_masterworkers/INFO] alltoall for rank 2 +> [Jupiter:alltoall_mpi#2:(8) 0.047582] [smpi_masterworkers/INFO] after alltoall 2 > [Jupiter:worker:(3) 11.586581] [smpi_masterworkers/INFO] Exiting now. > [Tremblay:master:(1) 0.000000] [smpi_masterworkers/INFO] Got 2 workers and 20 tasks to process > [Tremblay:master:(1) 0.000000] [smpi_masterworkers/INFO] Sending task 0 of 20 to mailbox 'Ginette' @@ -42,3 +42,13 @@ $ ./masterworker_mailbox_smpi ${srcdir:=.}/../../platforms/small_platform_with_r > [Tremblay:master:(1) 8.379411] [smpi_masterworkers/INFO] Sending task 16 of 20 to mailbox 'Ginette' > [Tremblay:master:(1) 9.365086] [smpi_masterworkers/INFO] Sending task 17 of 20 to mailbox 'Jupiter' > [Tremblay:master:(1) 9.534241] [smpi_masterworkers/INFO] Sending task 18 of 20 to mailbox 'Ginette' +> [Ginette:launcher:(10) 10.000000] [smpi_masterworkers/INFO] Start another alltoall_mpi instance +> [Ginette:alltoall_mpi#0:(11) 10.000000] [smpi_masterworkers/INFO] alltoall for rank 0 +> [Bourassa:alltoall_mpi#1:(12) 10.000000] [smpi_masterworkers/INFO] alltoall for rank 1 +> [Jupiter:alltoall_mpi#2:(13) 10.000000] [smpi_masterworkers/INFO] alltoall for rank 2 +> [Fafard:alltoall_mpi#3:(14) 10.000000] [smpi_masterworkers/INFO] alltoall for rank 3 +> [Ginette:alltoall_mpi#0:(11) 10.036773] [smpi_masterworkers/INFO] after alltoall 0 +> [Bourassa:alltoall_mpi#1:(12) 10.046578] [smpi_masterworkers/INFO] after alltoall 1 +> [Fafard:alltoall_mpi#3:(14) 10.046865] [smpi_masterworkers/INFO] after alltoall 3 +> [Jupiter:alltoall_mpi#2:(13) 10.046865] [smpi_masterworkers/INFO] after alltoall 2 +> [Ginette:launcher:(10) 10.046865] [smpi_masterworkers/INFO] This other alltoall_mpi instance terminated. \ No newline at end of file diff --git a/examples/smpi/trace/trace.c b/examples/smpi/trace/trace.c index 1fd66c744d..0ae2cefbb7 100644 --- a/examples/smpi/trace/trace.c +++ b/examples/smpi/trace/trace.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/smpi/trace/trace.tesh b/examples/smpi/trace/trace.tesh index 9a0cbdc094..20a4b07696 100644 --- a/examples/smpi/trace/trace.tesh +++ b/examples/smpi/trace/trace.tesh @@ -4,7 +4,7 @@ p Test instrumentation of SMPI -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-file ${bindir:=.}/smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg --cfg=tracing/smpi/computing:yes --cfg=smpi/simulate-computation:no --cfg=tracing/smpi/sleeping:yes -np 3 ${bindir:=.}/smpi_trace --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-file ${bindir:=.}/smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=tracing/smpi/computing:yes --cfg=smpi/simulate-computation:no --cfg=tracing/smpi/sleeping:yes -np 3 ${bindir:=.}/smpi_trace --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning ! output sort 19 $ tail -n +3 ${bindir:=.}/smpi_trace.trace @@ -1345,10 +1345,10 @@ $ tail -n +3 ${bindir:=.}/smpi_trace.trace $ rm -f ${bindir:=.}/smpi_trace.trace -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-resource -trace-file ${bindir:=.}/smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg --cfg=smpi/host-speed:1f -np 3 ${bindir:=.}/smpi_trace --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-resource -trace-file ${bindir:=.}/smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=smpi/host-speed:1f -np 3 ${bindir:=.}/smpi_trace --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning $ rm -f ${bindir:=.}/smpi_trace.trace -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace --cfg=tracing/smpi/display-sizes:yes --cfg=tracing/smpi/computing:yes --cfg=tracing/smpi/internals:yes -trace-file ${bindir:=.}/smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg --cfg=smpi/host-speed:1f -np 3 ${bindir:=.}/smpi_trace --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace --cfg=tracing/smpi/display-sizes:yes --cfg=tracing/smpi/computing:yes --cfg=tracing/smpi/internals:yes -trace-file ${bindir:=.}/smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=smpi/host-speed:1f -np 3 ${bindir:=.}/smpi_trace --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning $ rm -f ${bindir:=.}/smpi_trace.trace diff --git a/examples/smpi/trace_call_location/trace_call_location.c b/examples/smpi/trace_call_location/trace_call_location.c index 7bdab1336b..310d95e365 100644 --- a/examples/smpi/trace_call_location/trace_call_location.c +++ b/examples/smpi/trace_call_location/trace_call_location.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/smpi/trace_simple/trace_simple.c b/examples/smpi/trace_simple/trace_simple.c index 53e1c459f2..544d2b16df 100644 --- a/examples/smpi/trace_simple/trace_simple.c +++ b/examples/smpi/trace_simple/trace_simple.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/examples/smpi/trace_simple/trace_simple.tesh b/examples/smpi/trace_simple/trace_simple.tesh index c0cd72dd7d..541e177097 100644 --- a/examples/smpi/trace_simple/trace_simple.tesh +++ b/examples/smpi/trace_simple/trace_simple.tesh @@ -3,19 +3,19 @@ # Go for the first test p SMPI test -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-resource -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg -np 3 ${bindir:=.}/smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-resource -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml -np 3 ${bindir:=.}/smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning p Another SMPI test, with only -trace -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg -np 3 ${bindir:=.}/smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml -np 3 ${bindir:=.}/smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning p Testing without trace parameters -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg -np 3 ${bindir:=.}//smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml -np 3 ${bindir:=.}/smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning p Testing grouped tracing -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-grouped -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg -np 3 ${bindir:=.}/smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace -trace-grouped -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml -np 3 ${bindir:=.}/smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning p Testing with parameters but without activating them with the safe switch (-trace) -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace-resource -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml --cfg=path:${srcdir:=.}/../msg -np 3 ${bindir:=.}/smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -trace-resource -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/../hostfile -platform ${platfdir:=.}/small_platform.xml -np 3 ${bindir:=.}/smpi_trace_simple --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning $ rm -f smpi_trace.trace diff --git a/examples/sthread/CMakeLists.txt b/examples/sthread/CMakeLists.txt index bf915fc8c7..a3d86817e9 100644 --- a/examples/sthread/CMakeLists.txt +++ b/examples/sthread/CMakeLists.txt @@ -5,7 +5,8 @@ find_package(Threads REQUIRED) ######################################################################### foreach(x - mutex-simple) + mutex-simple mutex-recursive + producer-consumer) if("${CMAKE_SYSTEM}" MATCHES "Linux") add_executable (pthread-${x} EXCLUDE_FROM_ALL pthread-${x}.c) @@ -14,13 +15,64 @@ foreach(x add_dependencies(tests pthread-${x}) ADD_TESH_FACTORIES(pthread-${x} "^thread" --setenv libdir=${CMAKE_BINARY_DIR}/lib --cd ${CMAKE_BINARY_DIR}/examples/sthread ${CMAKE_CURRENT_SOURCE_DIR}/pthread-${x}.tesh) + + if(SIMGRID_HAVE_MC) + add_dependencies(tests-mc pthread-${x}) + ADD_TESH_FACTORIES(pthread-mc-${x} "^thread" --setenv libdir=${CMAKE_BINARY_DIR}/lib --cd ${CMAKE_BINARY_DIR}/examples/sthread ${CMAKE_CURRENT_SOURCE_DIR}/pthread-mc-${x}.tesh) + endif() + endif() + + set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/pthread-${x}.tesh + ${CMAKE_CURRENT_SOURCE_DIR}/pthread-mc-${x}.tesh) + set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/pthread-${x}.c) + +endforeach() + +# Regular pthread examples that may deadlock: test sthread + MC in that case +############################################################################ + +foreach(x + mutex-simpledeadlock) + + if("${CMAKE_SYSTEM}" MATCHES "Linux") # sthread is linux-only + + add_executable (pthread-${x} EXCLUDE_FROM_ALL pthread-${x}.c) + set_target_properties(pthread-${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + target_link_libraries(pthread-${x} PRIVATE Threads::Threads) + + if(SIMGRID_HAVE_MC) + add_dependencies(tests-mc pthread-${x}) + ADD_TESH_FACTORIES(pthread-mc-${x} "^thread" --setenv libdir=${CMAKE_BINARY_DIR}/lib --cd ${CMAKE_BINARY_DIR}/examples/sthread ${CMAKE_CURRENT_SOURCE_DIR}/pthread-mc-${x}.tesh) + endif() endif() - set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/pthread-${x}.tesh) + set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/pthread-mc-${x}.tesh) set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/pthread-${x}.c) endforeach() +# C++ tests with sthread+MC that live in their own directory +######################################################## +foreach(example + stdobject) + + if("${CMAKE_SYSTEM}" MATCHES "Linux") # sthread is linux-only + + add_executable (${example} EXCLUDE_FROM_ALL ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.cpp) + set_target_properties(${example} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + target_link_libraries(${example} PRIVATE Threads::Threads) + set_target_properties(${example} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${example}) + + if(SIMGRID_HAVE_MC) + add_dependencies(tests-mc ${example}) + ADD_TESH_FACTORIES(sthread-mc-${example} "^thread" --setenv libdir=${CMAKE_BINARY_DIR}/lib --cd ${CMAKE_BINARY_DIR}/examples/sthread/${example} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh) + endif() + endif() + + set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh) + set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.cpp) +endforeach() + # Regular sthread examples: test the internal interface for debugging purpose ############################################################################# @@ -31,10 +83,12 @@ foreach(x set_target_properties(sthread-${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(sthread-${x} sthread) set_property(TARGET sthread-${x} APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") + add_dependencies(tests sthread-${x}) + ADD_TESH_FACTORIES(sthread-${x} "^thread" --cd ${CMAKE_BINARY_DIR}/examples/sthread ${CMAKE_CURRENT_SOURCE_DIR}/sthread-${x}.tesh) endif() -# set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/sthread-${x}.tesh) + set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/sthread-${x}.tesh) set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/sthread-${x}.c) endforeach() diff --git a/examples/sthread/pthread-mc-mutex-recursive.tesh b/examples/sthread/pthread-mc-mutex-recursive.tesh new file mode 100644 index 0000000000..485712903a --- /dev/null +++ b/examples/sthread/pthread-mc-mutex-recursive.tesh @@ -0,0 +1,14 @@ +# We ignore the LD_PRELOAD lines from the expected output because they contain the build path +! ignore .*LD_PRELOAD.* + +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-mutex-recursive +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. +> Got the lock on the default mutex. +> Failed to relock the default mutex. +> Got the lock on the recursive mutex. +> Got the lock again on the recursive mutex. +> Got the lock on the default mutex. +> Failed to relock the default mutex. +> Got the lock on the recursive mutex. +> Got the lock again on the recursive mutex. +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 17 unique states visited; 1 backtracks (3 transition replays, 21 states visited overall) diff --git a/examples/sthread/pthread-mc-mutex-simple.tesh b/examples/sthread/pthread-mc-mutex-simple.tesh new file mode 100644 index 0000000000..b352717928 --- /dev/null +++ b/examples/sthread/pthread-mc-mutex-simple.tesh @@ -0,0 +1,14 @@ + +# We ignore the LD_PRELOAD lines from the expected output because they contain the build path +! ignore .*LD_PRELOAD.* + +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-mutex-simple +> All threads are started. +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. +> The thread 0 is terminating. +> The thread 1 is terminating. +> User's main is terminating. +> The thread 1 is terminating. +> The thread 0 is terminating. +> User's main is terminating. +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 18 unique states visited; 2 backtracks (2 transition replays, 22 states visited overall) diff --git a/examples/sthread/pthread-mc-mutex-simpledeadlock.tesh b/examples/sthread/pthread-mc-mutex-simpledeadlock.tesh new file mode 100644 index 0000000000..eaa6b2b458 --- /dev/null +++ b/examples/sthread/pthread-mc-mutex-simpledeadlock.tesh @@ -0,0 +1,109 @@ + +# We ignore the LD_PRELOAD lines from the expected output because they contain the build path +! ignore .*LD_PRELOAD.* + +# This test raises a deadlock, thus the return code of 3 +! expect return 3 +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-mutex-simpledeadlock +> All threads are started. +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. +> The thread 0 is terminating. +> The thread 1 is terminating. +> User's main is terminating. +> [0.000000] [mc_global/INFO] ************************** +> [0.000000] [mc_global/INFO] *** DEADLOCK DETECTED *** +> [0.000000] [mc_global/INFO] ************************** +> [0.000000] [ker_engine/INFO] 3 actors are still running, waiting for something. +> [0.000000] [ker_engine/INFO] Legend of the following listing: "Actor (@): " +> [0.000000] [ker_engine/INFO] Actor 1 (main thread@Lilibeth) simcall ActorJoin(pid:2) +> [0.000000] [ker_engine/INFO] Actor 2 (thread 1@Lilibeth) simcall MUTEX_WAIT(mutex_id:1 owner:3) +> [0.000000] [ker_engine/INFO] Actor 3 (thread 2@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2) +> [0.000000] [mc_global/INFO] Counter-example execution trace: +> [0.000000] [mc_global/INFO] Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) +> [0.000000] [mc_global/INFO] Actor 2 in simcall MUTEX_WAIT(mutex: 0, owner: 2) +> [0.000000] [mc_global/INFO] Actor 3 in simcall MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) +> [0.000000] [mc_global/INFO] Actor 2 in simcall MUTEX_ASYNC_LOCK(mutex: 1, owner: 3) +> [0.000000] [mc_global/INFO] Actor 3 in simcall MUTEX_WAIT(mutex: 1, owner: 3) +> [0.000000] [mc_global/INFO] Actor 3 in simcall MUTEX_ASYNC_LOCK(mutex: 0, owner: 2) +> [0.000000] [mc_Session/INFO] You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'2;2;3;2;3;3' +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 21 unique states visited; 3 backtracks (11 transition replays, 35 states visited overall) + + +# The return code of a replay is not modified +! expect return 0 +! output display +! setenv LD_PRELOAD=${libdir:=.}/libsthread.so +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/pthread-mutex-simpledeadlock --cfg=model-check/replay:'2;2;3;2;3;3' + +# The output contains build paths, and cannot be tested with tesh, unfortunately +# Here, it will produce the following output (if you don't build out of the tree, you'll get another output): + +# $ LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-mutex-simpledeadlock --cfg=model-check/replay:'2;2;3;2;3;3' +# sthread is intercepting the execution of ./pthread-mutex-simpledeadlock +# [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/replay' to '2;2;3;2;3;3' +# [0.000000] [mc_record/INFO] path=2;2;3;2;3;3 +# All threads are started. +# [0.000000] [mc_record/INFO] *********************************************************************************** +# [0.000000] [mc_record/INFO] * Path chunk #1 '2/0' Actor thread 1(pid:2): MUTEX_ASYNC_LOCK(mutex_id:0 owner:none) +# [0.000000] [mc_record/INFO] *********************************************************************************** +# Backtrace (displayed in actor thread 1): +# -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:26 +# -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 +# -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 +# -> #3 thread_fun1 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:21 +# +# [0.000000] [mc_record/INFO] *********************************************************************************** +# [0.000000] [mc_record/INFO] * Path chunk #2 '2/0' Actor thread 1(pid:2): MUTEX_WAIT(mutex_id:0 owner:2) +# [0.000000] [mc_record/INFO] *********************************************************************************** +# Backtrace (displayed in actor thread 1): +# -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:29 +# -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 +# -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 +# -> #3 thread_fun1 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:21 +# +# [0.000000] [mc_record/INFO] *********************************************************************************** +# [0.000000] [mc_record/INFO] * Path chunk #3 '3/0' Actor thread 2(pid:3): MUTEX_ASYNC_LOCK(mutex_id:1 owner:none) +# [0.000000] [mc_record/INFO] *********************************************************************************** +# Backtrace (displayed in actor thread 2): +# -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:26 +# -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 +# -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 +# -> #3 thread_fun2 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:31 +# +# [0.000000] [mc_record/INFO] *********************************************************************************** +# [0.000000] [mc_record/INFO] * Path chunk #4 '2/0' Actor thread 1(pid:2): MUTEX_ASYNC_LOCK(mutex_id:1 owner:3) +# [0.000000] [mc_record/INFO] *********************************************************************************** +# Backtrace (displayed in actor thread 1): +# -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:26 +# -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 +# -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 +# -> #3 thread_fun1 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:22 +# +# [0.000000] [mc_record/INFO] *********************************************************************************** +# [0.000000] [mc_record/INFO] * Path chunk #5 '3/0' Actor thread 2(pid:3): MUTEX_WAIT(mutex_id:1 owner:3) +# [0.000000] [mc_record/INFO] *********************************************************************************** +# Backtrace (displayed in actor thread 2): +# -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:29 +# -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 +# -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 +# -> #3 thread_fun2 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:31 +# +# [0.000000] [mc_record/INFO] *********************************************************************************** +# [0.000000] [mc_record/INFO] * Path chunk #6 '3/0' Actor thread 2(pid:3): MUTEX_ASYNC_LOCK(mutex_id:0 owner:2) +# [0.000000] [mc_record/INFO] *********************************************************************************** +# Backtrace (displayed in actor thread 2): +# -> #0 simgrid::s4u::Mutex::lock() at ../../src/s4u/s4u_Mutex.cpp:26 +# -> #1 sthread_mutex_lock at ../../src/sthread/sthread_impl.cpp:188 +# -> #2 pthread_mutex_lock at ../../src/sthread/sthread.c:141 +# -> #3 thread_fun2 at ../../examples/sthread/pthread-mutex-simpledeadlock.c:32 +# +# [0.000000] [mc_record/INFO] The replay of the trace is complete. DEADLOCK detected. +# [0.000000] [ker_engine/INFO] 3 actors are still running, waiting for something. +# [0.000000] [ker_engine/INFO] Legend of the following listing: "Actor (@): " +# [0.000000] [ker_engine/INFO] Actor 1 (main thread@Lilibeth) simcall ActorJoin(pid:2) +# [0.000000] [ker_engine/INFO] Actor 2 (thread 1@Lilibeth) simcall MUTEX_WAIT(mutex_id:1 owner:3) +# [0.000000] [ker_engine/INFO] Actor 3 (thread 2@Lilibeth) simcall MUTEX_WAIT(mutex_id:0 owner:2) +# [0.000000] [sthread/INFO] All threads exited. Terminating the simulation. +# [0.000000] ../../src/kernel/EngineImpl.cpp:265: [ker_engine/WARNING] Process called exit when leaving - Skipping cleanups +# [0.000000] ../../src/kernel/EngineImpl.cpp:265: [ker_engine/WARNING] Process called exit when leaving - Skipping cleanups +# diff --git a/examples/sthread/pthread-mc-producer-consumer.tesh b/examples/sthread/pthread-mc-producer-consumer.tesh new file mode 100644 index 0000000000..2ec84f7eee --- /dev/null +++ b/examples/sthread/pthread-mc-producer-consumer.tesh @@ -0,0 +1,16 @@ +# We ignore the LD_PRELOAD lines from the expected output because they contain the build path +! ignore .*LD_PRELOAD.* + +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-producer-consumer -q -C 1 -P 1 +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 203 unique states visited; 23 backtracks (396 transition replays, 622 states visited overall) + +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:sdpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-producer-consumer -q -C 1 -P 1 +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'sdpor' +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: sdpor. +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 347 unique states visited; 45 backtracks (736 transition replays, 1128 states visited overall) + +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../bin/simgrid-mc --cfg=model-check/reduction:odpor --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/pthread-producer-consumer -q -C 1 -P 1 +> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check/reduction' to 'odpor' +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: odpor. +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 133 unique states visited; 4 backtracks (58 transition replays, 195 states visited overall) \ No newline at end of file diff --git a/examples/sthread/pthread-mutex-recursive.c b/examples/sthread/pthread-mutex-recursive.c new file mode 100644 index 0000000000..63c9cccb23 --- /dev/null +++ b/examples/sthread/pthread-mutex-recursive.c @@ -0,0 +1,66 @@ +/* Copyright (c) 2002-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* Code with both recursive and non-recursive mutexes */ + +#include +#include +#include + +// Structure to hold the mutex's name and pointer to the actual mutex +typedef struct { + const char* name; + pthread_mutex_t* mutex; +} ThreadData; + +static void* thread_function(void* arg) +{ + ThreadData* data = (ThreadData*)arg; + pthread_mutex_t* mutex = data->mutex; + const char* name = data->name; + + pthread_mutex_lock(mutex); + fprintf(stderr, "Got the lock on the %s mutex.\n", name); + + // Attempt to relock the mutex - This behavior depends on the mutex type + if (pthread_mutex_trylock(mutex) == 0) { + fprintf(stderr, "Got the lock again on the %s mutex.\n", name); + pthread_mutex_unlock(mutex); + } else { + fprintf(stderr, "Failed to relock the %s mutex.\n", name); + } + + pthread_mutex_unlock(mutex); + + // pthread_exit(NULL); TODO: segfaulting + return NULL; +} + +int main() +{ + pthread_t thread1; + pthread_t thread2; + pthread_mutex_t mutex_dflt = PTHREAD_MUTEX_INITIALIZER; // Non-recursive mutex + + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_t mutex_rec; + pthread_mutex_init(&mutex_rec, &attr); + + ThreadData data1 = {"default", &mutex_dflt}; + ThreadData data2 = {"recursive", &mutex_rec}; + + pthread_create(&thread1, NULL, thread_function, &data1); + pthread_create(&thread2, NULL, thread_function, &data2); + + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + + pthread_mutex_destroy(&mutex_dflt); + pthread_mutex_destroy(&mutex_rec); + + return 0; +} diff --git a/examples/sthread/pthread-mutex-recursive.tesh b/examples/sthread/pthread-mutex-recursive.tesh new file mode 100644 index 0000000000..0879b2c14e --- /dev/null +++ b/examples/sthread/pthread-mutex-recursive.tesh @@ -0,0 +1,6 @@ +$ env ASAN_OPTIONS=verify_asan_link_order=0:$ASAN_OPTIONS LD_PRELOAD=${libdir:=.}/libsthread.so ./pthread-mutex-recursive +> Got the lock on the default mutex. +> Failed to relock the default mutex. +> Got the lock on the recursive mutex. +> Got the lock again on the recursive mutex. +> [0.000000] [sthread/INFO] All threads exited. Terminating the simulation. diff --git a/examples/sthread/pthread-mutex-simple.c b/examples/sthread/pthread-mutex-simple.c index d97bfe8ca1..a7dea6bd6b 100644 --- a/examples/sthread/pthread-mutex-simple.c +++ b/examples/sthread/pthread-mutex-simple.c @@ -1,3 +1,8 @@ +/* Copyright (c) 2002-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + /* Simple test code with no bug */ #include @@ -21,8 +26,8 @@ int main(int argc, char* argv[]) int id[2] = {0, 1}; pthread_t thread1; pthread_t thread2; - pthread_create(&thread1, NULL, thread_fun, (void*)&id[0]); - pthread_create(&thread2, NULL, thread_fun, (void*)&id[1]); + pthread_create(&thread1, NULL, thread_fun, &id[0]); + pthread_create(&thread2, NULL, thread_fun, &id[1]); fprintf(stderr, "All threads are started.\n"); pthread_join(thread1, NULL); pthread_join(thread2, NULL); diff --git a/examples/sthread/pthread-mutex-simple.tesh b/examples/sthread/pthread-mutex-simple.tesh index 1dd09bd29b..f4b3f3cd6b 100644 --- a/examples/sthread/pthread-mutex-simple.tesh +++ b/examples/sthread/pthread-mutex-simple.tesh @@ -1,7 +1,6 @@ $ env ASAN_OPTIONS=verify_asan_link_order=0:$ASAN_OPTIONS LD_PRELOAD=${libdir:=.}/libsthread.so ./pthread-mutex-simple -> [0.000000] [sthread/INFO] Starting the simulation. -> The thread 0 is terminating. > All threads are started. +> The thread 0 is terminating. > The thread 1 is terminating. > User's main is terminating. > [0.000000] [sthread/INFO] All threads exited. Terminating the simulation. diff --git a/examples/sthread/pthread-mutex-simpledeadlock.c b/examples/sthread/pthread-mutex-simpledeadlock.c new file mode 100644 index 0000000000..92a04a1ace --- /dev/null +++ b/examples/sthread/pthread-mutex-simpledeadlock.c @@ -0,0 +1,58 @@ +/* Copyright (c) 2002-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* Simple test code that may deadlock: + + Thread 1 locks mutex1 then mutex2 while thread 2 locks in reverse order. + Deadlock occurs when each thread get one mutex and then ask for the other one. + */ + +#include +#include + +pthread_mutex_t mutex1; +pthread_mutex_t mutex2; + +static void* thread_fun1(void* val) +{ + pthread_mutex_lock(&mutex1); + pthread_mutex_lock(&mutex2); + pthread_mutex_unlock(&mutex1); + pthread_mutex_unlock(&mutex2); + + fprintf(stderr, "The thread %d is terminating.\n", *(int*)val); + return NULL; +} +static void* thread_fun2(void* val) +{ + pthread_mutex_lock(&mutex2); + pthread_mutex_lock(&mutex1); + pthread_mutex_unlock(&mutex1); + pthread_mutex_unlock(&mutex2); + + fprintf(stderr, "The thread %d is terminating.\n", *(int*)val); + return NULL; +} + +int main(int argc, char* argv[]) +{ + pthread_mutex_init(&mutex1, NULL); + pthread_mutex_init(&mutex2, NULL); + + int id[2] = {0, 1}; + pthread_t thread1; + pthread_t thread2; + pthread_create(&thread1, NULL, thread_fun1, &id[0]); + pthread_create(&thread2, NULL, thread_fun2, &id[1]); + fprintf(stderr, "All threads are started.\n"); + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); + + pthread_mutex_destroy(&mutex1); + pthread_mutex_destroy(&mutex2); + + fprintf(stderr, "User's main is terminating.\n"); + return 0; +} diff --git a/examples/sthread/pthread-producer-consumer.c b/examples/sthread/pthread-producer-consumer.c new file mode 100644 index 0000000000..fe3fe5d960 --- /dev/null +++ b/examples/sthread/pthread-producer-consumer.c @@ -0,0 +1,114 @@ +/* Copyright (c) 2002-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* Simple producer/consumer example with pthreads and semaphores */ + +#include +#include +#include +#include +#include +#include + +int AmountProduced = 3; /* Amount of items produced by a producer */ +int AmountConsumed = 3; /* Amount of items consumed by a consumer */ +int ProducerCount = 2; /* Amount of producer threads*/ +int ConsumerCount = 2; /* Amount of consumer threads*/ +int BufferSize = 4; /* Size of the buffer */ + +sem_t empty; +sem_t full; +int in = 0; +int out = 0; +int* buffer; +pthread_mutex_t mutex; +int do_output = 1; + +static void* producer(void* id) +{ + for (int i = 0; i < AmountProduced; i++) { + sem_wait(&empty); + pthread_mutex_lock(&mutex); + buffer[in] = i; + if (do_output) + fprintf(stderr, "Producer %d: Insert Item %d at %d\n", *((int*)id), buffer[in], in); + in = (in + 1) % BufferSize; + pthread_mutex_unlock(&mutex); + sem_post(&full); + } + return NULL; +} +static void* consumer(void* id) +{ + for (int i = 0; i < AmountConsumed; i++) { + sem_wait(&full); + pthread_mutex_lock(&mutex); + if (do_output) { + int item = buffer[out]; + fprintf(stderr, "Consumer %d: Remove Item %d from %d\n", *((int*)id), item, out); + } + out = (out + 1) % BufferSize; + pthread_mutex_unlock(&mutex); + sem_post(&empty); + } + return NULL; +} + +int main(int argc, char** argv) +{ + int opt; + while ((opt = getopt(argc, argv, "c:C:p:P:q")) != -1) { + switch (opt) { + case 'q': + do_output = 0; + break; + case 'c': + AmountConsumed = atoi(optarg); + break; + case 'C': + ConsumerCount = atoi(optarg); + break; + case 'p': + AmountProduced = atoi(optarg); + break; + case 'P': + ProducerCount = atoi(optarg); + break; + default: /* '?' */ + printf("unknown option: %c\n", optopt); + break; + } + } + pthread_t* pro = malloc(ProducerCount * sizeof(pthread_t)); + pthread_t* con = malloc(ConsumerCount * sizeof(pthread_t)); + buffer = malloc(sizeof(int) * BufferSize); + pthread_mutex_init(&mutex, NULL); + sem_init(&empty, 0, BufferSize); + sem_init(&full, 0, 0); + + int* ids = malloc(sizeof(int) * (ProducerCount + ConsumerCount)); + for (int i = 0; i < ProducerCount + ConsumerCount; i++) + ids[i] = i + 1; // The identity of each thread (for debug messages) + + for (int i = 0; i < ProducerCount; i++) + pthread_create(&pro[i], NULL, producer, &ids[i]); + for (int i = 0; i < ConsumerCount; i++) + pthread_create(&con[i], NULL, consumer, &ids[i]); + + for (int i = 0; i < ProducerCount; i++) + pthread_join(pro[i], NULL); + for (int i = 0; i < ConsumerCount; i++) + pthread_join(con[i], NULL); + + pthread_mutex_destroy(&mutex); + sem_destroy(&empty); + sem_destroy(&full); + free(pro); + free(con); + free(buffer); + free(ids); + + return 0; +} diff --git a/examples/sthread/pthread-producer-consumer.tesh b/examples/sthread/pthread-producer-consumer.tesh new file mode 100644 index 0000000000..471fbe8102 --- /dev/null +++ b/examples/sthread/pthread-producer-consumer.tesh @@ -0,0 +1,21 @@ +$ env ASAN_OPTIONS=verify_asan_link_order=0:$ASAN_OPTIONS LD_PRELOAD=${libdir:=.}/libsthread.so ./pthread-producer-consumer +> Producer 1: Insert Item 0 at 0 +> Producer 2: Insert Item 0 at 1 +> Consumer 1: Remove Item 0 from 0 +> Producer 1: Insert Item 1 at 2 +> Consumer 2: Remove Item 0 from 1 +> Producer 2: Insert Item 1 at 3 +> Consumer 1: Remove Item 1 from 2 +> Producer 1: Insert Item 2 at 0 +> Consumer 2: Remove Item 1 from 3 +> Producer 2: Insert Item 2 at 1 +> Consumer 1: Remove Item 2 from 0 +> Consumer 2: Remove Item 2 from 1 +> [0.000000] [sthread/INFO] All threads exited. Terminating the simulation. + +$ env ASAN_OPTIONS=verify_asan_link_order=0:$ASAN_OPTIONS LD_PRELOAD=${libdir:=.}/libsthread.so ./pthread-producer-consumer -c 2 -C 1 -p 2 -P 1 +> Producer 1: Insert Item 0 at 0 +> Consumer 1: Remove Item 0 from 0 +> Producer 1: Insert Item 1 at 1 +> Consumer 1: Remove Item 1 from 1 +> [0.000000] [sthread/INFO] All threads exited. Terminating the simulation. diff --git a/examples/sthread/stdobject/stdobject.cpp b/examples/sthread/stdobject/stdobject.cpp new file mode 100644 index 0000000000..c2af786d2c --- /dev/null +++ b/examples/sthread/stdobject/stdobject.cpp @@ -0,0 +1,40 @@ +#include +#include +#include + +// shared collection object +std::vector v = {1, 2, 3, 5, 8, 13}; + +extern "C" { +extern int sthread_access_begin(void* addr, const char* objname, const char* file, int line, const char* func) + __attribute__((weak)); +extern void sthread_access_end(void* addr, const char* objname, const char* file, int line, const char* func) + __attribute__((weak)); +} + +#define STHREAD_ACCESS(obj) \ + for (bool first = sthread_access_begin(static_cast(obj), #obj, __FILE__, __LINE__, __func__) || true; first; \ + sthread_access_end(static_cast(obj), #obj, __FILE__, __LINE__, __func__), first = false) + +static void thread_code() +{ + // Add another integer to the vector + STHREAD_ACCESS(&v) v.push_back(21); +} + +int main() +{ + std::cout << "starting two helpers...\n"; + std::thread helper1(thread_code); + std::thread helper2(thread_code); + + std::cout << "waiting for helpers to finish..." << std::endl; + helper1.join(); + helper2.join(); + + // Print out the vector + std::cout << "v = { "; + for (int n : v) + std::cout << n << ", "; + std::cout << "}; \n"; +} \ No newline at end of file diff --git a/examples/sthread/stdobject/stdobject.tesh b/examples/sthread/stdobject/stdobject.tesh new file mode 100644 index 0000000000..602c3f4589 --- /dev/null +++ b/examples/sthread/stdobject/stdobject.tesh @@ -0,0 +1,26 @@ +# This test raises a property violation, thus the return code of 1 +! expect return 1 + +# We ignore the LD_PRELOAD lines from the expected output because they contain the build path +! ignore .*LD_PRELOAD.* + +$ $VALGRIND_NO_TRACE_CHILDREN ${bindir:=.}/../../../bin/simgrid-mc --cfg=model-check/setenv:LD_PRELOAD=${libdir:=.}/libsthread.so ${bindir:=.}/stdobject "--log=root.fmt:[%11.6r]%e(%a@%h)%e%m%n" --log=no_loc +> starting two helpers... +> waiting for helpers to finish... +> [ 0.000000] (maestro@) Start a DFS exploration. Reduction is: dpor. +> [ 0.000000] (maestro@) thread 1 takes &v +> [ 0.000000] (maestro@) thread 1 releases &v +> [ 0.000000] (maestro@) thread 2 takes &v +> [ 0.000000] (maestro@) thread 2 releases &v +> v = { 1, 2, 3, 5, 8, 13, 21, 21, }; +> [ 0.000000] (maestro@) thread 1 takes &v +> [ 0.000000] (maestro@) thread 2 takes &v +> [ 0.000000] (maestro@) Unprotected concurent access to &v: thread 1 from 1 location vs thread 2 (locations hidden because of --log=no_loc). +> [ 0.000000] (maestro@) ************************** +> [ 0.000000] (maestro@) *** PROPERTY NOT VALID *** +> [ 0.000000] (maestro@) ************************** +> [ 0.000000] (maestro@) Counter-example execution trace: +> [ 0.000000] (maestro@) Actor 2 in simcall BeginObjectAccess(&v) +> [ 0.000000] (maestro@) Actor 3 in simcall BeginObjectAccess(&v) +> [ 0.000000] (maestro@) You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with --cfg=model-check/replay:'2;3' +> [ 0.000000] (maestro@) DFS exploration ended. 7 unique states visited; 1 backtracks (1 transition replays, 9 states visited overall) diff --git a/examples/sthread/sthread-mutex-simple.c b/examples/sthread/sthread-mutex-simple.c index c0f48f68c5..dccec547f7 100644 --- a/examples/sthread/sthread-mutex-simple.c +++ b/examples/sthread/sthread-mutex-simple.c @@ -5,11 +5,12 @@ sthread_mutex_t mutex; -static void* thread_fun(void* ignore) +static void* thread_fun(void* val) { sthread_mutex_lock(&mutex); sthread_mutex_unlock(&mutex); + fprintf(stderr, "The thread %d is terminating.\n", *(int*)val); return NULL; } @@ -17,15 +18,17 @@ int main(int argc, char* argv[]) { sthread_mutex_init(&mutex, NULL); + int id[2] = {0, 1}; sthread_t thread1; sthread_t thread2; - sthread_create(&thread1, NULL, thread_fun, NULL); - sthread_create(&thread2, NULL, thread_fun, NULL); + sthread_create(&thread1, NULL, thread_fun, &id[0]); + sthread_create(&thread2, NULL, thread_fun, &id[1]); + fprintf(stderr, "All threads are started.\n"); sthread_join(thread1, NULL); sthread_join(thread2, NULL); sthread_mutex_destroy(&mutex); - fprintf(stderr, "done\n"); + fprintf(stderr, "User's main is terminating.\n"); return 0; } diff --git a/examples/sthread/sthread-mutex-simple.tesh b/examples/sthread/sthread-mutex-simple.tesh new file mode 100644 index 0000000000..67afd1a12b --- /dev/null +++ b/examples/sthread/sthread-mutex-simple.tesh @@ -0,0 +1,6 @@ +$ ./sthread-mutex-simple +> All threads are started. +> The thread 0 is terminating. +> The thread 1 is terminating. +> User's main is terminating. +> [0.000000] [sthread/INFO] All threads exited. Terminating the simulation. diff --git a/include/simgrid/Exception.hpp b/include/simgrid/Exception.hpp index 342bd4bb2e..4b14e56cfe 100644 --- a/include/simgrid/Exception.hpp +++ b/include/simgrid/Exception.hpp @@ -1,16 +1,14 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +/* This file defines all possible exceptions that could occur in a SimGrid library. */ + #ifndef SIMGRID_EXCEPTIONS_HPP #define SIMGRID_EXCEPTIONS_HPP -/** @file exception.hpp SimGrid-specific Exceptions - * - * Defines all possible exception that could occur in a SimGrid library. - */ - +#include #include #include #include @@ -28,15 +26,13 @@ namespace xbt { * Constitute the contextual information of where an exception was thrown * * These tuples (__FILE__, __LINE__, __func__, backtrace, procname, pid) - * are best created with @ref XBT_THROW_POINT. - * - * @ingroup XBT_ex + * are best created with the macro XBT_THROW_POINT. */ class ThrowPoint { public: ThrowPoint() = default; explicit ThrowPoint(const char* file, int line, const char* function, Backtrace&& bt, std::string&& actor_name, - int pid) + aid_t pid) : file_(file) , line_(line) , function_(function) @@ -51,12 +47,13 @@ public: const char* function_ = nullptr; Backtrace backtrace_; std::string procname_ = ""; /**< Name of the process who thrown this */ - int pid_ = 0; /**< PID of the process who thrown this */ + aid_t pid_ = 0; /**< PID of the process who thrown this */ }; /** Create a ThrowPoint with (__FILE__, __LINE__, __func__) */ #define XBT_THROW_POINT \ - ::simgrid::xbt::ThrowPoint(__FILE__, __LINE__, __func__, simgrid::xbt::Backtrace(), xbt_procname(), xbt_getpid()) + ::simgrid::xbt::ThrowPoint(__FILE__, __LINE__, __func__, simgrid::xbt::Backtrace(), sg_actor_self_get_name(), \ + sg_actor_self_get_pid()) class XBT_PUBLIC ImpossibleError : public std::logic_error { public: @@ -183,17 +180,16 @@ class XBT_PUBLIC ForcefulKillException { */ public: ForcefulKillException() = default; - explicit ForcefulKillException(const std::string& msg) : msg_(std::string("Actor killed (") + msg + std::string(").")) - { - } + explicit ForcefulKillException(const std::string& msg) : msg_("Actor killed (" + msg + ").") {} ~ForcefulKillException(); const char* what() const noexcept { return msg_.c_str(); } XBT_ATTRIB_NORETURN static void do_throw(); - static bool try_n_catch(const std::function& try_block); + XBT_ATTRIB_DEPRECATED_v338("Please manifest if you actually need this function") static bool try_n_catch( + const std::function& try_block); private: - std::string msg_ = std::string("Actor killed."); + std::string msg_ = "Actor killed."; }; } // namespace simgrid diff --git a/include/simgrid/activity_set.h b/include/simgrid/activity_set.h new file mode 100644 index 0000000000..9f80ad7561 --- /dev/null +++ b/include/simgrid/activity_set.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef INCLUDE_SIMGRID_ACTIVITY_SET_H +#define INCLUDE_SIMGRID_ACTIVITY_SET_H + +#include +#include /* ssize_t */ + +/* C interface */ +SG_BEGIN_DECL + +XBT_PUBLIC sg_activity_set_t sg_activity_set_init(); +XBT_PUBLIC void sg_activity_set_push(sg_activity_set_t as, sg_activity_t acti); +XBT_PUBLIC void sg_activity_set_erase(sg_activity_set_t as, sg_activity_t acti); +XBT_PUBLIC size_t sg_activity_set_size(sg_activity_set_t as); +XBT_PUBLIC int sg_activity_set_empty(sg_activity_set_t as); + +XBT_PUBLIC sg_activity_t sg_activity_set_test_any(sg_activity_set_t as); +XBT_PUBLIC void sg_activity_set_wait_all(sg_activity_set_t as); +/** Returns true if it terminated successfully (or false on timeout) */ +XBT_PUBLIC int sg_activity_set_wait_all_for(sg_activity_set_t as, double timeout); +XBT_PUBLIC sg_activity_t sg_activity_set_wait_any(sg_activity_set_t as); +XBT_PUBLIC sg_activity_t sg_activity_set_wait_any_for(sg_activity_set_t as, double timeout); +XBT_PUBLIC void sg_activity_set_delete(sg_activity_set_t as); + +/** You must call this function manually on activities extracted from an activity_set with waitany and friends */ +XBT_PUBLIC void sg_activity_unref(sg_activity_t acti); + +SG_END_DECL + +#endif /* INCLUDE_SIMGRID_ACTIVITY_SET_H */ diff --git a/include/simgrid/actor.h b/include/simgrid/actor.h index f20322c8f8..fb34364914 100644 --- a/include/simgrid/actor.h +++ b/include/simgrid/actor.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -72,6 +72,7 @@ XBT_PUBLIC void sg_actor_detach(); XBT_PUBLIC sg_actor_t sg_actor_self(); XBT_PUBLIC aid_t sg_actor_self_get_pid(); XBT_PUBLIC aid_t sg_actor_self_get_ppid(); +/** Returns the name of the current actor (or "maestro" if maestro is running) */ XBT_PUBLIC const char* sg_actor_self_get_name(); XBT_PUBLIC void* sg_actor_self_get_data(); XBT_PUBLIC void sg_actor_self_set_data(void* data); diff --git a/include/simgrid/barrier.h b/include/simgrid/barrier.h index f7b2f5739d..a3c7da0a7e 100644 --- a/include/simgrid/barrier.h +++ b/include/simgrid/barrier.h @@ -1,6 +1,6 @@ /* Public interface to the Barrier datatype */ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/simgrid/chrono.hpp b/include/simgrid/chrono.hpp index 46849ec0eb..73a9c68914 100644 --- a/include/simgrid/chrono.hpp +++ b/include/simgrid/chrono.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/simgrid/comm.h b/include/simgrid/comm.h index 3767ebc528..538122f18e 100644 --- a/include/simgrid/comm.h +++ b/include/simgrid/comm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,16 +12,23 @@ /* C interface */ SG_BEGIN_DECL +XBT_PUBLIC int sg_comm_isinstance(sg_activity_t acti); + XBT_PUBLIC void sg_comm_detach(sg_comm_t comm, void (*clean_function)(void*)); XBT_PUBLIC int sg_comm_test(sg_comm_t comm); XBT_PUBLIC sg_error_t sg_comm_wait(sg_comm_t comm); XBT_PUBLIC sg_error_t sg_comm_wait_for(sg_comm_t comm, double timeout); -XBT_PUBLIC void sg_comm_wait_all(sg_comm_t* comms, size_t count); -XBT_PUBLIC size_t sg_comm_wait_all_for(sg_comm_t* comms, size_t count, double timeout); -XBT_PUBLIC ssize_t sg_comm_wait_any_for(sg_comm_t* comms, size_t count, double timeout); -XBT_PUBLIC ssize_t sg_comm_wait_any(sg_comm_t* comms, size_t count); XBT_PUBLIC void sg_comm_unref(sg_comm_t comm); +#ifndef DOXYGEN +XBT_ATTRIB_DEPRECATED_v339("Please use sg_activity_set_t instead") XBT_PUBLIC + void sg_comm_wait_all(sg_comm_t* comms, size_t count); +XBT_ATTRIB_DEPRECATED_v339("Please use sg_activity_set_t instead") XBT_PUBLIC + ssize_t sg_comm_wait_any_for(sg_comm_t* comms, size_t count, double timeout); +XBT_ATTRIB_DEPRECATED_v339("Please use sg_activity_set_t instead") XBT_PUBLIC + ssize_t sg_comm_wait_any(sg_comm_t* comms, size_t count); +#endif + SG_END_DECL #endif /* INCLUDE_SIMGRID_COMM_H_ */ diff --git a/include/simgrid/cond.h b/include/simgrid/cond.h index 4c32ac5e39..0613837d24 100644 --- a/include/simgrid/cond.h +++ b/include/simgrid/cond.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/simgrid/config.h.in b/include/simgrid/config.h.in index e0d14a13b3..6ef3fd76b1 100644 --- a/include/simgrid/config.h.in +++ b/include/simgrid/config.h.in @@ -1,6 +1,6 @@ /* simgrid/config.h - Results of the configure made visible to user code. */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,8 +9,6 @@ #define SIMGRID_PUBLIC_CONFIG_H #include -/* Was MSG compiled in? */ -#cmakedefine01 SIMGRID_HAVE_MSG /* Were mallocators (object pools) compiled in? */ #cmakedefine01 SIMGRID_HAVE_MALLOCATOR /* Was the model-checking compiled in? */ @@ -20,4 +18,6 @@ #cmakedefine NS3_MINOR_VERSION @NS3_MINOR_VERSION@ /* Was the Eigen3 support compiled in? */ #cmakedefine01 SIMGRID_HAVE_EIGEN3 +/* Was the JSON support compiled in? */ +#cmakedefine01 SIMGRID_HAVE_JSON #endif /* SIMGRID_PUBLIC_CONFIG_H */ diff --git a/include/simgrid/disk.h b/include/simgrid/disk.h index 073219c255..c5032fef0b 100644 --- a/include/simgrid/disk.h +++ b/include/simgrid/disk.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2020-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2020-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/simgrid/engine.h b/include/simgrid/engine.h index dda7f55165..b5b652485e 100644 --- a/include/simgrid/engine.h +++ b/include/simgrid/engine.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,9 +11,9 @@ SG_BEGIN_DECL /* C interface */ - /** Initialize the SimGrid engine, taking the command line parameters of your main function. */ - XBT_PUBLIC void - simgrid_init(int* argc, char** argv); +/** Initialize the SimGrid engine, taking the command line parameters of your main function. */ +XBT_PUBLIC void +simgrid_init(int* argc, char** argv); /** Creates a new platform, including hosts, links, and the routing table. * @@ -51,9 +51,9 @@ XBT_PUBLIC void simgrid_set_maestro(void (*code)(void*), void* data); /** @brief Allow other libraries to react to the --help flag, too * - * When finding --help on the command line, simgrid usually stops right after displaying its help message. - * If you are writing a library using simgrid, you may want to display your own help message before everything stops. - * If so, just call this function before having simgrid parsing the command line, and you will be given the control + * When finding --help on the command line, SimGrid usually stops right after displaying its help message. + * If you are writing a library using SimGrid, you may want to display your own help message before everything stops. + * If so, just call this function before having SimGrid parsing the command line, and you will be given the control * even if the user is asking for help. */ XBT_PUBLIC void sg_config_continue_after_help(); diff --git a/include/simgrid/exec.h b/include/simgrid/exec.h index ba29c861b6..565684c3e9 100644 --- a/include/simgrid/exec.h +++ b/include/simgrid/exec.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,6 +12,8 @@ /* C interface */ SG_BEGIN_DECL +XBT_PUBLIC int sg_exec_isinstance(sg_activity_t acti); + XBT_PUBLIC void sg_exec_set_bound(sg_exec_t exec, double bound); XBT_PUBLIC const char* sg_exec_get_name(const_sg_exec_t exec); XBT_PUBLIC void sg_exec_set_name(sg_exec_t exec, const char* name); @@ -24,8 +26,11 @@ XBT_PUBLIC void sg_exec_cancel(sg_exec_t exec); XBT_PUBLIC int sg_exec_test(sg_exec_t exec); XBT_PUBLIC sg_error_t sg_exec_wait(sg_exec_t exec); XBT_PUBLIC sg_error_t sg_exec_wait_for(sg_exec_t exec, double timeout); -XBT_PUBLIC ssize_t sg_exec_wait_any_for(sg_exec_t* execs, size_t count, double timeout); -XBT_PUBLIC ssize_t sg_exec_wait_any(sg_exec_t* execs, size_t count); + +XBT_ATTRIB_DEPRECATED_v339("Please use sg_activity_set_t instead") XBT_PUBLIC ssize_t + sg_exec_wait_any_for(sg_exec_t* execs, size_t count, double timeout); +XBT_ATTRIB_DEPRECATED_v339("Please use sg_activity_set_t instead") XBT_PUBLIC ssize_t + sg_exec_wait_any(sg_exec_t* execs, size_t count); SG_END_DECL diff --git a/include/simgrid/forward.h b/include/simgrid/forward.h index 9b81d2a643..e2a0606227 100644 --- a/include/simgrid/forward.h +++ b/include/simgrid/forward.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -19,8 +19,14 @@ namespace s4u { class Activity; /** Smart pointer to a simgrid::s4u::Activity */ using ActivityPtr = boost::intrusive_ptr; -XBT_PUBLIC void intrusive_ptr_release(const Activity* actor); -XBT_PUBLIC void intrusive_ptr_add_ref(const Activity* actor); +XBT_PUBLIC void intrusive_ptr_release(const Activity* act); +XBT_PUBLIC void intrusive_ptr_add_ref(const Activity* act); + +class ActivitySet; +/** Smart pointer to a simgrid::s4u::Activity */ +using ActivitySetPtr = boost::intrusive_ptr; +XBT_PUBLIC void intrusive_ptr_release(const ActivitySet* as); +XBT_PUBLIC void intrusive_ptr_add_ref(const ActivitySet* as); class Actor; /** Smart pointer to a simgrid::s4u::Actor */ @@ -31,8 +37,8 @@ XBT_PUBLIC void intrusive_ptr_add_ref(const Actor* actor); class Barrier; /** Smart pointer to a simgrid::s4u::Barrier */ using BarrierPtr = boost::intrusive_ptr; -XBT_PUBLIC void intrusive_ptr_release(Barrier* m); -XBT_PUBLIC void intrusive_ptr_add_ref(Barrier* m); +XBT_PUBLIC void intrusive_ptr_release(Barrier* b); +XBT_PUBLIC void intrusive_ptr_add_ref(Barrier* b); class Comm; /** Smart pointer to a simgrid::s4u::Comm */ @@ -70,6 +76,14 @@ class SplitDuplexLink; class Mailbox; +class Mess; +/** Smart pointer to a simgrid::s4u::Mess */ +using MessPtr = boost::intrusive_ptr; +XBT_PUBLIC void intrusive_ptr_release(Mess* c); +XBT_PUBLIC void intrusive_ptr_add_ref(Mess* c); + +class MessageQueue; + class Mutex; XBT_PUBLIC void intrusive_ptr_release(const Mutex* m); XBT_PUBLIC void intrusive_ptr_add_ref(const Mutex* m); @@ -91,6 +105,19 @@ XBT_PUBLIC void intrusive_ptr_release(const Semaphore* m); XBT_PUBLIC void intrusive_ptr_add_ref(const Semaphore* m); class Disk; + +class Task; +/** Smart pointer to a simgrid::s4u::Task */ +using TaskPtr = boost::intrusive_ptr; +XBT_PUBLIC void intrusive_ptr_release(Task* o); +XBT_PUBLIC void intrusive_ptr_add_ref(Task* o); +class ExecTask; +using ExecTaskPtr = boost::intrusive_ptr; +class CommTask; +using CommTaskPtr = boost::intrusive_ptr; +class IoTask; +using IoTaskPtr = boost::intrusive_ptr; + /** * @brief Callback to dynamically change the resource's capacity * @@ -117,6 +144,10 @@ using ActorCodeFactory = std::function args)> class Simcall; class SimcallObserver; +class MutexObserver; +class ConditionVariableObserver; +class ObjectAccessSimcallObserver; +class ObjectAccessSimcallItem; } // namespace actor namespace activity { @@ -137,6 +168,8 @@ namespace activity { using ConditionVariableImplPtr = boost::intrusive_ptr; XBT_PUBLIC void intrusive_ptr_add_ref(ConditionVariableImpl* cond); XBT_PUBLIC void intrusive_ptr_release(ConditionVariableImpl* cond); + class ConditionVariableAcquisitionImpl; + using ConditionVariableAcquisitionImplPtr = boost::intrusive_ptr; class CommImpl; using CommImplPtr = boost::intrusive_ptr; @@ -144,6 +177,8 @@ namespace activity { using ExecImplPtr = boost::intrusive_ptr; class IoImpl; using IoImplPtr = boost::intrusive_ptr; + class MessImpl; + using MessImplPtr = boost::intrusive_ptr; class MutexImpl; using MutexImplPtr = boost::intrusive_ptr; class MutexAcquisitionImpl; @@ -162,6 +197,7 @@ namespace activity { using SleepImplPtr = boost::intrusive_ptr; class MailboxImpl; + class MessageQueueImpl; } namespace context { class Context; @@ -176,6 +212,7 @@ class System; } namespace resource { class Action; +class CpuAction; class CpuImpl; class Model; class Resource; @@ -183,12 +220,12 @@ class CpuModel; class HostImpl; class HostModel; class NetworkModel; -class NetworkModelIntf; class LinkImpl; class StandardLinkImpl; class SplitDuplexLinkImpl; class NetworkAction; class DiskImpl; +using DiskImplPtr = boost::intrusive_ptr; class DiskModel; class VirtualMachineImpl; class VMModel; @@ -208,10 +245,13 @@ class Profile; } // namespace kernel namespace mc { class State; +class RemoteApp; } } // namespace simgrid using s4u_Actor = simgrid::s4u::Actor; +using s4u_Activity = simgrid::s4u::Activity; +using s4u_ActivitySet = simgrid::s4u::ActivitySet; using s4u_Barrier = simgrid::s4u::Barrier; using s4u_Comm = simgrid::s4u::Comm; using s4u_Exec = simgrid::s4u::Exec; @@ -220,28 +260,19 @@ using s4u_Link = simgrid::s4u::Link; using s4u_File = simgrid::s4u::File; using s4u_ConditionVariable = simgrid::s4u::ConditionVariable; using s4u_Mailbox = simgrid::s4u::Mailbox; +using s4u_MessageQueue = simgrid::s4u::MessageQueue; using s4u_Mutex = simgrid::s4u::Mutex; using s4u_Semaphore = simgrid::s4u::Semaphore; using s4u_Disk = simgrid::s4u::Disk; using s4u_NetZone = simgrid::s4u::NetZone; using s4u_VM = simgrid::s4u::VirtualMachine; -using smx_timer_t - XBT_ATTRIB_DEPRECATED_v335("Please use simgrid::kernel::timer::Timer*") = simgrid::kernel::timer::Timer*; -using smx_actor_t - XBT_ATTRIB_DEPRECATED_v335("Please use simgrid::kernel::actor::ActorImpl*") = simgrid::kernel::actor::ActorImpl*; using smx_activity_t = simgrid::kernel::activity::ActivityImpl*; -using smx_cond_t XBT_ATTRIB_DEPRECATED_v335("Please use simgrid::kernel::activity::ConditionVariableImpl*") = - simgrid::kernel::activity::ConditionVariableImpl*; -using smx_mailbox_t XBT_ATTRIB_DEPRECATED_v335("Please use simgrid::kernel::activity::MailboxImpl*") = - simgrid::kernel::activity::MailboxImpl*; -using smx_mutex_t XBT_ATTRIB_DEPRECATED_v335("Please use simgrid::kernel::activity::MutexImpl*") = - simgrid::kernel::activity::MutexImpl*; -using smx_sem_t XBT_ATTRIB_DEPRECATED_v335("Please use simgrid::kernel::activity::SemaphoreImpl*") = - simgrid::kernel::activity::SemaphoreImpl*; #else typedef struct s4u_Actor s4u_Actor; +typedef struct s4u_Activity s4u_Activity; +typedef struct s4u_ActivitySet s4u_ActivitySet; typedef struct s4u_Barrier s4u_Barrier; typedef struct s4u_Comm s4u_Comm; typedef struct s4u_Exec s4u_Exec; @@ -250,34 +281,28 @@ typedef struct s4u_Link s4u_Link; typedef struct s4u_File s4u_File; typedef struct s4u_ConditionVariable s4u_ConditionVariable; typedef struct s4u_Mailbox s4u_Mailbox; +typedef struct s4u_MessageQueue s4u_MessageQueue; typedef struct s4u_Mutex s4u_Mutex; typedef struct s4u_Semaphore s4u_Semaphore; typedef struct s4u_Disk s4u_Disk; typedef struct s4u_NetZone s4u_NetZone; typedef struct s4u_VM s4u_VM; -XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef struct s_smx_timer* smx_timer_t; -XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef struct s_smx_actor* smx_actor_t; typedef struct s_smx_activity* smx_activity_t; -XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef struct s_smx_cond_t* smx_cond_t; -XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef struct s_smx_mailbox* smx_mailbox_t; -XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef struct s_smx_mutex* smx_mutex_t; -XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef struct s_smx_sem* smx_sem_t; #endif /** Pointer to a SimGrid barrier object */ typedef s4u_Barrier* sg_bar_t; -/** Constant pointer to a SimGrid barrier object */ -XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef const s4u_Barrier* const_sg_bar_t; typedef s4u_Comm* sg_comm_t; -XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef const s4u_Comm* const_sg_comm_t; typedef s4u_Exec* sg_exec_t; typedef const s4u_Exec* const_sg_exec_t; typedef s4u_ConditionVariable* sg_cond_t; typedef const s4u_ConditionVariable* const_sg_cond_t; typedef s4u_Mailbox* sg_mailbox_t; typedef const s4u_Mailbox* const_sg_mailbox_t; +typedef s4u_MessageQueue* sg_messagequeue_t; +typedef const s4u_MessageQueue* const_sg_messagequeue_t; typedef s4u_Mutex* sg_mutex_t; typedef const s4u_Mutex* const_sg_mutex_t; typedef s4u_Semaphore* sg_sem_t; @@ -301,13 +326,23 @@ typedef s4u_Actor* sg_actor_t; /** Pointer to a constant actor object */ typedef const s4u_Actor* const_sg_actor_t; +/** Pointer to an activity object */ +typedef s4u_Activity* sg_activity_t; +/** Pointer to a constant activity object */ +typedef const s4u_Activity* const_sg_activity_t; + +/** Pointer to an activity set object */ +typedef s4u_ActivitySet* sg_activity_set_t; +/** Pointer to a constant activity set object */ +typedef const s4u_ActivitySet* const_sg_activity_set_t; + /** @ingroup m_datatypes_management_details - * @brief Type for any simgrid size + * @brief Type for any SimGrid size */ typedef unsigned long long sg_size_t; /** @ingroup m_datatypes_management_details - * @brief Type for any simgrid offset + * @brief Type for any SimGrid offset */ typedef long long sg_offset_t; @@ -315,13 +350,13 @@ typedef long long sg_offset_t; typedef long aid_t; typedef enum { - SG_OK, - SG_ERROR_CANCELED, - SG_ERROR_TIMEOUT, - SG_ERROR_HOST, - SG_ERROR_NETWORK, - SG_ERROR_STORAGE, - SG_ERROR_VM + SG_OK /** Code returned when no problem occured */, + SG_ERROR_CANCELED /** Code returned when something got canceled before completion */, + SG_ERROR_TIMEOUT /** Code returned when timeout elapsed */, + SG_ERROR_HOST /** Code returned when a host fails */, + SG_ERROR_NETWORK /** Code returned when a communication fails because of the network or because of the remote host */, + SG_ERROR_STORAGE /** Code returned when a storage fails */, + SG_ERROR_VM /** Code returned when a VM fails */ } sg_error_t; XBT_PUBLIC int SMPI_is_inited(); diff --git a/include/simgrid/host.h b/include/simgrid/host.h index 37efe414fc..57c0a94f0c 100644 --- a/include/simgrid/host.h +++ b/include/simgrid/host.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -115,9 +115,6 @@ XBT_PUBLIC double sg_host_get_route_latency(const_sg_host_t from, const_sg_host_ XBT_PUBLIC double sg_host_get_route_bandwidth(const_sg_host_t from, const_sg_host_t to); XBT_PUBLIC void sg_host_sendto(sg_host_t from, sg_host_t to, double byte_amount); -XBT_ATTRIB_DEPRECATED_v335("Please manifest if you actually need this function") XBT_PUBLIC - void sg_host_dump(const_sg_host_t ws); - XBT_PUBLIC void sg_host_get_actor_list(const_sg_host_t host, xbt_dynar_t whereto); SG_END_DECL diff --git a/include/simgrid/instr.h b/include/simgrid/instr.h index cff543619a..91ff4e9168 100644 --- a/include/simgrid/instr.h +++ b/include/simgrid/instr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,17 +7,15 @@ #define INSTR_H_ #include -#include // XBT_ATTRIB_DEPRECATED_v334 #ifdef __cplusplus #include #include -namespace simgrid { -namespace instr { +namespace simgrid::instr { /* User-variables related functions*/ /* for host variables */ -XBT_PUBLIC void declare_host_variable(const std::string& variable, const std::string& color = std::string("")); +XBT_PUBLIC void declare_host_variable(const std::string& variable, const std::string& color = ""); XBT_PUBLIC void set_host_variable(const std::string& host, const std::string& variable, double value, double time = simgrid_get_clock()); XBT_PUBLIC void add_host_variable(const std::string& host, const std::string& variable, double value, @@ -27,7 +25,7 @@ XBT_PUBLIC void sub_host_variable(const std::string& host, const std::string& va XBT_PUBLIC const std::set>& get_host_variables(); /* for link variables */ -XBT_PUBLIC void declare_link_variable(const std::string& variable, const std::string& color = std::string("")); +XBT_PUBLIC void declare_link_variable(const std::string& variable, const std::string& color = ""); XBT_PUBLIC void set_link_variable(const std::string& link, const std::string& variable, double value, double time = simgrid_get_clock()); XBT_PUBLIC void add_link_variable(const std::string& link, const std::string& variable, double value, @@ -44,7 +42,7 @@ XBT_PUBLIC void sub_link_variable(const std::string& src, const std::string& dst XBT_PUBLIC const std::set>& get_link_variables(); /* for VM variables */ -XBT_PUBLIC void declare_vm_variable(const std::string& variable, const std::string& color = std::string("")); +XBT_PUBLIC void declare_vm_variable(const std::string& variable, const std::string& color = ""); XBT_PUBLIC void set_vm_variable(const std::string& vm, const std::string& variable, double value, double time = simgrid_get_clock()); XBT_PUBLIC void add_vm_variable(const std::string& vm, const std::string& variable, double value, @@ -56,7 +54,7 @@ XBT_PUBLIC const std::set>& get_vm_variables(); /* Functions to manage tracing marks (used for trace comparison experiments) */ XBT_PUBLIC void declare_mark(const std::string& mark_type); XBT_PUBLIC void declare_mark_value(const std::string& mark_type, const std::string& mark_value, - const std::string& mark_color = std::string("1 1 1")); + const std::string& mark_color = "1 1 1"); XBT_PUBLIC void mark(const std::string& mark_type, const std::string& mark_value); XBT_PUBLIC const std::set>& get_marks(); @@ -67,8 +65,7 @@ XBT_PUBLIC const std::set>& get_tracing_categories(); XBT_PUBLIC void platform_graph_export_graphviz(const std::string& output_filename); /* Function used by graphicator (transform a SimGrid platform file in a CSV file with the network topology) */ XBT_PUBLIC void platform_graph_export_csv(const std::string& output_filename); -} // namespace instr -} // namespace simgrid +} // namespace simgrid::instr #endif SG_BEGIN_DECL @@ -82,92 +79,6 @@ XBT_PUBLIC void TRACE_host_set_state(const char* host, const char* state, const XBT_PUBLIC void TRACE_host_push_state(const char* host, const char* state, const char* value); XBT_PUBLIC void TRACE_host_pop_state(const char* host, const char* state); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::platform_graph_export_graphviz") XBT_PUBLIC - int TRACE_platform_graph_export_graphviz(const char* filename); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_tracing_category") XBT_PUBLIC - void TRACE_category(const char* category); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_tracing_category") XBT_PUBLIC - void TRACE_category_with_color(const char* category, const char* color); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::get_tracing_categories") XBT_PUBLIC xbt_dynar_t - TRACE_get_categories(); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_mark") XBT_PUBLIC - void TRACE_declare_mark(const char* mark_type); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_mark_value") XBT_PUBLIC - void TRACE_declare_mark_value_with_color(const char* mark_type, const char* mark_value, const char* mark_color); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_mark_value") XBT_PUBLIC - void TRACE_declare_mark_value(const char* mark_type, const char* mark_value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::mark") XBT_PUBLIC - void TRACE_mark(const char* mark_type, const char* mark_value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::get_marks") XBT_PUBLIC xbt_dynar_t TRACE_get_marks(); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_vm_variable") XBT_PUBLIC - void TRACE_vm_variable_declare(const char* variable); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_vm_variable") XBT_PUBLIC - void TRACE_vm_variable_declare_with_color(const char* variable, const char* color); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::set_vm_variable") XBT_PUBLIC - void TRACE_vm_variable_set(const char* vm, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::add_vm_variable") XBT_PUBLIC - void TRACE_vm_variable_add(const char* vm, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::sub_vm_variable") XBT_PUBLIC - void TRACE_vm_variable_sub(const char* vm, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::set_vm_variable") XBT_PUBLIC - void TRACE_vm_variable_set_with_time(double time, const char* vm, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::add_vm_variable") XBT_PUBLIC - void TRACE_vm_variable_add_with_time(double time, const char* vm, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::sub_vm_variable") XBT_PUBLIC - void TRACE_vm_variable_sub_with_time(double time, const char* vm, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_host_variable") XBT_PUBLIC - void TRACE_host_variable_declare(const char* variable); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_host_variable") XBT_PUBLIC - void TRACE_host_variable_declare_with_color(const char* variable, const char* color); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::set_host_variable") XBT_PUBLIC - void TRACE_host_variable_set(const char* host, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::add_host_variable") XBT_PUBLIC - void TRACE_host_variable_add(const char* host, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::sub_host_variable") XBT_PUBLIC - void TRACE_host_variable_sub(const char* host, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::set_host_variable") XBT_PUBLIC - void TRACE_host_variable_set_with_time(double time, const char* host, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::add_host_variable") XBT_PUBLIC - void TRACE_host_variable_add_with_time(double time, const char* host, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::sub_host_variable") XBT_PUBLIC - void TRACE_host_variable_sub_with_time(double time, const char* host, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::get_host_variables") XBT_PUBLIC xbt_dynar_t - TRACE_get_host_variables(); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_link_variable") XBT_PUBLIC - void TRACE_link_variable_declare(const char* var); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::declare_link_variable") XBT_PUBLIC - void TRACE_link_variable_declare_with_color(const char* var, const char* color); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::set_link_variable") XBT_PUBLIC - void TRACE_link_variable_set(const char* link, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::add_link_variable") XBT_PUBLIC - void TRACE_link_variable_add(const char* link, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::sub_link_variable") XBT_PUBLIC - void TRACE_link_variable_sub(const char* link, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::set_link_variable") XBT_PUBLIC - void TRACE_link_variable_set_with_time(double time, const char* link, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::add_link_variable") XBT_PUBLIC - void TRACE_link_variable_add_with_time(double time, const char* link, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::sub_link_variable") XBT_PUBLIC - void TRACE_link_variable_sub_with_time(double time, const char* link, const char* variable, double value); - -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::set_link_variable") XBT_PUBLIC - void TRACE_link_srcdst_variable_set(const char* src, const char* dst, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::add_link_variable") XBT_PUBLIC - void TRACE_link_srcdst_variable_add(const char* src, const char* dst, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr:sub_link_variable") XBT_PUBLIC - void TRACE_link_srcdst_variable_sub(const char* src, const char* dst, const char* variable, double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::set_link_variable") XBT_PUBLIC - void TRACE_link_srcdst_variable_set_with_time(double time, const char* src, const char* dst, const char* variable, - double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::add_link_variable") XBT_PUBLIC - void TRACE_link_srcdst_variable_add_with_time(double time, const char* src, const char* dst, const char* variable, - double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr:sub_link_variable") XBT_PUBLIC - void TRACE_link_srcdst_variable_sub_with_time(double time, const char* src, const char* dst, const char* variable, - double value); -XBT_ATTRIB_DEPRECATED_v334("Please use simgrid::instr::get_link_variables") XBT_PUBLIC xbt_dynar_t - TRACE_get_link_variables(); - SG_END_DECL #endif /* INSTR_H_ */ diff --git a/include/simgrid/kernel/ProfileBuilder.hpp b/include/simgrid/kernel/ProfileBuilder.hpp index b4e5a1f359..8ec4f7ca8e 100644 --- a/include/simgrid/kernel/ProfileBuilder.hpp +++ b/include/simgrid/kernel/ProfileBuilder.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,10 +9,7 @@ #include #include -namespace simgrid { -namespace kernel { -namespace profile { - +namespace simgrid::kernel::profile { /** @brief Modeling of the availability profile (due to an external load) or the churn * @@ -75,8 +72,6 @@ public: static Profile* from_callback(const std::string& name, const std::function& cb, double repeat_delay); }; -} // namespace profile -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::profile #endif /* SIMGRID_KERNEL_PROFILEBUILDER_HPP */ diff --git a/include/simgrid/kernel/Timer.hpp b/include/simgrid/kernel/Timer.hpp index eca90a1abe..010a66f8fa 100644 --- a/include/simgrid/kernel/Timer.hpp +++ b/include/simgrid/kernel/Timer.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2021-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,9 +12,7 @@ #include -namespace simgrid { -namespace kernel { -namespace timer { +namespace simgrid::kernel::timer { inline auto& kernel_timers() // avoid static initialization order fiasco { @@ -48,8 +46,6 @@ public: static bool execute_all(); }; -} // namespace timer -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::timer #endif /* SRC_KERNEL_TIMER_TIMER_HPP_ */ diff --git a/include/simgrid/kernel/resource/Action.hpp b/include/simgrid/kernel/resource/Action.hpp index ac27f95182..48b1143466 100644 --- a/include/simgrid/kernel/resource/Action.hpp +++ b/include/simgrid/kernel/resource/Action.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,12 +13,11 @@ #include #include #include +#include static constexpr double NO_MAX_DURATION = -1.0; -namespace simgrid { -namespace kernel { -namespace resource { +namespace simgrid::kernel::resource { using heap_element_type = std::pair; using heap_type = @@ -68,7 +67,6 @@ class XBT_PUBLIC Action { double cost_; Model* model_; - void* data_ = nullptr; /**< for your convenience - XBT_ATTRIB_DEPRECATED_v334 */ activity::ActivityImpl* activity_ = nullptr; /* LMM */ @@ -157,17 +155,6 @@ public: /** @brief Get the finish time of the current action */ double get_finish_time() const { return finish_time_; } - /** @brief Get the user data associated to the current action */ - XBT_ATTRIB_DEPRECATED_v334("Please manifest if you actually need this function") void* get_data() const - { - return data_; - } - /** @brief Set the user data associated to the current action */ - XBT_ATTRIB_DEPRECATED_v334("Please manifest if you actually need this function") void set_data(void* data) - { - data_ = data; - } - /** @brief Get the user data associated to the current action */ activity::ActivityImpl* get_activity() const { return activity_; } /** @brief Set the user data associated to the current action */ @@ -227,7 +214,7 @@ public: /** @brief Get the tracing category associated to the current action */ const std::string& get_category() const { return category_; } /** @brief Set the tracing category of the current Action */ - void set_category(const std::string& category) { category_ = category; } + void set_category(std::string_view category) { category_ = category; } /** @brief Get the sharing_penalty (RTT or 1/thread_count) of the current Action */ double get_sharing_penalty() const { return sharing_penalty_; }; @@ -273,7 +260,5 @@ public: void set_suspend_state(Action::SuspendStates state) { suspended_ = state; } }; -} // namespace resource -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::resource #endif diff --git a/include/simgrid/kernel/resource/Model.hpp b/include/simgrid/kernel/resource/Model.hpp index c893e3232f..3a5affb668 100644 --- a/include/simgrid/kernel/resource/Model.hpp +++ b/include/simgrid/kernel/resource/Model.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,14 +10,8 @@ #include #include -namespace simgrid { -namespace kernel { -namespace resource { +namespace simgrid::kernel::resource { -/** @ingroup SURF_interface - * @brief SURF model interface class - * @details A model is an object which handle the interactions between its Resources and its Actions - */ class XBT_PUBLIC Model { public: /** @brief Possible update mechanisms */ @@ -114,8 +108,6 @@ private: ActionHeap action_heap_; }; -} // namespace resource -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::resource #endif diff --git a/include/simgrid/kernel/resource/NetworkModelIntf.hpp b/include/simgrid/kernel/resource/NetworkModelIntf.hpp deleted file mode 100644 index ee1c446c59..0000000000 --- a/include/simgrid/kernel/resource/NetworkModelIntf.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_KERNEL_RESOURCE_NETWORKMODELINTF_HPP -#define SIMGRID_KERNEL_RESOURCE_NETWORKMODELINTF_HPP - -#include - -#include -#include - -namespace simgrid { -namespace kernel { -namespace resource { - -/** @ingroup SURF_interface - * @brief Network Model interface class - */ -class XBT_PUBLIC NetworkModelIntf { -protected: - ~NetworkModelIntf() = default; - -public: - /** - * @brief Callback to set the bandwidth and latency factors used in a communication - * - * This callback offers more flexibility when setting the network factors. - * It is an alternative to SimGrid's configs, such as network/latency-factors - * and network/bandwidth-factors. - * - * @param size Communication size in bytes - * @param src Source host - * @param dst Destination host - * @param links Vectors with the links used in this comm - * @param netzones Set with NetZones involved in the comm - * @return Multiply factor - */ - using NetworkFactorCb = double(double size, const s4u::Host* src, const s4u::Host* dst, - const std::vector& links, - const std::unordered_set& netzones); - /** @brief Configure the latency factor callback */ - virtual void set_lat_factor_cb(const std::function& cb) = 0; - /** @brief Configure the bandwidth factor callback */ - virtual void set_bw_factor_cb(const std::function& cb) = 0; -}; - -} // namespace resource -} // namespace kernel -} // namespace simgrid - -#endif /* SIMGRID_KERNEL_RESOURCE_NETWORKMODELINTF_HPP */ diff --git a/include/simgrid/kernel/routing/ClusterZone.hpp b/include/simgrid/kernel/routing/ClusterZone.hpp index aee536d14f..8fc45120af 100644 --- a/include/simgrid/kernel/routing/ClusterZone.hpp +++ b/include/simgrid/kernel/routing/ClusterZone.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,9 +11,7 @@ #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** * @brief Placeholder for old ClusterZone class @@ -150,8 +148,6 @@ public: return node_pos_with_loopback(id) + (has_limiter_ ? 1 : 0); } }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing #endif /* SIMGRID_ROUTING_CLUSTER_HPP_ */ diff --git a/include/simgrid/kernel/routing/DijkstraZone.hpp b/include/simgrid/kernel/routing/DijkstraZone.hpp index 3ce8c77ebe..dbaef58130 100644 --- a/include/simgrid/kernel/routing/DijkstraZone.hpp +++ b/include/simgrid/kernel/routing/DijkstraZone.hpp @@ -1,16 +1,14 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_ROUTING_DIJKSTRA_HPP_ -#define SURF_ROUTING_DIJKSTRA_HPP_ +#ifndef SIMGRID_ROUTING_DIJKSTRA_HPP_ +#define SIMGRID_ROUTING_DIJKSTRA_HPP_ #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** @ingroup ROUTING_API * @brief NetZone with an explicit routing computed on need with Dijkstra @@ -53,8 +51,6 @@ public: void add_route(NetPoint* src, NetPoint* dst, NetPoint* gw_src, NetPoint* gw_dst, const std::vector& link_list, bool symmetrical) override; }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing -#endif /* SURF_ROUTING_DIJKSTRA_HPP_ */ +#endif /* SIMGRID_ROUTING_DIJKSTRA_HPP_ */ diff --git a/include/simgrid/kernel/routing/DragonflyZone.hpp b/include/simgrid/kernel/routing/DragonflyZone.hpp index 6488b063f5..acb1122ae5 100644 --- a/include/simgrid/kernel/routing/DragonflyZone.hpp +++ b/include/simgrid/kernel/routing/DragonflyZone.hpp @@ -1,17 +1,15 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_ROUTING_CLUSTER_DRAGONFLY_HPP_ -#define SURF_ROUTING_CLUSTER_DRAGONFLY_HPP_ +#ifndef SIMGRID_ROUTING_CLUSTER_DRAGONFLY_HPP_ +#define SIMGRID_ROUTING_CLUSTER_DRAGONFLY_HPP_ #include #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { class DragonflyRouter { public: @@ -109,7 +107,5 @@ private: unsigned int num_links_per_link_ = 1; // splitduplex -> 2, only for local link std::vector routers_; }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing #endif diff --git a/include/simgrid/kernel/routing/EmptyZone.hpp b/include/simgrid/kernel/routing/EmptyZone.hpp index a65125234f..f5fd3340e6 100644 --- a/include/simgrid/kernel/routing/EmptyZone.hpp +++ b/include/simgrid/kernel/routing/EmptyZone.hpp @@ -1,17 +1,15 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_ROUTING_NONE_HPP_ -#define SURF_ROUTING_NONE_HPP_ +#ifndef SIMGRID_ROUTING_NONE_HPP_ +#define SIMGRID_ROUTING_NONE_HPP_ #include #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** @ingroup ROUTING_API * @brief NetZone with no routing, useful with the constant network model @@ -32,8 +30,6 @@ public: void get_graph(const s_xbt_graph_t* graph, std::map>* /*nodes*/, std::map>* /*edges*/) override; }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing -#endif /* SURF_ROUTING_NONE_HPP_ */ +#endif /* SIMGRID_ROUTING_NONE_HPP_ */ diff --git a/include/simgrid/kernel/routing/FatTreeZone.hpp b/include/simgrid/kernel/routing/FatTreeZone.hpp index 7e6acce610..fabeea233a 100644 --- a/include/simgrid/kernel/routing/FatTreeZone.hpp +++ b/include/simgrid/kernel/routing/FatTreeZone.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,9 +8,7 @@ #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { class XBT_PRIVATE FatTreeLink; @@ -159,8 +157,6 @@ public: void build_upper_levels(const s4u::ClusterCallbacks& set_callbacks); void generate_dot_file(const std::string& filename = "fat_tree.dot") const; }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing #endif diff --git a/include/simgrid/kernel/routing/FloydZone.hpp b/include/simgrid/kernel/routing/FloydZone.hpp index ceaa58a3b5..6cfaa76075 100644 --- a/include/simgrid/kernel/routing/FloydZone.hpp +++ b/include/simgrid/kernel/routing/FloydZone.hpp @@ -1,16 +1,14 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_ROUTING_FLOYD_HPP_ -#define SURF_ROUTING_FLOYD_HPP_ +#ifndef SIMGRID_ROUTING_FLOYD_HPP_ +#define SIMGRID_ROUTING_FLOYD_HPP_ #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** @ingroup ROUTING_API * @brief NetZone with an explicit routing computed at initialization with Floyd-Warshal @@ -39,8 +37,6 @@ public: void add_route(NetPoint* src, NetPoint* dst, NetPoint* gw_src, NetPoint* gw_dst, const std::vector& link_list, bool symmetrical) override; }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing -#endif /* SURF_ROUTING_FLOYD_HPP_ */ +#endif /* SIMGRID_ROUTING_FLOYD_HPP_ */ diff --git a/include/simgrid/kernel/routing/FullZone.hpp b/include/simgrid/kernel/routing/FullZone.hpp index 314eb89b46..3a83895bb3 100644 --- a/include/simgrid/kernel/routing/FullZone.hpp +++ b/include/simgrid/kernel/routing/FullZone.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,9 +8,7 @@ #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** @ingroup ROUTING_API * @brief NetZone with an explicit routing provided by the user @@ -33,8 +31,6 @@ public: void add_route(NetPoint* src, NetPoint* dst, NetPoint* gw_src, NetPoint* gw_dst, const std::vector& link_list, bool symmetrical) override; }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing #endif /* SIMGRID_ROUTING_FULL_HPP_ */ diff --git a/include/simgrid/kernel/routing/NetPoint.hpp b/include/simgrid/kernel/routing/NetPoint.hpp index 72f1c8dd35..aca24523c9 100644 --- a/include/simgrid/kernel/routing/NetPoint.hpp +++ b/include/simgrid/kernel/routing/NetPoint.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -16,8 +16,7 @@ namespace simgrid { extern template class XBT_PUBLIC xbt::Extendable; -namespace kernel { -namespace routing { +namespace kernel::routing { /** @ingroup ROUTING_API * @brief Network cards are the vertices in the graph representing the network, used to compute paths between nodes. @@ -54,8 +53,7 @@ private: NetPoint::Type component_type_; NetZoneImpl* englobing_zone_ = nullptr; }; -} // namespace routing -} // namespace kernel +} // namespace kernel::routing } // namespace simgrid XBT_PUBLIC simgrid::kernel::routing::NetPoint* sg_netpoint_by_name_or_null(const char* name); diff --git a/include/simgrid/kernel/routing/NetZoneImpl.hpp b/include/simgrid/kernel/routing/NetZoneImpl.hpp index 55a1748a6f..ed13e52c52 100644 --- a/include/simgrid/kernel/routing/NetZoneImpl.hpp +++ b/include/simgrid/kernel/routing/NetZoneImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -16,9 +16,7 @@ #include #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { class Route { public: @@ -76,12 +74,13 @@ class XBT_PUBLIC NetZoneImpl : public xbt::PropertyHolder { s4u::NetZone piface_; // our content, as known to our graph routing algorithm (maps vertex_id -> vertex) - std::vector vertices_; + std::vector vertices_; std::map> links_; /* save split-duplex links separately, keep links_ with only LinkImpl* seen by the user * members of a split-duplex are saved in the links_ */ std::map, std::less<>> split_duplex_links_; std::map> hosts_; + std::map> gateways_; NetZoneImpl* parent_ = nullptr; std::vector children_; // sub-netzones @@ -89,7 +88,7 @@ class XBT_PUBLIC NetZoneImpl : public xbt::PropertyHolder { bool sealed_ = false; // We cannot add more content when sealed std::map, BypassRoute*> bypass_routes_; // src x dst -> route - routing::NetPoint* netpoint_ = nullptr; // Our representative in the parent NetZone + NetPoint* netpoint_ = nullptr; // Our representative in the parent NetZone protected: explicit NetZoneImpl(const std::string& name); @@ -144,7 +143,7 @@ public: const s4u::NetZone* get_iface() const { return &piface_; } s4u::NetZone* get_iface() { return &piface_; } unsigned int get_table_size() const { return vertices_.size(); } - std::vector get_vertices() const { return vertices_; } + std::vector get_vertices() const { return vertices_; } NetZoneImpl* get_parent() const { return parent_; } /** @brief Returns the list of direct children (no grand-children). This returns the internal data, no copy. * Don't mess with it.*/ @@ -158,7 +157,12 @@ public: const char* get_cname() const { return name_.c_str(); }; /** @brief Gets the netpoint associated to this netzone */ - kernel::routing::NetPoint* get_netpoint() const { return netpoint_; } + NetPoint* get_netpoint() const { return netpoint_; } + + void set_gateway(const std::string& name, NetPoint* router); + /** @brief Gets the gateway associated to this netzone */ + NetPoint* get_gateway() const; + NetPoint* get_gateway(const std::string& name) const { return gateways_.at(name); } std::vector get_all_hosts() const; size_t get_host_count() const; @@ -269,7 +273,7 @@ public: /*** Called on each newly created regular route (not on bypass routes) */ static xbt::signal const& link_list)> - on_route_creation; // XBT_ATTRIB_DEPRECATED_v332 : should be an internal signal used by NS3.. if necessary, + on_route_creation; // FIXME: XBT_ATTRIB_DEPRECATED_v332: should be an internal signal used by NS3.. if necessary, // callback shouldn't use LinkImpl* private: @@ -287,8 +291,6 @@ private: virtual resource::StandardLinkImpl* do_create_link(const std::string& name, const std::vector& bandwidths); void add_child(NetZoneImpl* new_zone); }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing #endif /* SIMGRID_ROUTING_NETZONEIMPL_HPP */ diff --git a/include/simgrid/kernel/routing/RoutedZone.hpp b/include/simgrid/kernel/routing/RoutedZone.hpp index 0e657cc710..cf96ee0de6 100644 --- a/include/simgrid/kernel/routing/RoutedZone.hpp +++ b/include/simgrid/kernel/routing/RoutedZone.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,9 +8,7 @@ #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** @ingroup ROUTING_API * @brief NetZone with an explicit routing (abstract class) @@ -59,8 +57,6 @@ protected: void add_route_check_params(NetPoint* src, NetPoint* dst, NetPoint* gw_src, NetPoint* gw_dst, const std::vector& link_list, bool symmetrical) const; }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing #endif /* SIMGRID_ROUTING_GENERIC_HPP_ */ diff --git a/include/simgrid/kernel/routing/StarZone.hpp b/include/simgrid/kernel/routing/StarZone.hpp index 372d270d74..dc533e0dcf 100644 --- a/include/simgrid/kernel/routing/StarZone.hpp +++ b/include/simgrid/kernel/routing/StarZone.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,9 +11,7 @@ #include #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** @ingroup ROUTING_API * @brief NetZone where components are connected following a star topology @@ -93,8 +91,6 @@ private: bool symmetrical) const; std::unordered_map routes_; }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing #endif /* SIMGRID_KERNEL_ROUTING_STARZONE_HPP_ */ diff --git a/include/simgrid/kernel/routing/TorusZone.hpp b/include/simgrid/kernel/routing/TorusZone.hpp index 22f2511202..4eeed3e691 100644 --- a/include/simgrid/kernel/routing/TorusZone.hpp +++ b/include/simgrid/kernel/routing/TorusZone.hpp @@ -1,18 +1,16 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_ROUTING_CLUSTER_TORUS_HPP_ -#define SURF_ROUTING_CLUSTER_TORUS_HPP_ +#ifndef SIMGRID_ROUTING_CLUSTER_TORUS_HPP_ +#define SIMGRID_ROUTING_CLUSTER_TORUS_HPP_ #include #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** @ingroup ROUTING_API * @brief NetZone using a Torus topology @@ -32,7 +30,5 @@ public: static std::vector parse_topo_parameters(const std::string& topo_parameters); }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing #endif diff --git a/include/simgrid/kernel/routing/VivaldiZone.hpp b/include/simgrid/kernel/routing/VivaldiZone.hpp index 2b4d6b2d2a..c64353ad15 100644 --- a/include/simgrid/kernel/routing/VivaldiZone.hpp +++ b/include/simgrid/kernel/routing/VivaldiZone.hpp @@ -1,17 +1,15 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_ROUTING_VIVALDI_HPP_ -#define SURF_ROUTING_VIVALDI_HPP_ +#ifndef SIMGRID_ROUTING_VIVALDI_HPP_ +#define SIMGRID_ROUTING_VIVALDI_HPP_ #include #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** @ingroup ROUTING_API * @brief NetZone modeling peers connected to the cloud through a private link @@ -60,8 +58,6 @@ public: std::vector coords; }; } // namespace vivaldi -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing -#endif /* SURF_ROUTING_VIVALDI_HPP_ */ +#endif /* SIMGRID_ROUTING_VIVALDI_HPP_ */ diff --git a/include/simgrid/kernel/routing/WifiZone.hpp b/include/simgrid/kernel/routing/WifiZone.hpp index ee3961bc66..d2c61082bf 100644 --- a/include/simgrid/kernel/routing/WifiZone.hpp +++ b/include/simgrid/kernel/routing/WifiZone.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,9 +8,7 @@ #include -namespace simgrid { -namespace kernel { -namespace routing { +namespace simgrid::kernel::routing { /** @ingroup ROUTING_API * @brief NetZone modeling a Wifi zone @@ -33,8 +31,6 @@ public: void get_local_route(const NetPoint* src, const NetPoint* dst, Route* into, double* latency) override; NetPoint* get_access_point() const { return access_point_; } }; -} // namespace routing -} // namespace kernel -} // namespace simgrid +} // namespace simgrid::kernel::routing #endif /* SIMGRID_ROUTING_WIFI_HPP_ */ diff --git a/include/simgrid/link.h b/include/simgrid/link.h index c35ebfab07..82416b2541 100644 --- a/include/simgrid/link.h +++ b/include/simgrid/link.h @@ -1,6 +1,6 @@ /* Public interface to the Link datatype */ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/simgrid/mailbox.h b/include/simgrid/mailbox.h index 7680a6d73b..557f13da5f 100644 --- a/include/simgrid/mailbox.h +++ b/include/simgrid/mailbox.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/simgrid/modelchecker.h b/include/simgrid/modelchecker.h index 661fc12b1b..09566a3b82 100644 --- a/include/simgrid/modelchecker.h +++ b/include/simgrid/modelchecker.h @@ -1,72 +1,27 @@ /* simgrid/modelchecker.h - Formal Verification made possible in SimGrid */ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -/** \file modelchecker.h - * - * This is the API used by the user simulated program to communicate - * with the MC. - */ - #ifndef SIMGRID_MODELCHECKER_H #define SIMGRID_MODELCHECKER_H -#include /* SIMGRID_HAVE_MC ? */ -#include - #include /* size_t */ +#include SG_BEGIN_DECL /** Explore every branches where that function returns a value between min and max (inclusive) */ XBT_PUBLIC int MC_random(int min, int max); -#if SIMGRID_HAVE_MC - -/* Internal variable used to check if we're running under the MC - * - * Please don't use directly: you should use MC_is_active. */ -extern XBT_PUBLIC int _sg_do_model_check; -extern XBT_PUBLIC int _sg_mc_max_visited_states; - -#define MC_is_active() _sg_do_model_check -#define MC_visited_reduction() _sg_mc_max_visited_states - -/** Assertion for the model-checker - * - * This function is used to define safety properties to verify. - */ +/** Assertion for the model-checker: Defines a safety property to verify */ XBT_PUBLIC void MC_assert(int); -XBT_PUBLIC void MC_automaton_new_propositional_symbol(const char* id, int (*fct)(void)); -XBT_PUBLIC void MC_automaton_new_propositional_symbol_pointer(const char* id, int* value); - -XBT_PUBLIC void MC_cut(void); -XBT_PUBLIC void MC_ignore(void* addr, size_t size); - -XBT_PUBLIC void MC_ignore_heap(void* address, size_t size); -XBT_PUBLIC void MC_unignore_heap(void* address, size_t size); -XBT_PUBLIC void MC_ignore_global_variable(const char* var_name); - -#else - -#define MC_is_active() 0 -#define MC_visited_reduction() 0 - -#define MC_assert(a) xbt_assert(a) -#define MC_automaton_new_propositional_symbol(a, b) ((void)0) -#define MC_automaton_new_propositional_symbol_pointer(a, b) ((void)0) -#define MC_cut() ((void)0) -#define MC_ignore(a, b) ((void)0) - -#define MC_ignore_heap(a,s) ((void)0) -#define MC_remove_ignore_heap(a,s) ((void)0) -#define MC_ignore_global_variable(v) ((void)0) - -#endif +/** Check whether the model-checker is currently active, ie if this process was started with simgrid-mc. + * It is off in simulation or when replaying MC traces (see MC_record_replay_is_active()) */ +XBT_PUBLIC int MC_is_active(); SG_END_DECL diff --git a/include/simgrid/msg.h b/include/simgrid/msg.h deleted file mode 100644 index 60cc280972..0000000000 --- a/include/simgrid/msg.h +++ /dev/null @@ -1,420 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MSG_H -#define SIMGRID_MSG_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif - -#ifdef __cplusplus -namespace simgrid { -namespace msg { -class Comm; -class Task; -} -} -using sg_msg_Comm = simgrid::msg::Comm; -using sg_msg_Task = simgrid::msg::Task; -#else -typedef struct msg_Comm sg_msg_Comm; -typedef struct msg_Task sg_msg_Task; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** @brief Return code of most MSG functions */ -/* Keep these code as binary values: java bindings manipulate | of these values */ -typedef enum { - MSG_OK = 0, /**< @brief Everything is right. Keep on going this way ! */ - MSG_TIMEOUT = 1, /**< @brief nothing good happened before the timer you provided elapsed */ - MSG_TRANSFER_FAILURE = 2, /**< @brief There has been a problem during you task - transfer. Either the network is down or the remote host has been - shutdown. */ - MSG_HOST_FAILURE = 4, /**< @brief System shutdown. The host on which you are - running has just been rebooted. Free your datastructures and - return now !*/ - MSG_TASK_CANCELED = 8 /**< @brief Canceled task. This task has been canceled by somebody!*/ -} msg_error_t; - -/* *************************** Network Zones ******************************** */ -typedef sg_netzone_t msg_netzone_t; - -XBT_PUBLIC msg_netzone_t MSG_zone_get_root(); -XBT_PUBLIC const char* MSG_zone_get_name(const_sg_netzone_t zone); -XBT_PUBLIC msg_netzone_t MSG_zone_get_by_name(const char* name); -XBT_PUBLIC void MSG_zone_get_sons(const_sg_netzone_t zone, xbt_dict_t whereto); -XBT_PUBLIC const char* MSG_zone_get_property_value(const_sg_netzone_t zone, const char* name); -XBT_PUBLIC void MSG_zone_set_property_value(msg_netzone_t zone, const char* name, const char* value); -XBT_PUBLIC void MSG_zone_get_hosts(const_sg_netzone_t zone, xbt_dynar_t whereto); - -/* ******************************** Hosts ************************************ */ -/** @brief Host datatype. - * - * A location (or host) is any possible place where a process may run. Thus it is represented as a - * physical resource with computing capabilities, some mailboxes to enable running process to - * communicate with remote ones, and some private data that can be only accessed by local process. - */ -typedef sg_host_t msg_host_t; - -/** @brief Finds a msg_host_t using its name. */ -XBT_PUBLIC sg_host_t MSG_get_host_by_name(const char* name); -/** @brief Finds a msg_host_t using its name. */ -XBT_PUBLIC sg_host_t MSG_host_by_name(const char* name); - -/** @brief Returns the amount of host found in the platform */ -XBT_PUBLIC size_t MSG_get_host_number(); - -/** @brief Returns the name of this host */ -XBT_PUBLIC const char* MSG_host_get_name(const_sg_host_t host); -/** @brief Returns the user data of this host */ -XBT_PUBLIC void* MSG_host_get_data(const_sg_host_t host); -/** @brief Sets the user data of this host */ -XBT_PUBLIC void MSG_host_set_data(sg_host_t host, void* data); - -XBT_PUBLIC double MSG_host_get_speed(const_sg_host_t host); -XBT_PUBLIC double MSG_host_get_power_peak_at(const_sg_host_t host, int pstate_index); -XBT_PUBLIC int MSG_host_get_core_number(const_sg_host_t host); -XBT_PUBLIC int MSG_host_get_nb_pstates(const_sg_host_t host); -XBT_PUBLIC int MSG_host_get_pstate(const_sg_host_t host); -XBT_PUBLIC void MSG_host_set_pstate(sg_host_t host, int pstate); -/** @brief Start the host if it is off - * - * @beginrst - * See also :cpp:func:`MSG_host_is_on()` to test the current state of the host, and :ref:`plugin_host_energy` - * for more info on DVFS. - * @endrst - */ -XBT_PUBLIC void MSG_host_on(sg_host_t h); -/** @brief Stop the host if it is on - * - * @beginrst - * See also :cpp:func:`MSG_host_is_on()` to test the current state of the host, and :ref:`plugin_host_energy` - * for more info on DVFS. - * @endrst - */ -XBT_PUBLIC void MSG_host_off(sg_host_t h); -XBT_PUBLIC int MSG_host_is_on(const_sg_host_t h); -XBT_PUBLIC xbt_dict_t MSG_host_get_properties(const_sg_host_t host); -XBT_PUBLIC const char* MSG_host_get_property_value(const_sg_host_t host, const char* name); -XBT_PUBLIC void MSG_host_set_property_value(sg_host_t host, const char* name, const char* value); -XBT_PUBLIC void MSG_host_get_process_list(const_sg_host_t host, xbt_dynar_t whereto); - -/** @brief Return the location on which the current process is executed */ -XBT_PUBLIC sg_host_t MSG_host_self(); -XBT_PUBLIC double MSG_host_get_load(const_sg_host_t host); - -/* ******************************** VMs ************************************* */ -typedef sg_vm_t msg_vm_t; - -XBT_PUBLIC msg_vm_t MSG_vm_create_core(msg_host_t pm, const char* name); -XBT_PUBLIC msg_vm_t MSG_vm_create_multicore(msg_host_t pm, const char* name, int coreAmount); - -XBT_PUBLIC int MSG_vm_is_created(const_sg_vm_t vm); -XBT_PUBLIC int MSG_vm_is_running(const_sg_vm_t vm); -XBT_PUBLIC int MSG_vm_is_suspended(const_sg_vm_t vm); - -XBT_PUBLIC const char* MSG_vm_get_name(const_sg_vm_t vm); -XBT_PUBLIC void MSG_vm_set_ramsize(msg_vm_t vm, size_t size); -XBT_PUBLIC size_t MSG_vm_get_ramsize(const_sg_vm_t vm); -XBT_PUBLIC msg_host_t MSG_vm_get_pm(const_sg_vm_t vm); -XBT_PUBLIC void MSG_vm_set_bound(msg_vm_t vm, double bound); - -XBT_PUBLIC void MSG_vm_start(msg_vm_t vm); -XBT_PUBLIC void MSG_vm_suspend(msg_vm_t vm); -XBT_PUBLIC void MSG_vm_resume(msg_vm_t vm); -XBT_PUBLIC void MSG_vm_shutdown(msg_vm_t vm); -XBT_PUBLIC void MSG_vm_destroy(msg_vm_t vm); - -/* ******************************** Actor/process *************************** */ -/** Processes are independent agents that can do stuff on their own. - * They are in charge of executing your code interacting with the simulated world. - * A process may be defined as a code with some private data. - * Processes must be located on hosts (#msg_host_t), and they exchange data by sending tasks (#msg_task_t) - * that are similar to envelops containing data. - * - * @hideinitializer - */ -typedef sg_actor_t msg_process_t; - -XBT_PUBLIC int MSG_process_get_PID(const_sg_actor_t process); -XBT_PUBLIC int MSG_process_get_PPID(const_sg_actor_t process); -/** @brief Return a process from its PID (or NULL if not found). - * - * Note that the PID are unique in the whole simulation, not only on a given host. - */ -XBT_PUBLIC sg_actor_t MSG_process_from_PID(int pid); -XBT_PUBLIC const char* MSG_process_get_name(const_sg_actor_t process); -XBT_PUBLIC sg_host_t MSG_process_get_host(const_sg_actor_t process); - -/*property handlers*/ -XBT_PUBLIC xbt_dict_t MSG_process_get_properties(const_sg_actor_t process); -XBT_PUBLIC const char* MSG_process_get_property_value(const_sg_actor_t process, const char* name); - -XBT_PUBLIC void MSG_process_suspend(msg_process_t process); -XBT_PUBLIC void MSG_process_resume(msg_process_t process); -XBT_PUBLIC int MSG_process_is_suspended(const_sg_actor_t process); -XBT_PUBLIC void MSG_process_restart(msg_process_t process); -/** @brief Sets the "auto-restart" flag of the process. - * - * If the flag is set, the process will be automatically restarted when its host comes back up. - */ -XBT_PUBLIC void MSG_process_auto_restart_set(msg_process_t process, int auto_restart); -/** @brief Indicates that this process should not prevent the simulation from ending - * - * SimGrid simulations run until all non-daemon processes are stopped. - */ -XBT_PUBLIC void MSG_process_daemonize(msg_process_t process); -/** @brief Immediately changes the host on which this process runs */ -XBT_PUBLIC void MSG_process_migrate(msg_process_t process, msg_host_t host); -/** @brief Wait for the completion of a process. - * - * @param process the process to wait for - * @param timeout wait until the process is over, or the timeout occurs - */ -XBT_PUBLIC void MSG_process_join(const_sg_actor_t process, double timeout); -/** @brief Kills a process */ -XBT_PUBLIC void MSG_process_kill(msg_process_t process); -/** @brief Kill all running process */ -XBT_PUBLIC void MSG_process_killall(); -/** @brief Specifies the time at which the process should be automatically killed */ -XBT_PUBLIC void MSG_process_set_kill_time(msg_process_t process, double kill_time); -/** @brief Yield the current actor; let the other actors execute first */ -XBT_PUBLIC void MSG_process_yield(); -/*** @brief Sleep for the specified number of seconds */ -XBT_PUBLIC msg_error_t MSG_process_sleep(double nb_sec); -XBT_PUBLIC msg_process_t MSG_process_self(); -XBT_PUBLIC aid_t MSG_process_self_PID(); -XBT_PUBLIC aid_t MSG_process_self_PPID(); -XBT_PUBLIC const char* MSG_process_self_name(); -XBT_PUBLIC void MSG_process_ref(const_sg_actor_t process); -XBT_PUBLIC void MSG_process_unref(const_sg_actor_t process); - -/** @brief Object representing an ongoing communication between processes. - * - * @beginrst - * Such beast is usually obtained by using :cpp:func:`MSG_task_isend`, :cpp:func:`MSG_task_irecv` or friends. - * @endrst - */ -typedef sg_msg_Comm* msg_comm_t; -typedef const sg_msg_Comm* const_msg_comm_t; - -/** @brief Task datatype. - * - * Since most scheduling algorithms rely on a concept of task that can be either computed locally or - * transferred on another processor, it seems to be the right level of abstraction for our purposes. - * A task may then be defined by a computing amount, a message size and - * some private data. - */ -typedef sg_msg_Task* msg_task_t; -typedef const sg_msg_Task* const_msg_task_t; - -/* ******************************** Task ************************************ */ - - -/** @brief Default value for an uninitialized #msg_task_t. */ -#define MSG_TASK_UNINITIALIZED NULL - -/************************** Global ******************************************/ -/** @brief set a configuration variable - * - * @beginrst - * Do --help on any simgrid binary to see the list of currently existing configuration variables, and see Section - * :ref:`options`. - * @endrst - * - * Example: - * MSG_config("host/model","ptask_L07"); - */ -XBT_PUBLIC void MSG_config(const char* key, const char* value); -/** @brief Initialize the MSG internal data. - * @hideinitializer - * - * It also checks that the link-time and compile-time versions of SimGrid do - * match, so you should use this version instead of the #MSG_init_nocheck - * function that does the same initializations, but without this check. - * - * We allow linking against compiled versions that differ in the patch level. - */ -#define MSG_init(argc, argv) \ - do { \ - sg_version_check(SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR, SIMGRID_VERSION_PATCH); \ - MSG_init_nocheck((argc), (argv)); \ - } while (0) - -XBT_PUBLIC void MSG_init_nocheck(int* argc, char** argv); -/** @brief Launch the MSG simulation */ -XBT_PUBLIC msg_error_t MSG_main(); -/** @brief Registers the main function of a process in a global table. - * - * This table is then used by #MSG_launch_application. - * @param name the reference name of the function. - * @param code the function (must have the same prototype than the main function of any C program: int ..(int argc, char - * *argv[])) - */ -XBT_PUBLIC void MSG_function_register(const char* name, int (*code)(int, char**)); -/** @brief Registers a code function as being the default value. - * - * This function will get used by MSG_launch_application() when there is no registered function of the requested name - * in. - * - * @param code the function (must have the same prototype than the main function of any C program: int ..(int argc, char - * *argv[])) - */ -XBT_PUBLIC void MSG_function_register_default(int (*code)(int, char**)); -/** @brief Creates a new platform, including hosts, links and the routing_table */ -XBT_PUBLIC void MSG_create_environment(const char* file); -/** @brief Creates the application described in the provided file */ -XBT_PUBLIC void MSG_launch_application(const char* file); - -/** @brief A clock (in second). */ -XBT_PUBLIC double MSG_get_clock(); -/** @brief Returns the amount of messages sent since the simulation start */ -XBT_PUBLIC unsigned long int MSG_get_sent_msg(); - -/************************** Process handling *********************************/ -XBT_PUBLIC msg_process_t MSG_process_create(const char* name, int (*code)(int, char**), void* data, msg_host_t host); -XBT_PUBLIC msg_process_t MSG_process_create_with_arguments(const char* name, int (*code)(int, char**), void* data, - msg_host_t host, int argc, char** argv); -XBT_PUBLIC msg_process_t MSG_process_create_with_environment(const char* name, int (*code)(int, char**), void* data, - msg_host_t host, int argc, char** argv, - xbt_dict_t properties); - -XBT_PUBLIC msg_process_t MSG_process_attach(const char* name, void* data, msg_host_t host, xbt_dict_t properties); -XBT_PUBLIC void MSG_process_detach(); - -XBT_PUBLIC void MSG_process_set_data_cleanup(void_f_pvoid_t data_cleanup); - -XBT_PUBLIC void* MSG_process_get_data(const_sg_actor_t process); -XBT_PUBLIC msg_error_t MSG_process_set_data(msg_process_t process, void* data); - -XBT_PUBLIC void MSG_process_on_exit(int_f_int_pvoid_t fun, void* data); - -/************************** Task handling ************************************/ -XBT_PUBLIC msg_task_t MSG_task_create(const char* name, double flops_amount, double bytes_amount, void* data); -XBT_PUBLIC msg_task_t MSG_parallel_task_create(const char* name, int host_nb, const msg_host_t* host_list, - double* flops_amount, double* bytes_amount, void* data); -XBT_PUBLIC void* MSG_task_get_data(const_msg_task_t task); -XBT_PUBLIC void MSG_task_set_data(msg_task_t task, void* data); -XBT_PUBLIC msg_process_t MSG_task_get_sender(const_msg_task_t task); -XBT_PUBLIC msg_host_t MSG_task_get_source(const_msg_task_t task); -XBT_PUBLIC const char* MSG_task_get_name(const_msg_task_t task); -XBT_PUBLIC void MSG_task_set_name(msg_task_t task, const char* name); -XBT_PUBLIC msg_error_t MSG_task_cancel(msg_task_t task); -XBT_PUBLIC msg_error_t MSG_task_destroy(msg_task_t task); - -XBT_PUBLIC msg_error_t MSG_task_execute(msg_task_t task); -XBT_PUBLIC msg_error_t MSG_parallel_task_execute(msg_task_t task); -XBT_PUBLIC msg_error_t MSG_parallel_task_execute_with_timeout(msg_task_t task, double timeout); -XBT_PUBLIC void MSG_task_set_priority(msg_task_t task, double priority); -XBT_PUBLIC void MSG_task_set_bound(msg_task_t task, double bound); - -XBT_PUBLIC void MSG_task_set_flops_amount(msg_task_t task, double flops_amount); -XBT_PUBLIC double MSG_task_get_flops_amount(const_msg_task_t task); -XBT_PUBLIC double MSG_task_get_remaining_work_ratio(const_msg_task_t task); -XBT_PUBLIC void MSG_task_set_bytes_amount(msg_task_t task, double bytes_amount); - -XBT_PUBLIC double MSG_task_get_remaining_communication(const_msg_task_t task); -XBT_PUBLIC double MSG_task_get_bytes_amount(const_msg_task_t task); - -XBT_PUBLIC msg_error_t MSG_task_receive_with_timeout(msg_task_t* task, const char* alias, double timeout); - -XBT_PUBLIC msg_error_t MSG_task_receive(msg_task_t* task, const char* alias); -#define MSG_task_recv(t, a) MSG_task_receive((t), (a)) - -XBT_PUBLIC msg_error_t MSG_task_receive_with_timeout_bounded(msg_task_t* task, const char* alias, double timeout, - double rate); -XBT_PUBLIC msg_error_t MSG_task_receive_bounded(msg_task_t* task, const char* alias, double rate); -#define MSG_task_recv_bounded(t, a, r) MSG_task_receive_bounded((t), (a), (r)) - -XBT_PUBLIC msg_comm_t MSG_task_isend(msg_task_t task, const char* alias); -XBT_PUBLIC msg_comm_t MSG_task_isend_bounded(msg_task_t task, const char* alias, double maxrate); - -XBT_PUBLIC void MSG_task_dsend(msg_task_t task, const char* alias, void_f_pvoid_t cleanup); -XBT_PUBLIC void MSG_task_dsend_bounded(msg_task_t task, const char* alias, void_f_pvoid_t cleanup, double maxrate); -XBT_PUBLIC msg_comm_t MSG_task_irecv(msg_task_t* task, const char* alias); -XBT_PUBLIC msg_comm_t MSG_task_irecv_bounded(msg_task_t* task, const char* alias, double rate); -XBT_PUBLIC int MSG_comm_test(msg_comm_t comm); -XBT_PUBLIC int MSG_comm_testany(const_xbt_dynar_t comms); -XBT_PUBLIC void MSG_comm_destroy(const_msg_comm_t comm); -XBT_PUBLIC msg_error_t MSG_comm_wait(msg_comm_t comm, double timeout); -XBT_PUBLIC void MSG_comm_waitall(msg_comm_t* comm, int nb_elem, double timeout); -XBT_PUBLIC int MSG_comm_waitany(const_xbt_dynar_t comms); -XBT_PUBLIC msg_task_t MSG_comm_get_task(const_msg_comm_t comm); -XBT_PUBLIC msg_error_t MSG_comm_get_status(const_msg_comm_t comm); - -/** @brief Check if there is a communication going on in a mailbox. - * - * @param alias the name of the mailbox to be considered - * - * @return Returns 1 if there is a communication, 0 otherwise - */ -XBT_PUBLIC int MSG_task_listen(const char* alias); -XBT_PUBLIC msg_error_t MSG_task_send_with_timeout(msg_task_t task, const char* alias, double timeout); -XBT_PUBLIC msg_error_t MSG_task_send_with_timeout_bounded(msg_task_t task, const char* alias, double timeout, - double maxrate); -XBT_PUBLIC msg_error_t MSG_task_send(msg_task_t task, const char* alias); -XBT_PUBLIC msg_error_t MSG_task_send_bounded(msg_task_t task, const char* alias, double rate); -XBT_PUBLIC int MSG_task_listen_from(const char* alias); -XBT_PUBLIC void MSG_task_set_category(msg_task_t task, const char* category); -XBT_PUBLIC const char* MSG_task_get_category(const_msg_task_t task); - -/************************** Mailbox handling ************************************/ - -/* @brief set a mailbox in eager mode. - * All messages sent to this mailbox will be transferred to the receiver without waiting for the receive call. - * The receive call will still be necessary to use the received data. - * If there is a need to receive some messages asynchronously, and some not, two different mailboxes should be used. - * - * This call should be done before issuing any receive, and on the receiver's side only - */ -XBT_PUBLIC void MSG_mailbox_set_async(const char* alias); - -/** @brief Opaque type representing a semaphore */ -typedef sg_sem_t msg_sem_t; -XBT_PUBLIC msg_sem_t MSG_sem_init(int initial_value); -XBT_PUBLIC void MSG_sem_acquire(msg_sem_t sem); -XBT_PUBLIC int MSG_sem_acquire_timeout(msg_sem_t sem, double timeout); -XBT_PUBLIC void MSG_sem_release(msg_sem_t sem); -XBT_PUBLIC int MSG_sem_get_capacity(const_sg_sem_t sem); -XBT_PUBLIC void MSG_sem_destroy(const_sg_sem_t sem); -XBT_PUBLIC int MSG_sem_would_block(const_sg_sem_t sem); - -/** @brief Opaque type representing a barrier identifier */ -typedef sg_bar_t msg_bar_t; -/** @brief Initializes a barrier, with count elements */ -XBT_PUBLIC msg_bar_t MSG_barrier_init(unsigned int count); -/** @brief Destroys barrier */ -XBT_PUBLIC void MSG_barrier_destroy(sg_bar_t bar); -/** @brief Performs a barrier already initialized */ -XBT_PUBLIC int MSG_barrier_wait(msg_bar_t bar); - -/* ****************************************************************************************** */ -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/simgrid/mutex.h b/include/simgrid/mutex.h index 11f7a06b7e..12c5fa4a54 100644 --- a/include/simgrid/mutex.h +++ b/include/simgrid/mutex.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/simgrid/plugins/ProducerConsumer.hpp b/include/simgrid/plugins/ProducerConsumer.hpp index 6f4f909aef..d4438e4ad7 100644 --- a/include/simgrid/plugins/ProducerConsumer.hpp +++ b/include/simgrid/plugins/ProducerConsumer.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2021-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,15 +22,21 @@ XBT_LOG_EXTERNAL_CATEGORY(producer_consumer); /** Stock implementation of a generic monitored queue to solve the producer-consumer problem */ -namespace simgrid { -namespace plugin { +namespace simgrid::plugin { template class ProducerConsumer; template using ProducerConsumerPtr = boost::intrusive_ptr>; -XBT_PUBLIC_DATA unsigned long pc_id; +class ProducerConsumerId { +private: + static unsigned long pc_id; + +protected: + const std::string id = "ProducerConsumer" + std::to_string(pc_id); + ProducerConsumerId() { ++pc_id; } +}; -template class ProducerConsumer { +template class ProducerConsumer : public ProducerConsumerId { public: /** This ProducerConsumer plugin can use two different transfer modes: * - TransferMode::MAILBOX: this mode induces a s4u::Comm between the actors doing the calls to put() and get(). @@ -45,8 +51,6 @@ public: enum class TransferMode { MAILBOX = 0, QUEUE }; private: - std::string id; - /* Implementation of a Monitor to handle the data exchanges */ s4u::MutexPtr mutex_; s4u::ConditionVariablePtr can_put_; @@ -75,9 +79,6 @@ private: { xbt_assert(max_queue_size > 0, "Max queue size of 0 is not allowed"); - id = std::string("ProducerConsumer") + std::to_string(pc_id); - pc_id++; - mutex_ = s4u::Mutex::create(); can_put_ = s4u::ConditionVariable::create(); can_get_ = s4u::ConditionVariable::create(); @@ -102,7 +103,7 @@ public: */ ProducerConsumer* set_max_queue_size(unsigned int max_queue_size) { - std::unique_lock lock(*mutex_); + const std::scoped_lock lock(*mutex_); max_queue_size_ = max_queue_size; return this; } @@ -139,7 +140,7 @@ public: */ s4u::CommPtr put_async(T* data, size_t simulated_size_in_bytes) { - std::unique_lock lock(*mutex_); + std::unique_lock lock(*mutex_); s4u::CommPtr comm = nullptr; XBT_CVERB(producer_consumer, (size() < max_queue_size_) ? "can put" : "must wait"); @@ -147,7 +148,6 @@ public: can_put_->wait(lock); if (tmode_ == TransferMode::MAILBOX) { comm = mbox_->put_init(data, simulated_size_in_bytes) - ->set_copy_data_callback(s4u::Comm::copy_pointer_callback) ->start(); } else queue_.push(data); @@ -177,7 +177,7 @@ public: */ s4u::CommPtr get_async(T** data) { - std::unique_lock lock(*mutex_); + std::unique_lock lock(*mutex_); s4u::CommPtr comm = nullptr; XBT_CVERB(producer_consumer, empty() ? "must wait" : "can get"); while (empty()) @@ -185,7 +185,6 @@ public: if (tmode_ == TransferMode::MAILBOX) comm = mbox_->get_init() ->set_dst_data(reinterpret_cast(data), sizeof(void*)) - ->set_copy_data_callback(s4u::Comm::copy_pointer_callback) ->start(); else { *data = queue_.front(); @@ -214,7 +213,6 @@ public: } }; -} // namespace plugin -} // namespace simgrid +} // namespace simgrid::plugin #endif // SIMGRID_PLUGIN_PRODUCERCONSUMER_HPP diff --git a/include/simgrid/plugins/battery.hpp b/include/simgrid/plugins/battery.hpp new file mode 100644 index 0000000000..fc395053df --- /dev/null +++ b/include/simgrid/plugins/battery.hpp @@ -0,0 +1,149 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_PLUGINS_BATTERY_HPP_ +#define SIMGRID_PLUGINS_BATTERY_HPP_ + +#include +#include +#include +#include +#include + +namespace simgrid::plugins { + +class Battery; +using BatteryPtr = boost::intrusive_ptr; +XBT_PUBLIC void intrusive_ptr_release(Battery* o); +XBT_PUBLIC void intrusive_ptr_add_ref(Battery* o); + +class BatteryModel : public kernel::resource::Model { + std::vector batteries_; + +public: + explicit BatteryModel(); + + void add_battery(BatteryPtr b); + void update_actions_state(double now, double delta) override; + double next_occurring_event(double now) override; +}; + +class Battery { + + friend BatteryModel; + +public: + enum Flow { CHARGE, DISCHARGE }; + + class Handler { + friend Battery; + + public: + enum Persistancy { PERSISTANT, ONESHOT }; + + private: + double state_of_charge_; + Flow flow_; + double time_delta_ = -1; + std::function callback_; + Persistancy persistancy_; + + public: + Handler(double state_of_charge, Flow flow, Persistancy p, std::function callback); + static std::shared_ptr init(double state_of_charge, Flow flow, Persistancy p, + std::function callback); + + /** @ingroup plugin_battery + * @return The state of charge at which the Handler will happen. + * @note For Battery::Handler objects + */ + double get_state_of_charge() { return state_of_charge_; } + /** @ingroup plugin_battery + * @return The flow in which the Handler will happen, either when the Battery is charging or discharging. + * @note For Battery::Handler objects + */ + Flow get_flow() { return flow_; } + /** @ingroup plugin_battery + * @return The time delta until the Handler happen. + -1 means that is will never happen with the current state the Battery, + for instance when there is no load connected to the Battery. + * @note For Battery::Handler objects + */ + double get_time_delta() { return time_delta_; } + /** @ingroup plugin_battery + * @return The callback to trigger when the Handler happen. + * @note For Battery::Handler objects + */ + std::function get_callback() { return callback_; } + /** @ingroup plugin_battery + * @return true if its a recurrent Handler. + * @note For Battery::Handler objects + */ + Persistancy get_persistancy() { return persistancy_; } + }; + +private: + static std::shared_ptr battery_model_; + + std::string name_; + double nominal_charge_power_w_ = -INFINITY; + double nominal_discharge_power_w_ = INFINITY; + double charge_efficiency_ = 1; + double discharge_efficiency_ = 1; + double initial_capacity_wh_ = 0; + double energy_budget_j_ = 0; + + std::map host_loads_ = {}; + std::map> named_loads_ = {}; + std::vector> handlers_; + + double capacity_wh_ = 0; + double energy_stored_j_ = 0; + double energy_provided_j_ = 0; + double energy_consumed_j_ = 0; + double last_updated_ = 0; + + explicit Battery() = default; + explicit Battery(const std::string& name, double state_of_charge, double nominal_charge_power_w, + double nominal_discharge_power_w, double charge_efficiency, double discharge_efficiency, + double initial_capacity_wh, int cycles); + static void init_plugin(); + void update(); + double next_occurring_handler(); + + std::atomic_int_fast32_t refcount_{0}; +#ifndef DOXYGEN + friend void intrusive_ptr_release(Battery* o) + { + if (o->refcount_.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + delete o; + } + } + friend void intrusive_ptr_add_ref(Battery* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); } +#endif + +public: + static BatteryPtr init(); + static BatteryPtr init(const std::string& name, double state_of_charge, double nominal_charge_power_w, + double nominal_discharge_power_w, double charge_efficiency, double discharge_efficiency, + double initial_capacity_wh, int cycles); + void set_load(const std::string& name, double power_w); + void set_load(const std::string& name, bool active); + void connect_host(s4u::Host* host, bool active = true); + std::string get_name() const { return name_; } + double get_state_of_charge(); + double get_state_of_health(); + double get_capacity(); + double get_energy_provided(); + double get_energy_consumed(); + double get_energy_stored(std::string unit = "J"); + std::shared_ptr schedule_handler(double state_of_charge, Flow flow, Handler::Persistancy p, + std::function callback); + std::vector> get_handlers(); + void delete_handler(std::shared_ptr handler); +}; +} // namespace simgrid::plugins +#endif \ No newline at end of file diff --git a/include/simgrid/plugins/chiller.hpp b/include/simgrid/plugins/chiller.hpp new file mode 100644 index 0000000000..78d1db0343 --- /dev/null +++ b/include/simgrid/plugins/chiller.hpp @@ -0,0 +1,107 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ +#ifndef SIMGRID_PLUGINS_CHILLER_H_ +#define SIMGRID_PLUGINS_CHILLER_H_ + +#include +#include +#include + +namespace simgrid::plugins { + +/** @ingroup plugin_chiller */ +class Chiller; +/** @ingroup plugin_chiller */ +using ChillerPtr = boost::intrusive_ptr; +XBT_PUBLIC void intrusive_ptr_release(Chiller* o); +XBT_PUBLIC void intrusive_ptr_add_ref(Chiller* o); + +class ChillerModel : public kernel::resource::Model { + std::vector chillers_; + +public: + explicit ChillerModel(); + + void add_chiller(ChillerPtr b); + void update_actions_state(double now, double delta) override; + double next_occurring_event(double now) override; +}; + +class Chiller { + + friend ChillerModel; + +private: + static std::shared_ptr chiller_model_; + + std::string name_; + double air_mass_kg_; + double specific_heat_j_per_kg_per_c_; + double alpha_; + double cooling_efficiency_; + double temp_in_c_; + double temp_out_c_; + double goal_temp_c_; + double max_power_w_; + + std::set hosts_ = {}; + bool active_ = true; + double power_w_ = 0; + double energy_consumed_j_ = 0; + double last_updated_ = 0; + + explicit Chiller(const std::string& name, double air_mass_kg, double specific_heat_j_per_kg_per_c, double alpha, + double cooling_efficiency, double initial_temp_c, double goal_temp_c, double max_power_w); + + static void init_plugin(); + void update(); + + std::atomic_int_fast32_t refcount_{0}; +#ifndef DOXYGEN + friend void intrusive_ptr_release(Chiller* o) + { + if (o->refcount_.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + delete o; + } + } + friend void intrusive_ptr_add_ref(Chiller* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); } +#endif + + static xbt::signal on_power_change; + xbt::signal on_this_power_change; + +public: + static ChillerPtr init(const std::string& name, double air_mass_kg, double specific_heat_j_per_kg_per_c, double alpha, + double cooling_efficiency, double initial_temp_c, double goal_temp_c, double max_power_w); + + ChillerPtr set_name(std::string name); + ChillerPtr set_air_mass(double air_mass_kg); + ChillerPtr set_specific_heat(double specific_heat_j_per_kg_per_c); + ChillerPtr set_alpha(double alpha); + ChillerPtr set_cooling_efficiency(double cooling_efficiency); + ChillerPtr set_goal_temp(double goal_temp_c); + ChillerPtr set_max_power(double max_power_w); + ChillerPtr set_active(bool active); + ChillerPtr add_host(simgrid::s4u::Host* host); + ChillerPtr remove_host(simgrid::s4u::Host* host); + + std::string get_name() { return name_; } + const char* get_cname() { return name_.c_str(); } + double get_air_mass() { return air_mass_kg_; } + double get_specific_heat() { return specific_heat_j_per_kg_per_c_; } + double get_alpha() { return alpha_; } + double get_cooling_efficiency() { return cooling_efficiency_; } + double get_goal_temp() { return goal_temp_c_; } + double get_max_power() { return max_power_w_; } + bool is_active() { return active_; } + double get_temp_in() { return temp_in_c_; } + double get_power() { return power_w_; } + double get_energy_consumed() { return energy_consumed_j_; } + double get_time_to_goal_temp() const; +}; + +} // namespace simgrid::plugins +#endif diff --git a/include/simgrid/plugins/dvfs.h b/include/simgrid/plugins/dvfs.h index 8cc0222bcb..2f5de8027a 100644 --- a/include/simgrid/plugins/dvfs.h +++ b/include/simgrid/plugins/dvfs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. +/* Copyright (c) 2017-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -15,10 +15,6 @@ SG_BEGIN_DECL XBT_PUBLIC void sg_host_dvfs_plugin_init(); -#if SIMGRID_HAVE_MSG -#define MSG_host_dvfs_plugin_init() sg_host_dvfs_plugin_init() -#endif // SIMGRID_HAVE_MSG - SG_END_DECL #endif diff --git a/include/simgrid/plugins/energy.h b/include/simgrid/plugins/energy.h index cc57f33e15..ee63dd862e 100644 --- a/include/simgrid/plugins/energy.h +++ b/include/simgrid/plugins/energy.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -31,18 +31,6 @@ XBT_PUBLIC int sg_link_energy_is_inited(); * @brief Initialize the wifi energy plugin */ XBT_PUBLIC void sg_wifi_energy_plugin_init(); -#if SIMGRID_HAVE_MSG - -#define MSG_host_energy_plugin_init() sg_host_energy_plugin_init() -#define MSG_host_get_consumed_energy(host) sg_host_get_consumed_energy(host) -#define MSG_host_get_idle_consumption_at(host,pstate) sg_host_get_idle_consumption_at((host), (pstate)) -#define MSG_host_get_wattmin_at(host,pstate) sg_host_get_wattmin_at((host), (pstate)) -#define MSG_host_get_wattmax_at(host,pstate) sg_host_get_wattmax_at((host), (pstate)) -#define MSG_host_get_power_range_slope_at(host,pstate) sg_host_get_power_range_slope_at((host), (pstate)) -#define MSG_host_get_current_consumption(host) sg_host_get_current_consumption(host) - -#endif // SIMGRID_HAVE_MSG - SG_END_DECL #endif diff --git a/include/simgrid/plugins/file_system.h b/include/simgrid/plugins/file_system.h index 28c31ea4d9..82632b4a25 100644 --- a/include/simgrid/plugins/file_system.h +++ b/include/simgrid/plugins/file_system.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -46,30 +46,6 @@ XBT_PUBLIC sg_size_t sg_disk_get_size_used(const_sg_disk_t d); XBT_PUBLIC sg_size_t sg_disk_get_size(const_sg_disk_t d); XBT_PUBLIC const char* sg_disk_get_mount_point(const_sg_disk_t d); -#if SIMGRID_HAVE_MSG - -typedef sg_file_t msg_file_t; // MSG backwards compatibility - -#define MSG_file_open(fullpath, data) sg_file_open((fullpath), (data)) -#define MSG_file_read(fd, size) sg_file_read((fd), (size)) -#define MSG_file_write(fd, size) sg_file_write((fd), (size)) -#define MSG_file_close(fd) sg_file_close(fd) -#define MSG_file_get_name(fd) sg_file_get_name(fd) -#define MSG_file_get_size(fd) sg_file_get_size(fd) -#define MSG_file_dump(fd) sg_file_dump(fd) -#define MSG_file_get_data(fd) sg_file_get_data(fd) -#define MSG_file_set_data(fd, data) sg_file_set_data((fd), (data)) -#define MSG_file_seek(fd, offset, origin) sg_file_seek((fd), (offset), (origin)) -#define MSG_file_tell(fd) sg_file_tell(fd) -#define MSG_file_move(fd, fullpath) sg_file_get_size((fd), (fullpath)) -#define MSG_file_unlink(fd) sg_file_unlink(fd) -#define MSG_file_rcopy(file, host, fullpath) sg_file_rcopy((file), (host), (fullpath)) -#define MSG_file_rmove(file, host, fullpath) sg_file_rmove((file), (host), (fullpath)) - -#define MSG_storage_file_system_init() sg_storage_file_system_init() - -#endif // SIMGRID_HAVE_MSG - SG_END_DECL // C++ interface @@ -126,6 +102,7 @@ public: void seek(sg_offset_t pos); /** Sets the file head to the given position. */ void seek(sg_offset_t pos, int origin); /** Sets the file head to the given position from a given origin. */ sg_size_t tell() const; /** Retrieves the current file position */ + void update_position(sg_offset_t); /** set new position in file, grow it if necessary, and increased usage */ /** Rename a file. WARNING: It is forbidden to move the file to another mount point */ void move(const std::string& fullpath) const; @@ -162,6 +139,7 @@ public: class XBT_PUBLIC FileDescriptorHostExt { public: static simgrid::xbt::Extension EXTENSION_ID; + static int max_file_descriptors; FileDescriptorHostExt() = default; FileDescriptorHostExt(const FileDescriptorHostExt&) = delete; FileDescriptorHostExt& operator=(const FileDescriptorHostExt&) = delete; diff --git a/include/simgrid/plugins/jbod.hpp b/include/simgrid/plugins/jbod.hpp new file mode 100644 index 0000000000..202ec3c45e --- /dev/null +++ b/include/simgrid/plugins/jbod.hpp @@ -0,0 +1,97 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_PLUGIN_JBOD_HPP +#define SIMGRID_PLUGIN_JBOD_HPP +#include +#include + +namespace simgrid::plugin { + +class Jbod; +using JbodPtr = boost::intrusive_ptr; +class JbodIo; +using JbodIoPtr = boost::intrusive_ptr; + +class Jbod { +public: + enum class RAID {RAID0 = 0, RAID1 = 1, RAID4 = 4 , RAID5 = 5, RAID6 = 6}; + s4u::Host* get_controller() const { return controller_; } + int get_parity_disk_idx() { return parity_disk_idx_; } + void update_parity_disk_idx() { parity_disk_idx_ = (parity_disk_idx_- 1) % num_disks_; } + + int get_next_read_disk_idx() { return (++read_disk_idx_) % num_disks_; } + + JbodIoPtr read_async(sg_size_t size); + sg_size_t read(sg_size_t size); + + JbodIoPtr write_async(sg_size_t size); + sg_size_t write(sg_size_t size); + + static JbodPtr create_jbod(s4u::NetZone* zone, const std::string& name, double speed, unsigned int num_disks, + RAID raid_level, double read_bandwidth, double write_bandwidth); + +protected: + void set_controller(s4u::Host* host) { controller_ = host; } + void set_num_disks(unsigned int num_disks) { num_disks_ = num_disks; } + void set_parity_disk_idx(unsigned int index) { parity_disk_idx_ = index; } + void set_read_disk_idx(int index) { read_disk_idx_ = index; } + void set_raid_level(RAID raid_level) { raid_level_ = raid_level; } + +private: + s4u::Host* controller_; + unsigned int num_disks_; + RAID raid_level_; + unsigned int parity_disk_idx_; + int read_disk_idx_; + std::atomic_int_fast32_t refcount_{1}; +#ifndef DOXYGEN + friend void intrusive_ptr_release(Jbod* jbod) + { + if (jbod->refcount_.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + delete jbod; + } + } + friend void intrusive_ptr_add_ref(Jbod* jbod) { jbod->refcount_.fetch_add(1, std::memory_order_relaxed); } +#endif +}; + +class JbodIo { + const Jbod* jbod_; + s4u::CommPtr transfer_; + s4u::ExecPtr parity_block_comp_; + std::vector pending_ios_; + s4u::Io::OpType type_; + std::atomic_int_fast32_t refcount_{0}; +public: + + explicit JbodIo(const Jbod* jbod, const s4u::CommPtr transfer, const s4u::ExecPtr parity_block_comp, + const std::vector& pending_ios, s4u::Io::OpType type) + : jbod_(jbod), transfer_(transfer), parity_block_comp_(parity_block_comp), pending_ios_(pending_ios), type_(type) + {} + + void wait(); + +#ifndef DOXYGEN + friend void intrusive_ptr_release(JbodIo* io) + { + if (io->refcount_.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + delete io; + } + } + friend void intrusive_ptr_add_ref(JbodIo* io) { io->refcount_.fetch_add(1, std::memory_order_relaxed); } +#endif +}; + +/* Refcounting functions */ +XBT_PUBLIC void intrusive_ptr_release(const Jbod* io); +XBT_PUBLIC void intrusive_ptr_add_ref(const Jbod* io); +XBT_PUBLIC void intrusive_ptr_release(const JbodIo* io); +XBT_PUBLIC void intrusive_ptr_add_ref(const JbodIo* io); + +} // namespace simgrid::plugin +#endif diff --git a/include/simgrid/plugins/live_migration.h b/include/simgrid/plugins/live_migration.h index 1bdf7bc17f..52f0ed6ada 100644 --- a/include/simgrid/plugins/live_migration.h +++ b/include/simgrid/plugins/live_migration.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -29,18 +29,6 @@ XBT_PUBLIC int sg_vm_is_migrating(const_sg_vm_t vm); XBT_PUBLIC sg_vm_t sg_vm_create_migratable(sg_host_t pm, const char* name, int coreAmount, int ramsize, int mig_netspeed, int dp_intensity); -#if SIMGRID_HAVE_MSG - -#define MSG_vm_live_migration_plugin_init() sg_vm_live_migration_plugin_init() - -#define MSG_vm_create_migratable(pm, name, coreAmount, ramsize, mig_netspeed, dp_intensity) \ - sg_vm_create_migratable((pm), (name), (coreAmount), (ramsize), (mig_netspeed), (dp_intensity)) - -#define MSG_vm_is_migrating(vm) sg_vm_is_migrating(vm) -#define MSG_vm_migrate(vm, dst_pm) sg_vm_migrate((vm), (dst_pm)) - -#endif // SIMGRID_HAVE_MSG - SG_END_DECL #endif diff --git a/include/simgrid/plugins/load.h b/include/simgrid/plugins/load.h index 02175c8435..41f95636f6 100644 --- a/include/simgrid/plugins/load.h +++ b/include/simgrid/plugins/load.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -29,19 +29,6 @@ XBT_PUBLIC double sg_link_get_avg_load(const_sg_link_t link); XBT_PUBLIC double sg_link_get_min_instantaneous_load(const_sg_link_t link); XBT_PUBLIC double sg_link_get_max_instantaneous_load(const_sg_link_t link); -#if SIMGRID_HAVE_MSG - -#define MSG_host_load_plugin_init() sg_host_load_plugin_init() -/** @brief Returns the current load of that host, as a ratio = achieved_flops / (core_current_speed * core_amount) - * - * See simgrid::plugin::HostLoad::get_current_load() for the full documentation. - */ -#define MSG_host_get_current_load(host) sg_host_get_current_load(host) -#define MSG_host_get_computed_flops(host) sg_host_get_computed_flops(host) -#define MSG_host_get_avg_load(host) sg_host_get_avg_load(host) - -#endif // SIMGRID_HAVE_MSG - SG_END_DECL #endif diff --git a/include/simgrid/plugins/ns3.hpp b/include/simgrid/plugins/ns3.hpp index 94e1a40d0e..f639047b40 100644 --- a/include/simgrid/plugins/ns3.hpp +++ b/include/simgrid/plugins/ns3.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,7 +13,7 @@ #include namespace simgrid { -/** Returns the ns3 node from a simgrid host */ +/** Returns the ns3 node from a SimGrid host */ XBT_PUBLIC ns3::Ptr get_ns3node_from_sghost(const simgrid::s4u::Host* host); }; // namespace simgrid diff --git a/include/simgrid/plugins/solar_panel.hpp b/include/simgrid/plugins/solar_panel.hpp new file mode 100644 index 0000000000..849c366c1f --- /dev/null +++ b/include/simgrid/plugins/solar_panel.hpp @@ -0,0 +1,77 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ +#ifndef SIMGRID_PLUGINS_SOLAR_PANEL_H_ +#define SIMGRID_PLUGINS_SOLAR_PANEL_H_ + +#include +#include +#include + +namespace simgrid::plugins { + +/** @ingroup plugin_solar_panel */ +class SolarPanel; +/** @ingroup plugin_solar_panel */ +using SolarPanelPtr = boost::intrusive_ptr; +XBT_PUBLIC void intrusive_ptr_release(SolarPanel* o); +XBT_PUBLIC void intrusive_ptr_add_ref(SolarPanel* o); + +class SolarPanel { + + std::string name_; + double area_m2_; + double conversion_efficiency_; + double solar_irradiance_w_per_m2_; + double min_power_w_; + double max_power_w_; + double power_w_ = -1; + + explicit SolarPanel(std::string name, double area_m2, double conversion_efficiency, double solar_irradiance_w_per_m2, + double min_power_w, double max_power_w); + void update(); + + std::atomic_int_fast32_t refcount_{0}; +#ifndef DOXYGEN + friend void intrusive_ptr_release(SolarPanel* o) + { + if (o->refcount_.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + delete o; + } + } + friend void intrusive_ptr_add_ref(SolarPanel* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); } +#endif + + static xbt::signal on_power_change; + xbt::signal on_this_power_change; + +public: + static SolarPanelPtr init(const std::string& name, double area_m2, double conversion_efficiency, + double solar_irradiance_w_per_m2, double min_power_w, double max_power_w); + + SolarPanelPtr set_name(std::string name); + SolarPanelPtr set_area(double area_m2); + SolarPanelPtr set_conversion_efficiency(double e); + SolarPanelPtr set_solar_irradiance(double solar_irradiance_w_per_m2); + SolarPanelPtr set_min_power(double power_w); + SolarPanelPtr set_max_power(double power_w); + + std::string get_name() const { return name_; } + const char* get_cname() const { return name_.c_str(); } + double get_area() const { return area_m2_; } + double get_conversion_efficiency() const { return conversion_efficiency_; } + double get_solar_irradiance() const { return solar_irradiance_w_per_m2_; } + double get_min_power() const { return min_power_w_; } + double get_max_power() const { return max_power_w_; } + double get_power() const { return power_w_; } + + /** Add a callback fired after this solar panel power changed. */ + void on_this_power_change_cb(const std::function& func) { on_this_power_change.connect(func); }; + /** Add a callback fired after a solar panel power changed. + * Triggered after the on_this_power_change function.**/ + static void on_power_change_cb(const std::function& cb) { on_power_change.connect(cb); } +}; +} // namespace simgrid::plugins +#endif diff --git a/include/simgrid/s4u.hpp b/include/simgrid/s4u.hpp index 7f7f52a870..8ddbf1aac3 100644 --- a/include/simgrid/s4u.hpp +++ b/include/simgrid/s4u.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -19,11 +19,16 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include + #include #endif /* SIMGRID_S4U_S4U_H */ diff --git a/include/simgrid/s4u/Activity.hpp b/include/simgrid/s4u/Activity.hpp index 353fcdbaa0..8b9f48508d 100644 --- a/include/simgrid/s4u/Activity.hpp +++ b/include/simgrid/s4u/Activity.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -33,12 +34,15 @@ namespace s4u { */ class XBT_PUBLIC Activity : public xbt::Extendable { #ifndef DOXYGEN + friend ActivitySet; friend Comm; friend Exec; friend Io; + friend Mess; friend kernel::activity::ActivityImpl; friend std::vector create_DAG_from_dot(const std::string& filename); friend std::vector create_DAG_from_DAX(const std::string& filename); + friend std::vector create_DAG_from_json(const std::string& filename); #endif public: @@ -63,7 +67,7 @@ protected: XBT_CVERB(s4u_activity, "Remove a dependency from '%s' on '%s'", get_cname(), b->get_cname()); b->dependencies_.erase(this); if (b->dependencies_solved()) { - b->vetoable_start(); + b->start(); } successors_.pop_back(); } @@ -73,8 +77,8 @@ protected: { if(this == a) throw std::invalid_argument("Cannot be its own successor"); - auto p = std::find_if(successors_.begin(), successors_.end(), [a](ActivityPtr const& i){ return i.get() == a.get(); }); - if (p != successors_.end()) + + if (std::any_of(begin(successors_), end(successors_), [a](ActivityPtr const& i) { return i.get() == a.get(); })) throw std::invalid_argument("Dependency already exists"); successors_.push_back(a); @@ -86,50 +90,56 @@ protected: if(this == a) throw std::invalid_argument("Cannot ask to remove itself from successors list"); - auto p = std::find_if(successors_.begin(), successors_.end(), [a](ActivityPtr const& i){ return i.get() == a.get(); }); - if (p != successors_.end()){ - successors_.erase(p); - a->dependencies_.erase({this}); - } else + auto p = + std::find_if(successors_.begin(), successors_.end(), [a](ActivityPtr const& i) { return i.get() == a.get(); }); + if (p == successors_.end()) throw std::invalid_argument("Dependency does not exist. Can not be removed."); + + successors_.erase(p); + a->dependencies_.erase({this}); } static std::set* vetoed_activities_; -private: - static xbt::signal on_veto; - static xbt::signal on_completion; - static xbt::signal on_suspended; - static xbt::signal on_resumed; + /** Set the [remaining] amount of work that this Activity will entail + * + * It is forbidden to change the amount of work once the Activity is started */ + Activity* set_remaining(double remains); + + virtual void fire_on_start() const = 0; + virtual void fire_on_this_start() const = 0; + virtual void fire_on_completion() const = 0; + virtual void fire_on_this_completion() const = 0; + virtual void fire_on_suspend() const = 0; + virtual void fire_on_this_suspend() const = 0; + virtual void fire_on_resume() const = 0; + virtual void fire_on_this_resume() const = 0; + virtual void fire_on_veto() = 0; + virtual void fire_on_this_veto() = 0; public: - /*! Add a callback fired each time that the activity fails to start because of a veto (e.g., unsolved dependency or no - * resource assigned) */ - static void on_veto_cb(const std::function& cb) { on_veto.connect(cb); } - /*! Add a callback fired when the activity completes (either normally, cancelled or failed) */ - static void on_completion_cb(const std::function& cb) { on_completion.connect(cb); } - /*! Add a callback fired when the activity is suspended */ - static void on_suspended_cb(const std::function& cb) { on_suspended.connect(cb); } - /*! Add a callback fired when the activity is resumed after being suspended */ - static void on_resumed_cb(const std::function& cb) { on_resumed.connect(cb); } - - void vetoable_start() + void start() { state_ = State::STARTING; if (dependencies_solved() && is_assigned()) { XBT_CVERB(s4u_activity, "'%s' is assigned to a resource and all dependencies are solved. Let's start", get_cname()); - start(); + do_start(); } else { if (vetoed_activities_ != nullptr) vetoed_activities_->insert(this); - on_veto(*this); + fire_on_veto(); + fire_on_this_veto(); } } void complete(Activity::State state) { + // Ensure that the current activity remains alive until the end of the function, even if its last reference is + // released by the on_completion() callbacks. + ActivityPtr keepalive(this); state_ = state; - on_completion(*this); + fire_on_completion(); + fire_on_this_completion(); if (state == State::FINISHED) release_dependencies(); } @@ -146,11 +156,9 @@ public: * * This function is optional: you can call wait() even if you didn't call start() */ - virtual Activity* start() = 0; + virtual Activity* do_start() = 0; /** Tests whether the given activity is terminated yet. */ virtual bool test(); - /*! take a vector s4u::ActivityPtr and return the rank of the first finished one (or -1 if none is done). */ - static ssize_t test_any(const std::vector& activities); /** Blocks the current actor until the activity is terminated */ Activity* wait() { return wait_for(-1.0); } @@ -160,11 +168,6 @@ public: /** Blocks the current actor until the activity is terminated, or until the time limit is reached\n * Raises: timeout exception. */ void wait_until(double time_limit); - /*! take a vector of s4u::ActivityPtr and return when one of them is finished. - * The return value is the rank of the first finished ActivityPtr. */ - static ssize_t wait_any(const std::vector& activities) { return wait_any_for(activities, -1); } - /*! Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.*/ - static ssize_t wait_any_for(const std::vector& activities, double timeout); /** Cancel that activity */ Activity* cancel(); @@ -186,10 +189,6 @@ public: /** Get the remaining amount of work that this Activity entails. When it's 0, it's done. */ virtual double get_remaining() const; - /** Set the [remaining] amount of work that this Activity will entail - * - * It is forbidden to change the amount of work once the Activity is started */ - Activity* set_remaining(double remains); double get_start_time() const; double get_finish_time() const; @@ -200,6 +199,9 @@ public: kernel::activity::ActivityImpl* get_impl() const { return pimpl_.get(); } #ifndef DOXYGEN + static ssize_t deprecated_wait_any_for(const std::vector& activities, double timeout); // XBT_ATTRIB_DEPRECATED_v339 + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static ssize_t test_any(const std::vector& activities); + friend void intrusive_ptr_release(Activity* a) { if (a->refcount_.fetch_sub(1, std::memory_order_release) == 1) { @@ -231,7 +233,61 @@ template class Activity_T : public Activity { std::string name_ = "unnamed"; std::string tracing_category_ = ""; + inline static xbt::signal on_start; + xbt::signal on_this_start; + inline static xbt::signal on_completion; + xbt::signal on_this_completion; + inline static xbt::signal on_suspend; + xbt::signal on_this_suspend; + inline static xbt::signal on_resume; + xbt::signal on_this_resume; + inline static xbt::signal on_veto; + xbt::signal on_this_veto; + +protected: + void fire_on_start() const override { on_start(static_cast(*this)); } + void fire_on_this_start() const override { on_this_start(static_cast(*this)); } + void fire_on_completion() const override { on_completion(static_cast(*this)); } + void fire_on_this_completion() const override { on_this_completion(static_cast(*this)); } + void fire_on_suspend() const override { on_suspend(static_cast(*this)); } + void fire_on_this_suspend() const override { on_this_suspend(static_cast(*this)); } + void fire_on_resume() const override { on_resume(static_cast(*this)); } + void fire_on_this_resume() const override { on_this_resume(static_cast(*this)); } + void fire_on_veto() override { on_veto(static_cast(*this)); } + void fire_on_this_veto() override { on_this_veto(static_cast(*this)); } + public: + /*! \static Add a callback fired when any activity starts (no veto) */ + static void on_start_cb(const std::function& cb) { on_start.connect(cb); } + /*! Add a callback fired when this specific activity starts (no veto) */ + void on_this_start_cb(const std::function& cb) { on_this_start.connect(cb); } + /*! \static Add a callback fired when any activity completes (either normally, cancelled or failed) */ + static void on_completion_cb(const std::function& cb) { on_completion.connect(cb); } + /*! Add a callback fired when this specific activity completes (either normally, cancelled or failed) */ + void on_this_completion_cb(const std::function& cb) { on_this_completion.connect(cb); } + /*! \static Add a callback fired when any activity is suspended */ + static void on_suspend_cb(const std::function& cb) { on_suspend.connect(cb); } + /*! Add a callback fired when this specific activity is suspended */ + void on_this_suspend_cb(const std::function& cb) { on_this_suspend.connect(cb); } + /*! \static Add a callback fired when any activity is resumed after being suspended */ + static void on_resume_cb(const std::function& cb) { on_resume.connect(cb); } + /*! Add a callback fired when this specific activity is resumed after being suspended */ + void on_this_resume_cb(const std::function& cb) { on_this_resume.connect(cb); } + /*! \static Add a callback fired each time that any activity fails to start because of a veto (e.g., unsolved + * dependency or no resource assigned) */ + static void on_veto_cb(const std::function& cb) { on_veto.connect(cb); } + /*! Add a callback fired each time that this specific activity fails to start because of a veto (e.g., unsolved + * dependency or no resource assigned) */ + void on_this_veto_cb(const std::function& cb) { on_this_veto.connect(cb); } + +#ifndef DOXYGEN + XBT_ATTRIB_DEPRECATED_v338("Please use on_suspend_cb() instead") static void on_suspended_cb(const std::function& cb) { on_suspend.connect(cb); } + XBT_ATTRIB_DEPRECATED_v338("Please use on_resume_cb() instead") static void on_resumed_cb(const std::function& cb) { on_resume.connect(cb); } + + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static ssize_t wait_any(const std::vector& activities) { return deprecated_wait_any_for(activities, -1); } + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static ssize_t wait_any_for(const std::vector& activities, double timeout) { return deprecated_wait_any_for(activities, timeout); } +#endif + AnyActivity* add_successor(ActivityPtr a) { Activity::add_successor(a); @@ -242,7 +298,7 @@ public: Activity::remove_successor(a); return static_cast(this); } - AnyActivity* set_name(const std::string& name) + AnyActivity* set_name(std::string_view name) { name_ = name; return static_cast(this); @@ -250,34 +306,26 @@ public: const std::string& get_name() const override { return name_; } const char* get_cname() const override { return name_.c_str(); } - AnyActivity* set_tracing_category(const std::string& category) + AnyActivity* set_tracing_category(std::string_view category) { - xbt_assert(get_state() == State::INITED, "Cannot change the tracing category of an activity after its start"); + xbt_assert(get_state() == State::INITED || get_state() == State::STARTING, + "Cannot change the tracing category of an activity after its start"); tracing_category_ = category; return static_cast(this); } const std::string& get_tracing_category() const { return tracing_category_; } - XBT_ATTRIB_DEPRECATED_v334("Please use Activity::set_data()") AnyActivity* set_user_data(void* data) - { - set_data(data); - return static_cast(this); - } - - XBT_ATTRIB_DEPRECATED_v334("Please use Activity::get_data<>()") void* get_user_data() const + AnyActivity* start() { - return get_data(); - } - - AnyActivity* vetoable_start() - { - Activity::vetoable_start(); + Activity::start(); return static_cast(this); } AnyActivity* cancel() { return static_cast(Activity::cancel()); } AnyActivity* wait() { return wait_for(-1.0); } - virtual AnyActivity* wait_for(double timeout) { return static_cast(Activity::wait_for(timeout)); } + virtual AnyActivity* wait_for(double timeout) { + return static_cast(Activity::wait_for(timeout)); + } #ifndef DOXYGEN /* The refcounting is done in the ancestor class, Activity, but we want each of the classes benefiting of the CRTP diff --git a/include/simgrid/s4u/ActivitySet.hpp b/include/simgrid/s4u/ActivitySet.hpp new file mode 100644 index 0000000000..10ec7c86ec --- /dev/null +++ b/include/simgrid/s4u/ActivitySet.hpp @@ -0,0 +1,104 @@ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_S4U_ACTIVITYSET_HPP +#define SIMGRID_S4U_ACTIVITYSET_HPP + +#include +#include + +#include + +namespace simgrid { + +extern template class XBT_PUBLIC xbt::Extendable; + +namespace s4u { +/** @brief ActivitiesSet + * + * This class is a container of activities, allowing to wait for the completion of any or all activities in the set. + * This is somehow similar to the select(2) system call under UNIX, allowing you to wait for the next event about these + * activities. + */ +class XBT_PUBLIC ActivitySet : public xbt::Extendable { + std::atomic_int_fast32_t refcount_{1}; + std::vector activities_; // Use vectors, not sets for better reproductibility accross architectures + std::vector failed_activities_; + + void handle_failed_activities(); + +public: + ActivitySet() = default; + ActivitySet(const std::vector init) : activities_(init) {} + ~ActivitySet() = default; + + /** Add an activity to the set */ + void push(ActivityPtr a) { activities_.push_back(a); } + /** Remove that activity from the set (no-op if the activity is not in the set) */ + void erase(ActivityPtr a); + + /** Get the amount of activities in the set. Failed activities (if any) are not counted */ + int size() { return activities_.size(); } + /** Return whether the set is empty. Failed activities (if any) are not counted */ + int empty() { return activities_.empty(); } + + /** Wait for the completion of all activities in the set, but not longer than the provided timeout + * + * On timeout, an exception is raised. + * + * In any case, the completed activities remain in the set. Use test_any() to retrieve them. + */ + void wait_all_for(double timeout); + /** Wait for the completion of all activities in the set. The set is NOT emptied afterward. */ + void wait_all() { wait_all_for(-1); } + /** Returns the first terminated activity if any, or ActivityPtr(nullptr) if no activity is terminated */ + ActivityPtr test_any(); + + /** Wait for the completion of one activity from the set, but not longer than the provided timeout. + * + * See wait_any() for details. + * + * @return the first terminated activity, which is automatically removed from the set. + */ + + ActivityPtr wait_any_for(double timeout); + /** Wait for the completion of one activity from the set. + * + * If an activity fails during that time, an exception is raised, and the failed exception is marked as failed in the + * set. Use get_failed_activity() to retrieve it. + * + * If more than one activity failed, the other ones are also removed from the set. Use get_failed_activity() several + * time to retrieve them all. + * + * @return the first terminated activity, which is automatically removed from the set. If more than one activity + * terminated at the same timestamp, then the other ones are still in the set. Use either test_any() or wait_any() to + * retrieve the other ones. + */ + ActivityPtr wait_any() { return wait_any_for(-1); } + + /** Return one of the failed activity of the set that was revealed during the previous wait operation, or + * ActivityPtr() if no failed activity exist in the set. */ + ActivityPtr get_failed_activity(); + /** Return whether the set contains any failed activity. */ + bool has_failed_activities() { return not failed_activities_.empty(); } + + // boost::intrusive_ptr support: + friend void intrusive_ptr_add_ref(ActivitySet* as) + { + XBT_ATTRIB_UNUSED auto previous = as->refcount_.fetch_add(1); + xbt_assert(previous != 0); + } + + friend void intrusive_ptr_release(ActivitySet* as) + { + if (as->refcount_.fetch_sub(1) == 1) + delete as; + } +}; + +} // namespace s4u +} // namespace simgrid + +#endif diff --git a/include/simgrid/s4u/Actor.hpp b/include/simgrid/s4u/Actor.hpp index b75614c5f1..f3af5b9d41 100644 --- a/include/simgrid/s4u/Actor.hpp +++ b/include/simgrid/s4u/Actor.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -102,16 +101,16 @@ XBT_PUBLIC void execute(double flop, double priority); * * These objects are somewhat surprising from a modeling point of view. For example, the unit of their speed is * somewhere between flop/sec and byte/sec. Arbitrary parallel executions will simply not work with the usual platform - * models, and you must :ref:`use the ptask_L07 host model ` for that. Note that you can mix + * models, and you must :ref:`use the ptask_L07 host model ` for that. Note that you can mix * regular executions and communications with parallel executions, provided that the host model is ptask_L07. * * @endrst */ -/** Block the current actor until the built parallel execution completes */ +/** Block the current actor until the built parallel execution completes. */ XBT_PUBLIC void parallel_execute(const std::vector& hosts, const std::vector& flops_amounts, const std::vector& bytes_amounts); -/** Block the current actor until the built multi-thread execution completes */ +/** Block the current actor until the built multi-thread execution completes. */ XBT_PUBLIC void thread_execute(s4u::Host* host, double flop_amounts, int thread_count); /** Initialize a sequential execution that must then be started manually */ @@ -210,37 +209,60 @@ public: int get_refcount() const; // ***** Actor creation ***** - /** Retrieve a reference to myself */ + /** \static + * Retrieve a reference to myself + */ static Actor* self(); private: static xbt::signal on_creation; static xbt::signal on_suspend; + xbt::signal on_this_suspend; static xbt::signal on_resume; + xbt::signal on_this_resume; static xbt::signal on_sleep; + xbt::signal on_this_sleep; static xbt::signal on_wake_up; + xbt::signal on_this_wake_up; static xbt::signal on_host_change; + xbt::signal on_this_host_change; static xbt::signal on_termination; + xbt::signal on_this_termination; static xbt::signal on_destruction; + xbt::signal on_this_destruction; public: - /** Add a callback fired when a new actor has been created **/ + /** \static Add a callback fired when a new actor has been created **/ static void on_creation_cb(const std::function& cb) { on_creation.connect(cb); } - /** Add a callback fired when an actor has been suspended**/ + /** \static Add a callback fired when any actor is suspended (right before the suspend) **/ static void on_suspend_cb(const std::function& cb) { on_suspend.connect(cb); } - /** Add a callback fired when an actor has been resumed **/ + /** Add a callback fired when this specific actor is suspended (right before the suspend) **/ + void on_this_suspend_cb(const std::function& cb) { on_this_suspend.connect(cb); } + /** \static Add a callback fired when any actor is resumed (right before the resume) **/ static void on_resume_cb(const std::function& cb) { on_resume.connect(cb); } - /** Add a callback fired when an actor starts sleeping **/ + /** Add a callback fired when this specific actor is resumed (right before the resume) **/ + void on_this_resume_cb(const std::function& cb) { on_this_resume.connect(cb); } + /** \static Add a callback fired when any actor starts sleeping **/ static void on_sleep_cb(const std::function& cb) { on_sleep.connect(cb); } - /** Add a callback fired when an actor wakes up from a sleep **/ + /** Add a callback fired when this specific actor starts sleeping **/ + void on_this_sleep_cb(const std::function& cb) { on_this_sleep.connect(cb); } + /** \static Add a callback fired when any actor wakes up from a sleep **/ static void on_wake_up_cb(const std::function& cb) { on_wake_up.connect(cb); } - /** Add a callback fired when an actor is has been migrated to another host **/ + /** Add a callback fired when this specific actor wakes up from a sleep **/ + void on_this_wake_up_cb(const std::function& cb) { on_this_wake_up.connect(cb); } + /** \static Add a callback fired when any actor is has been migrated to another host **/ static void on_host_change_cb(const std::function& cb) { on_host_change.connect(cb); } + /** Add a callback fired when this specific actor is has been migrated to another host **/ + void on_this_host_change_cb(const std::function& cb) + { + on_this_host_change.connect(cb); + } - /** Add a callback fired when an actor terminates its code. + /** \static + * Add a callback fired when any actor terminates its code. * @beginrst * The actor may continue to exist if it is still referenced in the simulation, but it's not active anymore. * If you want to free extra data when the actor's destructor is called, use :cpp:func:`Actor::on_destruction_cb`. @@ -248,19 +270,28 @@ public: * @endrst */ static void on_termination_cb(const std::function& cb) { on_termination.connect(cb); } - /** Add a callback fired when an actor is about to disappear (its destructor was called). - * This signal is fired for any destructed actor, which is mostly useful when designing plugins and extensions. - * If you want to react to the end of the actor's code, use Actor::on_termination instead. - * If you want to register to the termination of a given actor, use this_actor::on_exit() instead.*/ + /** Add a callback fired when this specific actor terminates its code. + * @beginrst + * The actor may continue to exist if it is still referenced in the simulation, but it's not active anymore. + * If you want to free extra data when the actor's destructor is called, use :cpp:func:`Actor::on_this_destruction_cb`. + * @endrst + */ + void on_this_termination_cb(const std::function& cb) { on_this_termination.connect(cb); } + /** \static Add a callback fired when an actor is about to disappear (its destructor was called). + * This signal is fired for any destructed actor, which is mostly useful when designing plugins and extensions. */ static void on_destruction_cb(const std::function& cb) { on_destruction.connect(cb); } + /** Add a callback fired when this specific actor is about to disappear (its destructor was called). */ + void on_this_destruction_cb(const std::function& cb) { on_this_destruction.connect(cb); } - /** Create an actor from a @c std::function. + /** \static + * Create an actor from a @c std::function. * If the actor is restarted, it gets a fresh copy of the function. * @verbatim embed:rst:inline See the :ref:`example `. @endverbatim */ static ActorPtr create(const std::string& name, s4u::Host* host, const std::function& code); - /** Create an actor, but don't start it yet. + /** \static + * Create an actor, but don't start it yet. * - * This is useful to set some properties or extension before actually starting it */ + * This is useful to set some properties or extension before actually starting it */ static ActorPtr init(const std::string& name, s4u::Host* host); ActorPtr set_stacksize(unsigned stacksize); /** Start a previously initialized actor */ @@ -281,14 +312,16 @@ public: ActorPtr start(const std::function& code, std::vector args); - /** Create an actor from a callable thing. + /** \static + * Create an actor from a callable thing. * @verbatim embed:rst:inline See the :ref:`example `. @endverbatim */ template static ActorPtr create(const std::string& name, s4u::Host* host, F code) { return create(name, host, std::function(std::move(code))); } - /** Create an actor using a callable thing and its arguments. + /** \static + * Create an actor using a callable thing and its arguments. * * Note that the arguments will be copied, so move-only parameters are forbidden. * @verbatim embed:rst:inline See the :ref:`example `. @endverbatim */ @@ -304,7 +337,8 @@ public: return create(name, host, std::bind(std::move(code), std::move(args)...)); } - /** Create actor from function name and a vector of strings as arguments. + /** \static + * Create actor from function name and a vector of strings as arguments. * @verbatim embed:rst:inline See the :ref:`example `. @endverbatim */ static ActorPtr create(const std::string& name, s4u::Host* host, const std::string& function, std::vector args); @@ -319,10 +353,11 @@ public: /** Returns whether or not this actor has been daemonized or not **/ bool is_daemon() const; + static bool is_maestro(); /** Retrieves the name of that actor as a C++ string */ - const simgrid::xbt::string& get_name() const; + const std::string& get_name() const; /** Retrieves the name of that actor as a C string */ const char* get_cname() const; /** Retrieves the host on which that actor is running */ @@ -392,7 +427,9 @@ public: */ void kill(); - /** Retrieves the actor that have the given PID (or nullptr if not existing) */ + /** \static + * Retrieves the actor that have the given PID (or nullptr if not existing) + */ static ActorPtr by_pid(aid_t pid); /** Wait for the actor to finish. @@ -411,7 +448,9 @@ public: /** Kill that actor and restart it from start. */ Actor* restart(); - /** Kill all actors (but the issuer). Being killed is not something that actors can delay or avoid. */ + /** \static + * Kill all actors (but the issuer). Being killed is not something that actors can delay or avoid. + */ static void kill_all(); /** Returns the internal implementation of this actor */ diff --git a/include/simgrid/s4u/Barrier.hpp b/include/simgrid/s4u/Barrier.hpp index e066d41225..2d6db86085 100644 --- a/include/simgrid/s4u/Barrier.hpp +++ b/include/simgrid/s4u/Barrier.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,8 +15,7 @@ #include #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { class XBT_PUBLIC Barrier { kernel::activity::BarrierImpl* pimpl_; @@ -30,7 +29,7 @@ public: Barrier& operator=(Barrier const&) = delete; #endif - /** Creates a barrier for the given amount of actors */ + /** \static Creates a barrier for the given amount of actors */ static BarrierPtr create(unsigned int expected_actors); /** Blocks into the barrier. Every waiting actors will be unlocked once the expected amount of actors reaches the barrier */ int wait(); @@ -43,7 +42,6 @@ public: friend XBT_PUBLIC void intrusive_ptr_release(Barrier* barrier); #endif }; -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif diff --git a/include/simgrid/s4u/Comm.hpp b/include/simgrid/s4u/Comm.hpp index 84b0cbbb3f..57f6443c29 100644 --- a/include/simgrid/s4u/Comm.hpp +++ b/include/simgrid/s4u/Comm.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,14 +12,14 @@ #include #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** @brief Communication async * * Represents all asynchronous communications, that you can test or wait onto. */ class XBT_PUBLIC Comm : public Activity_T { friend Mailbox; // Factory of comms + friend kernel::activity::CommImpl; /* specified for normal mailbox-based communications*/ Mailbox* mailbox_ = nullptr; kernel::actor::ActorImpl* sender_ = nullptr; @@ -37,23 +37,43 @@ class XBT_PUBLIC Comm : public Activity_T { std::function copy_data_function_; Comm() = default; + Comm* do_start() override; -public: - /* signals and related callbacks */ -#ifndef DOXYGEN - /* FIXME signals should be private */ static xbt::signal on_send; + xbt::signal on_this_send; static xbt::signal on_recv; - static xbt::signal on_start; -#endif + xbt::signal on_this_recv; + +protected: + void fire_on_completion() const override { + /* The completion signal of a Comm has to be thrown only once and not by the sender AND the receiver. + then Comm::on_completion is thrown in the kernel in CommImpl::finish. + */ + } + void fire_on_this_completion() const override { + /* The completion signal of a Comm has to be thrown only once and not by the sender AND the receiver. + then Comm::on_this_completion is thrown in the kernel in CommImpl::finish. + */ + } + /* These ensure that the on_completion signals are really thrown */ + void fire_on_completion_for_real() const { Activity_T::fire_on_completion(); } + void fire_on_this_completion_for_real() const { Activity_T::fire_on_this_completion(); } +public: + /*! \static Add a callback fired when the send of any Comm is posted */ static void on_send_cb(const std::function& cb) { on_send.connect(cb); } + /*! Add a callback fired when the send of this specific Comm is posted */ + void on_this_send_cb(const std::function& cb) { on_this_send.connect(cb); } + /*! \static Add a callback fired when the recv of any Comm is posted */ static void on_recv_cb(const std::function& cb) { on_recv.connect(cb); } - static void on_start_cb(const std::function& cb) { on_start.connect(cb); } - /* More callbacks */ + /*! Add a callback fired when the recv of this specific Comm is posted */ + void on_this_recv_cb(const std::function& cb) { on_this_recv.connect(cb); } + CommPtr set_copy_data_callback(const std::function& callback); - static void copy_buffer_callback(kernel::activity::CommImpl*, void*, size_t); - static void copy_pointer_callback(kernel::activity::CommImpl*, void*, size_t); + XBT_ATTRIB_DEPRECATED_v338("Please manifest if you actually need this function") static void copy_buffer_callback( + kernel::activity::CommImpl*, void*, size_t); + XBT_ATTRIB_DEPRECATED_v338("Please manifest if you actually need this function") static void copy_pointer_callback( + kernel::activity::CommImpl*, void*, size_t); ~Comm() override; @@ -67,7 +87,8 @@ public: const std::function& copy_data_fun, void* data, double timeout, double rate); - /* "One-sided" communications. This way of communicating bypasses the mailbox and actors mechanism. It creates a + /* \static + * "One-sided" communications. This way of communicating bypasses the mailbox and actors mechanism. It creates a * communication (vetoabled, asynchronous, or synchronous) directly between two hosts. There is really no limit on * the hosts involved. In particular, the actor creating such a communication does not have to be on one of the * involved hosts! Enjoy the comfort of the simulator :) @@ -128,8 +149,11 @@ public: CommPtr set_dst_data(void** buff, size_t size); /** Retrieve where the data will be copied on the receiver side */ void* get_dst_data() const { return dst_buff_; } - /** Retrieve the size of the received data. Not to be mixed with @ref Activity::set_remaining() */ + /** Retrieve the size of the received data. Not to be mixed with @ref Activity::get_remaining() */ size_t get_dst_data_size() const { return dst_buff_size_; } + /** Retrieve the payload associated to the communication. You can only do that once the comm is (gracefully) + * terminated, and it is only setup by the default copy_data callback (not the SMPI one) */ + void* get_payload() const; /* Common functions */ @@ -146,9 +170,9 @@ public: bool is_assigned() const override; Actor* get_sender() const; + Actor* get_receiver() const; /* Comm life cycle */ - Comm* start() override; /** Start the comm, and ignore its result. It can be completely forgotten after that. */ Comm* detach(); /** Start the comm, and ignore its result. It can be completely forgotten after that. */ @@ -160,22 +184,19 @@ public: Comm* wait_for(double timeout) override; - /*! take a vector s4u::CommPtr and return the rank of the first finished one (or -1 if none is done). */ - static ssize_t test_any(const std::vector& comms); +#ifndef DOXYGEN + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static ssize_t wait_any(const std::vector& comms) { return deprecated_wait_any_for(comms, -1); } + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static ssize_t wait_any_for(const std::vector& comms, double timeout) { return deprecated_wait_any_for(comms, timeout); } - /*! take a vector s4u::CommPtr and return when one of them is finished. - * The return value is the rank of the first finished CommPtr. */ - static ssize_t wait_any(const std::vector& comms) { return wait_any_for(comms, -1); } - /*! Same as wait_any, but with a timeout. Return -1 if the timeout occurs.*/ - static ssize_t wait_any_for(const std::vector& comms, double timeout); + static ssize_t deprecated_wait_any_for(const std::vector& comms, + double timeout); // XBT_ATTRIB_DEPRECATED_v339 - /*! take a vector s4u::CommPtr and return when all of them is finished. */ - static void wait_all(const std::vector& comms); - /*! Same as wait_all, but with a timeout. Return the number of terminated comm (less than comms.size() if the timeout - * occurs). */ - static size_t wait_all_for(const std::vector& comms, double timeout); + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static ssize_t test_any(const std::vector& comms); + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static void wait_all(const std::vector& comms); + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static size_t + wait_all_for(const std::vector& comms, double timeout); +#endif }; -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif /* SIMGRID_S4U_COMM_HPP */ diff --git a/include/simgrid/s4u/ConditionVariable.hpp b/include/simgrid/s4u/ConditionVariable.hpp index d090776c38..448b4a8391 100644 --- a/include/simgrid/s4u/ConditionVariable.hpp +++ b/include/simgrid/s4u/ConditionVariable.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,8 +14,7 @@ #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** * @beginrst @@ -44,7 +43,7 @@ private: #endif public: - /** Create a new condition variable and return a smart pointer + /** \static Create a new condition variable and return a smart pointer * * @beginrst * You should only manipulate :cpp:type:`simgrid::s4u::ConditionVariablePtr`, as created by this function (see also :ref:`s4u_raii`). @@ -66,29 +65,9 @@ public: std::cv_status wait_until(const std::unique_lock& lock, double timeout_time); /// Wait for the given amount of seconds (specified as a plain double) std::cv_status wait_for(const std::unique_lock& lock, double duration); - /// Wait until predicate is true, or the given instant (specified as a plain double) - template bool wait_until(const std::unique_lock& lock, double timeout_time, P pred) - { - while (not pred()) - if (this->wait_until(lock, timeout_time) == std::cv_status::timeout) - return pred(); - return true; - } - /// As long as the predicate is false, wait for the given amount of seconds (specified as a plain double) - template bool wait_for(const std::unique_lock& lock, double duration, P pred) - { - return this->wait_until(lock, Engine::get_clock() + duration, std::move(pred)); - } // Wait function taking a C++ style time: - /// As long as the predicate is false, wait for the given amount of seconds (specified in C++ style) - template - bool wait_for(const std::unique_lock& lock, std::chrono::duration duration, P pred) - { - auto seconds = std::chrono::duration_cast(duration); - return this->wait_for(lock, seconds.count(), pred); - } /// Wait for the given amount of seconds (specified in C++ style) template std::cv_status wait_for(const std::unique_lock& lock, std::chrono::duration duration) @@ -103,13 +82,6 @@ public: auto timeout_native = std::chrono::time_point_cast(timeout_time); return this->wait_until(lock, timeout_native.time_since_epoch().count()); } - /** Wait until predicate is true, or the given instant (specified in C++ style) */ - template - bool wait_until(const std::unique_lock& lock, const SimulationTimePoint& timeout_time, P pred) - { - auto timeout_native = std::chrono::time_point_cast(timeout_time); - return this->wait_until(lock, timeout_native.time_since_epoch().count(), std::move(pred)); - } /** Unblock one actor blocked on that condition variable. If none was blocked, nothing happens. */ void notify_one(); @@ -117,7 +89,6 @@ public: void notify_all(); }; -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif diff --git a/include/simgrid/s4u/Disk.hpp b/include/simgrid/s4u/Disk.hpp index 671c4e31b9..eec006c2f6 100644 --- a/include/simgrid/s4u/Disk.hpp +++ b/include/simgrid/s4u/Disk.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -79,6 +79,13 @@ public: Disk* set_state_profile(kernel::profile::Profile* profile); Disk* set_read_bandwidth_profile(kernel::profile::Profile* profile); Disk* set_write_bandwidth_profile(kernel::profile::Profile* profile); + /** + * @brief Set the max amount of operations (either read or write) that can take place on this disk at the same time + * + * Use -1 to set no limit. + */ + Disk* set_concurrency_limit(int limit); + int get_concurrency_limit() const; IoPtr io_init(sg_size_t size, s4u::Io::OpType type) const; @@ -126,17 +133,35 @@ public: Disk* seal(); /* The signals */ - /** @brief Add a callback fired when a new Disk is created */ + /** @brief \static Add a callback fired when a new Disk is created */ static void on_creation_cb(const std::function& cb) { on_creation.connect(cb); } - /** @brief Add a callback fired when a Disk is destroyed */ + /** @brief \static Add a callback fired when any Disk is destroyed */ static void on_destruction_cb(const std::function& cb) { on_destruction.connect(cb); } - /** @brief Add a callback fired when a Disk's state changes */ - static void on_state_change_cb(const std::function& cb) { on_state_change.connect(cb); } + /** @brief Add a callback fired when this specific Disk is destroyed */ + void on_this_destruction_cb(const std::function& cb) { on_this_destruction.connect(cb); } + /** @brief \static Add a callback fired when any Disk is turned on or off */ + static void on_onoff_cb(const std::function& cb) + { + on_onoff.connect(cb); + } + /** @brief Add a callback fired when this specific Disk is turned on or off */ + void on_this_onoff_cb(const std::function& cb) + { + on_this_onoff.connect(cb); + } + + XBT_ATTRIB_DEPRECATED_v338("Please use on_onoff_cb() instead") static void on_state_change_cb( + const std::function& cb) + { + on_onoff.connect(cb); + } private: static xbt::signal on_creation; static xbt::signal on_destruction; - static xbt::signal on_state_change; + xbt::signal on_this_destruction; + static xbt::signal on_onoff; + xbt::signal on_this_onoff; }; } // namespace s4u diff --git a/include/simgrid/s4u/Engine.hpp b/include/simgrid/s4u/Engine.hpp index d20ae12114..2bdb4a9cce 100644 --- a/include/simgrid/s4u/Engine.hpp +++ b/include/simgrid/s4u/Engine.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -18,8 +18,7 @@ #include #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** @brief Simulation engine * * This is a singleton containing all the main functions of the simulation. @@ -41,9 +40,6 @@ public: ~Engine(); #endif - /** Finalize the default engine and all its dependencies */ - XBT_ATTRIB_DEPRECATED_v335("Users are not supposed to shutdown the Engine") void shutdown(); - /** Run the simulation until its end */ void run() const; @@ -56,9 +52,33 @@ public: static s4u::Engine* get_instance(); static s4u::Engine* get_instance(int* argc, char** argv); static bool has_instance() { return instance_ != nullptr; } + const std::vector& get_cmdline() const; + /** + * Creates a new platform, including hosts, links, and the routing table. + * + * @beginrst + * See also: :ref:`platform`. + * @endrst + */ void load_platform(const std::string& platf) const; + /** + * @brief Seals the platform, finishing the creation of its resources. + * + * This method is optional. The seal() is done automatically when you call Engine::run. + */ void seal_platform() const; + /** @brief Get a debug output of the platform. + * + * It looks like a XML platform file, but it may be very different from the input platform file: All netzones are + * flatified into a unique zone. This representation is mostly useful to debug your platform configuration and ensure + * that your assumptions over your configuration hold. This enables you to verify the exact list of links traversed + * between any two hosts, and the characteristics of every host and link. But you should not use the resulting file as + * an input platform file: it is very verbose, and thus much less efficient (in parsing time and runtime performance) + * than a regular platform file with the sufficient amount of intermediary netzones. Even if you use one zone only, + * specialized zones (such as clusters) are more efficient than the one with fully explicit routing used here. + */ + std::string flatify_platform() const; /** @verbatim embed:rst:inline Bind an actor name that could be found in :ref:`pf_tag_actor` tag to a function taking classical argc/argv parameters. See the :ref:`example `. @endverbatim */ void register_function(const std::string& name, const std::function& code); @@ -73,8 +93,8 @@ public: /** @verbatim embed:rst:inline Bind an actor name that could be found in :ref:`pf_tag_actor` tag to a class name passed as a template parameter. See the :ref:`example `. @endverbatim */ template void register_actor(const std::string& name) { - kernel::actor::ActorCodeFactory code_factory = [](std::vector args) { - return kernel::actor::ActorCode([args = std::move(args)]() mutable { + kernel::actor::ActorCodeFactory code_factory = [](std::vector args_factory) { + return kernel::actor::ActorCode([args = std::move(args_factory)]() mutable { F code(std::move(args)); code(); }); @@ -84,8 +104,8 @@ public: /** @verbatim embed:rst:inline Bind an actor name that could be found in :ref:`pf_tag_actor` tag to a function name passed as a parameter. See the :ref:`example `. @endverbatim */ template void register_actor(const std::string& name, F code) { - kernel::actor::ActorCodeFactory code_factory = [code](std::vector args) { - return kernel::actor::ActorCode([code, args = std::move(args)]() mutable { code(std::move(args)); }); + kernel::actor::ActorCodeFactory code_factory = [code](std::vector args_factory) { + return kernel::actor::ActorCode([code, args = std::move(args_factory)]() mutable { code(std::move(args)); }); }; register_function(name, code_factory); } @@ -105,8 +125,6 @@ protected: friend kernel::routing::NetZoneImpl; friend kernel::resource::HostImpl; friend kernel::resource::StandardLinkImpl; - void host_register(const std::string& name, Host* host); - void host_unregister(const std::string& name); void netpoint_register(simgrid::kernel::routing::NetPoint* card); void netpoint_unregister(simgrid::kernel::routing::NetPoint* card); void set_netzone_root(const NetZone* netzone); @@ -137,6 +155,7 @@ public: Link* link_by_name_or_null(const std::string& name) const; Mailbox* mailbox_by_name_or_create(const std::string& name) const; + MessageQueue* message_queue_by_name_or_create(const std::string& name) const; size_t get_actor_count() const; std::vector get_all_actors() const; @@ -171,21 +190,24 @@ public: /** @brief Retrieves all netzones of the type indicated by the template argument */ template std::vector get_filtered_netzones() const { - static_assert(std::is_base_of::value, + static_assert(std::is_base_of_v, "Filtering netzones is only possible for subclasses of kernel::routing::NetZoneImpl"); std::vector res; get_filtered_netzones_recursive(get_netzone_root(), &res); return res; } - kernel::EngineImpl* get_impl() const { return pimpl; } + kernel::EngineImpl* get_impl() const + { + return pimpl_; + } /** Returns whether SimGrid was initialized yet -- mostly for internal use */ static bool is_initialized(); /** @brief set a configuration variable * * @beginrst - * Do --help on any simgrid binary to see the list of currently existing configuration variables + * Do --help on any SimGrid binary to see the list of currently existing configuration variables * (see also :ref:`options`). * @endrst * @@ -234,19 +256,20 @@ private: static xbt::signal on_deadlock; static xbt::signal on_simulation_end; - kernel::EngineImpl* const pimpl; + kernel::EngineImpl* const pimpl_; static Engine* instance_; void initialize(int* argc, char** argv); }; std::vector create_DAG_from_dot(const std::string& filename); std::vector create_DAG_from_DAX(const std::string& filename); +std::vector create_DAG_from_json(const std::string& filename); #ifndef DOXYGEN /* Internal use only, no need to expose it */ template XBT_PRIVATE void get_filtered_netzones_recursive(const s4u::NetZone* current, std::vector* whereto) { - static_assert(std::is_base_of::value, + static_assert(std::is_base_of_v, "Filtering netzones is only possible for subclasses of kernel::routing::NetZoneImpl"); for (auto const& elem : current->get_children()) { get_filtered_netzones_recursive(elem, whereto); @@ -256,7 +279,6 @@ XBT_PRIVATE void get_filtered_netzones_recursive(const s4u::NetZone* current, st } } #endif -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif /* SIMGRID_S4U_ENGINE_HPP */ diff --git a/include/simgrid/s4u/Exec.hpp b/include/simgrid/s4u/Exec.hpp index b0cdbf259f..8167b87c24 100644 --- a/include/simgrid/s4u/Exec.hpp +++ b/include/simgrid/s4u/Exec.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,8 +11,7 @@ #include #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** Computation Activity, representing the asynchronous executions. * @@ -39,27 +38,17 @@ class XBT_PUBLIC Exec : public Activity_T { protected: explicit Exec(kernel::activity::ExecImplPtr pimpl); + Exec* do_start() override; void reset() const; - static xbt::signal on_start; - public: #ifndef DOXYGEN Exec(Exec const&) = delete; Exec& operator=(Exec const&) = delete; #endif - /*! Signal fired each time that an execution actually starts (no veto) */ - static void on_start_cb(const std::function& cb) { on_start.connect(cb); } - + /*! \static Initiate the creation of an Exec. Setters have to be called afterwards */ static ExecPtr init(); - Exec* start() override; - - /*! take a vector of s4u::ExecPtr and return when one of them is finished. - * The return value is the rank of the first finished ExecPtr. */ - static ssize_t wait_any(const std::vector& execs) { return wait_any_for(execs, -1); } - /*! Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.*/ - static ssize_t wait_any_for(const std::vector& execs, double timeout); /** @brief On sequential executions, returns the amount of flops that remain to be done; This cannot be used on * parallel executions. */ @@ -82,12 +71,21 @@ public: Host* get_host() const; unsigned int get_host_number() const; + int get_thread_count() const; double get_cost() const; bool is_parallel() const { return parallel_; } bool is_assigned() const override; + +#ifndef DOXYGEN + static ssize_t deprecated_wait_any_for(const std::vector& execs, double timeout); // XBT_ATTRIB_DEPRECATED_v339 + + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static ssize_t + wait_any(const std::vector& execs) { return deprecated_wait_any_for(execs, -1); } + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") static ssize_t + wait_any_for(const std::vector& execs, double timeout) { return deprecated_wait_any_for(execs, timeout); } +#endif }; -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif /* SIMGRID_S4U_EXEC_HPP */ diff --git a/include/simgrid/s4u/Host.hpp b/include/simgrid/s4u/Host.hpp index 8fbe49484b..28ce4691ef 100644 --- a/include/simgrid/s4u/Host.hpp +++ b/include/simgrid/s4u/Host.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,9 +7,9 @@ #define SIMGRID_S4U_HOST_HPP #include +#include #include #include -#include #include #include @@ -47,6 +47,14 @@ class XBT_PUBLIC Host : public xbt::Extendable { kernel::resource::CpuImpl* pimpl_cpu_ = nullptr; kernel::routing::NetPoint* pimpl_netpoint_ = nullptr; +#ifndef DOXYGEN + friend kernel::resource::CpuAction; // signal exec_state_changed +#endif + + static xbt::signal on_creation; + static xbt::signal on_destruction; + xbt::signal on_this_destruction; + static xbt::signal on_exec_state_change; public: explicit Host(kernel::resource::HostImpl* pimpl) : pimpl_(pimpl) {} @@ -55,22 +63,52 @@ protected: virtual ~Host(); // Call destroy() instead of manually deleting it. Host* set_netpoint(kernel::routing::NetPoint* netpoint); - static xbt::signal on_creation; - static xbt::signal on_destruction; - public: static xbt::signal on_speed_change; - static xbt::signal on_state_change; + xbt::signal on_this_speed_change; + static xbt::signal on_onoff; + xbt::signal on_this_onoff; + #endif - /** Add a callback fired on each newly created host */ + /** \static Add a callback fired on each newly created host */ static void on_creation_cb(const std::function& cb) { on_creation.connect(cb); } - /** Add a callback fired when the machine is turned on or off (called AFTER the change) */ - static void on_state_change_cb(const std::function& cb) { on_state_change.connect(cb); } - /** Add a callback fired when the speed of the machine is changed (called AFTER the change) + /** \static Add a callback fired when any machine is turned on or off (called AFTER the change) */ + static void on_onoff_cb(const std::function& cb) + { + on_onoff.connect(cb); + } + XBT_ATTRIB_DEPRECATED_v338("Please use on_onoff_cb() instead") static void on_state_change_cb( + const std::function& cb) + { + on_onoff.connect(cb); + } + /** Add a callback fired when this specific machine is turned on or off (called AFTER the change) */ + void on_this_onoff_cb(const std::function& cb) + { + on_this_onoff.connect(cb); + } + /** \static Add a callback fired when the speed of any machine is changed (called AFTER the change) * (either because of a pstate switch or because of an external load event coming from the profile) */ static void on_speed_change_cb(const std::function& cb) { on_speed_change.connect(cb); } - /** Add a callback fired just before destructing a host */ + /** Add a callback fired when the speed of this specific machine is changed (called AFTER the change) + * (either because of a pstate switch or because of an external load event coming from the profile) */ + void on_this_speed_change_cb(const std::function& cb) + { + on_this_speed_change.connect(cb); + } + /** \static Add a callback fired just before destructing any host */ static void on_destruction_cb(const std::function& cb) { on_destruction.connect(cb); } + /** Add a callback fired just before destructing this specific host */ + void on_this_destruction_cb(const std::function& cb) + { + on_this_destruction.connect(cb); + } + /** \static Add a callback fired when the state of any exec activity changes */ + static void on_exec_state_change_cb( + const std::function& cb) + { + on_exec_state_change.connect(cb); + } virtual void destroy(); #ifndef DOXYGEN @@ -79,15 +117,15 @@ public: Host& operator=(Host const&) = delete; #endif - /** Retrieve a host from its name, or return nullptr */ + /** \static Retrieve a host from its name, or return nullptr */ static Host* by_name_or_null(const std::string& name); - /** Retrieve a host from its name, or die */ + /** \static Retrieve a host from its name, or die */ static Host* by_name(const std::string& name); - /** Retrieves the host on which the running actor is located */ + /** \static Retrieves the host on which the running actor is located */ static Host* current(); /** Retrieves the name of that host as a C++ string */ - xbt::string const& get_name() const; + std::string const& get_name() const; /** Retrieves the name of that host as a C string */ const char* get_cname() const; @@ -134,7 +172,15 @@ public: Host* set_state_profile(kernel::profile::Profile* p); Host* set_speed_profile(kernel::profile::Profile* p); - /** @brief Convert the CPU's speed from string to double */ + /** + * @brief Set the max amount of executions that can take place on this host at the same time + * + * Use -1 to set no limit. + */ + Host* set_concurrency_limit(int limit); + int get_concurrency_limit() const; + + /** \static @brief Convert the CPU's speed from string to double */ static std::vector convert_pstate_speed_vector(const std::vector& speed_per_state); /** * @brief Set the CPU's speed @@ -232,6 +278,7 @@ public: void route_to(const Host* dest, std::vector& links, double* latency) const; void route_to(const Host* dest, std::vector& links, double* latency) const; + std::pair, double> route_to(const Host* dest) const; /** * @brief Seal this host diff --git a/include/simgrid/s4u/Io.hpp b/include/simgrid/s4u/Io.hpp index c3118c357d..0709a3b50c 100644 --- a/include/simgrid/s4u/Io.hpp +++ b/include/simgrid/s4u/Io.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,8 +11,7 @@ #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** I/O Activity, representing the asynchronous disk access. * @@ -25,23 +24,23 @@ class XBT_PUBLIC Io : public Activity_T { friend kernel::EngineImpl; #endif - static xbt::signal on_start; - protected: explicit Io(kernel::activity::IoImplPtr pimpl); + Io* do_start() override; + + static ssize_t deprecated_wait_any_for(const std::vector& ios, double timeout); // XBT_ATTRIB_DEPRECATED_v339 public: enum class OpType { READ, WRITE }; - static void on_start_cb(const std::function& cb) { on_start.connect(cb); } - + /*! \static Initiate the creation of an I/O. Setters have to be called afterwards */ static IoPtr init(); - Io* start() override; - /*! take a vector of s4u::IoPtr and return when one of them is finished. - * The return value is the rank of the first finished IoPtr. */ - static ssize_t wait_any(const std::vector& ios) { return wait_any_for(ios, -1); } - /*! Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.*/ - static ssize_t wait_any_for(const std::vector& ios, double timeout); +#ifndef DOXYGEN + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") + static ssize_t wait_any(const std::vector& ios) { return deprecated_wait_any_for(ios, -1); } + XBT_ATTRIB_DEPRECATED_v339("Please use ActivitySet instead") + static ssize_t wait_any_for(const std::vector& ios, double timeout) { return deprecated_wait_any_for(ios, timeout); } +#endif double get_remaining() const override; sg_size_t get_performed_ioops() const; @@ -50,12 +49,20 @@ public: IoPtr set_size(sg_size_t size); IoPtr set_op_type(OpType type); + static IoPtr streamto_init(Host* from, const Disk* from_disk, Host* to, const Disk* to_disk); + static IoPtr streamto_async(Host* from, const Disk* from_disk, Host* to, const Disk* to_disk, + uint64_t simulated_size_in_bytes); + static void streamto(Host* from, const Disk* from_disk, Host* to, const Disk* to_disk, + uint64_t simulated_size_in_bytes); + + IoPtr set_source(Host* from, const Disk* from_disk); + IoPtr set_destination(Host* to, const Disk* to_disk); + IoPtr update_priority(double priority); bool is_assigned() const override; }; -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif /* SIMGRID_S4U_IO_HPP */ diff --git a/include/simgrid/s4u/Link.hpp b/include/simgrid/s4u/Link.hpp index acb4092eeb..c2ac18e036 100644 --- a/include/simgrid/s4u/Link.hpp +++ b/include/simgrid/s4u/Link.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -45,11 +45,25 @@ protected: #endif public: - enum class SharingPolicy { NONLINEAR = 4, WIFI = 3, SPLITDUPLEX = 2, SHARED = 1, FATPIPE = 0 }; + /** Specifies how a given link is shared between concurrent communications */ + enum class SharingPolicy { + /// This policy takes a callback that specifies the maximal capacity as a function of the number of usage. See the + /// examples with 'degradation' in their name. + NONLINEAR = 4, + /// Pseudo-sharing policy requesting wifi-specific sharing. + WIFI = 3, + /// Each link is split in 2, UP and DOWN, one per direction. These links are SHARED. + SPLITDUPLEX = 2, + /// The bandwidth is shared between all comms using that link, regardless of their direction. + SHARED = 1, + /// Each comm can use the link fully, with no sharing (only a maximum). This is intended to represent the backbone + /// links that cannot be saturated by concurrent links, but have a maximal bandwidth. + FATPIPE = 0 + }; kernel::resource::StandardLinkImpl* get_impl() const; - /** @brief Retrieve a link from its name */ + /** \static @brief Retrieve a link from its name */ static Link* by_name(const std::string& name); static Link* by_name_or_null(const std::string& name); @@ -111,6 +125,7 @@ public: * @param limit Number of concurrent flows */ Link* set_concurrency_limit(int limit); + int get_concurrency_limit() const; /** @brief Set the level of communication speed of the given host on this wifi link. * @@ -129,7 +144,11 @@ public: void set_host_wifi_rate(const s4u::Host* host, int level) const; /** @brief Returns the current load (in bytes per second) */ - double get_usage() const; + double get_load() const; + +#ifndef DOXYGEN + XBT_ATTRIB_DEPRECATED_v338("Please use get_load() instead") double get_usage() const { return get_load(); } +#endif /** @brief Check if the Link is used (at least one flow uses the link) */ bool is_used() const; @@ -149,29 +168,56 @@ public: private: #ifndef DOXYGEN static xbt::signal on_creation; - static xbt::signal on_state_change; + static xbt::signal on_onoff; + xbt::signal on_this_onoff; static xbt::signal on_bandwidth_change; + xbt::signal on_this_bandwidth_change; static xbt::signal on_communication_state_change; static xbt::signal on_destruction; + xbt::signal on_this_destruction; #endif public: /* The signals */ - /** @brief Add a callback fired when a new Link is created */ + /** \static @brief Add a callback fired when a new Link is created */ static void on_creation_cb(const std::function& cb) { on_creation.connect(cb); } - /** @brief Add a callback fired when the state of a Link changes (when it is turned on or off) */ - static void on_state_change_cb(const std::function& cb) { on_state_change.connect(cb); } - /** @brief Add a callback fired when the bandwidth of a Link changes */ + /** \static @brief Add a callback fired when any Link is turned on or off */ + static void on_onoff_cb(const std::function& cb) + { + on_onoff.connect(cb); + } + /** @brief Add a callback fired when this specific Link is turned on or off */ + void on_this_onoff_cb(const std::function& cb) + { + on_this_onoff.connect(cb); + } + /** \static @brief Add a callback fired when the bandwidth of any Link changes */ static void on_bandwidth_change_cb(const std::function& cb) { on_bandwidth_change.connect(cb); } - /** @brief Add a callback fired when a communication changes it state (ready/done/cancel) */ + /** @brief Add a callback fired when the bandwidth of this specific Link changes */ + void on_this_bandwidth_change_cb(const std::function& cb) + { + on_this_bandwidth_change.connect(cb); + } + /** \static @brief Add a callback fired when a communication changes it state (ready/done/cancel) */ static void on_communication_state_change_cb( const std::function& cb) { on_communication_state_change.connect(cb); } - /** @brief Add a callback fired when a Link is destroyed */ + /** \static @brief Add a callback fired when any Link is destroyed */ static void on_destruction_cb(const std::function& cb) { on_destruction.connect(cb); } + /** @brief Add a callback fired when this specific Link is destroyed */ + void on_this_destruction_cb(const std::function& cb) + { + on_this_destruction.connect(cb); + } + + XBT_ATTRIB_DEPRECATED_v338("Please use on_onoff_cb() instead") static void on_state_change_cb( + const std::function& cb) + { + on_onoff.connect(cb); + } }; /** @@ -189,7 +235,7 @@ public: /** @brief Get the link direction down */ Link* get_link_down() const; - /** @brief Retrieve a link from its name */ + /** \static @brief Retrieve a link from its name */ static SplitDuplexLink* by_name(const std::string& name); }; diff --git a/include/simgrid/s4u/Mailbox.hpp b/include/simgrid/s4u/Mailbox.hpp index 96dab88c23..b8eddff976 100644 --- a/include/simgrid/s4u/Mailbox.hpp +++ b/include/simgrid/s4u/Mailbox.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,13 +10,11 @@ #include #include #include -#include #include #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** @brief Mailboxes: Network rendez-vous points. */ class XBT_PUBLIC Mailbox { @@ -36,11 +34,11 @@ protected: public: /** @brief Retrieves the name of that mailbox as a C++ string */ - const xbt::string& get_name() const; + const std::string& get_name() const; /** @brief Retrieves the name of that mailbox as a C string */ const char* get_cname() const; - /** Retrieve the mailbox associated to the given name. Mailboxes are created on demand. */ + /** \static Retrieve the mailbox associated to the given name. Mailboxes are created on demand. */ static Mailbox* by_name(const std::string& name); /** Returns whether the mailbox contains queued communications */ @@ -55,7 +53,11 @@ public: /** Look if there is a communication going on in a mailbox and return the PID of the sender actor */ aid_t listen_from() const; - /** Check if there is a communication ready to be consumed from a mailbox. */ + /** Check if there is a communication ready to be consumed from a mailbox. + * \beginrst + * See :ref:`this example `. + * \endrst + */ bool ready() const; /** Gets the first element in the queue (without dequeuing it), or nullptr if none is there */ @@ -116,6 +118,9 @@ public: CommPtr get_init(); /** Creates and start an async data reception to that mailbox */ template CommPtr get_async(T** data); + /** Creates and start an async data reception to that mailbox. Since the data location is not provided, you'll have to + * use Comm::get_payload once the comm terminates */ + CommPtr get_async(); /** Blocking data reception */ template T* get(); @@ -131,7 +136,7 @@ public: template CommPtr Mailbox::get_async(T** data) { CommPtr res = get_init()->set_dst_data(reinterpret_cast(data), sizeof(void*)); - res->vetoable_start(); + res->start(); return res; } @@ -148,7 +153,6 @@ template T* Mailbox::get(double timeout) get_async(&res)->wait_for(timeout); return res; } -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif /* SIMGRID_S4U_MAILBOX_HPP */ diff --git a/include/simgrid/s4u/Mess.hpp b/include/simgrid/s4u/Mess.hpp new file mode 100644 index 0000000000..81dcee98ff --- /dev/null +++ b/include/simgrid/s4u/Mess.hpp @@ -0,0 +1,65 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_S4U_MESS_HPP +#define SIMGRID_S4U_MESS_HPP + +#include +#include + +#include +#include + +namespace simgrid::s4u { + +class XBT_PUBLIC Mess : public Activity_T { +#ifndef DOXYGEN + friend MessageQueue; // Factory of messages + friend kernel::activity::MessImpl; +#endif + MessageQueue* queue_ = nullptr; + void* payload_ = nullptr; + size_t dst_buff_size_ = 0; + void* dst_buff_ = nullptr; + + Mess() = default; + Mess* do_start() override; + + static xbt::signal on_send; + xbt::signal on_this_send; + static xbt::signal on_recv; + xbt::signal on_this_recv; + + /* These ensure that the on_completion signals are really thrown */ + void fire_on_completion_for_real() const { Activity_T::fire_on_completion(); } + void fire_on_this_completion_for_real() const { Activity_T::fire_on_this_completion(); } + +public: +#ifndef DOXYGEN + Mess(Mess const&) = delete; + Mess& operator=(Mess const&) = delete; +#endif + + MessPtr set_queue(MessageQueue* queue); + MessageQueue* get_queue() const { return queue_; } + + /** Retrieve the payload associated to the communication. You can only do that once the comm is (gracefully) + * terminated */ + void* get_payload() const { return payload_; } + MessPtr set_payload(void* data); + MessPtr set_dst_data(void** buff, size_t size); + Actor* get_sender() const; + Actor* get_receiver() const; + + bool is_assigned() const override { return true; }; + + Mess* wait_for(double timeout) override; + + kernel::actor::ActorImpl* sender_ = nullptr; + kernel::actor::ActorImpl* receiver_ = nullptr; +}; +} // namespace simgrid::s4u + +#endif /* SIMGRID_S4U_MESS_HPP */ diff --git a/include/simgrid/s4u/MessageQueue.hpp b/include/simgrid/s4u/MessageQueue.hpp new file mode 100644 index 0000000000..dc00941216 --- /dev/null +++ b/include/simgrid/s4u/MessageQueue.hpp @@ -0,0 +1,112 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_S4U_MESSAGEQUEUE_HPP +#define SIMGRID_S4U_MESSAGEQUEUE_HPP + +#include +#include +#include + +#include + +namespace simgrid::s4u { + +class XBT_PUBLIC MessageQueue { +#ifndef DOXYGEN + friend Mess; + friend kernel::activity::MessageQueueImpl; +#endif + + kernel::activity::MessageQueueImpl* const pimpl_; + + explicit MessageQueue(kernel::activity::MessageQueueImpl * mqueue) : pimpl_(mqueue) {} + ~MessageQueue() = default; + +protected: + kernel::activity::MessageQueueImpl* get_impl() const { return pimpl_; } + +public: + /** @brief Retrieves the name of that message queue as a C++ string */ + const std::string& get_name() const; + /** @brief Retrieves the name of that message queue as a C string */ + const char* get_cname() const; + + /** \static Retrieve the message queye associated to the given name. Message queues are created on demand. */ + static MessageQueue* by_name(const std::string& name); + + /** Returns whether the message queue contains queued messages */ + bool empty() const; + + /* Returns the number of queued messages */ + size_t size() const; + + /** Gets the first element in the queue (without dequeuing it), or nullptr if none is there */ + kernel::activity::MessImplPtr front() const; + + /** Creates (but don't start) a data transmission to that message queue */ + MessPtr put_init(); + /** Creates (but don't start) a data transmission to that message queue. + * + * Please note that if you send a pointer to some data, you must ensure that your data remains live until + * consumption, or the receiver will get a pointer to a garbled memory area. + */ + MessPtr put_init(void* payload); + /** Creates and start a data transmission to that mailbox. + * + * Please note that if you send a pointer to some data, you must ensure that your data remains live until + * consumption, or the receiver will get a pointer to a garbled memory area. + */ + MessPtr put_async(void* payload); + + /** Blocking data transmission. + * + * Please note that if you send a pointer to some data, you must ensure that your data remains live until + * consumption, or the receiver will get a pointer to a garbled memory area. + */ + void put(void* payload); + /** Blocking data transmission with timeout */ + void put(void* payload, double timeout); + + /** Creates (but don't start) a data reception onto that message queue. */ + MessPtr get_init(); + /** Creates and start an async data reception to that message queue */ + template MessPtr get_async(T** data); + /** Creates and start an async data reception to that mailbox. Since the data location is not provided, you'll have to + * use Mess::get_payload once the messaging operation terminates */ + MessPtr get_async(); + + /** Blocking data reception */ + template T* get(); + template std::unique_ptr get_unique() { return std::unique_ptr(get()); } + + /** Blocking data reception with timeout */ + template T* get(double timeout); + template std::unique_ptr get_unique(double timeout) { return std::unique_ptr(get(timeout)); } +}; + +template MessPtr MessageQueue::get_async(T** data) +{ + MessPtr res = get_init()->set_dst_data(reinterpret_cast(data), sizeof(void*)); + res->start(); + return res; +} + +template T* MessageQueue::get() +{ + T* res = nullptr; + get_async(&res)->wait(); + return res; +} + +template T* MessageQueue::get(double timeout) +{ + T* res = nullptr; + get_async(&res)->wait_for(timeout); + return res; +} +} // namespace simgrid::s4u + +#endif /* SIMGRID_S4U_MESSAGEQUEUE_HPP */ diff --git a/include/simgrid/s4u/Mutex.hpp b/include/simgrid/s4u/Mutex.hpp index cebeca7dc1..29d9ed1043 100644 --- a/include/simgrid/s4u/Mutex.hpp +++ b/include/simgrid/s4u/Mutex.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,13 +6,15 @@ #ifndef SIMGRID_S4U_MUTEX_HPP #define SIMGRID_S4U_MUTEX_HPP +#include "simgrid/s4u/Actor.hpp" #include #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** @brief A classical mutex, but blocking in the simulation world. + * + * S4U mutexes are not recursive. If an actor tries to lock the same object twice, it deadlocks with itself. * * @beginrst * It is strictly impossible to use a real mutex, such as @@ -48,14 +50,16 @@ class XBT_PUBLIC Mutex { #endif public: - /** Constructs a new mutex */ - static MutexPtr create(); + /** \static Constructs a new mutex */ + static MutexPtr create(bool recursive = false); + void lock(); void unlock(); bool try_lock(); + + Actor* get_owner(); }; -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif /* SIMGRID_S4U_MUTEX_HPP */ diff --git a/include/simgrid/s4u/NetZone.hpp b/include/simgrid/s4u/NetZone.hpp index e974320790..68052708a5 100644 --- a/include/simgrid/s4u/NetZone.hpp +++ b/include/simgrid/s4u/NetZone.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,6 +6,7 @@ #ifndef SIMGRID_S4U_NETZONE_HPP #define SIMGRID_S4U_NETZONE_HPP +#include "simgrid/s4u/Host.hpp" #include #include #include @@ -14,11 +15,11 @@ #include #include #include +#include #include #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** @brief Networking Zones * @@ -57,7 +58,13 @@ public: const char* get_property(const std::string& key) const; void set_property(const std::string& key, const std::string& value); /** @brief Get the netpoint associated to this netzone */ - kernel::routing::NetPoint* get_netpoint(); + kernel::routing::NetPoint* get_netpoint() const; + /** @brief Get the gateway associated to this netzone */ + kernel::routing::NetPoint* get_gateway() const; + kernel::routing::NetPoint* get_gateway(const std::string& name) const; + void set_gateway(const s4u::Host* router) { set_gateway(router->get_netpoint()); } + void set_gateway(kernel::routing::NetPoint* router); + void set_gateway(const std::string& name, kernel::routing::NetPoint* router); void extract_xbt_graph(const s_xbt_graph_t* graph, std::map>* nodes, std::map>* edges); @@ -65,6 +72,24 @@ public: /* Add content to the netzone, at parsing time. It should be sealed afterward. */ unsigned long add_component(kernel::routing::NetPoint* elm); /* A host, a router or a netzone, whatever */ + /** + * @brief Add a route between 2 netzones, and same in other direction + * @param src Source netzone + * @param dst Destination netzone + * @param links List of links + */ + void add_route(const NetZone* src, const NetZone* dst, const std::vector& links); + +/** + * @brief Add a route between 2 netzones, and same in other direction + * @param src Source netzone + * @param dst Destination netzone + * @param link_list List of links and their direction used in this communication + * @param symmetrical Bi-directional communication + */ + void add_route(const NetZone* src, const NetZone* dst, const std::vector& link_list, bool symmetrical = true); + +#ifndef DOXYGEN /** * @brief Add a route between 2 netpoints * @@ -79,8 +104,44 @@ public: * @param link_list List of links and their direction used in this communication * @param symmetrical Bi-directional communication */ - void add_route(kernel::routing::NetPoint* src, kernel::routing::NetPoint* dst, kernel::routing::NetPoint* gw_src, - kernel::routing::NetPoint* gw_dst, const std::vector& link_list, bool symmetrical = true); + XBT_ATTRIB_DEPRECATED_v339("Please call add_route either from Host to Host or NetZone to NetZone") void add_route( + kernel::routing::NetPoint* src, kernel::routing::NetPoint* dst, kernel::routing::NetPoint* gw_src, + kernel::routing::NetPoint* gw_dst, const std::vector& link_list, bool symmetrical = true); + /** + * @brief Add a route between 2 netpoints, and same in other direction + * + * Create a route: + * - route between 2 hosts/routers in same netzone, no gateway is needed + * - route between 2 netzones, connecting 2 gateways. + * + * @param src Source netzone's netpoint + * @param dst Destination netzone' netpoint + * @param gw_src Netpoint of the gateway in the source netzone + * @param gw_dst Netpoint of the gateway in the destination netzone + * @param link_list List of links + */ + XBT_ATTRIB_DEPRECATED_v339("Please call add_route either from Host to Host or NetZone to NetZone") void add_route( + kernel::routing::NetPoint* src, kernel::routing::NetPoint* dst, kernel::routing::NetPoint* gw_src, + kernel::routing::NetPoint* gw_dst, const std::vector& links); +#endif + + /** + * @brief Add a route between 2 hosts + * + * @param src Source host + * @param dst Destination host + * @param link_list List of links and their direction used in this communication + * @param symmetrical Bi-directional communication + */ + void add_route(const Host* src, const Host* dst, const std::vector& link_list, bool symmetrical = true); + /** + * @brief Add a route between 2 hosts + * + * @param src Source host + * @param dst Destination host + * @param links List of links. The UP direction will be used on src->dst and DOWN direction on dst->src + */ + void add_route(const Host* src, const Host* dst, const std::vector& links); void add_bypass_route(kernel::routing::NetPoint* src, kernel::routing::NetPoint* dst, kernel::routing::NetPoint* gw_src, kernel::routing::NetPoint* gw_dst, @@ -93,7 +154,9 @@ private: #endif public: + /** \static Add a callback fired on each newly created NetZone */ static void on_creation_cb(const std::function& cb) { on_creation.connect(cb); } + /** \static Add a callback fired on each newly sealed NetZone */ static void on_seal_cb(const std::function& cb) { on_seal.connect(cb); } /** @@ -142,7 +205,7 @@ public: s4u::SplitDuplexLink* create_split_duplex_link(const std::string& name, const std::string& bandwidth); s4u::SplitDuplexLink* create_split_duplex_link(const std::string& name, double bandwidth); - kernel::resource::NetworkModelIntf* get_network_model() const; + kernel::resource::NetworkModel* get_network_model() const; /** * @brief Make a router within that NetZone @@ -153,6 +216,15 @@ public: /** @brief Seal this netzone configuration */ NetZone* seal(); + + void + set_latency_factor_cb(std::function& /*links*/, + const std::unordered_set& /*netzones*/)> const& cb) const; + void + set_bandwidth_factor_cb(std::function& /*links*/, + const std::unordered_set& /*netzones*/)> const& cb) const; }; // External constructors so that the types (and the types of their content) remain hidden @@ -179,8 +251,29 @@ struct ClusterCallbacks { * @param id: Internal identifier of the element * @return pair: returns a pair of netpoint and gateway. */ + // XBT_ATTRIB_DEPRECATED_v339 using ClusterNetPointCb = std::pair( NetZone* zone, const std::vector& coord, unsigned long id); + + /** + * @brief Callback used to set the NetZone located at some leaf of clusters (Torus, FatTree, etc) + * + * @param zone: The parent zone, needed for creating new resources (hosts, links) + * @param coord: the coordinates of the element + * @param id: Internal identifier of the element + * @return NetZone*: returns newly created netzone + */ + using ClusterNetZoneCb = NetZone*(NetZone* zone, const std::vector& coord, unsigned long id); + /** + * @brief Callback used to set the Host located at some leaf of clusters (Torus, FatTree, etc) + * + * @param zone: The parent zone, needed for creating new resources (hosts, links) + * @param coord: the coordinates of the element + * @param id: Internal identifier of the element + * @return Host*: returns newly created host + */ + using ClusterHostCb = Host*(NetZone* zone, const std::vector& coord, unsigned long id); + /** * @brief Callback used to set the links for some leaf of the cluster (Torus, FatTree, etc) * @@ -198,14 +291,36 @@ struct ClusterCallbacks { */ using ClusterLinkCb = Link*(NetZone* zone, const std::vector& coord, unsigned long id); - std::function netpoint; + bool by_netzone_ = false; + bool is_by_netzone() const { return by_netzone_; } + bool by_netpoint_ = false; // XBT_ATTRIB_DEPRECATED_v339 + bool is_by_netpoint() const { return by_netpoint_; } // XBT_ATTRIB_DEPRECATED_v339 + std::function netpoint; // XBT_ATTRIB_DEPRECATED_v339 + std::function host; + std::function netzone; std::function loopback = {}; std::function limiter = {}; + explicit ClusterCallbacks(const std::function& set_netzone) + : by_netzone_(true), netzone(set_netzone){/* nothing to do */}; + + ClusterCallbacks(const std::function& set_netzone, + const std::function& set_loopback, const std::function& set_limiter) + : by_netzone_(true), netzone(set_netzone), loopback(set_loopback), limiter(set_limiter){/* nothing to do */}; + + explicit ClusterCallbacks(const std::function& set_host) + : host(set_host) {/* nothing to do */}; + + ClusterCallbacks(const std::function& set_host, + const std::function& set_loopback, const std::function& set_limiter) + : host(set_host), loopback(set_loopback), limiter(set_limiter){/* nothing to do */}; + + XBT_ATTRIB_DEPRECATED_v339("Please use callback with either a Host/NetZone creation function as first parameter") explicit ClusterCallbacks(const std::function& set_netpoint) - : netpoint(set_netpoint){/*nothing to do */}; + : by_netpoint_(true), netpoint(set_netpoint){/* nothing to do */}; + XBT_ATTRIB_DEPRECATED_v339("Please use callback with either a Host/NetZone creation function as first parameter") ClusterCallbacks(const std::function& set_netpoint, const std::function& set_loopback, const std::function& set_limiter) - : netpoint(set_netpoint), loopback(set_loopback), limiter(set_limiter){/*nothing to do */}; + : by_netpoint_(true), netpoint(set_netpoint), loopback(set_loopback), limiter(set_limiter){/* nothing to do */}; }; /** * @brief Create a torus zone @@ -319,7 +434,6 @@ XBT_PUBLIC NetZone* create_dragonfly_zone(const std::string& name, const NetZone const DragonflyParams& parameters, const ClusterCallbacks& set_callbacks, double bandwidth, double latency, Link::SharingPolicy sharing_policy); -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif /* SIMGRID_S4U_NETZONE_HPP */ diff --git a/include/simgrid/s4u/Semaphore.hpp b/include/simgrid/s4u/Semaphore.hpp index c4e0691d7c..4c16f7ae9c 100644 --- a/include/simgrid/s4u/Semaphore.hpp +++ b/include/simgrid/s4u/Semaphore.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,8 +8,7 @@ #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** @brief A classical semaphore, but blocking in the simulation world * @@ -46,7 +45,7 @@ class XBT_PUBLIC Semaphore { #endif public: - /** Constructs a new semaphore */ + /** \static Constructs a new semaphore */ static SemaphorePtr create(unsigned int initial_capacity); void acquire(); @@ -57,7 +56,6 @@ public: bool would_block() const; }; -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif /* SIMGRID_S4U_SEMAPHORE_HPP */ diff --git a/include/simgrid/s4u/Task.hpp b/include/simgrid/s4u/Task.hpp new file mode 100644 index 0000000000..4c44875690 --- /dev/null +++ b/include/simgrid/s4u/Task.hpp @@ -0,0 +1,227 @@ +#ifndef SIMGRID_S4U_TASK_H_ +#define SIMGRID_S4U_TASK_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace simgrid::s4u { + +class XBT_PUBLIC Token : public xbt::Extendable {}; + +/** Task class */ +class XBT_PUBLIC Task { + + std::string name_; + + std::map amount_ = {{"instance_0", 0}, {"dispatcher", 0}, {"collector", 0}}; + std::map queued_firings_ = {{"instance_0", 0}, {"dispatcher", 0}, {"collector", 0}}; + std::map running_instances_ = {{"instance_0", 0}, {"dispatcher", 0}, {"collector", 0}}; + std::map count_ = {{"instance_0", 0}, {"dispatcher", 0}, {"collector", 0}}; + std::map parallelism_degree_ = {{"instance_0", 1}, {"dispatcher", 1}, {"collector", 1}}; + std::map internal_bytes_to_send_ = {{"instance_0", 0}, {"dispatcher", 0}}; + + std::function load_balancing_function_; + + std::set successors_ = {}; + std::map predecessors_ = {}; + std::atomic_int_fast32_t refcount_{0}; + + bool ready_to_run(std::string instance); + void receive(Task* source); + + std::shared_ptr token_ = nullptr; + std::map>> tokens_received_; + std::map> current_activities_ = { + {"instance_0", {}}, {"dispatcher", {}}, {"collector", {}}}; + + inline static xbt::signal on_start; + xbt::signal on_this_start; + inline static xbt::signal on_completion; + xbt::signal on_this_completion; + +protected: + explicit Task(const std::string& name); + virtual ~Task() = default; + + virtual void fire(std::string instance); + void complete(std::string instance); + + void store_activity(ActivityPtr a, const std::string& instance) { current_activities_[instance].push_back(a); } + + virtual void add_instances(int n); + virtual void remove_instances(int n); + +public: + /** @param name The new name of this Task */ + void set_name(std::string name); + /** Retrieves the name of that Task as a C++ string */ + const std::string& get_name() const { return name_; } + /** Retrieves the name of that Task as a C string */ + const char* get_cname() const { return name_.c_str(); } + /** @param amount The new amount of work this instance of this Task has to do + * @note In flops for ExecTasks instances and in bytes for CommTasks instances. In flops for dispatcher and collector + * instances */ + void set_amount(double amount, std::string instance = "instance_0"); + /** @return Amout of work this instance of this Task has to process */ + double get_amount(std::string instance = "instance_0") const { return amount_.at(instance); } + /** @return Amount of queued firings for this instance of this Task */ + int get_queued_firings(std::string instance = "instance_0") const { return queued_firings_.at(instance); } + /** @return Amount currently running of this instance of this Task */ + int get_running_count(std::string instance = "instance_0") const { return running_instances_.at(instance); } + /** @return Number of times this instance of this Task has been completed */ + int get_count(std::string instance = "collector") const { return count_.at(instance); } + /** @param n The parallelism degree to set + * @brief The parallelism degree defines how many of this instance can run in parallel. */ + void set_parallelism_degree(int n, std::string instance = "all"); + /** @return Parallelism degree of this instance of this Task */ + int get_parallelism_degree(std::string instance = "instance_0") const { return parallelism_degree_.at(instance); } + /** @param bytes The amount of bytes this instance has to send to the next instance of this Task + * @note This amount is used when the host is different between the dispatcher and the instance doing the work of the + * Task, or between the instance and the collector. */ + void set_internal_bytes(int bytes, std::string instance = "instance_0"); + /** @return Amount of bytes this instance of the Task has to send to the next instance */ + double get_internal_bytes(std::string instance = "instance_0") const { return internal_bytes_to_send_.at(instance); } + /** @param func The new balancing function + * @note This function is used by the dispatcher to determine which instance will effectively do the work. This + * function must return the name of the instance as a string. The default balancing function always returns + * "instance_0" */ + void set_load_balancing_function(std::function func); + /** @param token The new token */ + void set_token(std::shared_ptr token); + /** @param t A Smart pointer to a Task + * @return Oldest token received by this Task that was sent by Task t */ + std::shared_ptr get_token_from(TaskPtr t) const { return tokens_received_.at(t).front(); } + /** @param t A Smart pointer to a Task + * @return All tokens received by this Task that were sent by Task t */ + std::deque> get_tokens_from(TaskPtr t) const { return tokens_received_.at(t); } + /** @param t A Smart pointer to a Task + * @brief Pop the oldest token received by this Task that was sent by Task t */ + void deque_token_from(TaskPtr t); + /** @param t A Smart pointer to a Task + * @brief Add t as a successor of this Task */ + void add_successor(TaskPtr t); + /** @param t A Smart pointer to a Task + * @brief Remove t from the successors of this Task */ + void remove_successor(TaskPtr t); + /** @brief Remove all successors from this Task */ + void remove_all_successors(); + /** @return All successors of this Task */ + const std::set& get_successors() const { return successors_; } + /** @param n The number of firings to enqueue */ + void enqueue_firings(int n); + /** Add a callback fired before this task activity starts */ + void on_this_start_cb(const std::function& func) { on_this_start.connect(func); } + /** Add a callback fired before a task activity starts. + * Triggered after the on_this_start function**/ + static void on_start_cb(const std::function& cb) { on_start.connect(cb); } + /** Add a callback fired before this task activity ends */ + void on_this_completion_cb(const std::function& func) { on_this_completion.connect(func); }; + /** Add a callback fired after a task activity ends. + * Triggered after the on_this_end function, but before sending tokens to successors.**/ + static void on_completion_cb(const std::function& cb) { on_completion.connect(cb); } + +#ifndef DOXYGEN + friend void intrusive_ptr_release(Task* o) + { + if (o->refcount_.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + delete o; + } + } + friend void intrusive_ptr_add_ref(Task* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); } +#endif +}; + +/** CommTask class */ +class CommTask : public Task { + Host* source_; + Host* destination_; + + explicit CommTask(const std::string& name); + void fire(std::string instance) override; + +public: + static CommTaskPtr init(const std::string& name); + static CommTaskPtr init(const std::string& name, double bytes, Host* source, Host* destination); + + /** @param source The new source Host of this CommTask + * @return A Smart pointer to this CommTask */ + CommTaskPtr set_source(Host* source); + /** @return A pointer to the source Host of this CommTask */ + Host* get_source() const { return source_; } + /** @param destination The new destination of this CommTask + * @return A Smart pointer to the destination Host of this CommTask */ + CommTaskPtr set_destination(Host* destination); + /** @return A pointer to the destination Host of this CommTask */ + Host* get_destination() const { return destination_; } + /** @param bytes The amount of bytes this CommTask has to send */ + CommTaskPtr set_bytes(double bytes); + /** @return The amout of bytes this CommTask has to send */ + double get_bytes() const { return get_amount("instance_0"); } +}; + +/** ExecTask class */ +class ExecTask : public Task { + std::map host_ = {{"instance_0", nullptr}, {"dispatcher", nullptr}, {"collector", nullptr}}; + + explicit ExecTask(const std::string& name); + void fire(std::string instance) override; + +public: + static ExecTaskPtr init(const std::string& name); + static ExecTaskPtr init(const std::string& name, double flops, Host* host); + + /** @param host The new host of this instance of this ExecTask + * @return a Smart pointer to this ExecTask */ + ExecTaskPtr set_host(Host* host, std::string instance = "all"); + /** @return A pointer to the host of this instance of this ExecTask */ + Host* get_host(std::string instance = "instance_0") const { return host_.at(instance); } + /** @param flops The new amount of flops this instance of this Task has to execute + * @return A Smart pointer to this ExecTask */ + ExecTaskPtr set_flops(double flops, std::string instance = "instance_0"); + /** @return The amount of flops this instance of this ExecTask has to execute */ + double get_flops(std::string instance = "instance_0") const { return get_amount(instance); } + /** @param n The number of instances to add to this ExecTask */ + void add_instances(int n) override; + /** @param n The number of isntances to remove from this ExecTask */ + void remove_instances(int n) override; +}; + +/** IoTask class */ +class IoTask : public Task { + Disk* disk_; + Io::OpType type_; + explicit IoTask(const std::string& name); + void fire(std::string instance) override; + +public: + static IoTaskPtr init(const std::string& name); + static IoTaskPtr init(const std::string& name, double bytes, Disk* disk, Io::OpType type); + + /** @param disk The new disk of this IoTask + * @return A Smart pointer to this IoTask */ + IoTaskPtr set_disk(Disk* disk); + /** @return A pointer to the disk of this IoTask */ + Disk* get_disk() const { return disk_; } + /** @param bytes The new amount of bytes this IoTask has to write or read + * @return A Smart pointer to this IoTask */ + IoTaskPtr set_bytes(double bytes); + /** @return The amount of bytes this IoTask has to write or read */ + double get_bytes() const { return get_amount("instance_0"); } + /** @param type The type of operation this IoTask has to do + * @return A Smart pointer to this IoTask */ + IoTaskPtr set_op_type(Io::OpType type); + /** @return The type of operation this IoTask has to to */ + Io::OpType get_op_type() const { return type_; } +}; +} // namespace simgrid::s4u +#endif diff --git a/include/simgrid/s4u/VirtualMachine.hpp b/include/simgrid/s4u/VirtualMachine.hpp index 4382f3f621..b26902226d 100644 --- a/include/simgrid/s4u/VirtualMachine.hpp +++ b/include/simgrid/s4u/VirtualMachine.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,8 +10,7 @@ #include #include -namespace simgrid { -namespace s4u { +namespace simgrid::s4u { /** @brief Host extension for the VMs */ class VmHostExt { @@ -37,13 +36,21 @@ class XBT_PUBLIC VirtualMachine : public s4u::Host { /* Signals about the life cycle of the VM */ static xbt::signal on_vm_creation; static xbt::signal on_start; + xbt::signal on_this_start; static xbt::signal on_started; + xbt::signal on_this_started; static xbt::signal on_shutdown; + xbt::signal on_this_shutdown; static xbt::signal on_suspend; + xbt::signal on_this_suspend; static xbt::signal on_resume; + xbt::signal on_this_resume; static xbt::signal on_migration_start; + xbt::signal on_this_migration_start; static xbt::signal on_migration_end; + xbt::signal on_this_migration_end; static xbt::signal on_vm_destruction; + xbt::signal on_this_vm_destruction; #ifndef DOXYGEN friend kernel::resource::VirtualMachineImpl; // calls signals from Impl @@ -52,11 +59,6 @@ class XBT_PUBLIC VirtualMachine : public s4u::Host { #endif public: - XBT_ATTRIB_DEPRECATED_v336("Please use s4u::Host::create_vm") explicit VirtualMachine(const std::string& name, - Host* physical_host, - int core_amount, - size_t ramsize = 1024); - #ifndef DOXYGEN // No copy/move VirtualMachine(VirtualMachine const&) = delete; @@ -89,23 +91,71 @@ public: State get_state() const; /* Callbacks on signals */ + /*! \static Add a callback fired when any VM is created */ static void on_creation_cb(const std::function& cb) { on_vm_creation.connect(cb); } + /*! \static Add a callback fired when any VM starts */ static void on_start_cb(const std::function& cb) { on_start.connect(cb); } + /*! Add a callback fired when this specific VM starts */ + void on_this_start_cb(const std::function& cb) + { + on_this_start.connect(cb); + } + /*! \static Add a callback fired when any VM is actually started */ static void on_started_cb(const std::function& cb) { on_started.connect(cb); } + /*! Add a callback fired when this specific VM is actually started */ + void on_this_started_cb(const std::function& cb) + { + on_this_started.connect(cb); + } + /*! \static Add a callback fired when any VM is shut down */ static void on_shutdown_cb(const std::function& cb) { on_shutdown.connect(cb); } + /*! Add a callback fired when this specific VM is shut down */ + void on_this_shutdown_cb(const std::function& cb) + { + on_this_shutdown.connect(cb); + } + /*! \static Add a callback fired when any VM is suspended*/ static void on_suspend_cb(const std::function& cb) { on_suspend.connect(cb); } + /*! Add a callback fired when this specific VM is suspended*/ + void on_this_suspend_cb(const std::function& cb) + { + on_this_suspend.connect(cb); + } + /*! \static Add a callback fired when any VM is resumed*/ static void on_resume_cb(const std::function& cb) { on_resume.connect(cb); } + /*! Add a callback fired when this specific VM is resumed*/ + void on_this_resume_cb(const std::function& cb) + { + on_this_resume.connect(cb); + } + /*! \static Add a callback fired when any VM is destroyed*/ static void on_destruction_cb(const std::function& cb) { on_vm_destruction.connect(cb); } + /*! Add a callback fired when this specific VM is destroyed*/ + void on_this_destruction_cb(const std::function& cb) + { + on_this_vm_destruction.connect(cb); + } + /*! \static Add a callback fired when any VM starts a migration*/ static void on_migration_start_cb(const std::function& cb) { on_migration_start.connect(cb); } + /*! Add a callback fired when this specific VM starts a migration*/ + void on_this_migration_start_cb(const std::function& cb) + { + on_this_migration_start.connect(cb); + } + /*! \static Add a callback fired when any VM ends a migration*/ static void on_migration_end_cb(const std::function& cb) { on_migration_end.connect(cb); } + /*! Add a callback fired when this specific VM ends a migration*/ + void on_this_migration_end_cb(const std::function& cb) + { + on_this_migration_end.connect(cb); + } }; -} // namespace s4u -} // namespace simgrid +} // namespace simgrid::s4u #endif diff --git a/include/simgrid/semaphore.h b/include/simgrid/semaphore.h index 2f92f5655e..686d851e52 100644 --- a/include/simgrid/semaphore.h +++ b/include/simgrid/semaphore.h @@ -1,6 +1,6 @@ /* Public interface to the Link datatype */ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/simgrid/simix.h b/include/simgrid/simix.h deleted file mode 100644 index a7b67054ab..0000000000 --- a/include/simgrid/simix.h +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_SIMIX_H -#define SIMGRID_SIMIX_H - -#include -#include - -#ifndef SIMIX_H_NO_DEPRECATED_WARNING -#warning simgrid/simix.h is deprecated and will be removed in v3.35. -#endif - -/******************************* Networking ***********************************/ -SG_BEGIN_DECL - -/* parallelism */ -XBT_ATTRIB_DEPRECATED_v333("Please use kernel::context::is_parallel()") XBT_PUBLIC int SIMIX_context_is_parallel(); -XBT_ATTRIB_DEPRECATED_v333("Please use kernel::context::get_nthreads()") XBT_PUBLIC int SIMIX_context_get_nthreads(); -XBT_ATTRIB_DEPRECATED_v333("Please use kernel::context::set_nthreads()") XBT_PUBLIC - void SIMIX_context_set_nthreads(int nb_threads); -XBT_ATTRIB_DEPRECATED_v333("Please use kernel::context::get_parallel_mode()") XBT_PUBLIC e_xbt_parmap_mode_t - SIMIX_context_get_parallel_mode(); -XBT_ATTRIB_DEPRECATED_v333("Please use kernel::context::set_parallel_mode()") XBT_PUBLIC - void SIMIX_context_set_parallel_mode(e_xbt_parmap_mode_t mode); -XBT_ATTRIB_DEPRECATED_v333("Please use Actor::is_maestro()") XBT_PUBLIC int SIMIX_is_maestro(); - -/********************************** Global ************************************/ -/* Set some code to execute in the maestro (must be used before the engine creation) - * - * If no maestro code is registered (the default), the main thread - * is assumed to be the maestro. */ -XBT_ATTRIB_DEPRECATED_v333("Please use simgrid_set_maestro()") XBT_PUBLIC - void SIMIX_set_maestro(void (*code)(void*), void* data); - -SG_END_DECL - -/********************************* Process ************************************/ -SG_BEGIN_DECL -XBT_ATTRIB_DEPRECATED_v333("Please use kernel::actor::ActorImpl::self()") XBT_PUBLIC -#ifdef __cplusplus - simgrid::kernel::actor::ActorImpl* -#else - smx_actor_t -#endif - SIMIX_process_self(); -XBT_ATTRIB_DEPRECATED_v333("Please use xbt_procname()") XBT_PUBLIC const char* SIMIX_process_self_get_name(); -SG_END_DECL - -/****************************** Communication *********************************/ -#ifdef __cplusplus -XBT_ATTRIB_DEPRECATED_v333("Please use Engine::set_default_comm_data_copy_callback()") XBT_PUBLIC - void SIMIX_comm_set_copy_data_callback(void (*callback)(simgrid::kernel::activity::CommImpl*, void*, size_t)); - -XBT_ATTRIB_DEPRECATED_v333("Please use Comm::copy_buffer_callback()") XBT_PUBLIC - void SIMIX_comm_copy_pointer_callback(simgrid::kernel::activity::CommImpl* comm, void* buff, size_t buff_size); -XBT_ATTRIB_DEPRECATED_v333("Please use Comm::copy_pointer_callback()") XBT_PUBLIC - void SIMIX_comm_copy_buffer_callback(simgrid::kernel::activity::CommImpl* comm, void* buff, size_t buff_size); - -/******************************************************************************/ -/* SIMIX simcalls */ -/******************************************************************************/ -/* These functions are a system call-like interface to the simulation kernel. */ -/* They can also be called from maestro's context, and they are thread safe. */ -/******************************************************************************/ - -/************************** Communication simcalls ****************************/ - -XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::send()") XBT_PUBLIC - void simcall_comm_send(simgrid::kernel::actor::ActorImpl* sender, simgrid::kernel::activity::MailboxImpl* mbox, - double task_size, double rate, void* src_buff, size_t src_buff_size, - bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*), - void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, - double timeout); - -XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::isend()") XBT_PUBLIC simgrid::kernel::activity::ActivityImplPtr - simcall_comm_isend(simgrid::kernel::actor::ActorImpl* sender, simgrid::kernel::activity::MailboxImpl* mbox, - double task_size, double rate, void* src_buff, size_t src_buff_size, - bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*), void (*clean_fun)(void*), - void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, - bool detached); - -XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::recv()") XBT_PUBLIC - void simcall_comm_recv(simgrid::kernel::actor::ActorImpl* receiver, simgrid::kernel::activity::MailboxImpl* mbox, - void* dst_buff, size_t* dst_buff_size, - bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*), - void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, - double timeout, double rate); - -XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::irecv()") XBT_PUBLIC simgrid::kernel::activity::ActivityImplPtr - simcall_comm_irecv(simgrid::kernel::actor::ActorImpl* receiver, simgrid::kernel::activity::MailboxImpl* mbox, - void* dst_buff, size_t* dst_buff_size, - bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*), - void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, - double rate); - -XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::wait_any_for()") XBT_PUBLIC ssize_t - simcall_comm_waitany(simgrid::kernel::activity::CommImpl* comms[], size_t count, double timeout); -XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::wait_for()") XBT_PUBLIC - void simcall_comm_wait(simgrid::kernel::activity::ActivityImpl* comm, double timeout); -XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::test()") XBT_PUBLIC - bool simcall_comm_test(simgrid::kernel::activity::ActivityImpl* comm); -XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::test_any()") XBT_PUBLIC ssize_t - simcall_comm_testany(simgrid::kernel::activity::CommImpl* comms[], size_t count); - -#endif -#endif diff --git a/include/simgrid/simix.hpp b/include/simgrid/simix.hpp index fb8addfb3c..338c3372ae 100644 --- a/include/simgrid/simix.hpp +++ b/include/simgrid/simix.hpp @@ -1,5 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -18,15 +17,15 @@ XBT_PUBLIC void simcall_run_answered(std::function const& code, simgrid::kernel::actor::SimcallObserver* observer); XBT_PUBLIC void simcall_run_blocking(std::function const& code, simgrid::kernel::actor::SimcallObserver* observer); +XBT_PUBLIC void simcall_run_object_access(std::function const& code, + simgrid::kernel::actor::ObjectAccessSimcallItem* item); -namespace simgrid { -namespace kernel { -namespace actor { +namespace simgrid::kernel::actor { /** Execute some code in kernel context on behalf of the user code. * * Every modification of the environment must be protected this way: every setter, constructor and similar. - * Getters don't have to be protected this way. + * Getters don't have to be protected this way, and setters may use the simcall_object_access() variant (see below). * * This allows deterministic parallel simulation without any locking, even if almost nobody uses parallel simulation in * SimGrid. More interestingly it makes every modification of the simulated world observable by the model-checker, @@ -58,9 +57,32 @@ template typename std::result_of_t simcall_answered(F&& code, Sim return result.get(); } +/** Use a setter on the `item` object. That's a simcall only if running in parallel or with MC activated. + * + * Simulation without MC and without parallelism (contexts/nthreads=1) will not pay the price of a simcall for an + * harmless setter. When running in parallel, you want your write access to be done in a mutual exclusion way, while the + * getters can still occur out of order. + * + * When running in MC, you want to make this access visible to the checker. Actually in this case, it's not visible from + * the checker (and thus still use a fast track) if the setter is called from the actor that created the object. + */ +template typename std::result_of_t simcall_object_access(ObjectAccessSimcallItem* item, F&& code) +{ + // If we are in the maestro, we take the fast path and execute the code directly + if (simgrid::s4u::Actor::is_maestro()) + return std::forward(code)(); + + // If called from another thread, do a real simcall. It will be short-cut on need + using R = typename std::result_of_t; + simgrid::xbt::Result result; + simcall_run_object_access([&result, &code] { simgrid::xbt::fulfill_promise(result, std::forward(code)); }, item); + + return result.get(); +} + /** Execute some code (that does not return immediately) in kernel context * - * This is very similar to simcall() right above, but the calling actor will not get rescheduled until + * This is very similar to simcall_answered() above, but the calling actor will not get rescheduled until * actor->simcall_answer() is called explicitly. * * This is meant for blocking actions. For example, locking a mutex is a blocking simcall. @@ -91,8 +113,5 @@ auto simcall_blocking(F&& code, Observer* observer) -> decltype(observer->get_re simcall_blocking(std::forward(code), static_cast(observer)); return observer->get_result(); } -} // namespace actor -} // namespace kernel -} // namespace simgrid - +} // namespace simgrid::kernel::actor #endif diff --git a/include/simgrid/version.h.in b/include/simgrid/version.h.in index 10672caaf5..daa8e9cb03 100644 --- a/include/simgrid/version.h.in +++ b/include/simgrid/version.h.in @@ -1,6 +1,6 @@ /* src/simgrid/version.h - internal versioning info */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,6 +8,8 @@ #ifndef SIMGRID_VERSION_H #define SIMGRID_VERSION_H +#include "xbt/base.h" + #define SIMGRID_GIT_VERSION "@GIT_VERSION@" /** Define the version numbers of the used header files. diff --git a/include/simgrid/vm.h b/include/simgrid/vm.h index 845bd7650e..bd6e1ced97 100644 --- a/include/simgrid/vm.h +++ b/include/simgrid/vm.h @@ -1,6 +1,6 @@ /* Public interface to the Virtual Machine datatype */ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/simgrid/zone.h b/include/simgrid/zone.h index 58739662c4..62d439b5b3 100644 --- a/include/simgrid/zone.h +++ b/include/simgrid/zone.h @@ -1,6 +1,6 @@ /* Public interface to the Link datatype */ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/smpi/forward.hpp b/include/smpi/forward.hpp index db59a6ff0b..35938c41f2 100644 --- a/include/smpi/forward.hpp +++ b/include/smpi/forward.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,8 +10,7 @@ #ifdef __cplusplus #include -namespace simgrid { -namespace smpi { +namespace simgrid::smpi { class Colls; class Comm; @@ -31,8 +30,7 @@ class Topo_Graph; class Topo_Dist_Graph; class Win; -} -} +} // namespace simgrid::smpi using SMPI_Comm = simgrid::smpi::Comm; using SMPI_Datatype = simgrid::smpi::Datatype; diff --git a/include/smpi/mpi.h b/include/smpi/mpi.h index 2e71025b30..5d61fb047f 100644 --- a/include/smpi/mpi.h +++ b/include/smpi/mpi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -17,10 +17,8 @@ #include /* Load it before the define next line to not mess with the system headers */ -#if SIMGRID_HAVE_MC #undef assert #define assert(x) MC_assert(!!(x)) -#endif #ifdef TRACE_CALL_LOCATION /* Defined by smpicc on the command line */ #include diff --git a/include/smpi/mpif.h.in b/include/smpi/mpif.h.in index 94ce3cdfc9..04bd335788 100644 --- a/include/smpi/mpif.h.in +++ b/include/smpi/mpif.h.in @@ -1,5 +1,5 @@ ! -*- fortran -*- -! Copyright (c) 2010-2022. The SimGrid Team. +! Copyright (c) 2010-2023. The SimGrid Team. ! All rights reserved. ! This program is free software; you can redistribute it and/or modify it diff --git a/include/smpi/sampi.h b/include/smpi/sampi.h index c4a7e1e2e5..984c437235 100644 --- a/include/smpi/sampi.h +++ b/include/smpi/sampi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/smpi/smpi.h b/include/smpi/smpi.h index 468b31e6e3..08120350e4 100644 --- a/include/smpi/smpi.h +++ b/include/smpi/smpi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -21,15 +21,10 @@ #include #endif -#ifdef _WIN32 -#define MPI_CALL(type, name, args) \ - type name args; \ - type _XBT_CONCAT(P, name) args -#else #define MPI_CALL(type, name, args) \ type name args __attribute__((weak)); \ - type _XBT_CONCAT(P, name) args -#endif + type _XBT_CONCAT(P, name) \ + args SG_BEGIN_DECL #define MPI_THREAD_SINGLE 0 @@ -239,15 +234,11 @@ typedef SMPI_Info* MPI_Info; #define MPI_STATUSES_IGNORE ((MPI_Status*)NULL) #define MPI_STATUS_SIZE 5 -#if !defined(DLL_EXPORT) #if defined(c_plusplus) || defined(__cplusplus) #define SMPI_PREDEFINED_POINTER(type, internal) (static_cast (static_cast (&(internal)))) #else #define SMPI_PREDEFINED_POINTER(type, internal) ((type) ((void *) &(internal))) #endif -#else -#define SMPI_PREDEFINED_POINTER(type, internal) ((type) &(internal)) -#endif extern SMPI_Datatype smpi_MPI_DATATYPE_NULL; extern SMPI_Datatype smpi_MPI_CHAR; @@ -714,8 +705,13 @@ MPI_CALL(XBT_PUBLIC int, MPI_Irsend, MPI_CALL(XBT_PUBLIC int, MPI_Sendrecv, (const void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf, int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status* status)); +MPI_CALL(XBT_PUBLIC int, MPI_Isendrecv, + (const void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf, int recvcount, + MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Request* req)); MPI_CALL(XBT_PUBLIC int, MPI_Sendrecv_replace, (void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag, MPI_Comm comm, MPI_Status* status)); +MPI_CALL(XBT_PUBLIC int, MPI_Isendrecv_replace, (void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, + int src, int recvtag, MPI_Comm comm, MPI_Request* req)); MPI_CALL(XBT_PUBLIC int, MPI_Test, (MPI_Request * request, int* flag, MPI_Status* status)); MPI_CALL(XBT_PUBLIC int, MPI_Testany, (int count, MPI_Request requests[], int* index, int* flag, MPI_Status* status)); @@ -1132,13 +1128,21 @@ MPI_CALL(XBT_PUBLIC int, MPI_Ineighbor_alltoallw, const MPI_Aint* recvdisps, const MPI_Datatype* recvtypes, MPI_Comm comm, MPI_Request *request)); MPI_CALL(XBT_PUBLIC int, MPI_Status_f2c, (MPI_Fint *f_status, MPI_Status *c_status)); MPI_CALL(XBT_PUBLIC int, MPI_Status_c2f, (MPI_Status *c_status, MPI_Fint *f_status)); - +MPI_CALL(XBT_PUBLIC int, MPI_Parrived, (MPI_Request request, int partition, int *flag)); +MPI_CALL(XBT_PUBLIC int, MPI_Pready, (int partitions, MPI_Request request)); +MPI_CALL(XBT_PUBLIC int, MPI_Pready_range, (int partition_low, int partition_high, MPI_Request request)); +MPI_CALL(XBT_PUBLIC int, MPI_Pready_list, (int length, int partition_list[], MPI_Request request)); +MPI_CALL(XBT_PUBLIC int, MPI_Precv_init, (void* buf, int partitions, MPI_Count count, + MPI_Datatype datatype, int source, int tag, MPI_Comm comm, + MPI_Info info, MPI_Request *request)); +MPI_CALL(XBT_PUBLIC int, MPI_Psend_init, (const void* buf, int partitions, MPI_Count count, + MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, + MPI_Info info, MPI_Request *request)); //FIXME: End of all the not yet implemented stuff // smpi functions -XBT_PUBLIC int smpi_global_size(); XBT_PUBLIC MPI_Comm smpi_process_comm_self(); XBT_PUBLIC MPI_Info smpi_process_info_env(); XBT_PUBLIC void* smpi_process_get_user_data(); @@ -1170,11 +1174,11 @@ XBT_PUBLIC void smpi_comm_set_copy_data_callback(void (*callback)(smx_activity_t * called from the user's application! (With the __FILE__ and __LINE__ values * passed as parameters.) */ -XBT_PUBLIC void smpi_trace_set_call_location(const char* file, int line); +XBT_PUBLIC void smpi_trace_set_call_location(const char* file, int line, const char* call_name); /** Fortran binding **/ -XBT_PUBLIC void smpi_trace_set_call_location_(const char* file, const int* line); +XBT_PUBLIC void smpi_trace_set_call_location_(const char* file, const int* line, const char* call_name); /** Fortran binding + -fsecond-underscore **/ -XBT_PUBLIC void smpi_trace_set_call_location__(const char* file, const int* line); +XBT_PUBLIC void smpi_trace_set_call_location__(const char* file, const int* line, const char* call_name); #define SMPI_ITER_NAME1(line) _XBT_CONCAT(iter_count, line) #define SMPI_ITER_NAME(line) SMPI_ITER_NAME1(line) @@ -1242,8 +1246,15 @@ XBT_PUBLIC void SMPI_thread_create(); SG_END_DECL -/* C++ declarations for shared_malloc and default copy buffer callback */ #ifdef __cplusplus +XBT_PUBLIC void SMPI_app_instance_start(const char* name, std::function const& code, + std::vector const& hosts); +XBT_PUBLIC void SMPI_app_instance_join(const std::string& instance_id); + +/* This version without parameter is nice to use with SMPI_app_instance_start() */ +XBT_PUBLIC void MPI_Init(); + +/* C++ declarations for shared_malloc and default copy buffer callback */ XBT_PUBLIC int smpi_is_shared(const void* ptr, std::vector>& private_blocks, size_t* offset); std::vector> shift_and_frame_private_blocks(const std::vector>& vec, diff --git a/include/smpi/smpi_extended_traces.h b/include/smpi/smpi_extended_traces.h index 5159b50297..f0757ec0fc 100644 --- a/include/smpi/smpi_extended_traces.h +++ b/include/smpi/smpi_extended_traces.h @@ -1,4 +1,4 @@ -// Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. +// Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. // This program is free software; you can redistribute it and/or modify it // under the terms of the license (GNU LGPL) which comes with this package. @@ -7,390 +7,398 @@ // in tools/smpi/generate_smpi_defines.pl // DO NOT EDIT MANUALLY. ALL CHANGES WILL BE OVERWRITTEN! -#define MPI_Init(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Init(__VA_ARGS__)) -#define MPI_Finalize(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Finalize(__VA_ARGS__)) -#define MPI_Finalized(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Finalized(__VA_ARGS__)) -#define MPI_Init_thread(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Init_thread(__VA_ARGS__)) -#define MPI_Initialized(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Initialized(__VA_ARGS__)) -#define MPI_Query_thread(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Query_thread(__VA_ARGS__)) -#define MPI_Is_thread_main(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Is_thread_main(__VA_ARGS__)) -#define MPI_Get_version(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Get_version(__VA_ARGS__)) -#define MPI_Get_library_version(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Get_library_version(__VA_ARGS__)) -#define MPI_Get_processor_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Get_processor_name(__VA_ARGS__)) -#define MPI_Abort(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Abort(__VA_ARGS__)) -#define MPI_Alloc_mem(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Alloc_mem(__VA_ARGS__)) -#define MPI_Free_mem(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Free_mem(__VA_ARGS__)) -#define MPI_Wtime(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Wtime(__VA_ARGS__)) -#define MPI_Wtick(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Wtick(__VA_ARGS__)) -#define MPI_Buffer_attach(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Buffer_attach(__VA_ARGS__)) -#define MPI_Buffer_detach(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Buffer_detach(__VA_ARGS__)) -#define MPI_Address(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Address(__VA_ARGS__)) -#define MPI_Get_address(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Get_address(__VA_ARGS__)) -#define MPI_Aint_diff(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Aint_diff(__VA_ARGS__)) -#define MPI_Aint_add(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Aint_add(__VA_ARGS__)) -#define MPI_Error_class(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Error_class(__VA_ARGS__)) -#define MPI_Error_string(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Error_string(__VA_ARGS__)) -#define MPI_Attr_delete(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Attr_delete(__VA_ARGS__)) -#define MPI_Attr_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Attr_get(__VA_ARGS__)) -#define MPI_Attr_put(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Attr_put(__VA_ARGS__)) -#define MPI_Keyval_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Keyval_create(__VA_ARGS__)) -#define MPI_Keyval_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Keyval_free(__VA_ARGS__)) -#define MPI_Type_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_free(__VA_ARGS__)) -#define MPI_Type_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_size(__VA_ARGS__)) -#define MPI_Type_size_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_size_x(__VA_ARGS__)) -#define MPI_Type_get_extent(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_get_extent(__VA_ARGS__)) -#define MPI_Type_get_extent_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_get_extent_x(__VA_ARGS__)) -#define MPI_Type_get_true_extent(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_get_true_extent(__VA_ARGS__)) -#define MPI_Type_get_true_extent_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_get_true_extent_x(__VA_ARGS__)) -#define MPI_Type_extent(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_extent(__VA_ARGS__)) -#define MPI_Type_lb(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_lb(__VA_ARGS__)) -#define MPI_Type_ub(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_ub(__VA_ARGS__)) -#define MPI_Type_commit(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_commit(__VA_ARGS__)) -#define MPI_Type_hindexed(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_hindexed(__VA_ARGS__)) -#define MPI_Type_create_hindexed(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_hindexed(__VA_ARGS__)) -#define MPI_Type_create_hindexed_block(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_hindexed_block(__VA_ARGS__)) -#define MPI_Type_hvector(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_hvector(__VA_ARGS__)) -#define MPI_Type_create_hvector(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_hvector(__VA_ARGS__)) -#define MPI_Type_indexed(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_indexed(__VA_ARGS__)) -#define MPI_Type_create_indexed(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_indexed(__VA_ARGS__)) -#define MPI_Type_create_indexed_block(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_indexed_block(__VA_ARGS__)) -#define MPI_Type_struct(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_struct(__VA_ARGS__)) -#define MPI_Type_create_struct(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_struct(__VA_ARGS__)) -#define MPI_Type_vector(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_vector(__VA_ARGS__)) -#define MPI_Type_contiguous(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_contiguous(__VA_ARGS__)) -#define MPI_Type_create_resized(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_resized(__VA_ARGS__)) -#define MPI_Type_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_f2c(__VA_ARGS__)) -#define MPI_Type_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_c2f(__VA_ARGS__)) -#define MPI_Get_count(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Get_count(__VA_ARGS__)) -#define MPI_Type_get_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_get_attr(__VA_ARGS__)) -#define MPI_Type_set_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_set_attr(__VA_ARGS__)) -#define MPI_Type_delete_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_delete_attr(__VA_ARGS__)) -#define MPI_Type_create_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_keyval(__VA_ARGS__)) -#define MPI_Type_free_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_free_keyval(__VA_ARGS__)) -#define MPI_Type_dup(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_dup(__VA_ARGS__)) -#define MPI_Type_set_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_set_name(__VA_ARGS__)) -#define MPI_Type_get_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_get_name(__VA_ARGS__)) -#define MPI_Pack(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Pack(__VA_ARGS__)) -#define MPI_Pack_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Pack_size(__VA_ARGS__)) -#define MPI_Unpack(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Unpack(__VA_ARGS__)) -#define MPI_Op_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Op_create(__VA_ARGS__)) -#define MPI_Op_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Op_free(__VA_ARGS__)) -#define MPI_Op_commutative(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Op_commutative(__VA_ARGS__)) -#define MPI_Op_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Op_f2c(__VA_ARGS__)) -#define MPI_Op_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Op_c2f(__VA_ARGS__)) -#define MPI_Group_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_free(__VA_ARGS__)) -#define MPI_Group_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_size(__VA_ARGS__)) -#define MPI_Group_rank(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_rank(__VA_ARGS__)) -#define MPI_Group_translate_ranks(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_translate_ranks(__VA_ARGS__)) -#define MPI_Group_compare(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_compare(__VA_ARGS__)) -#define MPI_Group_union(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_union(__VA_ARGS__)) -#define MPI_Group_intersection(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_intersection(__VA_ARGS__)) -#define MPI_Group_difference(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_difference(__VA_ARGS__)) -#define MPI_Group_incl(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_incl(__VA_ARGS__)) -#define MPI_Group_excl(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_excl(__VA_ARGS__)) -#define MPI_Group_range_incl(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_range_incl(__VA_ARGS__)) -#define MPI_Group_range_excl(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_range_excl(__VA_ARGS__)) -#define MPI_Group_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_f2c(__VA_ARGS__)) -#define MPI_Group_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Group_c2f(__VA_ARGS__)) -#define MPI_Comm_rank(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_rank(__VA_ARGS__)) -#define MPI_Comm_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_size(__VA_ARGS__)) -#define MPI_Comm_get_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_get_name(__VA_ARGS__)) -#define MPI_Comm_set_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_set_name(__VA_ARGS__)) -#define MPI_Comm_dup(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_dup(__VA_ARGS__)) -#define MPI_Comm_dup_with_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_dup_with_info(__VA_ARGS__)) -#define MPI_Comm_get_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_get_attr(__VA_ARGS__)) -#define MPI_Comm_set_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_set_attr(__VA_ARGS__)) -#define MPI_Comm_delete_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_delete_attr(__VA_ARGS__)) -#define MPI_Comm_create_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_create_keyval(__VA_ARGS__)) -#define MPI_Comm_free_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_free_keyval(__VA_ARGS__)) -#define MPI_Comm_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_group(__VA_ARGS__)) -#define MPI_Comm_compare(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_compare(__VA_ARGS__)) -#define MPI_Comm_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_create(__VA_ARGS__)) -#define MPI_Comm_create_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_create_group(__VA_ARGS__)) -#define MPI_Comm_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_free(__VA_ARGS__)) -#define MPI_Comm_disconnect(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_disconnect(__VA_ARGS__)) -#define MPI_Comm_split(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_split(__VA_ARGS__)) -#define MPI_Comm_set_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_set_info(__VA_ARGS__)) -#define MPI_Comm_get_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_get_info(__VA_ARGS__)) -#define MPI_Comm_split_type(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_split_type(__VA_ARGS__)) -#define MPI_Comm_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_f2c(__VA_ARGS__)) -#define MPI_Comm_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_c2f(__VA_ARGS__)) -#define MPI_Start(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Start(__VA_ARGS__)) -#define MPI_Startall(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Startall(__VA_ARGS__)) -#define MPI_Request_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Request_free(__VA_ARGS__)) -#define MPI_Recv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Recv(__VA_ARGS__)) -#define MPI_Recv_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Recv_init(__VA_ARGS__)) -#define MPI_Irecv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Irecv(__VA_ARGS__)) -#define MPI_Send(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Send(__VA_ARGS__)) -#define MPI_Send_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Send_init(__VA_ARGS__)) -#define MPI_Isend(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Isend(__VA_ARGS__)) -#define MPI_Ssend(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ssend(__VA_ARGS__)) -#define MPI_Ssend_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ssend_init(__VA_ARGS__)) -#define MPI_Issend(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Issend(__VA_ARGS__)) -#define MPI_Bsend(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Bsend(__VA_ARGS__)) -#define MPI_Bsend_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Bsend_init(__VA_ARGS__)) -#define MPI_Ibsend(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ibsend(__VA_ARGS__)) -#define MPI_Rsend(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Rsend(__VA_ARGS__)) -#define MPI_Rsend_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Rsend_init(__VA_ARGS__)) -#define MPI_Irsend(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Irsend(__VA_ARGS__)) -#define MPI_Sendrecv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Sendrecv(__VA_ARGS__)) -#define MPI_Sendrecv_replace(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Sendrecv_replace(__VA_ARGS__)) -#define MPI_Test(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Test(__VA_ARGS__)) -#define MPI_Testany(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Testany(__VA_ARGS__)) -#define MPI_Testall(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Testall(__VA_ARGS__)) -#define MPI_Testsome(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Testsome(__VA_ARGS__)) -#define MPI_Test_cancelled(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Test_cancelled(__VA_ARGS__)) -#define MPI_Wait(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Wait(__VA_ARGS__)) -#define MPI_Waitany(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Waitany(__VA_ARGS__)) -#define MPI_Waitall(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Waitall(__VA_ARGS__)) -#define MPI_Waitsome(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Waitsome(__VA_ARGS__)) -#define MPI_Iprobe(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Iprobe(__VA_ARGS__)) -#define MPI_Probe(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Probe(__VA_ARGS__)) -#define MPI_Request_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Request_f2c(__VA_ARGS__)) -#define MPI_Request_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Request_c2f(__VA_ARGS__)) -#define MPI_Cancel(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Cancel(__VA_ARGS__)) -#define MPI_Bcast(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Bcast(__VA_ARGS__)) -#define MPI_Barrier(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Barrier(__VA_ARGS__)) -#define MPI_Ibarrier(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ibarrier(__VA_ARGS__)) -#define MPI_Ibcast(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ibcast(__VA_ARGS__)) -#define MPI_Igather(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Igather(__VA_ARGS__)) -#define MPI_Igatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Igatherv(__VA_ARGS__)) -#define MPI_Iallgather(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Iallgather(__VA_ARGS__)) -#define MPI_Iallgatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Iallgatherv(__VA_ARGS__)) -#define MPI_Iscatter(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Iscatter(__VA_ARGS__)) -#define MPI_Iscatterv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Iscatterv(__VA_ARGS__)) -#define MPI_Ireduce(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ireduce(__VA_ARGS__)) -#define MPI_Iallreduce(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Iallreduce(__VA_ARGS__)) -#define MPI_Iscan(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Iscan(__VA_ARGS__)) -#define MPI_Iexscan(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Iexscan(__VA_ARGS__)) -#define MPI_Ireduce_scatter(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ireduce_scatter(__VA_ARGS__)) -#define MPI_Ireduce_scatter_block(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ireduce_scatter_block(__VA_ARGS__)) -#define MPI_Ialltoall(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ialltoall(__VA_ARGS__)) -#define MPI_Ialltoallv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ialltoallv(__VA_ARGS__)) -#define MPI_Ialltoallw(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ialltoallw(__VA_ARGS__)) -#define MPI_Gather(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Gather(__VA_ARGS__)) -#define MPI_Gatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Gatherv(__VA_ARGS__)) -#define MPI_Allgather(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Allgather(__VA_ARGS__)) -#define MPI_Allgatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Allgatherv(__VA_ARGS__)) -#define MPI_Scatter(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Scatter(__VA_ARGS__)) -#define MPI_Scatterv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Scatterv(__VA_ARGS__)) -#define MPI_Reduce(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Reduce(__VA_ARGS__)) -#define MPI_Allreduce(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Allreduce(__VA_ARGS__)) -#define MPI_Scan(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Scan(__VA_ARGS__)) -#define MPI_Exscan(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Exscan(__VA_ARGS__)) -#define MPI_Reduce_scatter(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Reduce_scatter(__VA_ARGS__)) -#define MPI_Reduce_scatter_block(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Reduce_scatter_block(__VA_ARGS__)) -#define MPI_Alltoall(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Alltoall(__VA_ARGS__)) -#define MPI_Alltoallv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Alltoallv(__VA_ARGS__)) -#define MPI_Alltoallw(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Alltoallw(__VA_ARGS__)) -#define MPI_Reduce_local(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Reduce_local(__VA_ARGS__)) -#define MPI_Info_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_create(__VA_ARGS__)) -#define MPI_Info_set(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_set(__VA_ARGS__)) -#define MPI_Info_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_get(__VA_ARGS__)) -#define MPI_Info_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_free(__VA_ARGS__)) -#define MPI_Info_delete(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_delete(__VA_ARGS__)) -#define MPI_Info_dup(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_dup(__VA_ARGS__)) -#define MPI_Info_get_nkeys(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_get_nkeys(__VA_ARGS__)) -#define MPI_Info_get_nthkey(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_get_nthkey(__VA_ARGS__)) -#define MPI_Info_get_valuelen(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_get_valuelen(__VA_ARGS__)) -#define MPI_Info_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_f2c(__VA_ARGS__)) -#define MPI_Info_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Info_c2f(__VA_ARGS__)) -#define MPI_Win_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_free(__VA_ARGS__)) -#define MPI_Win_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_create(__VA_ARGS__)) -#define MPI_Win_allocate(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_allocate(__VA_ARGS__)) -#define MPI_Win_allocate_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_allocate_shared(__VA_ARGS__)) -#define MPI_Win_create_dynamic(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_create_dynamic(__VA_ARGS__)) -#define MPI_Win_attach(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_attach(__VA_ARGS__)) -#define MPI_Win_detach(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_detach(__VA_ARGS__)) -#define MPI_Win_set_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_set_name(__VA_ARGS__)) -#define MPI_Win_get_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_get_name(__VA_ARGS__)) -#define MPI_Win_set_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_set_info(__VA_ARGS__)) -#define MPI_Win_get_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_get_info(__VA_ARGS__)) -#define MPI_Win_get_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_get_group(__VA_ARGS__)) -#define MPI_Win_fence(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_fence(__VA_ARGS__)) -#define MPI_Win_get_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_get_attr(__VA_ARGS__)) -#define MPI_Win_set_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_set_attr(__VA_ARGS__)) -#define MPI_Win_delete_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_delete_attr(__VA_ARGS__)) -#define MPI_Win_create_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_create_keyval(__VA_ARGS__)) -#define MPI_Win_free_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_free_keyval(__VA_ARGS__)) -#define MPI_Win_complete(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_complete(__VA_ARGS__)) -#define MPI_Win_post(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_post(__VA_ARGS__)) -#define MPI_Win_start(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_start(__VA_ARGS__)) -#define MPI_Win_wait(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_wait(__VA_ARGS__)) -#define MPI_Win_lock(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_lock(__VA_ARGS__)) -#define MPI_Win_lock_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_lock_all(__VA_ARGS__)) -#define MPI_Win_unlock(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_unlock(__VA_ARGS__)) -#define MPI_Win_unlock_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_unlock_all(__VA_ARGS__)) -#define MPI_Win_flush(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_flush(__VA_ARGS__)) -#define MPI_Win_flush_local(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_flush_local(__VA_ARGS__)) -#define MPI_Win_flush_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_flush_all(__VA_ARGS__)) -#define MPI_Win_flush_local_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_flush_local_all(__VA_ARGS__)) -#define MPI_Win_shared_query(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_shared_query(__VA_ARGS__)) -#define MPI_Win_sync(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_sync(__VA_ARGS__)) -#define MPI_Win_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_f2c(__VA_ARGS__)) -#define MPI_Win_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_c2f(__VA_ARGS__)) -#define MPI_Get(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Get(__VA_ARGS__)) -#define MPI_Put(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Put(__VA_ARGS__)) -#define MPI_Accumulate(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Accumulate(__VA_ARGS__)) -#define MPI_Get_accumulate(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Get_accumulate(__VA_ARGS__)) -#define MPI_Rget(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Rget(__VA_ARGS__)) -#define MPI_Rput(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Rput(__VA_ARGS__)) -#define MPI_Raccumulate(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Raccumulate(__VA_ARGS__)) -#define MPI_Rget_accumulate(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Rget_accumulate(__VA_ARGS__)) -#define MPI_Fetch_and_op(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Fetch_and_op(__VA_ARGS__)) -#define MPI_Compare_and_swap(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Compare_and_swap(__VA_ARGS__)) -#define MPI_Cart_coords(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Cart_coords(__VA_ARGS__)) -#define MPI_Cart_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Cart_create(__VA_ARGS__)) -#define MPI_Cart_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Cart_get(__VA_ARGS__)) -#define MPI_Cart_rank(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Cart_rank(__VA_ARGS__)) -#define MPI_Cart_shift(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Cart_shift(__VA_ARGS__)) -#define MPI_Cart_sub(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Cart_sub(__VA_ARGS__)) -#define MPI_Cartdim_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Cartdim_get(__VA_ARGS__)) -#define MPI_Dims_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Dims_create(__VA_ARGS__)) -#define MPI_Request_get_status(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Request_get_status(__VA_ARGS__)) -#define MPI_Grequest_start(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Grequest_start(__VA_ARGS__)) -#define MPI_Grequest_complete(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Grequest_complete(__VA_ARGS__)) -#define MPI_Status_set_cancelled(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Status_set_cancelled(__VA_ARGS__)) -#define MPI_Status_set_elements(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Status_set_elements(__VA_ARGS__)) -#define MPI_Status_set_elements_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Status_set_elements_x(__VA_ARGS__)) -#define MPI_Type_create_subarray(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_subarray(__VA_ARGS__)) -#define MPI_File_open(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_open(__VA_ARGS__)) -#define MPI_File_close(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_close(__VA_ARGS__)) -#define MPI_File_delete(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_delete(__VA_ARGS__)) -#define MPI_File_get_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_size(__VA_ARGS__)) -#define MPI_File_get_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_group(__VA_ARGS__)) -#define MPI_File_get_amode(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_amode(__VA_ARGS__)) -#define MPI_File_set_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_set_info(__VA_ARGS__)) -#define MPI_File_get_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_info(__VA_ARGS__)) -#define MPI_File_read_at(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_at(__VA_ARGS__)) -#define MPI_File_read_at_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_at_all(__VA_ARGS__)) -#define MPI_File_write_at(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_at(__VA_ARGS__)) -#define MPI_File_write_at_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_at_all(__VA_ARGS__)) -#define MPI_File_read(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read(__VA_ARGS__)) -#define MPI_File_read_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_all(__VA_ARGS__)) -#define MPI_File_write(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write(__VA_ARGS__)) -#define MPI_File_write_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_all(__VA_ARGS__)) -#define MPI_File_seek(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_seek(__VA_ARGS__)) -#define MPI_File_get_position(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_position(__VA_ARGS__)) -#define MPI_File_read_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_shared(__VA_ARGS__)) -#define MPI_File_write_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_shared(__VA_ARGS__)) -#define MPI_File_read_ordered(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_ordered(__VA_ARGS__)) -#define MPI_File_write_ordered(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_ordered(__VA_ARGS__)) -#define MPI_File_seek_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_seek_shared(__VA_ARGS__)) -#define MPI_File_get_position_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_position_shared(__VA_ARGS__)) -#define MPI_File_sync(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_sync(__VA_ARGS__)) -#define MPI_File_set_view(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_set_view(__VA_ARGS__)) -#define MPI_File_get_view(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_view(__VA_ARGS__)) -#define MPI_Errhandler_set(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Errhandler_set(__VA_ARGS__)) -#define MPI_Errhandler_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Errhandler_create(__VA_ARGS__)) -#define MPI_Errhandler_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Errhandler_free(__VA_ARGS__)) -#define MPI_Errhandler_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Errhandler_get(__VA_ARGS__)) -#define MPI_Comm_set_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_set_errhandler(__VA_ARGS__)) -#define MPI_Comm_get_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_get_errhandler(__VA_ARGS__)) -#define MPI_Comm_create_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_create_errhandler(__VA_ARGS__)) -#define MPI_Comm_call_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_call_errhandler(__VA_ARGS__)) -#define MPI_Win_set_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_set_errhandler(__VA_ARGS__)) -#define MPI_Win_get_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_get_errhandler(__VA_ARGS__)) -#define MPI_Win_create_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_create_errhandler(__VA_ARGS__)) -#define MPI_Win_call_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_call_errhandler(__VA_ARGS__)) -#define MPI_Errhandler_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Errhandler_f2c(__VA_ARGS__)) -#define MPI_Errhandler_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Errhandler_c2f(__VA_ARGS__)) -#define MPI_Type_create_f90_integer(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_f90_integer(__VA_ARGS__)) -#define MPI_Type_create_f90_real(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_f90_real(__VA_ARGS__)) -#define MPI_Type_create_f90_complex(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_f90_complex(__VA_ARGS__)) -#define MPI_Type_get_contents(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_get_contents(__VA_ARGS__)) -#define MPI_Type_get_envelope(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_get_envelope(__VA_ARGS__)) -#define MPI_File_call_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_call_errhandler(__VA_ARGS__)) -#define MPI_File_create_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_create_errhandler(__VA_ARGS__)) -#define MPI_File_set_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_set_errhandler(__VA_ARGS__)) -#define MPI_File_get_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_errhandler(__VA_ARGS__)) -#define MPI_Cart_map(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Cart_map(__VA_ARGS__)) -#define MPI_Graph_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Graph_create(__VA_ARGS__)) -#define MPI_Graph_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Graph_get(__VA_ARGS__)) -#define MPI_Graph_map(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Graph_map(__VA_ARGS__)) -#define MPI_Graph_neighbors(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Graph_neighbors(__VA_ARGS__)) -#define MPI_Graph_neighbors_count(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Graph_neighbors_count(__VA_ARGS__)) -#define MPI_Graphdims_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Graphdims_get(__VA_ARGS__)) -#define MPI_Topo_test(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Topo_test(__VA_ARGS__)) -#define MPI_Add_error_class(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Add_error_class(__VA_ARGS__)) -#define MPI_Add_error_code(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Add_error_code(__VA_ARGS__)) -#define MPI_Add_error_string(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Add_error_string(__VA_ARGS__)) -#define MPI_Comm_test_inter(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_test_inter(__VA_ARGS__)) -#define MPI_Intercomm_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Intercomm_create(__VA_ARGS__)) -#define MPI_Intercomm_merge(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Intercomm_merge(__VA_ARGS__)) -#define MPI_Comm_remote_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_remote_group(__VA_ARGS__)) -#define MPI_Comm_remote_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_remote_size(__VA_ARGS__)) -#define MPI_Get_elements(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Get_elements(__VA_ARGS__)) -#define MPI_Get_elements_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Get_elements_x(__VA_ARGS__)) -#define MPI_Pcontrol(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Pcontrol(__VA_ARGS__)) -#define MPI_Type_create_darray(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_create_darray(__VA_ARGS__)) -#define MPI_Pack_external_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Pack_external_size(__VA_ARGS__)) -#define MPI_Pack_external(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Pack_external(__VA_ARGS__)) -#define MPI_Unpack_external(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Unpack_external(__VA_ARGS__)) -#define MPI_Type_match_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Type_match_size(__VA_ARGS__)) -#define MPI_Comm_connect(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_connect(__VA_ARGS__)) -#define MPI_Unpublish_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Unpublish_name(__VA_ARGS__)) -#define MPI_Publish_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Publish_name(__VA_ARGS__)) -#define MPI_Lookup_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Lookup_name(__VA_ARGS__)) -#define MPI_Comm_idup(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_idup(__VA_ARGS__)) -#define MPI_Comm_join(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_join(__VA_ARGS__)) -#define MPI_Open_port(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Open_port(__VA_ARGS__)) -#define MPI_Close_port(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Close_port(__VA_ARGS__)) -#define MPI_Comm_accept(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_accept(__VA_ARGS__)) -#define MPI_Comm_spawn(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_spawn(__VA_ARGS__)) -#define MPI_Comm_spawn_multiple(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_spawn_multiple(__VA_ARGS__)) -#define MPI_Comm_get_parent(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Comm_get_parent(__VA_ARGS__)) -#define MPI_Dist_graph_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Dist_graph_create(__VA_ARGS__)) -#define MPI_Dist_graph_create_adjacent(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Dist_graph_create_adjacent(__VA_ARGS__)) -#define MPI_Dist_graph_neighbors(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Dist_graph_neighbors(__VA_ARGS__)) -#define MPI_Dist_graph_neighbors_count(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Dist_graph_neighbors_count(__VA_ARGS__)) -#define MPI_Win_test(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Win_test(__VA_ARGS__)) -#define MPI_File_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_c2f(__VA_ARGS__)) -#define MPI_File_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_f2c(__VA_ARGS__)) -#define MPI_Register_datarep(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Register_datarep(__VA_ARGS__)) -#define MPI_File_set_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_set_size(__VA_ARGS__)) -#define MPI_File_preallocate(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_preallocate(__VA_ARGS__)) -#define MPI_File_iread_at(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iread_at(__VA_ARGS__)) -#define MPI_File_iwrite_at(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iwrite_at(__VA_ARGS__)) -#define MPI_File_iread_at_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iread_at_all(__VA_ARGS__)) -#define MPI_File_iwrite_at_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iwrite_at_all(__VA_ARGS__)) -#define MPI_File_iread(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iread(__VA_ARGS__)) -#define MPI_File_iwrite(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iwrite(__VA_ARGS__)) -#define MPI_File_iread_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iread_all(__VA_ARGS__)) -#define MPI_File_iwrite_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iwrite_all(__VA_ARGS__)) -#define MPI_File_get_byte_offset(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_byte_offset(__VA_ARGS__)) -#define MPI_File_iread_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iread_shared(__VA_ARGS__)) -#define MPI_File_iwrite_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_iwrite_shared(__VA_ARGS__)) -#define MPI_File_read_at_all_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_at_all_begin(__VA_ARGS__)) -#define MPI_File_read_at_all_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_at_all_end(__VA_ARGS__)) -#define MPI_File_write_at_all_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_at_all_begin(__VA_ARGS__)) -#define MPI_File_write_at_all_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_at_all_end(__VA_ARGS__)) -#define MPI_File_read_all_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_all_begin(__VA_ARGS__)) -#define MPI_File_read_all_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_all_end(__VA_ARGS__)) -#define MPI_File_write_all_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_all_begin(__VA_ARGS__)) -#define MPI_File_write_all_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_all_end(__VA_ARGS__)) -#define MPI_File_read_ordered_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_ordered_begin(__VA_ARGS__)) -#define MPI_File_read_ordered_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_read_ordered_end(__VA_ARGS__)) -#define MPI_File_write_ordered_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_ordered_begin(__VA_ARGS__)) -#define MPI_File_write_ordered_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_write_ordered_end(__VA_ARGS__)) -#define MPI_File_get_type_extent(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_type_extent(__VA_ARGS__)) -#define MPI_File_set_atomicity(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_set_atomicity(__VA_ARGS__)) -#define MPI_File_get_atomicity(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_File_get_atomicity(__VA_ARGS__)) -#define MPI_Message_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Message_f2c(__VA_ARGS__)) -#define MPI_Message_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Message_c2f(__VA_ARGS__)) -#define MPI_Mrecv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Mrecv(__VA_ARGS__)) -#define MPI_Mprobe(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Mprobe(__VA_ARGS__)) -#define MPI_Imrecv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Imrecv(__VA_ARGS__)) -#define MPI_Improbe(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Improbe(__VA_ARGS__)) -#define MPI_Neighbor_allgather(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Neighbor_allgather(__VA_ARGS__)) -#define MPI_Neighbor_allgatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Neighbor_allgatherv(__VA_ARGS__)) -#define MPI_Neighbor_alltoall(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Neighbor_alltoall(__VA_ARGS__)) -#define MPI_Neighbor_alltoallv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Neighbor_alltoallv(__VA_ARGS__)) -#define MPI_Neighbor_alltoallw(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Neighbor_alltoallw(__VA_ARGS__)) -#define MPI_Ineighbor_allgather(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ineighbor_allgather(__VA_ARGS__)) -#define MPI_Ineighbor_allgatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ineighbor_allgatherv(__VA_ARGS__)) -#define MPI_Ineighbor_alltoall(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ineighbor_alltoall(__VA_ARGS__)) -#define MPI_Ineighbor_alltoallv(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ineighbor_alltoallv(__VA_ARGS__)) -#define MPI_Ineighbor_alltoallw(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Ineighbor_alltoallw(__VA_ARGS__)) -#define MPI_Status_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Status_f2c(__VA_ARGS__)) -#define MPI_Status_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__), MPI_Status_c2f(__VA_ARGS__)) +#define MPI_Init(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Init"), MPI_Init(__VA_ARGS__)) +#define MPI_Finalize(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Finalize"), MPI_Finalize(__VA_ARGS__)) +#define MPI_Finalized(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Finalized"), MPI_Finalized(__VA_ARGS__)) +#define MPI_Init_thread(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Init_thread"), MPI_Init_thread(__VA_ARGS__)) +#define MPI_Initialized(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Initialized"), MPI_Initialized(__VA_ARGS__)) +#define MPI_Query_thread(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Query_thread"), MPI_Query_thread(__VA_ARGS__)) +#define MPI_Is_thread_main(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Is_thread_main"), MPI_Is_thread_main(__VA_ARGS__)) +#define MPI_Get_version(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Get_version"), MPI_Get_version(__VA_ARGS__)) +#define MPI_Get_library_version(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Get_library_version"), MPI_Get_library_version(__VA_ARGS__)) +#define MPI_Get_processor_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Get_processor_name"), MPI_Get_processor_name(__VA_ARGS__)) +#define MPI_Abort(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Abort"), MPI_Abort(__VA_ARGS__)) +#define MPI_Alloc_mem(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Alloc_mem"), MPI_Alloc_mem(__VA_ARGS__)) +#define MPI_Free_mem(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Free_mem"), MPI_Free_mem(__VA_ARGS__)) +#define MPI_Wtime(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Wtime"), MPI_Wtime(__VA_ARGS__)) +#define MPI_Wtick(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Wtick"), MPI_Wtick(__VA_ARGS__)) +#define MPI_Buffer_attach(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Buffer_attach"), MPI_Buffer_attach(__VA_ARGS__)) +#define MPI_Buffer_detach(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Buffer_detach"), MPI_Buffer_detach(__VA_ARGS__)) +#define MPI_Address(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Address"), MPI_Address(__VA_ARGS__)) +#define MPI_Get_address(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Get_address"), MPI_Get_address(__VA_ARGS__)) +#define MPI_Aint_diff(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Aint_diff"), MPI_Aint_diff(__VA_ARGS__)) +#define MPI_Aint_add(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Aint_add"), MPI_Aint_add(__VA_ARGS__)) +#define MPI_Error_class(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Error_class"), MPI_Error_class(__VA_ARGS__)) +#define MPI_Error_string(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Error_string"), MPI_Error_string(__VA_ARGS__)) +#define MPI_Attr_delete(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Attr_delete"), MPI_Attr_delete(__VA_ARGS__)) +#define MPI_Attr_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Attr_get"), MPI_Attr_get(__VA_ARGS__)) +#define MPI_Attr_put(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Attr_put"), MPI_Attr_put(__VA_ARGS__)) +#define MPI_Keyval_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Keyval_create"), MPI_Keyval_create(__VA_ARGS__)) +#define MPI_Keyval_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Keyval_free"), MPI_Keyval_free(__VA_ARGS__)) +#define MPI_Type_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_free"), MPI_Type_free(__VA_ARGS__)) +#define MPI_Type_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_size"), MPI_Type_size(__VA_ARGS__)) +#define MPI_Type_size_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_size_x"), MPI_Type_size_x(__VA_ARGS__)) +#define MPI_Type_get_extent(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_get_extent"), MPI_Type_get_extent(__VA_ARGS__)) +#define MPI_Type_get_extent_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_get_extent_x"), MPI_Type_get_extent_x(__VA_ARGS__)) +#define MPI_Type_get_true_extent(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_get_true_extent"), MPI_Type_get_true_extent(__VA_ARGS__)) +#define MPI_Type_get_true_extent_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_get_true_extent_x"), MPI_Type_get_true_extent_x(__VA_ARGS__)) +#define MPI_Type_extent(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_extent"), MPI_Type_extent(__VA_ARGS__)) +#define MPI_Type_lb(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_lb"), MPI_Type_lb(__VA_ARGS__)) +#define MPI_Type_ub(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_ub"), MPI_Type_ub(__VA_ARGS__)) +#define MPI_Type_commit(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_commit"), MPI_Type_commit(__VA_ARGS__)) +#define MPI_Type_hindexed(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_hindexed"), MPI_Type_hindexed(__VA_ARGS__)) +#define MPI_Type_create_hindexed(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_hindexed"), MPI_Type_create_hindexed(__VA_ARGS__)) +#define MPI_Type_create_hindexed_block(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_hindexed_block"), MPI_Type_create_hindexed_block(__VA_ARGS__)) +#define MPI_Type_hvector(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_hvector"), MPI_Type_hvector(__VA_ARGS__)) +#define MPI_Type_create_hvector(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_hvector"), MPI_Type_create_hvector(__VA_ARGS__)) +#define MPI_Type_indexed(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_indexed"), MPI_Type_indexed(__VA_ARGS__)) +#define MPI_Type_create_indexed(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_indexed"), MPI_Type_create_indexed(__VA_ARGS__)) +#define MPI_Type_create_indexed_block(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_indexed_block"), MPI_Type_create_indexed_block(__VA_ARGS__)) +#define MPI_Type_struct(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_struct"), MPI_Type_struct(__VA_ARGS__)) +#define MPI_Type_create_struct(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_struct"), MPI_Type_create_struct(__VA_ARGS__)) +#define MPI_Type_vector(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_vector"), MPI_Type_vector(__VA_ARGS__)) +#define MPI_Type_contiguous(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_contiguous"), MPI_Type_contiguous(__VA_ARGS__)) +#define MPI_Type_create_resized(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_resized"), MPI_Type_create_resized(__VA_ARGS__)) +#define MPI_Type_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_f2c"), MPI_Type_f2c(__VA_ARGS__)) +#define MPI_Type_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_c2f"), MPI_Type_c2f(__VA_ARGS__)) +#define MPI_Get_count(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Get_count"), MPI_Get_count(__VA_ARGS__)) +#define MPI_Type_get_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_get_attr"), MPI_Type_get_attr(__VA_ARGS__)) +#define MPI_Type_set_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_set_attr"), MPI_Type_set_attr(__VA_ARGS__)) +#define MPI_Type_delete_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_delete_attr"), MPI_Type_delete_attr(__VA_ARGS__)) +#define MPI_Type_create_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_keyval"), MPI_Type_create_keyval(__VA_ARGS__)) +#define MPI_Type_free_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_free_keyval"), MPI_Type_free_keyval(__VA_ARGS__)) +#define MPI_Type_dup(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_dup"), MPI_Type_dup(__VA_ARGS__)) +#define MPI_Type_set_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_set_name"), MPI_Type_set_name(__VA_ARGS__)) +#define MPI_Type_get_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_get_name"), MPI_Type_get_name(__VA_ARGS__)) +#define MPI_Pack(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pack"), MPI_Pack(__VA_ARGS__)) +#define MPI_Pack_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pack_size"), MPI_Pack_size(__VA_ARGS__)) +#define MPI_Unpack(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Unpack"), MPI_Unpack(__VA_ARGS__)) +#define MPI_Op_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Op_create"), MPI_Op_create(__VA_ARGS__)) +#define MPI_Op_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Op_free"), MPI_Op_free(__VA_ARGS__)) +#define MPI_Op_commutative(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Op_commutative"), MPI_Op_commutative(__VA_ARGS__)) +#define MPI_Op_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Op_f2c"), MPI_Op_f2c(__VA_ARGS__)) +#define MPI_Op_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Op_c2f"), MPI_Op_c2f(__VA_ARGS__)) +#define MPI_Group_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_free"), MPI_Group_free(__VA_ARGS__)) +#define MPI_Group_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_size"), MPI_Group_size(__VA_ARGS__)) +#define MPI_Group_rank(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_rank"), MPI_Group_rank(__VA_ARGS__)) +#define MPI_Group_translate_ranks(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_translate_ranks"), MPI_Group_translate_ranks(__VA_ARGS__)) +#define MPI_Group_compare(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_compare"), MPI_Group_compare(__VA_ARGS__)) +#define MPI_Group_union(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_union"), MPI_Group_union(__VA_ARGS__)) +#define MPI_Group_intersection(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_intersection"), MPI_Group_intersection(__VA_ARGS__)) +#define MPI_Group_difference(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_difference"), MPI_Group_difference(__VA_ARGS__)) +#define MPI_Group_incl(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_incl"), MPI_Group_incl(__VA_ARGS__)) +#define MPI_Group_excl(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_excl"), MPI_Group_excl(__VA_ARGS__)) +#define MPI_Group_range_incl(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_range_incl"), MPI_Group_range_incl(__VA_ARGS__)) +#define MPI_Group_range_excl(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_range_excl"), MPI_Group_range_excl(__VA_ARGS__)) +#define MPI_Group_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_f2c"), MPI_Group_f2c(__VA_ARGS__)) +#define MPI_Group_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Group_c2f"), MPI_Group_c2f(__VA_ARGS__)) +#define MPI_Comm_rank(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_rank"), MPI_Comm_rank(__VA_ARGS__)) +#define MPI_Comm_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_size"), MPI_Comm_size(__VA_ARGS__)) +#define MPI_Comm_get_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_get_name"), MPI_Comm_get_name(__VA_ARGS__)) +#define MPI_Comm_set_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_set_name"), MPI_Comm_set_name(__VA_ARGS__)) +#define MPI_Comm_dup(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_dup"), MPI_Comm_dup(__VA_ARGS__)) +#define MPI_Comm_dup_with_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_dup_with_info"), MPI_Comm_dup_with_info(__VA_ARGS__)) +#define MPI_Comm_get_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_get_attr"), MPI_Comm_get_attr(__VA_ARGS__)) +#define MPI_Comm_set_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_set_attr"), MPI_Comm_set_attr(__VA_ARGS__)) +#define MPI_Comm_delete_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_delete_attr"), MPI_Comm_delete_attr(__VA_ARGS__)) +#define MPI_Comm_create_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_create_keyval"), MPI_Comm_create_keyval(__VA_ARGS__)) +#define MPI_Comm_free_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_free_keyval"), MPI_Comm_free_keyval(__VA_ARGS__)) +#define MPI_Comm_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_group"), MPI_Comm_group(__VA_ARGS__)) +#define MPI_Comm_compare(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_compare"), MPI_Comm_compare(__VA_ARGS__)) +#define MPI_Comm_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_create"), MPI_Comm_create(__VA_ARGS__)) +#define MPI_Comm_create_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_create_group"), MPI_Comm_create_group(__VA_ARGS__)) +#define MPI_Comm_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_free"), MPI_Comm_free(__VA_ARGS__)) +#define MPI_Comm_disconnect(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_disconnect"), MPI_Comm_disconnect(__VA_ARGS__)) +#define MPI_Comm_split(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_split"), MPI_Comm_split(__VA_ARGS__)) +#define MPI_Comm_set_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_set_info"), MPI_Comm_set_info(__VA_ARGS__)) +#define MPI_Comm_get_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_get_info"), MPI_Comm_get_info(__VA_ARGS__)) +#define MPI_Comm_split_type(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_split_type"), MPI_Comm_split_type(__VA_ARGS__)) +#define MPI_Comm_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_f2c"), MPI_Comm_f2c(__VA_ARGS__)) +#define MPI_Comm_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_c2f"), MPI_Comm_c2f(__VA_ARGS__)) +#define MPI_Start(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Start"), MPI_Start(__VA_ARGS__)) +#define MPI_Startall(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Startall"), MPI_Startall(__VA_ARGS__)) +#define MPI_Request_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Request_free"), MPI_Request_free(__VA_ARGS__)) +#define MPI_Recv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Recv"), MPI_Recv(__VA_ARGS__)) +#define MPI_Recv_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Recv_init"), MPI_Recv_init(__VA_ARGS__)) +#define MPI_Irecv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Irecv"), MPI_Irecv(__VA_ARGS__)) +#define MPI_Send(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Send"), MPI_Send(__VA_ARGS__)) +#define MPI_Send_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Send_init"), MPI_Send_init(__VA_ARGS__)) +#define MPI_Isend(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Isend"), MPI_Isend(__VA_ARGS__)) +#define MPI_Ssend(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ssend"), MPI_Ssend(__VA_ARGS__)) +#define MPI_Ssend_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ssend_init"), MPI_Ssend_init(__VA_ARGS__)) +#define MPI_Issend(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Issend"), MPI_Issend(__VA_ARGS__)) +#define MPI_Bsend(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Bsend"), MPI_Bsend(__VA_ARGS__)) +#define MPI_Bsend_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Bsend_init"), MPI_Bsend_init(__VA_ARGS__)) +#define MPI_Ibsend(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ibsend"), MPI_Ibsend(__VA_ARGS__)) +#define MPI_Rsend(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Rsend"), MPI_Rsend(__VA_ARGS__)) +#define MPI_Rsend_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Rsend_init"), MPI_Rsend_init(__VA_ARGS__)) +#define MPI_Irsend(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Irsend"), MPI_Irsend(__VA_ARGS__)) +#define MPI_Sendrecv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Sendrecv"), MPI_Sendrecv(__VA_ARGS__)) +#define MPI_Isendrecv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Isendrecv"), MPI_Isendrecv(__VA_ARGS__)) +#define MPI_Sendrecv_replace(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Sendrecv_replace"), MPI_Sendrecv_replace(__VA_ARGS__)) +#define MPI_Isendrecv_replace(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Isendrecv_replace"), MPI_Isendrecv_replace(__VA_ARGS__)) +#define MPI_Test(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Test"), MPI_Test(__VA_ARGS__)) +#define MPI_Testany(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Testany"), MPI_Testany(__VA_ARGS__)) +#define MPI_Testall(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Testall"), MPI_Testall(__VA_ARGS__)) +#define MPI_Testsome(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Testsome"), MPI_Testsome(__VA_ARGS__)) +#define MPI_Test_cancelled(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Test_cancelled"), MPI_Test_cancelled(__VA_ARGS__)) +#define MPI_Wait(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Wait"), MPI_Wait(__VA_ARGS__)) +#define MPI_Waitany(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Waitany"), MPI_Waitany(__VA_ARGS__)) +#define MPI_Waitall(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Waitall"), MPI_Waitall(__VA_ARGS__)) +#define MPI_Waitsome(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Waitsome"), MPI_Waitsome(__VA_ARGS__)) +#define MPI_Iprobe(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Iprobe"), MPI_Iprobe(__VA_ARGS__)) +#define MPI_Probe(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Probe"), MPI_Probe(__VA_ARGS__)) +#define MPI_Request_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Request_f2c"), MPI_Request_f2c(__VA_ARGS__)) +#define MPI_Request_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Request_c2f"), MPI_Request_c2f(__VA_ARGS__)) +#define MPI_Cancel(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Cancel"), MPI_Cancel(__VA_ARGS__)) +#define MPI_Bcast(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Bcast"), MPI_Bcast(__VA_ARGS__)) +#define MPI_Barrier(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Barrier"), MPI_Barrier(__VA_ARGS__)) +#define MPI_Ibarrier(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ibarrier"), MPI_Ibarrier(__VA_ARGS__)) +#define MPI_Ibcast(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ibcast"), MPI_Ibcast(__VA_ARGS__)) +#define MPI_Igather(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Igather"), MPI_Igather(__VA_ARGS__)) +#define MPI_Igatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Igatherv"), MPI_Igatherv(__VA_ARGS__)) +#define MPI_Iallgather(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Iallgather"), MPI_Iallgather(__VA_ARGS__)) +#define MPI_Iallgatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Iallgatherv"), MPI_Iallgatherv(__VA_ARGS__)) +#define MPI_Iscatter(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Iscatter"), MPI_Iscatter(__VA_ARGS__)) +#define MPI_Iscatterv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Iscatterv"), MPI_Iscatterv(__VA_ARGS__)) +#define MPI_Ireduce(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ireduce"), MPI_Ireduce(__VA_ARGS__)) +#define MPI_Iallreduce(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Iallreduce"), MPI_Iallreduce(__VA_ARGS__)) +#define MPI_Iscan(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Iscan"), MPI_Iscan(__VA_ARGS__)) +#define MPI_Iexscan(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Iexscan"), MPI_Iexscan(__VA_ARGS__)) +#define MPI_Ireduce_scatter(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ireduce_scatter"), MPI_Ireduce_scatter(__VA_ARGS__)) +#define MPI_Ireduce_scatter_block(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ireduce_scatter_block"), MPI_Ireduce_scatter_block(__VA_ARGS__)) +#define MPI_Ialltoall(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ialltoall"), MPI_Ialltoall(__VA_ARGS__)) +#define MPI_Ialltoallv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ialltoallv"), MPI_Ialltoallv(__VA_ARGS__)) +#define MPI_Ialltoallw(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ialltoallw"), MPI_Ialltoallw(__VA_ARGS__)) +#define MPI_Gather(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Gather"), MPI_Gather(__VA_ARGS__)) +#define MPI_Gatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Gatherv"), MPI_Gatherv(__VA_ARGS__)) +#define MPI_Allgather(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Allgather"), MPI_Allgather(__VA_ARGS__)) +#define MPI_Allgatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Allgatherv"), MPI_Allgatherv(__VA_ARGS__)) +#define MPI_Scatter(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Scatter"), MPI_Scatter(__VA_ARGS__)) +#define MPI_Scatterv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Scatterv"), MPI_Scatterv(__VA_ARGS__)) +#define MPI_Reduce(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Reduce"), MPI_Reduce(__VA_ARGS__)) +#define MPI_Allreduce(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Allreduce"), MPI_Allreduce(__VA_ARGS__)) +#define MPI_Scan(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Scan"), MPI_Scan(__VA_ARGS__)) +#define MPI_Exscan(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Exscan"), MPI_Exscan(__VA_ARGS__)) +#define MPI_Reduce_scatter(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Reduce_scatter"), MPI_Reduce_scatter(__VA_ARGS__)) +#define MPI_Reduce_scatter_block(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Reduce_scatter_block"), MPI_Reduce_scatter_block(__VA_ARGS__)) +#define MPI_Alltoall(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Alltoall"), MPI_Alltoall(__VA_ARGS__)) +#define MPI_Alltoallv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Alltoallv"), MPI_Alltoallv(__VA_ARGS__)) +#define MPI_Alltoallw(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Alltoallw"), MPI_Alltoallw(__VA_ARGS__)) +#define MPI_Reduce_local(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Reduce_local"), MPI_Reduce_local(__VA_ARGS__)) +#define MPI_Info_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_create"), MPI_Info_create(__VA_ARGS__)) +#define MPI_Info_set(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_set"), MPI_Info_set(__VA_ARGS__)) +#define MPI_Info_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_get"), MPI_Info_get(__VA_ARGS__)) +#define MPI_Info_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_free"), MPI_Info_free(__VA_ARGS__)) +#define MPI_Info_delete(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_delete"), MPI_Info_delete(__VA_ARGS__)) +#define MPI_Info_dup(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_dup"), MPI_Info_dup(__VA_ARGS__)) +#define MPI_Info_get_nkeys(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_get_nkeys"), MPI_Info_get_nkeys(__VA_ARGS__)) +#define MPI_Info_get_nthkey(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_get_nthkey"), MPI_Info_get_nthkey(__VA_ARGS__)) +#define MPI_Info_get_valuelen(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_get_valuelen"), MPI_Info_get_valuelen(__VA_ARGS__)) +#define MPI_Info_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_f2c"), MPI_Info_f2c(__VA_ARGS__)) +#define MPI_Info_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Info_c2f"), MPI_Info_c2f(__VA_ARGS__)) +#define MPI_Win_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_free"), MPI_Win_free(__VA_ARGS__)) +#define MPI_Win_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_create"), MPI_Win_create(__VA_ARGS__)) +#define MPI_Win_allocate(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_allocate"), MPI_Win_allocate(__VA_ARGS__)) +#define MPI_Win_allocate_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_allocate_shared"), MPI_Win_allocate_shared(__VA_ARGS__)) +#define MPI_Win_create_dynamic(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_create_dynamic"), MPI_Win_create_dynamic(__VA_ARGS__)) +#define MPI_Win_attach(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_attach"), MPI_Win_attach(__VA_ARGS__)) +#define MPI_Win_detach(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_detach"), MPI_Win_detach(__VA_ARGS__)) +#define MPI_Win_set_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_set_name"), MPI_Win_set_name(__VA_ARGS__)) +#define MPI_Win_get_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_get_name"), MPI_Win_get_name(__VA_ARGS__)) +#define MPI_Win_set_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_set_info"), MPI_Win_set_info(__VA_ARGS__)) +#define MPI_Win_get_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_get_info"), MPI_Win_get_info(__VA_ARGS__)) +#define MPI_Win_get_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_get_group"), MPI_Win_get_group(__VA_ARGS__)) +#define MPI_Win_fence(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_fence"), MPI_Win_fence(__VA_ARGS__)) +#define MPI_Win_get_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_get_attr"), MPI_Win_get_attr(__VA_ARGS__)) +#define MPI_Win_set_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_set_attr"), MPI_Win_set_attr(__VA_ARGS__)) +#define MPI_Win_delete_attr(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_delete_attr"), MPI_Win_delete_attr(__VA_ARGS__)) +#define MPI_Win_create_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_create_keyval"), MPI_Win_create_keyval(__VA_ARGS__)) +#define MPI_Win_free_keyval(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_free_keyval"), MPI_Win_free_keyval(__VA_ARGS__)) +#define MPI_Win_complete(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_complete"), MPI_Win_complete(__VA_ARGS__)) +#define MPI_Win_post(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_post"), MPI_Win_post(__VA_ARGS__)) +#define MPI_Win_start(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_start"), MPI_Win_start(__VA_ARGS__)) +#define MPI_Win_wait(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_wait"), MPI_Win_wait(__VA_ARGS__)) +#define MPI_Win_lock(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_lock"), MPI_Win_lock(__VA_ARGS__)) +#define MPI_Win_lock_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_lock_all"), MPI_Win_lock_all(__VA_ARGS__)) +#define MPI_Win_unlock(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_unlock"), MPI_Win_unlock(__VA_ARGS__)) +#define MPI_Win_unlock_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_unlock_all"), MPI_Win_unlock_all(__VA_ARGS__)) +#define MPI_Win_flush(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_flush"), MPI_Win_flush(__VA_ARGS__)) +#define MPI_Win_flush_local(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_flush_local"), MPI_Win_flush_local(__VA_ARGS__)) +#define MPI_Win_flush_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_flush_all"), MPI_Win_flush_all(__VA_ARGS__)) +#define MPI_Win_flush_local_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_flush_local_all"), MPI_Win_flush_local_all(__VA_ARGS__)) +#define MPI_Win_shared_query(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_shared_query"), MPI_Win_shared_query(__VA_ARGS__)) +#define MPI_Win_sync(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_sync"), MPI_Win_sync(__VA_ARGS__)) +#define MPI_Win_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_f2c"), MPI_Win_f2c(__VA_ARGS__)) +#define MPI_Win_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_c2f"), MPI_Win_c2f(__VA_ARGS__)) +#define MPI_Get(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Get"), MPI_Get(__VA_ARGS__)) +#define MPI_Put(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Put"), MPI_Put(__VA_ARGS__)) +#define MPI_Accumulate(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Accumulate"), MPI_Accumulate(__VA_ARGS__)) +#define MPI_Get_accumulate(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Get_accumulate"), MPI_Get_accumulate(__VA_ARGS__)) +#define MPI_Rget(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Rget"), MPI_Rget(__VA_ARGS__)) +#define MPI_Rput(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Rput"), MPI_Rput(__VA_ARGS__)) +#define MPI_Raccumulate(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Raccumulate"), MPI_Raccumulate(__VA_ARGS__)) +#define MPI_Rget_accumulate(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Rget_accumulate"), MPI_Rget_accumulate(__VA_ARGS__)) +#define MPI_Fetch_and_op(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Fetch_and_op"), MPI_Fetch_and_op(__VA_ARGS__)) +#define MPI_Compare_and_swap(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Compare_and_swap"), MPI_Compare_and_swap(__VA_ARGS__)) +#define MPI_Cart_coords(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Cart_coords"), MPI_Cart_coords(__VA_ARGS__)) +#define MPI_Cart_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Cart_create"), MPI_Cart_create(__VA_ARGS__)) +#define MPI_Cart_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Cart_get"), MPI_Cart_get(__VA_ARGS__)) +#define MPI_Cart_rank(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Cart_rank"), MPI_Cart_rank(__VA_ARGS__)) +#define MPI_Cart_shift(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Cart_shift"), MPI_Cart_shift(__VA_ARGS__)) +#define MPI_Cart_sub(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Cart_sub"), MPI_Cart_sub(__VA_ARGS__)) +#define MPI_Cartdim_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Cartdim_get"), MPI_Cartdim_get(__VA_ARGS__)) +#define MPI_Dims_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Dims_create"), MPI_Dims_create(__VA_ARGS__)) +#define MPI_Request_get_status(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Request_get_status"), MPI_Request_get_status(__VA_ARGS__)) +#define MPI_Grequest_start(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Grequest_start"), MPI_Grequest_start(__VA_ARGS__)) +#define MPI_Grequest_complete(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Grequest_complete"), MPI_Grequest_complete(__VA_ARGS__)) +#define MPI_Status_set_cancelled(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Status_set_cancelled"), MPI_Status_set_cancelled(__VA_ARGS__)) +#define MPI_Status_set_elements(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Status_set_elements"), MPI_Status_set_elements(__VA_ARGS__)) +#define MPI_Status_set_elements_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Status_set_elements_x"), MPI_Status_set_elements_x(__VA_ARGS__)) +#define MPI_Type_create_subarray(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_subarray"), MPI_Type_create_subarray(__VA_ARGS__)) +#define MPI_File_open(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_open"), MPI_File_open(__VA_ARGS__)) +#define MPI_File_close(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_close"), MPI_File_close(__VA_ARGS__)) +#define MPI_File_delete(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_delete"), MPI_File_delete(__VA_ARGS__)) +#define MPI_File_get_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_size"), MPI_File_get_size(__VA_ARGS__)) +#define MPI_File_get_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_group"), MPI_File_get_group(__VA_ARGS__)) +#define MPI_File_get_amode(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_amode"), MPI_File_get_amode(__VA_ARGS__)) +#define MPI_File_set_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_set_info"), MPI_File_set_info(__VA_ARGS__)) +#define MPI_File_get_info(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_info"), MPI_File_get_info(__VA_ARGS__)) +#define MPI_File_read_at(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_at"), MPI_File_read_at(__VA_ARGS__)) +#define MPI_File_read_at_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_at_all"), MPI_File_read_at_all(__VA_ARGS__)) +#define MPI_File_write_at(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_at"), MPI_File_write_at(__VA_ARGS__)) +#define MPI_File_write_at_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_at_all"), MPI_File_write_at_all(__VA_ARGS__)) +#define MPI_File_read(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read"), MPI_File_read(__VA_ARGS__)) +#define MPI_File_read_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_all"), MPI_File_read_all(__VA_ARGS__)) +#define MPI_File_write(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write"), MPI_File_write(__VA_ARGS__)) +#define MPI_File_write_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_all"), MPI_File_write_all(__VA_ARGS__)) +#define MPI_File_seek(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_seek"), MPI_File_seek(__VA_ARGS__)) +#define MPI_File_get_position(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_position"), MPI_File_get_position(__VA_ARGS__)) +#define MPI_File_read_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_shared"), MPI_File_read_shared(__VA_ARGS__)) +#define MPI_File_write_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_shared"), MPI_File_write_shared(__VA_ARGS__)) +#define MPI_File_read_ordered(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_ordered"), MPI_File_read_ordered(__VA_ARGS__)) +#define MPI_File_write_ordered(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_ordered"), MPI_File_write_ordered(__VA_ARGS__)) +#define MPI_File_seek_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_seek_shared"), MPI_File_seek_shared(__VA_ARGS__)) +#define MPI_File_get_position_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_position_shared"), MPI_File_get_position_shared(__VA_ARGS__)) +#define MPI_File_sync(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_sync"), MPI_File_sync(__VA_ARGS__)) +#define MPI_File_set_view(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_set_view"), MPI_File_set_view(__VA_ARGS__)) +#define MPI_File_get_view(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_view"), MPI_File_get_view(__VA_ARGS__)) +#define MPI_Errhandler_set(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Errhandler_set"), MPI_Errhandler_set(__VA_ARGS__)) +#define MPI_Errhandler_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Errhandler_create"), MPI_Errhandler_create(__VA_ARGS__)) +#define MPI_Errhandler_free(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Errhandler_free"), MPI_Errhandler_free(__VA_ARGS__)) +#define MPI_Errhandler_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Errhandler_get"), MPI_Errhandler_get(__VA_ARGS__)) +#define MPI_Comm_set_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_set_errhandler"), MPI_Comm_set_errhandler(__VA_ARGS__)) +#define MPI_Comm_get_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_get_errhandler"), MPI_Comm_get_errhandler(__VA_ARGS__)) +#define MPI_Comm_create_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_create_errhandler"), MPI_Comm_create_errhandler(__VA_ARGS__)) +#define MPI_Comm_call_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_call_errhandler"), MPI_Comm_call_errhandler(__VA_ARGS__)) +#define MPI_Win_set_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_set_errhandler"), MPI_Win_set_errhandler(__VA_ARGS__)) +#define MPI_Win_get_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_get_errhandler"), MPI_Win_get_errhandler(__VA_ARGS__)) +#define MPI_Win_create_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_create_errhandler"), MPI_Win_create_errhandler(__VA_ARGS__)) +#define MPI_Win_call_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_call_errhandler"), MPI_Win_call_errhandler(__VA_ARGS__)) +#define MPI_Errhandler_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Errhandler_f2c"), MPI_Errhandler_f2c(__VA_ARGS__)) +#define MPI_Errhandler_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Errhandler_c2f"), MPI_Errhandler_c2f(__VA_ARGS__)) +#define MPI_Type_create_f90_integer(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_f90_integer"), MPI_Type_create_f90_integer(__VA_ARGS__)) +#define MPI_Type_create_f90_real(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_f90_real"), MPI_Type_create_f90_real(__VA_ARGS__)) +#define MPI_Type_create_f90_complex(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_f90_complex"), MPI_Type_create_f90_complex(__VA_ARGS__)) +#define MPI_Type_get_contents(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_get_contents"), MPI_Type_get_contents(__VA_ARGS__)) +#define MPI_Type_get_envelope(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_get_envelope"), MPI_Type_get_envelope(__VA_ARGS__)) +#define MPI_File_call_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_call_errhandler"), MPI_File_call_errhandler(__VA_ARGS__)) +#define MPI_File_create_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_create_errhandler"), MPI_File_create_errhandler(__VA_ARGS__)) +#define MPI_File_set_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_set_errhandler"), MPI_File_set_errhandler(__VA_ARGS__)) +#define MPI_File_get_errhandler(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_errhandler"), MPI_File_get_errhandler(__VA_ARGS__)) +#define MPI_Cart_map(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Cart_map"), MPI_Cart_map(__VA_ARGS__)) +#define MPI_Graph_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Graph_create"), MPI_Graph_create(__VA_ARGS__)) +#define MPI_Graph_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Graph_get"), MPI_Graph_get(__VA_ARGS__)) +#define MPI_Graph_map(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Graph_map"), MPI_Graph_map(__VA_ARGS__)) +#define MPI_Graph_neighbors(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Graph_neighbors"), MPI_Graph_neighbors(__VA_ARGS__)) +#define MPI_Graph_neighbors_count(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Graph_neighbors_count"), MPI_Graph_neighbors_count(__VA_ARGS__)) +#define MPI_Graphdims_get(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Graphdims_get"), MPI_Graphdims_get(__VA_ARGS__)) +#define MPI_Topo_test(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Topo_test"), MPI_Topo_test(__VA_ARGS__)) +#define MPI_Add_error_class(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Add_error_class"), MPI_Add_error_class(__VA_ARGS__)) +#define MPI_Add_error_code(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Add_error_code"), MPI_Add_error_code(__VA_ARGS__)) +#define MPI_Add_error_string(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Add_error_string"), MPI_Add_error_string(__VA_ARGS__)) +#define MPI_Comm_test_inter(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_test_inter"), MPI_Comm_test_inter(__VA_ARGS__)) +#define MPI_Intercomm_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Intercomm_create"), MPI_Intercomm_create(__VA_ARGS__)) +#define MPI_Intercomm_merge(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Intercomm_merge"), MPI_Intercomm_merge(__VA_ARGS__)) +#define MPI_Comm_remote_group(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_remote_group"), MPI_Comm_remote_group(__VA_ARGS__)) +#define MPI_Comm_remote_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_remote_size"), MPI_Comm_remote_size(__VA_ARGS__)) +#define MPI_Get_elements(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Get_elements"), MPI_Get_elements(__VA_ARGS__)) +#define MPI_Get_elements_x(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Get_elements_x"), MPI_Get_elements_x(__VA_ARGS__)) +#define MPI_Pcontrol(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pcontrol"), MPI_Pcontrol(__VA_ARGS__)) +#define MPI_Type_create_darray(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_create_darray"), MPI_Type_create_darray(__VA_ARGS__)) +#define MPI_Pack_external_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pack_external_size"), MPI_Pack_external_size(__VA_ARGS__)) +#define MPI_Pack_external(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pack_external"), MPI_Pack_external(__VA_ARGS__)) +#define MPI_Unpack_external(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Unpack_external"), MPI_Unpack_external(__VA_ARGS__)) +#define MPI_Type_match_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Type_match_size"), MPI_Type_match_size(__VA_ARGS__)) +#define MPI_Comm_connect(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_connect"), MPI_Comm_connect(__VA_ARGS__)) +#define MPI_Unpublish_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Unpublish_name"), MPI_Unpublish_name(__VA_ARGS__)) +#define MPI_Publish_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Publish_name"), MPI_Publish_name(__VA_ARGS__)) +#define MPI_Lookup_name(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Lookup_name"), MPI_Lookup_name(__VA_ARGS__)) +#define MPI_Comm_idup(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_idup"), MPI_Comm_idup(__VA_ARGS__)) +#define MPI_Comm_join(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_join"), MPI_Comm_join(__VA_ARGS__)) +#define MPI_Open_port(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Open_port"), MPI_Open_port(__VA_ARGS__)) +#define MPI_Close_port(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Close_port"), MPI_Close_port(__VA_ARGS__)) +#define MPI_Comm_accept(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_accept"), MPI_Comm_accept(__VA_ARGS__)) +#define MPI_Comm_spawn(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_spawn"), MPI_Comm_spawn(__VA_ARGS__)) +#define MPI_Comm_spawn_multiple(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_spawn_multiple"), MPI_Comm_spawn_multiple(__VA_ARGS__)) +#define MPI_Comm_get_parent(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Comm_get_parent"), MPI_Comm_get_parent(__VA_ARGS__)) +#define MPI_Dist_graph_create(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Dist_graph_create"), MPI_Dist_graph_create(__VA_ARGS__)) +#define MPI_Dist_graph_create_adjacent(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Dist_graph_create_adjacent"), MPI_Dist_graph_create_adjacent(__VA_ARGS__)) +#define MPI_Dist_graph_neighbors(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Dist_graph_neighbors"), MPI_Dist_graph_neighbors(__VA_ARGS__)) +#define MPI_Dist_graph_neighbors_count(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Dist_graph_neighbors_count"), MPI_Dist_graph_neighbors_count(__VA_ARGS__)) +#define MPI_Win_test(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Win_test"), MPI_Win_test(__VA_ARGS__)) +#define MPI_File_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_c2f"), MPI_File_c2f(__VA_ARGS__)) +#define MPI_File_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_f2c"), MPI_File_f2c(__VA_ARGS__)) +#define MPI_Register_datarep(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Register_datarep"), MPI_Register_datarep(__VA_ARGS__)) +#define MPI_File_set_size(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_set_size"), MPI_File_set_size(__VA_ARGS__)) +#define MPI_File_preallocate(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_preallocate"), MPI_File_preallocate(__VA_ARGS__)) +#define MPI_File_iread_at(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iread_at"), MPI_File_iread_at(__VA_ARGS__)) +#define MPI_File_iwrite_at(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iwrite_at"), MPI_File_iwrite_at(__VA_ARGS__)) +#define MPI_File_iread_at_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iread_at_all"), MPI_File_iread_at_all(__VA_ARGS__)) +#define MPI_File_iwrite_at_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iwrite_at_all"), MPI_File_iwrite_at_all(__VA_ARGS__)) +#define MPI_File_iread(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iread"), MPI_File_iread(__VA_ARGS__)) +#define MPI_File_iwrite(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iwrite"), MPI_File_iwrite(__VA_ARGS__)) +#define MPI_File_iread_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iread_all"), MPI_File_iread_all(__VA_ARGS__)) +#define MPI_File_iwrite_all(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iwrite_all"), MPI_File_iwrite_all(__VA_ARGS__)) +#define MPI_File_get_byte_offset(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_byte_offset"), MPI_File_get_byte_offset(__VA_ARGS__)) +#define MPI_File_iread_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iread_shared"), MPI_File_iread_shared(__VA_ARGS__)) +#define MPI_File_iwrite_shared(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_iwrite_shared"), MPI_File_iwrite_shared(__VA_ARGS__)) +#define MPI_File_read_at_all_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_at_all_begin"), MPI_File_read_at_all_begin(__VA_ARGS__)) +#define MPI_File_read_at_all_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_at_all_end"), MPI_File_read_at_all_end(__VA_ARGS__)) +#define MPI_File_write_at_all_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_at_all_begin"), MPI_File_write_at_all_begin(__VA_ARGS__)) +#define MPI_File_write_at_all_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_at_all_end"), MPI_File_write_at_all_end(__VA_ARGS__)) +#define MPI_File_read_all_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_all_begin"), MPI_File_read_all_begin(__VA_ARGS__)) +#define MPI_File_read_all_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_all_end"), MPI_File_read_all_end(__VA_ARGS__)) +#define MPI_File_write_all_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_all_begin"), MPI_File_write_all_begin(__VA_ARGS__)) +#define MPI_File_write_all_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_all_end"), MPI_File_write_all_end(__VA_ARGS__)) +#define MPI_File_read_ordered_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_ordered_begin"), MPI_File_read_ordered_begin(__VA_ARGS__)) +#define MPI_File_read_ordered_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_read_ordered_end"), MPI_File_read_ordered_end(__VA_ARGS__)) +#define MPI_File_write_ordered_begin(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_ordered_begin"), MPI_File_write_ordered_begin(__VA_ARGS__)) +#define MPI_File_write_ordered_end(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_write_ordered_end"), MPI_File_write_ordered_end(__VA_ARGS__)) +#define MPI_File_get_type_extent(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_type_extent"), MPI_File_get_type_extent(__VA_ARGS__)) +#define MPI_File_set_atomicity(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_set_atomicity"), MPI_File_set_atomicity(__VA_ARGS__)) +#define MPI_File_get_atomicity(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_File_get_atomicity"), MPI_File_get_atomicity(__VA_ARGS__)) +#define MPI_Message_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Message_f2c"), MPI_Message_f2c(__VA_ARGS__)) +#define MPI_Message_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Message_c2f"), MPI_Message_c2f(__VA_ARGS__)) +#define MPI_Mrecv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Mrecv"), MPI_Mrecv(__VA_ARGS__)) +#define MPI_Mprobe(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Mprobe"), MPI_Mprobe(__VA_ARGS__)) +#define MPI_Imrecv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Imrecv"), MPI_Imrecv(__VA_ARGS__)) +#define MPI_Improbe(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Improbe"), MPI_Improbe(__VA_ARGS__)) +#define MPI_Neighbor_allgather(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Neighbor_allgather"), MPI_Neighbor_allgather(__VA_ARGS__)) +#define MPI_Neighbor_allgatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Neighbor_allgatherv"), MPI_Neighbor_allgatherv(__VA_ARGS__)) +#define MPI_Neighbor_alltoall(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Neighbor_alltoall"), MPI_Neighbor_alltoall(__VA_ARGS__)) +#define MPI_Neighbor_alltoallv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Neighbor_alltoallv"), MPI_Neighbor_alltoallv(__VA_ARGS__)) +#define MPI_Neighbor_alltoallw(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Neighbor_alltoallw"), MPI_Neighbor_alltoallw(__VA_ARGS__)) +#define MPI_Ineighbor_allgather(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ineighbor_allgather"), MPI_Ineighbor_allgather(__VA_ARGS__)) +#define MPI_Ineighbor_allgatherv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ineighbor_allgatherv"), MPI_Ineighbor_allgatherv(__VA_ARGS__)) +#define MPI_Ineighbor_alltoall(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ineighbor_alltoall"), MPI_Ineighbor_alltoall(__VA_ARGS__)) +#define MPI_Ineighbor_alltoallv(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ineighbor_alltoallv"), MPI_Ineighbor_alltoallv(__VA_ARGS__)) +#define MPI_Ineighbor_alltoallw(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Ineighbor_alltoallw"), MPI_Ineighbor_alltoallw(__VA_ARGS__)) +#define MPI_Status_f2c(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Status_f2c"), MPI_Status_f2c(__VA_ARGS__)) +#define MPI_Status_c2f(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Status_c2f"), MPI_Status_c2f(__VA_ARGS__)) +#define MPI_Parrived(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Parrived"), MPI_Parrived(__VA_ARGS__)) +#define MPI_Pready(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pready"), MPI_Pready(__VA_ARGS__)) +#define MPI_Pready_range(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pready_range"), MPI_Pready_range(__VA_ARGS__)) +#define MPI_Pready_list(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Pready_list"), MPI_Pready_list(__VA_ARGS__)) +#define MPI_Precv_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Precv_init"), MPI_Precv_init(__VA_ARGS__)) +#define MPI_Psend_init(...) (smpi_trace_set_call_location(__FILE__, __LINE__, "MPI_Psend_init"), MPI_Psend_init(__VA_ARGS__)) diff --git a/include/smpi/smpi_extended_traces_fortran.h b/include/smpi/smpi_extended_traces_fortran.h index d35a42ba39..4e114f08c2 100644 --- a/include/smpi/smpi_extended_traces_fortran.h +++ b/include/smpi/smpi_extended_traces_fortran.h @@ -1,4 +1,4 @@ -! Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. +! Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. ! This program is free software; you can redistribute it and/or modify it ! under the terms of the license (GNU LGPL) which comes with this package. @@ -7,777 +7,793 @@ ! in tools/smpi/generate_smpi_defines.pl ! DO NOT EDIT MANUALLY. ALL CHANGES WILL BE OVERWRITTEN! -#define mpi_init smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Init -#define MPI_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Init -#define mpi_finalize smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Finalize -#define MPI_FINALIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Finalize -#define mpi_finalized smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Finalized -#define MPI_FINALIZED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Finalized -#define mpi_init_thread smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Init_thread -#define MPI_INIT_THREAD smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Init_thread -#define mpi_initialized smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Initialized -#define MPI_INITIALIZED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Initialized -#define mpi_query_thread smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Query_thread -#define MPI_QUERY_THREAD smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Query_thread -#define mpi_is_thread_main smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Is_thread_main -#define MPI_IS_THREAD_MAIN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Is_thread_main -#define mpi_get_version smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_version -#define MPI_GET_VERSION smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_version -#define mpi_get_library_version smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_library_version -#define MPI_GET_LIBRARY_VERSION smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_library_version -#define mpi_get_processor_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_processor_name -#define MPI_GET_PROCESSOR_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_processor_name -#define mpi_abort smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Abort -#define MPI_ABORT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Abort -#define mpi_alloc_mem smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Alloc_mem -#define MPI_ALLOC_MEM smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Alloc_mem -#define mpi_free_mem smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Free_mem -#define MPI_FREE_MEM smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Free_mem -#define mpi_wtime smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Wtime -#define MPI_WTIME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Wtime -#define mpi_wtick smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Wtick -#define MPI_WTICK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Wtick -#define mpi_buffer_attach smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_attach -#define MPI_BUFFER_ATTACH smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_attach -#define mpi_buffer_detach smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_detach -#define MPI_BUFFER_DETACH smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_detach -#define mpi_address smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Address -#define MPI_ADDRESS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Address -#define mpi_get_address smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_address -#define MPI_GET_ADDRESS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_address -#define mpi_aint_diff smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Aint_diff -#define MPI_AINT_DIFF smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Aint_diff -#define mpi_aint_add smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Aint_add -#define MPI_AINT_ADD smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Aint_add -#define mpi_error_class smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_class -#define MPI_ERROR_CLASS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_class -#define mpi_error_string smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_string -#define MPI_ERROR_STRING smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_string -#define mpi_attr_delete smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Attr_delete -#define MPI_ATTR_DELETE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Attr_delete -#define mpi_attr_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Attr_get -#define MPI_ATTR_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Attr_get -#define mpi_attr_put smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Attr_put -#define MPI_ATTR_PUT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Attr_put -#define mpi_keyval_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Keyval_create -#define MPI_KEYVAL_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Keyval_create -#define mpi_keyval_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Keyval_free -#define MPI_KEYVAL_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Keyval_free -#define mpi_type_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_free -#define MPI_TYPE_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_free -#define mpi_type_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_size -#define MPI_TYPE_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_size -#define mpi_type_size_x smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_size_x -#define MPI_TYPE_SIZE_X smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_size_x -#define mpi_type_get_extent smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_extent -#define MPI_TYPE_GET_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_extent -#define mpi_type_get_extent_x smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_extent_x -#define MPI_TYPE_GET_EXTENT_X smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_extent_x -#define mpi_type_get_true_extent smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_true_extent -#define MPI_TYPE_GET_TRUE_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_true_extent -#define mpi_type_get_true_extent_x smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_true_extent_x -#define MPI_TYPE_GET_TRUE_EXTENT_X smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_true_extent_x -#define mpi_type_extent smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_extent -#define MPI_TYPE_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_extent -#define mpi_type_lb smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_lb -#define MPI_TYPE_LB smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_lb -#define mpi_type_ub smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_ub -#define MPI_TYPE_UB smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_ub -#define mpi_type_commit smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_commit -#define MPI_TYPE_COMMIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_commit -#define mpi_type_hindexed smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_hindexed -#define MPI_TYPE_HINDEXED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_hindexed -#define mpi_type_create_hindexed smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_hindexed -#define MPI_TYPE_CREATE_HINDEXED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_hindexed -#define mpi_type_create_hindexed_block smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_hindexed_block -#define MPI_TYPE_CREATE_HINDEXED_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_hindexed_block -#define mpi_type_hvector smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_hvector -#define MPI_TYPE_HVECTOR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_hvector -#define mpi_type_create_hvector smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_hvector -#define MPI_TYPE_CREATE_HVECTOR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_hvector -#define mpi_type_indexed smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_indexed -#define MPI_TYPE_INDEXED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_indexed -#define mpi_type_create_indexed smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_indexed -#define MPI_TYPE_CREATE_INDEXED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_indexed -#define mpi_type_create_indexed_block smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_indexed_block -#define MPI_TYPE_CREATE_INDEXED_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_indexed_block -#define mpi_type_struct smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_struct -#define MPI_TYPE_STRUCT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_struct -#define mpi_type_create_struct smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_struct -#define MPI_TYPE_CREATE_STRUCT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_struct -#define mpi_type_vector smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_vector -#define MPI_TYPE_VECTOR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_vector -#define mpi_type_contiguous smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_contiguous -#define MPI_TYPE_CONTIGUOUS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_contiguous -#define mpi_type_create_resized smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_resized -#define MPI_TYPE_CREATE_RESIZED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_resized -#define mpi_type_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_f2c -#define MPI_TYPE_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_f2c -#define mpi_type_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_c2f -#define MPI_TYPE_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_c2f -#define mpi_get_count smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_count -#define MPI_GET_COUNT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_count -#define mpi_type_get_attr smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_attr -#define MPI_TYPE_GET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_attr -#define mpi_type_set_attr smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_set_attr -#define MPI_TYPE_SET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_set_attr -#define mpi_type_delete_attr smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_delete_attr -#define MPI_TYPE_DELETE_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_delete_attr -#define mpi_type_create_keyval smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_keyval -#define MPI_TYPE_CREATE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_keyval -#define mpi_type_free_keyval smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_free_keyval -#define MPI_TYPE_FREE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_free_keyval -#define mpi_type_dup smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_dup -#define MPI_TYPE_DUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_dup -#define mpi_type_set_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_set_name -#define MPI_TYPE_SET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_set_name -#define mpi_type_get_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_name -#define MPI_TYPE_GET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_name -#define mpi_pack smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pack -#define MPI_PACK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pack -#define mpi_pack_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pack_size -#define MPI_PACK_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pack_size -#define mpi_unpack smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Unpack -#define MPI_UNPACK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Unpack -#define mpi_op_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_create -#define MPI_OP_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_create -#define mpi_op_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_free -#define MPI_OP_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_free -#define mpi_op_commutative smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_commutative -#define MPI_OP_COMMUTATIVE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_commutative -#define mpi_op_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_f2c -#define MPI_OP_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_f2c -#define mpi_op_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_c2f -#define MPI_OP_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Op_c2f -#define mpi_group_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_free -#define MPI_GROUP_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_free -#define mpi_group_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_size -#define MPI_GROUP_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_size -#define mpi_group_rank smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_rank -#define MPI_GROUP_RANK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_rank -#define mpi_group_translate_ranks smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_translate_ranks -#define MPI_GROUP_TRANSLATE_RANKS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_translate_ranks -#define mpi_group_compare smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_compare -#define MPI_GROUP_COMPARE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_compare -#define mpi_group_union smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_union -#define MPI_GROUP_UNION smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_union -#define mpi_group_intersection smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_intersection -#define MPI_GROUP_INTERSECTION smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_intersection -#define mpi_group_difference smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_difference -#define MPI_GROUP_DIFFERENCE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_difference -#define mpi_group_incl smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_incl -#define MPI_GROUP_INCL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_incl -#define mpi_group_excl smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_excl -#define MPI_GROUP_EXCL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_excl -#define mpi_group_range_incl smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_range_incl -#define MPI_GROUP_RANGE_INCL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_range_incl -#define mpi_group_range_excl smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_range_excl -#define MPI_GROUP_RANGE_EXCL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_range_excl -#define mpi_group_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_f2c -#define MPI_GROUP_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_f2c -#define mpi_group_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_c2f -#define MPI_GROUP_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Group_c2f -#define mpi_comm_rank smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_rank -#define MPI_COMM_RANK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_rank -#define mpi_comm_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_size -#define MPI_COMM_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_size -#define mpi_comm_get_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_name -#define MPI_COMM_GET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_name -#define mpi_comm_set_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_name -#define MPI_COMM_SET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_name -#define mpi_comm_dup smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_dup -#define MPI_COMM_DUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_dup -#define mpi_comm_dup_with_info smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_dup_with_info -#define MPI_COMM_DUP_WITH_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_dup_with_info -#define mpi_comm_get_attr smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_attr -#define MPI_COMM_GET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_attr -#define mpi_comm_set_attr smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_attr -#define MPI_COMM_SET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_attr -#define mpi_comm_delete_attr smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_delete_attr -#define MPI_COMM_DELETE_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_delete_attr -#define mpi_comm_create_keyval smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_keyval -#define MPI_COMM_CREATE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_keyval -#define mpi_comm_free_keyval smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_free_keyval -#define MPI_COMM_FREE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_free_keyval -#define mpi_comm_group smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_group -#define MPI_COMM_GROUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_group -#define mpi_comm_compare smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_compare -#define MPI_COMM_COMPARE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_compare -#define mpi_comm_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create -#define MPI_COMM_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create -#define mpi_comm_create_group smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_group -#define MPI_COMM_CREATE_GROUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_group -#define mpi_comm_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_free -#define MPI_COMM_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_free -#define mpi_comm_disconnect smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_disconnect -#define MPI_COMM_DISCONNECT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_disconnect -#define mpi_comm_split smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_split -#define MPI_COMM_SPLIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_split -#define mpi_comm_set_info smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_info -#define MPI_COMM_SET_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_info -#define mpi_comm_get_info smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_info -#define MPI_COMM_GET_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_info -#define mpi_comm_split_type smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_split_type -#define MPI_COMM_SPLIT_TYPE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_split_type -#define mpi_comm_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_f2c -#define MPI_COMM_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_f2c -#define mpi_comm_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_c2f -#define MPI_COMM_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_c2f -#define mpi_start smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Start -#define MPI_START smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Start -#define mpi_startall smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Startall -#define MPI_STARTALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Startall -#define mpi_request_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Request_free -#define MPI_REQUEST_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Request_free -#define mpi_recv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Recv -#define MPI_RECV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Recv -#define mpi_recv_init smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Recv_init -#define MPI_RECV_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Recv_init -#define mpi_irecv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Irecv -#define MPI_IRECV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Irecv -#define mpi_send smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Send -#define MPI_SEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Send -#define mpi_send_init smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Send_init -#define MPI_SEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Send_init -#define mpi_isend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Isend -#define MPI_ISEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Isend -#define mpi_ssend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ssend -#define MPI_SSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ssend -#define mpi_ssend_init smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ssend_init -#define MPI_SSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ssend_init -#define mpi_issend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Issend -#define MPI_ISSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Issend -#define mpi_bsend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend -#define MPI_BSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend -#define mpi_bsend_init smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend_init -#define MPI_BSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend_init -#define mpi_ibsend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibsend -#define MPI_IBSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibsend -#define mpi_rsend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rsend -#define MPI_RSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rsend -#define mpi_rsend_init smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rsend_init -#define MPI_RSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rsend_init -#define mpi_irsend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Irsend -#define MPI_IRSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Irsend -#define mpi_sendrecv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Sendrecv -#define MPI_SENDRECV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Sendrecv -#define mpi_sendrecv_replace smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Sendrecv_replace -#define MPI_SENDRECV_REPLACE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Sendrecv_replace -#define mpi_test smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Test -#define MPI_TEST smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Test -#define mpi_testany smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Testany -#define MPI_TESTANY smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Testany -#define mpi_testall smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Testall -#define MPI_TESTALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Testall -#define mpi_testsome smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Testsome -#define MPI_TESTSOME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Testsome -#define mpi_test_cancelled smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Test_cancelled -#define MPI_TEST_CANCELLED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Test_cancelled -#define mpi_wait smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Wait -#define MPI_WAIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Wait -#define mpi_waitany smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Waitany -#define MPI_WAITANY smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Waitany -#define mpi_waitall smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Waitall -#define MPI_WAITALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Waitall -#define mpi_waitsome smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Waitsome -#define MPI_WAITSOME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Waitsome -#define mpi_iprobe smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iprobe -#define MPI_IPROBE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iprobe -#define mpi_probe smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Probe -#define MPI_PROBE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Probe -#define mpi_request_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Request_f2c -#define MPI_REQUEST_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Request_f2c -#define mpi_request_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Request_c2f -#define MPI_REQUEST_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Request_c2f -#define mpi_cancel smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cancel -#define MPI_CANCEL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cancel -#define mpi_bcast smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bcast -#define MPI_BCAST smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bcast -#define mpi_barrier smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Barrier -#define MPI_BARRIER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Barrier -#define mpi_ibarrier smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibarrier -#define MPI_IBARRIER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibarrier -#define mpi_ibcast smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibcast -#define MPI_IBCAST smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibcast -#define mpi_igather smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Igather -#define MPI_IGATHER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Igather -#define mpi_igatherv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Igatherv -#define MPI_IGATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Igatherv -#define mpi_iallgather smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallgather -#define MPI_IALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallgather -#define mpi_iallgatherv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallgatherv -#define MPI_IALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallgatherv -#define mpi_iscatter smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscatter -#define MPI_ISCATTER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscatter -#define mpi_iscatterv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscatterv -#define MPI_ISCATTERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscatterv -#define mpi_ireduce smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce -#define MPI_IREDUCE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce -#define mpi_iallreduce smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallreduce -#define MPI_IALLREDUCE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallreduce -#define mpi_iscan smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscan -#define MPI_ISCAN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscan -#define mpi_iexscan smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iexscan -#define MPI_IEXSCAN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iexscan -#define mpi_ireduce_scatter smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce_scatter -#define MPI_IREDUCE_SCATTER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce_scatter -#define mpi_ireduce_scatter_block smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce_scatter_block -#define MPI_IREDUCE_SCATTER_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce_scatter_block -#define mpi_ialltoall smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoall -#define MPI_IALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoall -#define mpi_ialltoallv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoallv -#define MPI_IALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoallv -#define mpi_ialltoallw smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoallw -#define MPI_IALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoallw -#define mpi_gather smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Gather -#define MPI_GATHER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Gather -#define mpi_gatherv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Gatherv -#define MPI_GATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Gatherv -#define mpi_allgather smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Allgather -#define MPI_ALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Allgather -#define mpi_allgatherv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Allgatherv -#define MPI_ALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Allgatherv -#define mpi_scatter smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Scatter -#define MPI_SCATTER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Scatter -#define mpi_scatterv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Scatterv -#define MPI_SCATTERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Scatterv -#define mpi_reduce smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Reduce -#define MPI_REDUCE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Reduce -#define mpi_allreduce smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Allreduce -#define MPI_ALLREDUCE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Allreduce -#define mpi_scan smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Scan -#define MPI_SCAN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Scan -#define mpi_exscan smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Exscan -#define MPI_EXSCAN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Exscan -#define mpi_reduce_scatter smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Reduce_scatter -#define MPI_REDUCE_SCATTER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Reduce_scatter -#define mpi_reduce_scatter_block smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Reduce_scatter_block -#define MPI_REDUCE_SCATTER_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Reduce_scatter_block -#define mpi_alltoall smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Alltoall -#define MPI_ALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Alltoall -#define mpi_alltoallv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Alltoallv -#define MPI_ALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Alltoallv -#define mpi_alltoallw smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Alltoallw -#define MPI_ALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Alltoallw -#define mpi_reduce_local smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Reduce_local -#define MPI_REDUCE_LOCAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Reduce_local -#define mpi_info_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_create -#define MPI_INFO_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_create -#define mpi_info_set smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_set -#define MPI_INFO_SET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_set -#define mpi_info_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_get -#define MPI_INFO_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_get -#define mpi_info_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_free -#define MPI_INFO_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_free -#define mpi_info_delete smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_delete -#define MPI_INFO_DELETE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_delete -#define mpi_info_dup smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_dup -#define MPI_INFO_DUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_dup -#define mpi_info_get_nkeys smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_get_nkeys -#define MPI_INFO_GET_NKEYS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_get_nkeys -#define mpi_info_get_nthkey smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_get_nthkey -#define MPI_INFO_GET_NTHKEY smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_get_nthkey -#define mpi_info_get_valuelen smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_get_valuelen -#define MPI_INFO_GET_VALUELEN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_get_valuelen -#define mpi_info_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_f2c -#define MPI_INFO_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_f2c -#define mpi_info_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_c2f -#define MPI_INFO_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Info_c2f -#define mpi_win_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_free -#define MPI_WIN_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_free -#define mpi_win_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create -#define MPI_WIN_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create -#define mpi_win_allocate smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_allocate -#define MPI_WIN_ALLOCATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_allocate -#define mpi_win_allocate_shared smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_allocate_shared -#define MPI_WIN_ALLOCATE_SHARED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_allocate_shared -#define mpi_win_create_dynamic smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_dynamic -#define MPI_WIN_CREATE_DYNAMIC smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_dynamic -#define mpi_win_attach smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_attach -#define MPI_WIN_ATTACH smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_attach -#define mpi_win_detach smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_detach -#define MPI_WIN_DETACH smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_detach -#define mpi_win_set_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_name -#define MPI_WIN_SET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_name -#define mpi_win_get_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_name -#define MPI_WIN_GET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_name -#define mpi_win_set_info smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_info -#define MPI_WIN_SET_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_info -#define mpi_win_get_info smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_info -#define MPI_WIN_GET_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_info -#define mpi_win_get_group smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_group -#define MPI_WIN_GET_GROUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_group -#define mpi_win_fence smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_fence -#define MPI_WIN_FENCE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_fence -#define mpi_win_get_attr smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_attr -#define MPI_WIN_GET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_attr -#define mpi_win_set_attr smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_attr -#define MPI_WIN_SET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_attr -#define mpi_win_delete_attr smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_delete_attr -#define MPI_WIN_DELETE_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_delete_attr -#define mpi_win_create_keyval smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_keyval -#define MPI_WIN_CREATE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_keyval -#define mpi_win_free_keyval smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_free_keyval -#define MPI_WIN_FREE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_free_keyval -#define mpi_win_complete smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_complete -#define MPI_WIN_COMPLETE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_complete -#define mpi_win_post smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_post -#define MPI_WIN_POST smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_post -#define mpi_win_start smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_start -#define MPI_WIN_START smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_start -#define mpi_win_wait smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_wait -#define MPI_WIN_WAIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_wait -#define mpi_win_lock smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_lock -#define MPI_WIN_LOCK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_lock -#define mpi_win_lock_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_lock_all -#define MPI_WIN_LOCK_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_lock_all -#define mpi_win_unlock smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_unlock -#define MPI_WIN_UNLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_unlock -#define mpi_win_unlock_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_unlock_all -#define MPI_WIN_UNLOCK_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_unlock_all -#define mpi_win_flush smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_flush -#define MPI_WIN_FLUSH smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_flush -#define mpi_win_flush_local smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_flush_local -#define MPI_WIN_FLUSH_LOCAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_flush_local -#define mpi_win_flush_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_flush_all -#define MPI_WIN_FLUSH_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_flush_all -#define mpi_win_flush_local_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_flush_local_all -#define MPI_WIN_FLUSH_LOCAL_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_flush_local_all -#define mpi_win_shared_query smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_shared_query -#define MPI_WIN_SHARED_QUERY smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_shared_query -#define mpi_win_sync smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_sync -#define MPI_WIN_SYNC smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_sync -#define mpi_win_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_f2c -#define MPI_WIN_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_f2c -#define mpi_win_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_c2f -#define MPI_WIN_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_c2f -#define mpi_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get -#define MPI_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get -#define mpi_put smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Put -#define MPI_PUT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Put -#define mpi_accumulate smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Accumulate -#define MPI_ACCUMULATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Accumulate -#define mpi_get_accumulate smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_accumulate -#define MPI_GET_ACCUMULATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_accumulate -#define mpi_rget smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rget -#define MPI_RGET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rget -#define mpi_rput smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rput -#define MPI_RPUT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rput -#define mpi_raccumulate smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Raccumulate -#define MPI_RACCUMULATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Raccumulate -#define mpi_rget_accumulate smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rget_accumulate -#define MPI_RGET_ACCUMULATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Rget_accumulate -#define mpi_fetch_and_op smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Fetch_and_op -#define MPI_FETCH_AND_OP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Fetch_and_op -#define mpi_compare_and_swap smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Compare_and_swap -#define MPI_COMPARE_AND_SWAP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Compare_and_swap -#define mpi_cart_coords smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_coords -#define MPI_CART_COORDS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_coords -#define mpi_cart_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_create -#define MPI_CART_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_create -#define mpi_cart_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_get -#define MPI_CART_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_get -#define mpi_cart_rank smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_rank -#define MPI_CART_RANK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_rank -#define mpi_cart_shift smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_shift -#define MPI_CART_SHIFT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_shift -#define mpi_cart_sub smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_sub -#define MPI_CART_SUB smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_sub -#define mpi_cartdim_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cartdim_get -#define MPI_CARTDIM_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cartdim_get -#define mpi_dims_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dims_create -#define MPI_DIMS_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dims_create -#define mpi_request_get_status smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Request_get_status -#define MPI_REQUEST_GET_STATUS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Request_get_status -#define mpi_grequest_start smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Grequest_start -#define MPI_GREQUEST_START smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Grequest_start -#define mpi_grequest_complete smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Grequest_complete -#define MPI_GREQUEST_COMPLETE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Grequest_complete -#define mpi_status_set_cancelled smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_set_cancelled -#define MPI_STATUS_SET_CANCELLED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_set_cancelled -#define mpi_status_set_elements smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_set_elements -#define MPI_STATUS_SET_ELEMENTS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_set_elements -#define mpi_status_set_elements_x smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_set_elements_x -#define MPI_STATUS_SET_ELEMENTS_X smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_set_elements_x -#define mpi_type_create_subarray smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_subarray -#define MPI_TYPE_CREATE_SUBARRAY smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_subarray -#define mpi_file_open smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_open -#define MPI_FILE_OPEN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_open -#define mpi_file_close smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_close -#define MPI_FILE_CLOSE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_close -#define mpi_file_delete smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_delete -#define MPI_FILE_DELETE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_delete -#define mpi_file_get_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_size -#define MPI_FILE_GET_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_size -#define mpi_file_get_group smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_group -#define MPI_FILE_GET_GROUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_group -#define mpi_file_get_amode smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_amode -#define MPI_FILE_GET_AMODE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_amode -#define mpi_file_set_info smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_info -#define MPI_FILE_SET_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_info -#define mpi_file_get_info smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_info -#define MPI_FILE_GET_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_info -#define mpi_file_read_at smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_at -#define MPI_FILE_READ_AT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_at -#define mpi_file_read_at_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_at_all -#define MPI_FILE_READ_AT_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_at_all -#define mpi_file_write_at smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_at -#define MPI_FILE_WRITE_AT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_at -#define mpi_file_write_at_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_at_all -#define MPI_FILE_WRITE_AT_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_at_all -#define mpi_file_read smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read -#define MPI_FILE_READ smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read -#define mpi_file_read_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_all -#define MPI_FILE_READ_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_all -#define mpi_file_write smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write -#define MPI_FILE_WRITE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write -#define mpi_file_write_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_all -#define MPI_FILE_WRITE_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_all -#define mpi_file_seek smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_seek -#define MPI_FILE_SEEK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_seek -#define mpi_file_get_position smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_position -#define MPI_FILE_GET_POSITION smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_position -#define mpi_file_read_shared smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_shared -#define MPI_FILE_READ_SHARED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_shared -#define mpi_file_write_shared smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_shared -#define MPI_FILE_WRITE_SHARED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_shared -#define mpi_file_read_ordered smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_ordered -#define MPI_FILE_READ_ORDERED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_ordered -#define mpi_file_write_ordered smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_ordered -#define MPI_FILE_WRITE_ORDERED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_ordered -#define mpi_file_seek_shared smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_seek_shared -#define MPI_FILE_SEEK_SHARED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_seek_shared -#define mpi_file_get_position_shared smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_position_shared -#define MPI_FILE_GET_POSITION_SHARED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_position_shared -#define mpi_file_sync smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_sync -#define MPI_FILE_SYNC smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_sync -#define mpi_file_set_view smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_view -#define MPI_FILE_SET_VIEW smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_view -#define mpi_file_get_view smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_view -#define MPI_FILE_GET_VIEW smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_view -#define mpi_errhandler_set smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_set -#define MPI_ERRHANDLER_SET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_set -#define mpi_errhandler_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_create -#define MPI_ERRHANDLER_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_create -#define mpi_errhandler_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_free -#define MPI_ERRHANDLER_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_free -#define mpi_errhandler_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_get -#define MPI_ERRHANDLER_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_get -#define mpi_comm_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_errhandler -#define MPI_COMM_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_errhandler -#define mpi_comm_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_errhandler -#define MPI_COMM_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_errhandler -#define mpi_comm_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_errhandler -#define MPI_COMM_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_errhandler -#define mpi_comm_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_call_errhandler -#define MPI_COMM_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_call_errhandler -#define mpi_win_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_errhandler -#define MPI_WIN_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_errhandler -#define mpi_win_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_errhandler -#define MPI_WIN_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_errhandler -#define mpi_win_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_errhandler -#define MPI_WIN_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_errhandler -#define mpi_win_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_call_errhandler -#define MPI_WIN_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_call_errhandler -#define mpi_errhandler_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_f2c -#define MPI_ERRHANDLER_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_f2c -#define mpi_errhandler_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_c2f -#define MPI_ERRHANDLER_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_c2f -#define mpi_type_create_f90_integer smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_f90_integer -#define MPI_TYPE_CREATE_F90_INTEGER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_f90_integer -#define mpi_type_create_f90_real smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_f90_real -#define MPI_TYPE_CREATE_F90_REAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_f90_real -#define mpi_type_create_f90_complex smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_f90_complex -#define MPI_TYPE_CREATE_F90_COMPLEX smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_f90_complex -#define mpi_type_get_contents smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_contents -#define MPI_TYPE_GET_CONTENTS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_contents -#define mpi_type_get_envelope smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_envelope -#define MPI_TYPE_GET_ENVELOPE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_envelope -#define mpi_file_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_call_errhandler -#define MPI_FILE_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_call_errhandler -#define mpi_file_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_create_errhandler -#define MPI_FILE_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_create_errhandler -#define mpi_file_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_errhandler -#define MPI_FILE_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_errhandler -#define mpi_file_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_errhandler -#define MPI_FILE_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_errhandler -#define mpi_cart_map smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_map -#define MPI_CART_MAP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cart_map -#define mpi_graph_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_create -#define MPI_GRAPH_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_create -#define mpi_graph_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_get -#define MPI_GRAPH_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_get -#define mpi_graph_map smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_map -#define MPI_GRAPH_MAP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_map -#define mpi_graph_neighbors smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_neighbors -#define MPI_GRAPH_NEIGHBORS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_neighbors -#define mpi_graph_neighbors_count smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_neighbors_count -#define MPI_GRAPH_NEIGHBORS_COUNT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graph_neighbors_count -#define mpi_graphdims_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graphdims_get -#define MPI_GRAPHDIMS_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graphdims_get -#define mpi_topo_test smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Topo_test -#define MPI_TOPO_TEST smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Topo_test -#define mpi_add_error_class smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_class -#define MPI_ADD_ERROR_CLASS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_class -#define mpi_add_error_code smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_code -#define MPI_ADD_ERROR_CODE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_code -#define mpi_add_error_string smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_string -#define MPI_ADD_ERROR_STRING smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_string -#define mpi_comm_test_inter smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_test_inter -#define MPI_COMM_TEST_INTER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_test_inter -#define mpi_intercomm_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Intercomm_create -#define MPI_INTERCOMM_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Intercomm_create -#define mpi_intercomm_merge smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Intercomm_merge -#define MPI_INTERCOMM_MERGE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Intercomm_merge -#define mpi_comm_remote_group smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_remote_group -#define MPI_COMM_REMOTE_GROUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_remote_group -#define mpi_comm_remote_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_remote_size -#define MPI_COMM_REMOTE_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_remote_size -#define mpi_get_elements smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_elements -#define MPI_GET_ELEMENTS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_elements -#define mpi_get_elements_x smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_elements_x -#define MPI_GET_ELEMENTS_X smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_elements_x -#define mpi_pcontrol smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pcontrol -#define MPI_PCONTROL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pcontrol -#define mpi_type_create_darray smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_darray -#define MPI_TYPE_CREATE_DARRAY smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_darray -#define mpi_pack_external_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pack_external_size -#define MPI_PACK_EXTERNAL_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pack_external_size -#define mpi_pack_external smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pack_external -#define MPI_PACK_EXTERNAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pack_external -#define mpi_unpack_external smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Unpack_external -#define MPI_UNPACK_EXTERNAL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Unpack_external -#define mpi_type_match_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_match_size -#define MPI_TYPE_MATCH_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_match_size -#define mpi_comm_connect smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_connect -#define MPI_COMM_CONNECT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_connect -#define mpi_unpublish_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Unpublish_name -#define MPI_UNPUBLISH_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Unpublish_name -#define mpi_publish_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Publish_name -#define MPI_PUBLISH_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Publish_name -#define mpi_lookup_name smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Lookup_name -#define MPI_LOOKUP_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Lookup_name -#define mpi_comm_idup smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_idup -#define MPI_COMM_IDUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_idup -#define mpi_comm_join smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_join -#define MPI_COMM_JOIN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_join -#define mpi_open_port smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Open_port -#define MPI_OPEN_PORT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Open_port -#define mpi_close_port smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Close_port -#define MPI_CLOSE_PORT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Close_port -#define mpi_comm_accept smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_accept -#define MPI_COMM_ACCEPT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_accept -#define mpi_comm_spawn smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_spawn -#define MPI_COMM_SPAWN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_spawn -#define mpi_comm_spawn_multiple smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_spawn_multiple -#define MPI_COMM_SPAWN_MULTIPLE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_spawn_multiple -#define mpi_comm_get_parent smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_parent -#define MPI_COMM_GET_PARENT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_parent -#define mpi_dist_graph_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dist_graph_create -#define MPI_DIST_GRAPH_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dist_graph_create -#define mpi_dist_graph_create_adjacent smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dist_graph_create_adjacent -#define MPI_DIST_GRAPH_CREATE_ADJACENT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dist_graph_create_adjacent -#define mpi_dist_graph_neighbors smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dist_graph_neighbors -#define MPI_DIST_GRAPH_NEIGHBORS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dist_graph_neighbors -#define mpi_dist_graph_neighbors_count smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dist_graph_neighbors_count -#define MPI_DIST_GRAPH_NEIGHBORS_COUNT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Dist_graph_neighbors_count -#define mpi_win_test smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_test -#define MPI_WIN_TEST smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_test -#define mpi_file_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_c2f -#define MPI_FILE_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_c2f -#define mpi_file_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_f2c -#define MPI_FILE_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_f2c -#define mpi_register_datarep smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Register_datarep -#define MPI_REGISTER_DATAREP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Register_datarep -#define mpi_file_set_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_size -#define MPI_FILE_SET_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_size -#define mpi_file_preallocate smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_preallocate -#define MPI_FILE_PREALLOCATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_preallocate -#define mpi_file_iread_at smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread_at -#define MPI_FILE_IREAD_AT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread_at -#define mpi_file_iwrite_at smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite_at -#define MPI_FILE_IWRITE_AT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite_at -#define mpi_file_iread_at_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread_at_all -#define MPI_FILE_IREAD_AT_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread_at_all -#define mpi_file_iwrite_at_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite_at_all -#define MPI_FILE_IWRITE_AT_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite_at_all -#define mpi_file_iread smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread -#define MPI_FILE_IREAD smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread -#define mpi_file_iwrite smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite -#define MPI_FILE_IWRITE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite -#define mpi_file_iread_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread_all -#define MPI_FILE_IREAD_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread_all -#define mpi_file_iwrite_all smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite_all -#define MPI_FILE_IWRITE_ALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite_all -#define mpi_file_get_byte_offset smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_byte_offset -#define MPI_FILE_GET_BYTE_OFFSET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_byte_offset -#define mpi_file_iread_shared smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread_shared -#define MPI_FILE_IREAD_SHARED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iread_shared -#define mpi_file_iwrite_shared smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite_shared -#define MPI_FILE_IWRITE_SHARED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_iwrite_shared -#define mpi_file_read_at_all_begin smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_at_all_begin -#define MPI_FILE_READ_AT_ALL_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_at_all_begin -#define mpi_file_read_at_all_end smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_at_all_end -#define MPI_FILE_READ_AT_ALL_END smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_at_all_end -#define mpi_file_write_at_all_begin smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_at_all_begin -#define MPI_FILE_WRITE_AT_ALL_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_at_all_begin -#define mpi_file_write_at_all_end smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_at_all_end -#define MPI_FILE_WRITE_AT_ALL_END smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_at_all_end -#define mpi_file_read_all_begin smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_all_begin -#define MPI_FILE_READ_ALL_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_all_begin -#define mpi_file_read_all_end smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_all_end -#define MPI_FILE_READ_ALL_END smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_all_end -#define mpi_file_write_all_begin smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_all_begin -#define MPI_FILE_WRITE_ALL_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_all_begin -#define mpi_file_write_all_end smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_all_end -#define MPI_FILE_WRITE_ALL_END smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_all_end -#define mpi_file_read_ordered_begin smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_ordered_begin -#define MPI_FILE_READ_ORDERED_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_ordered_begin -#define mpi_file_read_ordered_end smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_ordered_end -#define MPI_FILE_READ_ORDERED_END smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_read_ordered_end -#define mpi_file_write_ordered_begin smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_ordered_begin -#define MPI_FILE_WRITE_ORDERED_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_ordered_begin -#define mpi_file_write_ordered_end smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_ordered_end -#define MPI_FILE_WRITE_ORDERED_END smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_write_ordered_end -#define mpi_file_get_type_extent smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_type_extent -#define MPI_FILE_GET_TYPE_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_type_extent -#define mpi_file_set_atomicity smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_atomicity -#define MPI_FILE_SET_ATOMICITY smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_atomicity -#define mpi_file_get_atomicity smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_atomicity -#define MPI_FILE_GET_ATOMICITY smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_atomicity -#define mpi_message_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Message_f2c -#define MPI_MESSAGE_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Message_f2c -#define mpi_message_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Message_c2f -#define MPI_MESSAGE_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Message_c2f -#define mpi_mrecv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Mrecv -#define MPI_MRECV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Mrecv -#define mpi_mprobe smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Mprobe -#define MPI_MPROBE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Mprobe -#define mpi_imrecv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Imrecv -#define MPI_IMRECV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Imrecv -#define mpi_improbe smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Improbe -#define MPI_IMPROBE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Improbe -#define mpi_neighbor_allgather smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_allgather -#define MPI_NEIGHBOR_ALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_allgather -#define mpi_neighbor_allgatherv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_allgatherv -#define MPI_NEIGHBOR_ALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_allgatherv -#define mpi_neighbor_alltoall smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_alltoall -#define MPI_NEIGHBOR_ALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_alltoall -#define mpi_neighbor_alltoallv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_alltoallv -#define MPI_NEIGHBOR_ALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_alltoallv -#define mpi_neighbor_alltoallw smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_alltoallw -#define MPI_NEIGHBOR_ALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Neighbor_alltoallw -#define mpi_ineighbor_allgather smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_allgather -#define MPI_INEIGHBOR_ALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_allgather -#define mpi_ineighbor_allgatherv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_allgatherv -#define MPI_INEIGHBOR_ALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_allgatherv -#define mpi_ineighbor_alltoall smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_alltoall -#define MPI_INEIGHBOR_ALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_alltoall -#define mpi_ineighbor_alltoallv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_alltoallv -#define MPI_INEIGHBOR_ALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_alltoallv -#define mpi_ineighbor_alltoallw smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_alltoallw -#define MPI_INEIGHBOR_ALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ineighbor_alltoallw -#define mpi_status_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_f2c -#define MPI_STATUS_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_f2c -#define mpi_status_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_c2f -#define MPI_STATUS_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Status_c2f +#define mpi_init smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_init"); call MPI_Init +#define MPI_INIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INIT"); call MPI_Init +#define mpi_finalize smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_finalize"); call MPI_Finalize +#define MPI_FINALIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FINALIZE"); call MPI_Finalize +#define mpi_finalized smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_finalized"); call MPI_Finalized +#define MPI_FINALIZED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FINALIZED"); call MPI_Finalized +#define mpi_init_thread smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_init_thread"); call MPI_Init_thread +#define MPI_INIT_THREAD smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INIT_THREAD"); call MPI_Init_thread +#define mpi_initialized smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_initialized"); call MPI_Initialized +#define MPI_INITIALIZED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INITIALIZED"); call MPI_Initialized +#define mpi_query_thread smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_query_thread"); call MPI_Query_thread +#define MPI_QUERY_THREAD smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_QUERY_THREAD"); call MPI_Query_thread +#define mpi_is_thread_main smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_is_thread_main"); call MPI_Is_thread_main +#define MPI_IS_THREAD_MAIN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IS_THREAD_MAIN"); call MPI_Is_thread_main +#define mpi_get_version smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_get_version"); call MPI_Get_version +#define MPI_GET_VERSION smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GET_VERSION"); call MPI_Get_version +#define mpi_get_library_version smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_get_library_version"); call MPI_Get_library_version +#define MPI_GET_LIBRARY_VERSION smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GET_LIBRARY_VERSION"); call MPI_Get_library_version +#define mpi_get_processor_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_get_processor_name"); call MPI_Get_processor_name +#define MPI_GET_PROCESSOR_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GET_PROCESSOR_NAME"); call MPI_Get_processor_name +#define mpi_abort smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_abort"); call MPI_Abort +#define MPI_ABORT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ABORT"); call MPI_Abort +#define mpi_alloc_mem smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_alloc_mem"); call MPI_Alloc_mem +#define MPI_ALLOC_MEM smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ALLOC_MEM"); call MPI_Alloc_mem +#define mpi_free_mem smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_free_mem"); call MPI_Free_mem +#define MPI_FREE_MEM smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FREE_MEM"); call MPI_Free_mem +#define mpi_wtime smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_wtime"); call MPI_Wtime +#define MPI_WTIME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WTIME"); call MPI_Wtime +#define mpi_wtick smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_wtick"); call MPI_Wtick +#define MPI_WTICK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WTICK"); call MPI_Wtick +#define mpi_buffer_attach smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_buffer_attach"); call MPI_Buffer_attach +#define MPI_BUFFER_ATTACH smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_BUFFER_ATTACH"); call MPI_Buffer_attach +#define mpi_buffer_detach smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_buffer_detach"); call MPI_Buffer_detach +#define MPI_BUFFER_DETACH smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_BUFFER_DETACH"); call MPI_Buffer_detach +#define mpi_address smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_address"); call MPI_Address +#define MPI_ADDRESS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ADDRESS"); call MPI_Address +#define mpi_get_address smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_get_address"); call MPI_Get_address +#define MPI_GET_ADDRESS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GET_ADDRESS"); call MPI_Get_address +#define mpi_aint_diff smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_aint_diff"); call MPI_Aint_diff +#define MPI_AINT_DIFF smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_AINT_DIFF"); call MPI_Aint_diff +#define mpi_aint_add smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_aint_add"); call MPI_Aint_add +#define MPI_AINT_ADD smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_AINT_ADD"); call MPI_Aint_add +#define mpi_error_class smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_error_class"); call MPI_Error_class +#define MPI_ERROR_CLASS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ERROR_CLASS"); call MPI_Error_class +#define mpi_error_string smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_error_string"); call MPI_Error_string +#define MPI_ERROR_STRING smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ERROR_STRING"); call MPI_Error_string +#define mpi_attr_delete smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_attr_delete"); call MPI_Attr_delete +#define MPI_ATTR_DELETE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ATTR_DELETE"); call MPI_Attr_delete +#define mpi_attr_get smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_attr_get"); call MPI_Attr_get +#define MPI_ATTR_GET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ATTR_GET"); call MPI_Attr_get +#define mpi_attr_put smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_attr_put"); call MPI_Attr_put +#define MPI_ATTR_PUT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ATTR_PUT"); call MPI_Attr_put +#define mpi_keyval_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_keyval_create"); call MPI_Keyval_create +#define MPI_KEYVAL_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_KEYVAL_CREATE"); call MPI_Keyval_create +#define mpi_keyval_free smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_keyval_free"); call MPI_Keyval_free +#define MPI_KEYVAL_FREE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_KEYVAL_FREE"); call MPI_Keyval_free +#define mpi_type_free smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_free"); call MPI_Type_free +#define MPI_TYPE_FREE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_FREE"); call MPI_Type_free +#define mpi_type_size smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_size"); call MPI_Type_size +#define MPI_TYPE_SIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_SIZE"); call MPI_Type_size +#define mpi_type_size_x smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_size_x"); call MPI_Type_size_x +#define MPI_TYPE_SIZE_X smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_SIZE_X"); call MPI_Type_size_x +#define mpi_type_get_extent smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_get_extent"); call MPI_Type_get_extent +#define MPI_TYPE_GET_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_GET_EXTENT"); call MPI_Type_get_extent +#define mpi_type_get_extent_x smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_get_extent_x"); call MPI_Type_get_extent_x +#define MPI_TYPE_GET_EXTENT_X smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_GET_EXTENT_X"); call MPI_Type_get_extent_x +#define mpi_type_get_true_extent smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_get_true_extent"); call MPI_Type_get_true_extent +#define MPI_TYPE_GET_TRUE_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_GET_TRUE_EXTENT"); call MPI_Type_get_true_extent +#define mpi_type_get_true_extent_x smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_get_true_extent_x"); call MPI_Type_get_true_extent_x +#define MPI_TYPE_GET_TRUE_EXTENT_X smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_GET_TRUE_EXTENT_X"); call MPI_Type_get_true_extent_x +#define mpi_type_extent smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_extent"); call MPI_Type_extent +#define MPI_TYPE_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_EXTENT"); call MPI_Type_extent +#define mpi_type_lb smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_lb"); call MPI_Type_lb +#define MPI_TYPE_LB smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_LB"); call MPI_Type_lb +#define mpi_type_ub smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_ub"); call MPI_Type_ub +#define MPI_TYPE_UB smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_UB"); call MPI_Type_ub +#define mpi_type_commit smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_commit"); call MPI_Type_commit +#define MPI_TYPE_COMMIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_COMMIT"); call MPI_Type_commit +#define mpi_type_hindexed smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_hindexed"); call MPI_Type_hindexed +#define MPI_TYPE_HINDEXED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_HINDEXED"); call MPI_Type_hindexed +#define mpi_type_create_hindexed smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_hindexed"); call MPI_Type_create_hindexed +#define MPI_TYPE_CREATE_HINDEXED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_HINDEXED"); call MPI_Type_create_hindexed +#define mpi_type_create_hindexed_block smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_hindexed_block"); call MPI_Type_create_hindexed_block +#define MPI_TYPE_CREATE_HINDEXED_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_HINDEXED_BLOCK"); call MPI_Type_create_hindexed_block +#define mpi_type_hvector smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_hvector"); call MPI_Type_hvector +#define MPI_TYPE_HVECTOR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_HVECTOR"); call MPI_Type_hvector +#define mpi_type_create_hvector smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_hvector"); call MPI_Type_create_hvector +#define MPI_TYPE_CREATE_HVECTOR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_HVECTOR"); call MPI_Type_create_hvector +#define mpi_type_indexed smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_indexed"); call MPI_Type_indexed +#define MPI_TYPE_INDEXED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_INDEXED"); call MPI_Type_indexed +#define mpi_type_create_indexed smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_indexed"); call MPI_Type_create_indexed +#define MPI_TYPE_CREATE_INDEXED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_INDEXED"); call MPI_Type_create_indexed +#define mpi_type_create_indexed_block smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_indexed_block"); call MPI_Type_create_indexed_block +#define MPI_TYPE_CREATE_INDEXED_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_INDEXED_BLOCK"); call MPI_Type_create_indexed_block +#define mpi_type_struct smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_struct"); call MPI_Type_struct +#define MPI_TYPE_STRUCT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_STRUCT"); call MPI_Type_struct +#define mpi_type_create_struct smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_struct"); call MPI_Type_create_struct +#define MPI_TYPE_CREATE_STRUCT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_STRUCT"); call MPI_Type_create_struct +#define mpi_type_vector smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_vector"); call MPI_Type_vector +#define MPI_TYPE_VECTOR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_VECTOR"); call MPI_Type_vector +#define mpi_type_contiguous smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_contiguous"); call MPI_Type_contiguous +#define MPI_TYPE_CONTIGUOUS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CONTIGUOUS"); call MPI_Type_contiguous +#define mpi_type_create_resized smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_resized"); call MPI_Type_create_resized +#define MPI_TYPE_CREATE_RESIZED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_RESIZED"); call MPI_Type_create_resized +#define mpi_type_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_f2c"); call MPI_Type_f2c +#define MPI_TYPE_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_F2C"); call MPI_Type_f2c +#define mpi_type_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_c2f"); call MPI_Type_c2f +#define MPI_TYPE_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_C2F"); call MPI_Type_c2f +#define mpi_get_count smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_get_count"); call MPI_Get_count +#define MPI_GET_COUNT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GET_COUNT"); call MPI_Get_count +#define mpi_type_get_attr smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_get_attr"); call MPI_Type_get_attr +#define MPI_TYPE_GET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_GET_ATTR"); call MPI_Type_get_attr +#define mpi_type_set_attr smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_set_attr"); call MPI_Type_set_attr +#define MPI_TYPE_SET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_SET_ATTR"); call MPI_Type_set_attr +#define mpi_type_delete_attr smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_delete_attr"); call MPI_Type_delete_attr +#define MPI_TYPE_DELETE_ATTR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_DELETE_ATTR"); call MPI_Type_delete_attr +#define mpi_type_create_keyval smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_keyval"); call MPI_Type_create_keyval +#define MPI_TYPE_CREATE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_KEYVAL"); call MPI_Type_create_keyval +#define mpi_type_free_keyval smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_free_keyval"); call MPI_Type_free_keyval +#define MPI_TYPE_FREE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_FREE_KEYVAL"); call MPI_Type_free_keyval +#define mpi_type_dup smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_dup"); call MPI_Type_dup +#define MPI_TYPE_DUP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_DUP"); call MPI_Type_dup +#define mpi_type_set_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_set_name"); call MPI_Type_set_name +#define MPI_TYPE_SET_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_SET_NAME"); call MPI_Type_set_name +#define mpi_type_get_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_get_name"); call MPI_Type_get_name +#define MPI_TYPE_GET_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_GET_NAME"); call MPI_Type_get_name +#define mpi_pack smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_pack"); call MPI_Pack +#define MPI_PACK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PACK"); call MPI_Pack +#define mpi_pack_size smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_pack_size"); call MPI_Pack_size +#define MPI_PACK_SIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PACK_SIZE"); call MPI_Pack_size +#define mpi_unpack smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_unpack"); call MPI_Unpack +#define MPI_UNPACK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_UNPACK"); call MPI_Unpack +#define mpi_op_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_op_create"); call MPI_Op_create +#define MPI_OP_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_OP_CREATE"); call MPI_Op_create +#define mpi_op_free smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_op_free"); call MPI_Op_free +#define MPI_OP_FREE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_OP_FREE"); call MPI_Op_free +#define mpi_op_commutative smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_op_commutative"); call MPI_Op_commutative +#define MPI_OP_COMMUTATIVE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_OP_COMMUTATIVE"); call MPI_Op_commutative +#define mpi_op_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_op_f2c"); call MPI_Op_f2c +#define MPI_OP_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_OP_F2C"); call MPI_Op_f2c +#define mpi_op_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_op_c2f"); call MPI_Op_c2f +#define MPI_OP_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_OP_C2F"); call MPI_Op_c2f +#define mpi_group_free smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_free"); call MPI_Group_free +#define MPI_GROUP_FREE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_FREE"); call MPI_Group_free +#define mpi_group_size smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_size"); call MPI_Group_size +#define MPI_GROUP_SIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_SIZE"); call MPI_Group_size +#define mpi_group_rank smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_rank"); call MPI_Group_rank +#define MPI_GROUP_RANK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_RANK"); call MPI_Group_rank +#define mpi_group_translate_ranks smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_translate_ranks"); call MPI_Group_translate_ranks +#define MPI_GROUP_TRANSLATE_RANKS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_TRANSLATE_RANKS"); call MPI_Group_translate_ranks +#define mpi_group_compare smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_compare"); call MPI_Group_compare +#define MPI_GROUP_COMPARE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_COMPARE"); call MPI_Group_compare +#define mpi_group_union smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_union"); call MPI_Group_union +#define MPI_GROUP_UNION smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_UNION"); call MPI_Group_union +#define mpi_group_intersection smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_intersection"); call MPI_Group_intersection +#define MPI_GROUP_INTERSECTION smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_INTERSECTION"); call MPI_Group_intersection +#define mpi_group_difference smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_difference"); call MPI_Group_difference +#define MPI_GROUP_DIFFERENCE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_DIFFERENCE"); call MPI_Group_difference +#define mpi_group_incl smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_incl"); call MPI_Group_incl +#define MPI_GROUP_INCL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_INCL"); call MPI_Group_incl +#define mpi_group_excl smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_excl"); call MPI_Group_excl +#define MPI_GROUP_EXCL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_EXCL"); call MPI_Group_excl +#define mpi_group_range_incl smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_range_incl"); call MPI_Group_range_incl +#define MPI_GROUP_RANGE_INCL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_RANGE_INCL"); call MPI_Group_range_incl +#define mpi_group_range_excl smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_range_excl"); call MPI_Group_range_excl +#define MPI_GROUP_RANGE_EXCL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_RANGE_EXCL"); call MPI_Group_range_excl +#define mpi_group_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_f2c"); call MPI_Group_f2c +#define MPI_GROUP_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_F2C"); call MPI_Group_f2c +#define mpi_group_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_group_c2f"); call MPI_Group_c2f +#define MPI_GROUP_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GROUP_C2F"); call MPI_Group_c2f +#define mpi_comm_rank smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_rank"); call MPI_Comm_rank +#define MPI_COMM_RANK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_RANK"); call MPI_Comm_rank +#define mpi_comm_size smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_size"); call MPI_Comm_size +#define MPI_COMM_SIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_SIZE"); call MPI_Comm_size +#define mpi_comm_get_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_get_name"); call MPI_Comm_get_name +#define MPI_COMM_GET_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_GET_NAME"); call MPI_Comm_get_name +#define mpi_comm_set_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_set_name"); call MPI_Comm_set_name +#define MPI_COMM_SET_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_SET_NAME"); call MPI_Comm_set_name +#define mpi_comm_dup smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_dup"); call MPI_Comm_dup +#define MPI_COMM_DUP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_DUP"); call MPI_Comm_dup +#define mpi_comm_dup_with_info smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_dup_with_info"); call MPI_Comm_dup_with_info +#define MPI_COMM_DUP_WITH_INFO smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_DUP_WITH_INFO"); call MPI_Comm_dup_with_info +#define mpi_comm_get_attr smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_get_attr"); call MPI_Comm_get_attr +#define MPI_COMM_GET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_GET_ATTR"); call MPI_Comm_get_attr +#define mpi_comm_set_attr smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_set_attr"); call MPI_Comm_set_attr +#define MPI_COMM_SET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_SET_ATTR"); call MPI_Comm_set_attr +#define mpi_comm_delete_attr smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_delete_attr"); call MPI_Comm_delete_attr +#define MPI_COMM_DELETE_ATTR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_DELETE_ATTR"); call MPI_Comm_delete_attr +#define mpi_comm_create_keyval smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_create_keyval"); call MPI_Comm_create_keyval +#define MPI_COMM_CREATE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_CREATE_KEYVAL"); call MPI_Comm_create_keyval +#define mpi_comm_free_keyval smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_free_keyval"); call MPI_Comm_free_keyval +#define MPI_COMM_FREE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_FREE_KEYVAL"); call MPI_Comm_free_keyval +#define mpi_comm_group smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_group"); call MPI_Comm_group +#define MPI_COMM_GROUP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_GROUP"); call MPI_Comm_group +#define mpi_comm_compare smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_compare"); call MPI_Comm_compare +#define MPI_COMM_COMPARE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_COMPARE"); call MPI_Comm_compare +#define mpi_comm_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_create"); call MPI_Comm_create +#define MPI_COMM_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_CREATE"); call MPI_Comm_create +#define mpi_comm_create_group smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_create_group"); call MPI_Comm_create_group +#define MPI_COMM_CREATE_GROUP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_CREATE_GROUP"); call MPI_Comm_create_group +#define mpi_comm_free smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_free"); call MPI_Comm_free +#define MPI_COMM_FREE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_FREE"); call MPI_Comm_free +#define mpi_comm_disconnect smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_disconnect"); call MPI_Comm_disconnect +#define MPI_COMM_DISCONNECT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_DISCONNECT"); call MPI_Comm_disconnect +#define mpi_comm_split smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_split"); call MPI_Comm_split +#define MPI_COMM_SPLIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_SPLIT"); call MPI_Comm_split +#define mpi_comm_set_info smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_set_info"); call MPI_Comm_set_info +#define MPI_COMM_SET_INFO smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_SET_INFO"); call MPI_Comm_set_info +#define mpi_comm_get_info smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_get_info"); call MPI_Comm_get_info +#define MPI_COMM_GET_INFO smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_GET_INFO"); call MPI_Comm_get_info +#define mpi_comm_split_type smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_split_type"); call MPI_Comm_split_type +#define MPI_COMM_SPLIT_TYPE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_SPLIT_TYPE"); call MPI_Comm_split_type +#define mpi_comm_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_f2c"); call MPI_Comm_f2c +#define MPI_COMM_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_F2C"); call MPI_Comm_f2c +#define mpi_comm_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_c2f"); call MPI_Comm_c2f +#define MPI_COMM_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_C2F"); call MPI_Comm_c2f +#define mpi_start smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_start"); call MPI_Start +#define MPI_START smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_START"); call MPI_Start +#define mpi_startall smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_startall"); call MPI_Startall +#define MPI_STARTALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_STARTALL"); call MPI_Startall +#define mpi_request_free smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_request_free"); call MPI_Request_free +#define MPI_REQUEST_FREE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_REQUEST_FREE"); call MPI_Request_free +#define mpi_recv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_recv"); call MPI_Recv +#define MPI_RECV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_RECV"); call MPI_Recv +#define mpi_recv_init smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_recv_init"); call MPI_Recv_init +#define MPI_RECV_INIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_RECV_INIT"); call MPI_Recv_init +#define mpi_irecv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_irecv"); call MPI_Irecv +#define MPI_IRECV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IRECV"); call MPI_Irecv +#define mpi_send smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_send"); call MPI_Send +#define MPI_SEND smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_SEND"); call MPI_Send +#define mpi_send_init smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_send_init"); call MPI_Send_init +#define MPI_SEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_SEND_INIT"); call MPI_Send_init +#define mpi_isend smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_isend"); call MPI_Isend +#define MPI_ISEND smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ISEND"); call MPI_Isend +#define mpi_ssend smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ssend"); call MPI_Ssend +#define MPI_SSEND smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_SSEND"); call MPI_Ssend +#define mpi_ssend_init smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ssend_init"); call MPI_Ssend_init +#define MPI_SSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_SSEND_INIT"); call MPI_Ssend_init +#define mpi_issend smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_issend"); call MPI_Issend +#define MPI_ISSEND smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ISSEND"); call MPI_Issend +#define mpi_bsend smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_bsend"); call MPI_Bsend +#define MPI_BSEND smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_BSEND"); call MPI_Bsend +#define mpi_bsend_init smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_bsend_init"); call MPI_Bsend_init +#define MPI_BSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_BSEND_INIT"); call MPI_Bsend_init +#define mpi_ibsend smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ibsend"); call MPI_Ibsend +#define MPI_IBSEND smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IBSEND"); call MPI_Ibsend +#define mpi_rsend smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_rsend"); call MPI_Rsend +#define MPI_RSEND smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_RSEND"); call MPI_Rsend +#define mpi_rsend_init smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_rsend_init"); call MPI_Rsend_init +#define MPI_RSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_RSEND_INIT"); call MPI_Rsend_init +#define mpi_irsend smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_irsend"); call MPI_Irsend +#define MPI_IRSEND smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IRSEND"); call MPI_Irsend +#define mpi_sendrecv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_sendrecv"); call MPI_Sendrecv +#define MPI_SENDRECV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_SENDRECV"); call MPI_Sendrecv +#define mpi_isendrecv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_isendrecv"); call MPI_Isendrecv +#define MPI_ISENDRECV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ISENDRECV"); call MPI_Isendrecv +#define mpi_sendrecv_replace smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_sendrecv_replace"); call MPI_Sendrecv_replace +#define MPI_SENDRECV_REPLACE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_SENDRECV_REPLACE"); call MPI_Sendrecv_replace +#define mpi_isendrecv_replace smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_isendrecv_replace"); call MPI_Isendrecv_replace +#define MPI_ISENDRECV_REPLACE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ISENDRECV_REPLACE"); call MPI_Isendrecv_replace +#define mpi_test smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_test"); call MPI_Test +#define MPI_TEST smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TEST"); call MPI_Test +#define mpi_testany smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_testany"); call MPI_Testany +#define MPI_TESTANY smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TESTANY"); call MPI_Testany +#define mpi_testall smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_testall"); call MPI_Testall +#define MPI_TESTALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TESTALL"); call MPI_Testall +#define mpi_testsome smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_testsome"); call MPI_Testsome +#define MPI_TESTSOME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TESTSOME"); call MPI_Testsome +#define mpi_test_cancelled smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_test_cancelled"); call MPI_Test_cancelled +#define MPI_TEST_CANCELLED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TEST_CANCELLED"); call MPI_Test_cancelled +#define mpi_wait smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_wait"); call MPI_Wait +#define MPI_WAIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WAIT"); call MPI_Wait +#define mpi_waitany smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_waitany"); call MPI_Waitany +#define MPI_WAITANY smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WAITANY"); call MPI_Waitany +#define mpi_waitall smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_waitall"); call MPI_Waitall +#define MPI_WAITALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WAITALL"); call MPI_Waitall +#define mpi_waitsome smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_waitsome"); call MPI_Waitsome +#define MPI_WAITSOME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WAITSOME"); call MPI_Waitsome +#define mpi_iprobe smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_iprobe"); call MPI_Iprobe +#define MPI_IPROBE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IPROBE"); call MPI_Iprobe +#define mpi_probe smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_probe"); call MPI_Probe +#define MPI_PROBE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PROBE"); call MPI_Probe +#define mpi_request_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_request_f2c"); call MPI_Request_f2c +#define MPI_REQUEST_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_REQUEST_F2C"); call MPI_Request_f2c +#define mpi_request_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_request_c2f"); call MPI_Request_c2f +#define MPI_REQUEST_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_REQUEST_C2F"); call MPI_Request_c2f +#define mpi_cancel smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_cancel"); call MPI_Cancel +#define MPI_CANCEL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CANCEL"); call MPI_Cancel +#define mpi_bcast smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_bcast"); call MPI_Bcast +#define MPI_BCAST smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_BCAST"); call MPI_Bcast +#define mpi_barrier smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_barrier"); call MPI_Barrier +#define MPI_BARRIER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_BARRIER"); call MPI_Barrier +#define mpi_ibarrier smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ibarrier"); call MPI_Ibarrier +#define MPI_IBARRIER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IBARRIER"); call MPI_Ibarrier +#define mpi_ibcast smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ibcast"); call MPI_Ibcast +#define MPI_IBCAST smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IBCAST"); call MPI_Ibcast +#define mpi_igather smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_igather"); call MPI_Igather +#define MPI_IGATHER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IGATHER"); call MPI_Igather +#define mpi_igatherv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_igatherv"); call MPI_Igatherv +#define MPI_IGATHERV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IGATHERV"); call MPI_Igatherv +#define mpi_iallgather smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_iallgather"); call MPI_Iallgather +#define MPI_IALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IALLGATHER"); call MPI_Iallgather +#define mpi_iallgatherv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_iallgatherv"); call MPI_Iallgatherv +#define MPI_IALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IALLGATHERV"); call MPI_Iallgatherv +#define mpi_iscatter smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_iscatter"); call MPI_Iscatter +#define MPI_ISCATTER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ISCATTER"); call MPI_Iscatter +#define mpi_iscatterv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_iscatterv"); call MPI_Iscatterv +#define MPI_ISCATTERV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ISCATTERV"); call MPI_Iscatterv +#define mpi_ireduce smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ireduce"); call MPI_Ireduce +#define MPI_IREDUCE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IREDUCE"); call MPI_Ireduce +#define mpi_iallreduce smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_iallreduce"); call MPI_Iallreduce +#define MPI_IALLREDUCE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IALLREDUCE"); call MPI_Iallreduce +#define mpi_iscan smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_iscan"); call MPI_Iscan +#define MPI_ISCAN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ISCAN"); call MPI_Iscan +#define mpi_iexscan smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_iexscan"); call MPI_Iexscan +#define MPI_IEXSCAN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IEXSCAN"); call MPI_Iexscan +#define mpi_ireduce_scatter smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ireduce_scatter"); call MPI_Ireduce_scatter +#define MPI_IREDUCE_SCATTER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IREDUCE_SCATTER"); call MPI_Ireduce_scatter +#define mpi_ireduce_scatter_block smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ireduce_scatter_block"); call MPI_Ireduce_scatter_block +#define MPI_IREDUCE_SCATTER_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IREDUCE_SCATTER_BLOCK"); call MPI_Ireduce_scatter_block +#define mpi_ialltoall smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ialltoall"); call MPI_Ialltoall +#define MPI_IALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IALLTOALL"); call MPI_Ialltoall +#define mpi_ialltoallv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ialltoallv"); call MPI_Ialltoallv +#define MPI_IALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IALLTOALLV"); call MPI_Ialltoallv +#define mpi_ialltoallw smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ialltoallw"); call MPI_Ialltoallw +#define MPI_IALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IALLTOALLW"); call MPI_Ialltoallw +#define mpi_gather smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_gather"); call MPI_Gather +#define MPI_GATHER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GATHER"); call MPI_Gather +#define mpi_gatherv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_gatherv"); call MPI_Gatherv +#define MPI_GATHERV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GATHERV"); call MPI_Gatherv +#define mpi_allgather smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_allgather"); call MPI_Allgather +#define MPI_ALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ALLGATHER"); call MPI_Allgather +#define mpi_allgatherv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_allgatherv"); call MPI_Allgatherv +#define MPI_ALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ALLGATHERV"); call MPI_Allgatherv +#define mpi_scatter smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_scatter"); call MPI_Scatter +#define MPI_SCATTER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_SCATTER"); call MPI_Scatter +#define mpi_scatterv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_scatterv"); call MPI_Scatterv +#define MPI_SCATTERV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_SCATTERV"); call MPI_Scatterv +#define mpi_reduce smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_reduce"); call MPI_Reduce +#define MPI_REDUCE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_REDUCE"); call MPI_Reduce +#define mpi_allreduce smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_allreduce"); call MPI_Allreduce +#define MPI_ALLREDUCE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ALLREDUCE"); call MPI_Allreduce +#define mpi_scan smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_scan"); call MPI_Scan +#define MPI_SCAN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_SCAN"); call MPI_Scan +#define mpi_exscan smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_exscan"); call MPI_Exscan +#define MPI_EXSCAN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_EXSCAN"); call MPI_Exscan +#define mpi_reduce_scatter smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_reduce_scatter"); call MPI_Reduce_scatter +#define MPI_REDUCE_SCATTER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_REDUCE_SCATTER"); call MPI_Reduce_scatter +#define mpi_reduce_scatter_block smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_reduce_scatter_block"); call MPI_Reduce_scatter_block +#define MPI_REDUCE_SCATTER_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_REDUCE_SCATTER_BLOCK"); call MPI_Reduce_scatter_block +#define mpi_alltoall smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_alltoall"); call MPI_Alltoall +#define MPI_ALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ALLTOALL"); call MPI_Alltoall +#define mpi_alltoallv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_alltoallv"); call MPI_Alltoallv +#define MPI_ALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ALLTOALLV"); call MPI_Alltoallv +#define mpi_alltoallw smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_alltoallw"); call MPI_Alltoallw +#define MPI_ALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ALLTOALLW"); call MPI_Alltoallw +#define mpi_reduce_local smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_reduce_local"); call MPI_Reduce_local +#define MPI_REDUCE_LOCAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_REDUCE_LOCAL"); call MPI_Reduce_local +#define mpi_info_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_create"); call MPI_Info_create +#define MPI_INFO_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_CREATE"); call MPI_Info_create +#define mpi_info_set smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_set"); call MPI_Info_set +#define MPI_INFO_SET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_SET"); call MPI_Info_set +#define mpi_info_get smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_get"); call MPI_Info_get +#define MPI_INFO_GET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_GET"); call MPI_Info_get +#define mpi_info_free smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_free"); call MPI_Info_free +#define MPI_INFO_FREE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_FREE"); call MPI_Info_free +#define mpi_info_delete smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_delete"); call MPI_Info_delete +#define MPI_INFO_DELETE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_DELETE"); call MPI_Info_delete +#define mpi_info_dup smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_dup"); call MPI_Info_dup +#define MPI_INFO_DUP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_DUP"); call MPI_Info_dup +#define mpi_info_get_nkeys smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_get_nkeys"); call MPI_Info_get_nkeys +#define MPI_INFO_GET_NKEYS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_GET_NKEYS"); call MPI_Info_get_nkeys +#define mpi_info_get_nthkey smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_get_nthkey"); call MPI_Info_get_nthkey +#define MPI_INFO_GET_NTHKEY smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_GET_NTHKEY"); call MPI_Info_get_nthkey +#define mpi_info_get_valuelen smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_get_valuelen"); call MPI_Info_get_valuelen +#define MPI_INFO_GET_VALUELEN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_GET_VALUELEN"); call MPI_Info_get_valuelen +#define mpi_info_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_f2c"); call MPI_Info_f2c +#define MPI_INFO_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_F2C"); call MPI_Info_f2c +#define mpi_info_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_info_c2f"); call MPI_Info_c2f +#define MPI_INFO_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INFO_C2F"); call MPI_Info_c2f +#define mpi_win_free smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_free"); call MPI_Win_free +#define MPI_WIN_FREE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_FREE"); call MPI_Win_free +#define mpi_win_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_create"); call MPI_Win_create +#define MPI_WIN_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_CREATE"); call MPI_Win_create +#define mpi_win_allocate smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_allocate"); call MPI_Win_allocate +#define MPI_WIN_ALLOCATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_ALLOCATE"); call MPI_Win_allocate +#define mpi_win_allocate_shared smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_allocate_shared"); call MPI_Win_allocate_shared +#define MPI_WIN_ALLOCATE_SHARED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_ALLOCATE_SHARED"); call MPI_Win_allocate_shared +#define mpi_win_create_dynamic smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_create_dynamic"); call MPI_Win_create_dynamic +#define MPI_WIN_CREATE_DYNAMIC smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_CREATE_DYNAMIC"); call MPI_Win_create_dynamic +#define mpi_win_attach smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_attach"); call MPI_Win_attach +#define MPI_WIN_ATTACH smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_ATTACH"); call MPI_Win_attach +#define mpi_win_detach smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_detach"); call MPI_Win_detach +#define MPI_WIN_DETACH smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_DETACH"); call MPI_Win_detach +#define mpi_win_set_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_set_name"); call MPI_Win_set_name +#define MPI_WIN_SET_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_SET_NAME"); call MPI_Win_set_name +#define mpi_win_get_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_get_name"); call MPI_Win_get_name +#define MPI_WIN_GET_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_GET_NAME"); call MPI_Win_get_name +#define mpi_win_set_info smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_set_info"); call MPI_Win_set_info +#define MPI_WIN_SET_INFO smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_SET_INFO"); call MPI_Win_set_info +#define mpi_win_get_info smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_get_info"); call MPI_Win_get_info +#define MPI_WIN_GET_INFO smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_GET_INFO"); call MPI_Win_get_info +#define mpi_win_get_group smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_get_group"); call MPI_Win_get_group +#define MPI_WIN_GET_GROUP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_GET_GROUP"); call MPI_Win_get_group +#define mpi_win_fence smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_fence"); call MPI_Win_fence +#define MPI_WIN_FENCE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_FENCE"); call MPI_Win_fence +#define mpi_win_get_attr smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_get_attr"); call MPI_Win_get_attr +#define MPI_WIN_GET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_GET_ATTR"); call MPI_Win_get_attr +#define mpi_win_set_attr smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_set_attr"); call MPI_Win_set_attr +#define MPI_WIN_SET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_SET_ATTR"); call MPI_Win_set_attr +#define mpi_win_delete_attr smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_delete_attr"); call MPI_Win_delete_attr +#define MPI_WIN_DELETE_ATTR smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_DELETE_ATTR"); call MPI_Win_delete_attr +#define mpi_win_create_keyval smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_create_keyval"); call MPI_Win_create_keyval +#define MPI_WIN_CREATE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_CREATE_KEYVAL"); call MPI_Win_create_keyval +#define mpi_win_free_keyval smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_free_keyval"); call MPI_Win_free_keyval +#define MPI_WIN_FREE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_FREE_KEYVAL"); call MPI_Win_free_keyval +#define mpi_win_complete smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_complete"); call MPI_Win_complete +#define MPI_WIN_COMPLETE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_COMPLETE"); call MPI_Win_complete +#define mpi_win_post smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_post"); call MPI_Win_post +#define MPI_WIN_POST smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_POST"); call MPI_Win_post +#define mpi_win_start smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_start"); call MPI_Win_start +#define MPI_WIN_START smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_START"); call MPI_Win_start +#define mpi_win_wait smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_wait"); call MPI_Win_wait +#define MPI_WIN_WAIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_WAIT"); call MPI_Win_wait +#define mpi_win_lock smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_lock"); call MPI_Win_lock +#define MPI_WIN_LOCK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_LOCK"); call MPI_Win_lock +#define mpi_win_lock_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_lock_all"); call MPI_Win_lock_all +#define MPI_WIN_LOCK_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_LOCK_ALL"); call MPI_Win_lock_all +#define mpi_win_unlock smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_unlock"); call MPI_Win_unlock +#define MPI_WIN_UNLOCK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_UNLOCK"); call MPI_Win_unlock +#define mpi_win_unlock_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_unlock_all"); call MPI_Win_unlock_all +#define MPI_WIN_UNLOCK_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_UNLOCK_ALL"); call MPI_Win_unlock_all +#define mpi_win_flush smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_flush"); call MPI_Win_flush +#define MPI_WIN_FLUSH smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_FLUSH"); call MPI_Win_flush +#define mpi_win_flush_local smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_flush_local"); call MPI_Win_flush_local +#define MPI_WIN_FLUSH_LOCAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_FLUSH_LOCAL"); call MPI_Win_flush_local +#define mpi_win_flush_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_flush_all"); call MPI_Win_flush_all +#define MPI_WIN_FLUSH_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_FLUSH_ALL"); call MPI_Win_flush_all +#define mpi_win_flush_local_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_flush_local_all"); call MPI_Win_flush_local_all +#define MPI_WIN_FLUSH_LOCAL_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_FLUSH_LOCAL_ALL"); call MPI_Win_flush_local_all +#define mpi_win_shared_query smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_shared_query"); call MPI_Win_shared_query +#define MPI_WIN_SHARED_QUERY smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_SHARED_QUERY"); call MPI_Win_shared_query +#define mpi_win_sync smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_sync"); call MPI_Win_sync +#define MPI_WIN_SYNC smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_SYNC"); call MPI_Win_sync +#define mpi_win_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_f2c"); call MPI_Win_f2c +#define MPI_WIN_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_F2C"); call MPI_Win_f2c +#define mpi_win_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_c2f"); call MPI_Win_c2f +#define MPI_WIN_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_C2F"); call MPI_Win_c2f +#define mpi_get smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_get"); call MPI_Get +#define MPI_GET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GET"); call MPI_Get +#define mpi_put smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_put"); call MPI_Put +#define MPI_PUT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PUT"); call MPI_Put +#define mpi_accumulate smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_accumulate"); call MPI_Accumulate +#define MPI_ACCUMULATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ACCUMULATE"); call MPI_Accumulate +#define mpi_get_accumulate smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_get_accumulate"); call MPI_Get_accumulate +#define MPI_GET_ACCUMULATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GET_ACCUMULATE"); call MPI_Get_accumulate +#define mpi_rget smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_rget"); call MPI_Rget +#define MPI_RGET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_RGET"); call MPI_Rget +#define mpi_rput smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_rput"); call MPI_Rput +#define MPI_RPUT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_RPUT"); call MPI_Rput +#define mpi_raccumulate smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_raccumulate"); call MPI_Raccumulate +#define MPI_RACCUMULATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_RACCUMULATE"); call MPI_Raccumulate +#define mpi_rget_accumulate smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_rget_accumulate"); call MPI_Rget_accumulate +#define MPI_RGET_ACCUMULATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_RGET_ACCUMULATE"); call MPI_Rget_accumulate +#define mpi_fetch_and_op smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_fetch_and_op"); call MPI_Fetch_and_op +#define MPI_FETCH_AND_OP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FETCH_AND_OP"); call MPI_Fetch_and_op +#define mpi_compare_and_swap smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_compare_and_swap"); call MPI_Compare_and_swap +#define MPI_COMPARE_AND_SWAP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMPARE_AND_SWAP"); call MPI_Compare_and_swap +#define mpi_cart_coords smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_cart_coords"); call MPI_Cart_coords +#define MPI_CART_COORDS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CART_COORDS"); call MPI_Cart_coords +#define mpi_cart_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_cart_create"); call MPI_Cart_create +#define MPI_CART_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CART_CREATE"); call MPI_Cart_create +#define mpi_cart_get smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_cart_get"); call MPI_Cart_get +#define MPI_CART_GET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CART_GET"); call MPI_Cart_get +#define mpi_cart_rank smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_cart_rank"); call MPI_Cart_rank +#define MPI_CART_RANK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CART_RANK"); call MPI_Cart_rank +#define mpi_cart_shift smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_cart_shift"); call MPI_Cart_shift +#define MPI_CART_SHIFT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CART_SHIFT"); call MPI_Cart_shift +#define mpi_cart_sub smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_cart_sub"); call MPI_Cart_sub +#define MPI_CART_SUB smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CART_SUB"); call MPI_Cart_sub +#define mpi_cartdim_get smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_cartdim_get"); call MPI_Cartdim_get +#define MPI_CARTDIM_GET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CARTDIM_GET"); call MPI_Cartdim_get +#define mpi_dims_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_dims_create"); call MPI_Dims_create +#define MPI_DIMS_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_DIMS_CREATE"); call MPI_Dims_create +#define mpi_request_get_status smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_request_get_status"); call MPI_Request_get_status +#define MPI_REQUEST_GET_STATUS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_REQUEST_GET_STATUS"); call MPI_Request_get_status +#define mpi_grequest_start smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_grequest_start"); call MPI_Grequest_start +#define MPI_GREQUEST_START smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GREQUEST_START"); call MPI_Grequest_start +#define mpi_grequest_complete smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_grequest_complete"); call MPI_Grequest_complete +#define MPI_GREQUEST_COMPLETE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GREQUEST_COMPLETE"); call MPI_Grequest_complete +#define mpi_status_set_cancelled smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_status_set_cancelled"); call MPI_Status_set_cancelled +#define MPI_STATUS_SET_CANCELLED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_STATUS_SET_CANCELLED"); call MPI_Status_set_cancelled +#define mpi_status_set_elements smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_status_set_elements"); call MPI_Status_set_elements +#define MPI_STATUS_SET_ELEMENTS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_STATUS_SET_ELEMENTS"); call MPI_Status_set_elements +#define mpi_status_set_elements_x smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_status_set_elements_x"); call MPI_Status_set_elements_x +#define MPI_STATUS_SET_ELEMENTS_X smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_STATUS_SET_ELEMENTS_X"); call MPI_Status_set_elements_x +#define mpi_type_create_subarray smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_subarray"); call MPI_Type_create_subarray +#define MPI_TYPE_CREATE_SUBARRAY smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_SUBARRAY"); call MPI_Type_create_subarray +#define mpi_file_open smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_open"); call MPI_File_open +#define MPI_FILE_OPEN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_OPEN"); call MPI_File_open +#define mpi_file_close smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_close"); call MPI_File_close +#define MPI_FILE_CLOSE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_CLOSE"); call MPI_File_close +#define mpi_file_delete smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_delete"); call MPI_File_delete +#define MPI_FILE_DELETE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_DELETE"); call MPI_File_delete +#define mpi_file_get_size smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_size"); call MPI_File_get_size +#define MPI_FILE_GET_SIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_SIZE"); call MPI_File_get_size +#define mpi_file_get_group smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_group"); call MPI_File_get_group +#define MPI_FILE_GET_GROUP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_GROUP"); call MPI_File_get_group +#define mpi_file_get_amode smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_amode"); call MPI_File_get_amode +#define MPI_FILE_GET_AMODE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_AMODE"); call MPI_File_get_amode +#define mpi_file_set_info smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_set_info"); call MPI_File_set_info +#define MPI_FILE_SET_INFO smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_SET_INFO"); call MPI_File_set_info +#define mpi_file_get_info smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_info"); call MPI_File_get_info +#define MPI_FILE_GET_INFO smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_INFO"); call MPI_File_get_info +#define mpi_file_read_at smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_at"); call MPI_File_read_at +#define MPI_FILE_READ_AT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_AT"); call MPI_File_read_at +#define mpi_file_read_at_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_at_all"); call MPI_File_read_at_all +#define MPI_FILE_READ_AT_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_AT_ALL"); call MPI_File_read_at_all +#define mpi_file_write_at smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_at"); call MPI_File_write_at +#define MPI_FILE_WRITE_AT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_AT"); call MPI_File_write_at +#define mpi_file_write_at_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_at_all"); call MPI_File_write_at_all +#define MPI_FILE_WRITE_AT_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_AT_ALL"); call MPI_File_write_at_all +#define mpi_file_read smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read"); call MPI_File_read +#define MPI_FILE_READ smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ"); call MPI_File_read +#define mpi_file_read_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_all"); call MPI_File_read_all +#define MPI_FILE_READ_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_ALL"); call MPI_File_read_all +#define mpi_file_write smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write"); call MPI_File_write +#define MPI_FILE_WRITE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE"); call MPI_File_write +#define mpi_file_write_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_all"); call MPI_File_write_all +#define MPI_FILE_WRITE_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_ALL"); call MPI_File_write_all +#define mpi_file_seek smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_seek"); call MPI_File_seek +#define MPI_FILE_SEEK smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_SEEK"); call MPI_File_seek +#define mpi_file_get_position smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_position"); call MPI_File_get_position +#define MPI_FILE_GET_POSITION smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_POSITION"); call MPI_File_get_position +#define mpi_file_read_shared smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_shared"); call MPI_File_read_shared +#define MPI_FILE_READ_SHARED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_SHARED"); call MPI_File_read_shared +#define mpi_file_write_shared smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_shared"); call MPI_File_write_shared +#define MPI_FILE_WRITE_SHARED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_SHARED"); call MPI_File_write_shared +#define mpi_file_read_ordered smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_ordered"); call MPI_File_read_ordered +#define MPI_FILE_READ_ORDERED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_ORDERED"); call MPI_File_read_ordered +#define mpi_file_write_ordered smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_ordered"); call MPI_File_write_ordered +#define MPI_FILE_WRITE_ORDERED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_ORDERED"); call MPI_File_write_ordered +#define mpi_file_seek_shared smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_seek_shared"); call MPI_File_seek_shared +#define MPI_FILE_SEEK_SHARED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_SEEK_SHARED"); call MPI_File_seek_shared +#define mpi_file_get_position_shared smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_position_shared"); call MPI_File_get_position_shared +#define MPI_FILE_GET_POSITION_SHARED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_POSITION_SHARED"); call MPI_File_get_position_shared +#define mpi_file_sync smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_sync"); call MPI_File_sync +#define MPI_FILE_SYNC smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_SYNC"); call MPI_File_sync +#define mpi_file_set_view smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_set_view"); call MPI_File_set_view +#define MPI_FILE_SET_VIEW smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_SET_VIEW"); call MPI_File_set_view +#define mpi_file_get_view smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_view"); call MPI_File_get_view +#define MPI_FILE_GET_VIEW smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_VIEW"); call MPI_File_get_view +#define mpi_errhandler_set smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_errhandler_set"); call MPI_Errhandler_set +#define MPI_ERRHANDLER_SET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ERRHANDLER_SET"); call MPI_Errhandler_set +#define mpi_errhandler_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_errhandler_create"); call MPI_Errhandler_create +#define MPI_ERRHANDLER_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ERRHANDLER_CREATE"); call MPI_Errhandler_create +#define mpi_errhandler_free smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_errhandler_free"); call MPI_Errhandler_free +#define MPI_ERRHANDLER_FREE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ERRHANDLER_FREE"); call MPI_Errhandler_free +#define mpi_errhandler_get smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_errhandler_get"); call MPI_Errhandler_get +#define MPI_ERRHANDLER_GET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ERRHANDLER_GET"); call MPI_Errhandler_get +#define mpi_comm_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_set_errhandler"); call MPI_Comm_set_errhandler +#define MPI_COMM_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_SET_ERRHANDLER"); call MPI_Comm_set_errhandler +#define mpi_comm_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_get_errhandler"); call MPI_Comm_get_errhandler +#define MPI_COMM_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_GET_ERRHANDLER"); call MPI_Comm_get_errhandler +#define mpi_comm_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_create_errhandler"); call MPI_Comm_create_errhandler +#define MPI_COMM_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_CREATE_ERRHANDLER"); call MPI_Comm_create_errhandler +#define mpi_comm_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_call_errhandler"); call MPI_Comm_call_errhandler +#define MPI_COMM_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_CALL_ERRHANDLER"); call MPI_Comm_call_errhandler +#define mpi_win_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_set_errhandler"); call MPI_Win_set_errhandler +#define MPI_WIN_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_SET_ERRHANDLER"); call MPI_Win_set_errhandler +#define mpi_win_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_get_errhandler"); call MPI_Win_get_errhandler +#define MPI_WIN_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_GET_ERRHANDLER"); call MPI_Win_get_errhandler +#define mpi_win_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_create_errhandler"); call MPI_Win_create_errhandler +#define MPI_WIN_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_CREATE_ERRHANDLER"); call MPI_Win_create_errhandler +#define mpi_win_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_call_errhandler"); call MPI_Win_call_errhandler +#define MPI_WIN_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_CALL_ERRHANDLER"); call MPI_Win_call_errhandler +#define mpi_errhandler_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_errhandler_f2c"); call MPI_Errhandler_f2c +#define MPI_ERRHANDLER_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ERRHANDLER_F2C"); call MPI_Errhandler_f2c +#define mpi_errhandler_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_errhandler_c2f"); call MPI_Errhandler_c2f +#define MPI_ERRHANDLER_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ERRHANDLER_C2F"); call MPI_Errhandler_c2f +#define mpi_type_create_f90_integer smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_f90_integer"); call MPI_Type_create_f90_integer +#define MPI_TYPE_CREATE_F90_INTEGER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_F90_INTEGER"); call MPI_Type_create_f90_integer +#define mpi_type_create_f90_real smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_f90_real"); call MPI_Type_create_f90_real +#define MPI_TYPE_CREATE_F90_REAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_F90_REAL"); call MPI_Type_create_f90_real +#define mpi_type_create_f90_complex smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_f90_complex"); call MPI_Type_create_f90_complex +#define MPI_TYPE_CREATE_F90_COMPLEX smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_F90_COMPLEX"); call MPI_Type_create_f90_complex +#define mpi_type_get_contents smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_get_contents"); call MPI_Type_get_contents +#define MPI_TYPE_GET_CONTENTS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_GET_CONTENTS"); call MPI_Type_get_contents +#define mpi_type_get_envelope smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_get_envelope"); call MPI_Type_get_envelope +#define MPI_TYPE_GET_ENVELOPE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_GET_ENVELOPE"); call MPI_Type_get_envelope +#define mpi_file_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_call_errhandler"); call MPI_File_call_errhandler +#define MPI_FILE_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_CALL_ERRHANDLER"); call MPI_File_call_errhandler +#define mpi_file_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_create_errhandler"); call MPI_File_create_errhandler +#define MPI_FILE_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_CREATE_ERRHANDLER"); call MPI_File_create_errhandler +#define mpi_file_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_set_errhandler"); call MPI_File_set_errhandler +#define MPI_FILE_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_SET_ERRHANDLER"); call MPI_File_set_errhandler +#define mpi_file_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_errhandler"); call MPI_File_get_errhandler +#define MPI_FILE_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_ERRHANDLER"); call MPI_File_get_errhandler +#define mpi_cart_map smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_cart_map"); call MPI_Cart_map +#define MPI_CART_MAP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CART_MAP"); call MPI_Cart_map +#define mpi_graph_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_graph_create"); call MPI_Graph_create +#define MPI_GRAPH_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GRAPH_CREATE"); call MPI_Graph_create +#define mpi_graph_get smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_graph_get"); call MPI_Graph_get +#define MPI_GRAPH_GET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GRAPH_GET"); call MPI_Graph_get +#define mpi_graph_map smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_graph_map"); call MPI_Graph_map +#define MPI_GRAPH_MAP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GRAPH_MAP"); call MPI_Graph_map +#define mpi_graph_neighbors smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_graph_neighbors"); call MPI_Graph_neighbors +#define MPI_GRAPH_NEIGHBORS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GRAPH_NEIGHBORS"); call MPI_Graph_neighbors +#define mpi_graph_neighbors_count smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_graph_neighbors_count"); call MPI_Graph_neighbors_count +#define MPI_GRAPH_NEIGHBORS_COUNT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GRAPH_NEIGHBORS_COUNT"); call MPI_Graph_neighbors_count +#define mpi_graphdims_get smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_graphdims_get"); call MPI_Graphdims_get +#define MPI_GRAPHDIMS_GET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GRAPHDIMS_GET"); call MPI_Graphdims_get +#define mpi_topo_test smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_topo_test"); call MPI_Topo_test +#define MPI_TOPO_TEST smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TOPO_TEST"); call MPI_Topo_test +#define mpi_add_error_class smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_add_error_class"); call MPI_Add_error_class +#define MPI_ADD_ERROR_CLASS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ADD_ERROR_CLASS"); call MPI_Add_error_class +#define mpi_add_error_code smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_add_error_code"); call MPI_Add_error_code +#define MPI_ADD_ERROR_CODE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ADD_ERROR_CODE"); call MPI_Add_error_code +#define mpi_add_error_string smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_add_error_string"); call MPI_Add_error_string +#define MPI_ADD_ERROR_STRING smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_ADD_ERROR_STRING"); call MPI_Add_error_string +#define mpi_comm_test_inter smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_test_inter"); call MPI_Comm_test_inter +#define MPI_COMM_TEST_INTER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_TEST_INTER"); call MPI_Comm_test_inter +#define mpi_intercomm_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_intercomm_create"); call MPI_Intercomm_create +#define MPI_INTERCOMM_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INTERCOMM_CREATE"); call MPI_Intercomm_create +#define mpi_intercomm_merge smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_intercomm_merge"); call MPI_Intercomm_merge +#define MPI_INTERCOMM_MERGE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INTERCOMM_MERGE"); call MPI_Intercomm_merge +#define mpi_comm_remote_group smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_remote_group"); call MPI_Comm_remote_group +#define MPI_COMM_REMOTE_GROUP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_REMOTE_GROUP"); call MPI_Comm_remote_group +#define mpi_comm_remote_size smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_remote_size"); call MPI_Comm_remote_size +#define MPI_COMM_REMOTE_SIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_REMOTE_SIZE"); call MPI_Comm_remote_size +#define mpi_get_elements smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_get_elements"); call MPI_Get_elements +#define MPI_GET_ELEMENTS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GET_ELEMENTS"); call MPI_Get_elements +#define mpi_get_elements_x smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_get_elements_x"); call MPI_Get_elements_x +#define MPI_GET_ELEMENTS_X smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_GET_ELEMENTS_X"); call MPI_Get_elements_x +#define mpi_pcontrol smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_pcontrol"); call MPI_Pcontrol +#define MPI_PCONTROL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PCONTROL"); call MPI_Pcontrol +#define mpi_type_create_darray smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_create_darray"); call MPI_Type_create_darray +#define MPI_TYPE_CREATE_DARRAY smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_CREATE_DARRAY"); call MPI_Type_create_darray +#define mpi_pack_external_size smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_pack_external_size"); call MPI_Pack_external_size +#define MPI_PACK_EXTERNAL_SIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PACK_EXTERNAL_SIZE"); call MPI_Pack_external_size +#define mpi_pack_external smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_pack_external"); call MPI_Pack_external +#define MPI_PACK_EXTERNAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PACK_EXTERNAL"); call MPI_Pack_external +#define mpi_unpack_external smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_unpack_external"); call MPI_Unpack_external +#define MPI_UNPACK_EXTERNAL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_UNPACK_EXTERNAL"); call MPI_Unpack_external +#define mpi_type_match_size smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_type_match_size"); call MPI_Type_match_size +#define MPI_TYPE_MATCH_SIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_TYPE_MATCH_SIZE"); call MPI_Type_match_size +#define mpi_comm_connect smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_connect"); call MPI_Comm_connect +#define MPI_COMM_CONNECT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_CONNECT"); call MPI_Comm_connect +#define mpi_unpublish_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_unpublish_name"); call MPI_Unpublish_name +#define MPI_UNPUBLISH_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_UNPUBLISH_NAME"); call MPI_Unpublish_name +#define mpi_publish_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_publish_name"); call MPI_Publish_name +#define MPI_PUBLISH_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PUBLISH_NAME"); call MPI_Publish_name +#define mpi_lookup_name smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_lookup_name"); call MPI_Lookup_name +#define MPI_LOOKUP_NAME smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_LOOKUP_NAME"); call MPI_Lookup_name +#define mpi_comm_idup smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_idup"); call MPI_Comm_idup +#define MPI_COMM_IDUP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_IDUP"); call MPI_Comm_idup +#define mpi_comm_join smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_join"); call MPI_Comm_join +#define MPI_COMM_JOIN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_JOIN"); call MPI_Comm_join +#define mpi_open_port smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_open_port"); call MPI_Open_port +#define MPI_OPEN_PORT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_OPEN_PORT"); call MPI_Open_port +#define mpi_close_port smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_close_port"); call MPI_Close_port +#define MPI_CLOSE_PORT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_CLOSE_PORT"); call MPI_Close_port +#define mpi_comm_accept smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_accept"); call MPI_Comm_accept +#define MPI_COMM_ACCEPT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_ACCEPT"); call MPI_Comm_accept +#define mpi_comm_spawn smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_spawn"); call MPI_Comm_spawn +#define MPI_COMM_SPAWN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_SPAWN"); call MPI_Comm_spawn +#define mpi_comm_spawn_multiple smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_spawn_multiple"); call MPI_Comm_spawn_multiple +#define MPI_COMM_SPAWN_MULTIPLE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_SPAWN_MULTIPLE"); call MPI_Comm_spawn_multiple +#define mpi_comm_get_parent smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_comm_get_parent"); call MPI_Comm_get_parent +#define MPI_COMM_GET_PARENT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_COMM_GET_PARENT"); call MPI_Comm_get_parent +#define mpi_dist_graph_create smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_dist_graph_create"); call MPI_Dist_graph_create +#define MPI_DIST_GRAPH_CREATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_DIST_GRAPH_CREATE"); call MPI_Dist_graph_create +#define mpi_dist_graph_create_adjacent smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_dist_graph_create_adjacent"); call MPI_Dist_graph_create_adjacent +#define MPI_DIST_GRAPH_CREATE_ADJACENT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_DIST_GRAPH_CREATE_ADJACENT"); call MPI_Dist_graph_create_adjacent +#define mpi_dist_graph_neighbors smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_dist_graph_neighbors"); call MPI_Dist_graph_neighbors +#define MPI_DIST_GRAPH_NEIGHBORS smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_DIST_GRAPH_NEIGHBORS"); call MPI_Dist_graph_neighbors +#define mpi_dist_graph_neighbors_count smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_dist_graph_neighbors_count"); call MPI_Dist_graph_neighbors_count +#define MPI_DIST_GRAPH_NEIGHBORS_COUNT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_DIST_GRAPH_NEIGHBORS_COUNT"); call MPI_Dist_graph_neighbors_count +#define mpi_win_test smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_win_test"); call MPI_Win_test +#define MPI_WIN_TEST smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_WIN_TEST"); call MPI_Win_test +#define mpi_file_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_c2f"); call MPI_File_c2f +#define MPI_FILE_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_C2F"); call MPI_File_c2f +#define mpi_file_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_f2c"); call MPI_File_f2c +#define MPI_FILE_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_F2C"); call MPI_File_f2c +#define mpi_register_datarep smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_register_datarep"); call MPI_Register_datarep +#define MPI_REGISTER_DATAREP smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_REGISTER_DATAREP"); call MPI_Register_datarep +#define mpi_file_set_size smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_set_size"); call MPI_File_set_size +#define MPI_FILE_SET_SIZE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_SET_SIZE"); call MPI_File_set_size +#define mpi_file_preallocate smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_preallocate"); call MPI_File_preallocate +#define MPI_FILE_PREALLOCATE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_PREALLOCATE"); call MPI_File_preallocate +#define mpi_file_iread_at smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iread_at"); call MPI_File_iread_at +#define MPI_FILE_IREAD_AT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IREAD_AT"); call MPI_File_iread_at +#define mpi_file_iwrite_at smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iwrite_at"); call MPI_File_iwrite_at +#define MPI_FILE_IWRITE_AT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IWRITE_AT"); call MPI_File_iwrite_at +#define mpi_file_iread_at_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iread_at_all"); call MPI_File_iread_at_all +#define MPI_FILE_IREAD_AT_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IREAD_AT_ALL"); call MPI_File_iread_at_all +#define mpi_file_iwrite_at_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iwrite_at_all"); call MPI_File_iwrite_at_all +#define MPI_FILE_IWRITE_AT_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IWRITE_AT_ALL"); call MPI_File_iwrite_at_all +#define mpi_file_iread smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iread"); call MPI_File_iread +#define MPI_FILE_IREAD smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IREAD"); call MPI_File_iread +#define mpi_file_iwrite smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iwrite"); call MPI_File_iwrite +#define MPI_FILE_IWRITE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IWRITE"); call MPI_File_iwrite +#define mpi_file_iread_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iread_all"); call MPI_File_iread_all +#define MPI_FILE_IREAD_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IREAD_ALL"); call MPI_File_iread_all +#define mpi_file_iwrite_all smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iwrite_all"); call MPI_File_iwrite_all +#define MPI_FILE_IWRITE_ALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IWRITE_ALL"); call MPI_File_iwrite_all +#define mpi_file_get_byte_offset smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_byte_offset"); call MPI_File_get_byte_offset +#define MPI_FILE_GET_BYTE_OFFSET smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_BYTE_OFFSET"); call MPI_File_get_byte_offset +#define mpi_file_iread_shared smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iread_shared"); call MPI_File_iread_shared +#define MPI_FILE_IREAD_SHARED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IREAD_SHARED"); call MPI_File_iread_shared +#define mpi_file_iwrite_shared smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_iwrite_shared"); call MPI_File_iwrite_shared +#define MPI_FILE_IWRITE_SHARED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_IWRITE_SHARED"); call MPI_File_iwrite_shared +#define mpi_file_read_at_all_begin smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_at_all_begin"); call MPI_File_read_at_all_begin +#define MPI_FILE_READ_AT_ALL_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_AT_ALL_BEGIN"); call MPI_File_read_at_all_begin +#define mpi_file_read_at_all_end smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_at_all_end"); call MPI_File_read_at_all_end +#define MPI_FILE_READ_AT_ALL_END smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_AT_ALL_END"); call MPI_File_read_at_all_end +#define mpi_file_write_at_all_begin smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_at_all_begin"); call MPI_File_write_at_all_begin +#define MPI_FILE_WRITE_AT_ALL_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_AT_ALL_BEGIN"); call MPI_File_write_at_all_begin +#define mpi_file_write_at_all_end smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_at_all_end"); call MPI_File_write_at_all_end +#define MPI_FILE_WRITE_AT_ALL_END smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_AT_ALL_END"); call MPI_File_write_at_all_end +#define mpi_file_read_all_begin smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_all_begin"); call MPI_File_read_all_begin +#define MPI_FILE_READ_ALL_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_ALL_BEGIN"); call MPI_File_read_all_begin +#define mpi_file_read_all_end smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_all_end"); call MPI_File_read_all_end +#define MPI_FILE_READ_ALL_END smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_ALL_END"); call MPI_File_read_all_end +#define mpi_file_write_all_begin smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_all_begin"); call MPI_File_write_all_begin +#define MPI_FILE_WRITE_ALL_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_ALL_BEGIN"); call MPI_File_write_all_begin +#define mpi_file_write_all_end smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_all_end"); call MPI_File_write_all_end +#define MPI_FILE_WRITE_ALL_END smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_ALL_END"); call MPI_File_write_all_end +#define mpi_file_read_ordered_begin smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_ordered_begin"); call MPI_File_read_ordered_begin +#define MPI_FILE_READ_ORDERED_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_ORDERED_BEGIN"); call MPI_File_read_ordered_begin +#define mpi_file_read_ordered_end smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_read_ordered_end"); call MPI_File_read_ordered_end +#define MPI_FILE_READ_ORDERED_END smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_READ_ORDERED_END"); call MPI_File_read_ordered_end +#define mpi_file_write_ordered_begin smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_ordered_begin"); call MPI_File_write_ordered_begin +#define MPI_FILE_WRITE_ORDERED_BEGIN smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_ORDERED_BEGIN"); call MPI_File_write_ordered_begin +#define mpi_file_write_ordered_end smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_write_ordered_end"); call MPI_File_write_ordered_end +#define MPI_FILE_WRITE_ORDERED_END smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_WRITE_ORDERED_END"); call MPI_File_write_ordered_end +#define mpi_file_get_type_extent smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_type_extent"); call MPI_File_get_type_extent +#define MPI_FILE_GET_TYPE_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_TYPE_EXTENT"); call MPI_File_get_type_extent +#define mpi_file_set_atomicity smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_set_atomicity"); call MPI_File_set_atomicity +#define MPI_FILE_SET_ATOMICITY smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_SET_ATOMICITY"); call MPI_File_set_atomicity +#define mpi_file_get_atomicity smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_file_get_atomicity"); call MPI_File_get_atomicity +#define MPI_FILE_GET_ATOMICITY smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_FILE_GET_ATOMICITY"); call MPI_File_get_atomicity +#define mpi_message_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_message_f2c"); call MPI_Message_f2c +#define MPI_MESSAGE_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_MESSAGE_F2C"); call MPI_Message_f2c +#define mpi_message_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_message_c2f"); call MPI_Message_c2f +#define MPI_MESSAGE_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_MESSAGE_C2F"); call MPI_Message_c2f +#define mpi_mrecv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_mrecv"); call MPI_Mrecv +#define MPI_MRECV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_MRECV"); call MPI_Mrecv +#define mpi_mprobe smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_mprobe"); call MPI_Mprobe +#define MPI_MPROBE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_MPROBE"); call MPI_Mprobe +#define mpi_imrecv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_imrecv"); call MPI_Imrecv +#define MPI_IMRECV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IMRECV"); call MPI_Imrecv +#define mpi_improbe smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_improbe"); call MPI_Improbe +#define MPI_IMPROBE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_IMPROBE"); call MPI_Improbe +#define mpi_neighbor_allgather smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_neighbor_allgather"); call MPI_Neighbor_allgather +#define MPI_NEIGHBOR_ALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_NEIGHBOR_ALLGATHER"); call MPI_Neighbor_allgather +#define mpi_neighbor_allgatherv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_neighbor_allgatherv"); call MPI_Neighbor_allgatherv +#define MPI_NEIGHBOR_ALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_NEIGHBOR_ALLGATHERV"); call MPI_Neighbor_allgatherv +#define mpi_neighbor_alltoall smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_neighbor_alltoall"); call MPI_Neighbor_alltoall +#define MPI_NEIGHBOR_ALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_NEIGHBOR_ALLTOALL"); call MPI_Neighbor_alltoall +#define mpi_neighbor_alltoallv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_neighbor_alltoallv"); call MPI_Neighbor_alltoallv +#define MPI_NEIGHBOR_ALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_NEIGHBOR_ALLTOALLV"); call MPI_Neighbor_alltoallv +#define mpi_neighbor_alltoallw smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_neighbor_alltoallw"); call MPI_Neighbor_alltoallw +#define MPI_NEIGHBOR_ALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_NEIGHBOR_ALLTOALLW"); call MPI_Neighbor_alltoallw +#define mpi_ineighbor_allgather smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ineighbor_allgather"); call MPI_Ineighbor_allgather +#define MPI_INEIGHBOR_ALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INEIGHBOR_ALLGATHER"); call MPI_Ineighbor_allgather +#define mpi_ineighbor_allgatherv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ineighbor_allgatherv"); call MPI_Ineighbor_allgatherv +#define MPI_INEIGHBOR_ALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INEIGHBOR_ALLGATHERV"); call MPI_Ineighbor_allgatherv +#define mpi_ineighbor_alltoall smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ineighbor_alltoall"); call MPI_Ineighbor_alltoall +#define MPI_INEIGHBOR_ALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INEIGHBOR_ALLTOALL"); call MPI_Ineighbor_alltoall +#define mpi_ineighbor_alltoallv smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ineighbor_alltoallv"); call MPI_Ineighbor_alltoallv +#define MPI_INEIGHBOR_ALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INEIGHBOR_ALLTOALLV"); call MPI_Ineighbor_alltoallv +#define mpi_ineighbor_alltoallw smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_ineighbor_alltoallw"); call MPI_Ineighbor_alltoallw +#define MPI_INEIGHBOR_ALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_INEIGHBOR_ALLTOALLW"); call MPI_Ineighbor_alltoallw +#define mpi_status_f2c smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_status_f2c"); call MPI_Status_f2c +#define MPI_STATUS_F2C smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_STATUS_F2C"); call MPI_Status_f2c +#define mpi_status_c2f smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_status_c2f"); call MPI_Status_c2f +#define MPI_STATUS_C2F smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_STATUS_C2F"); call MPI_Status_c2f +#define mpi_parrived smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_parrived"); call MPI_Parrived +#define MPI_PARRIVED smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PARRIVED"); call MPI_Parrived +#define mpi_pready smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_pready"); call MPI_Pready +#define MPI_PREADY smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PREADY"); call MPI_Pready +#define mpi_pready_range smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_pready_range"); call MPI_Pready_range +#define MPI_PREADY_RANGE smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PREADY_RANGE"); call MPI_Pready_range +#define mpi_pready_list smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_pready_list"); call MPI_Pready_list +#define MPI_PREADY_LIST smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PREADY_LIST"); call MPI_Pready_list +#define mpi_precv_init smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_precv_init"); call MPI_Precv_init +#define MPI_PRECV_INIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PRECV_INIT"); call MPI_Precv_init +#define mpi_psend_init smpi_trace_set_call_location(__FILE__,__LINE__,"mpi_psend_init"); call MPI_Psend_init +#define MPI_PSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__,"MPI_PSEND_INIT"); call MPI_Psend_init diff --git a/include/smpi/smpi_helpers.h b/include/smpi/smpi_helpers.h index 5317deec37..ec5d479bec 100644 --- a/include/smpi/smpi_helpers.h +++ b/include/smpi/smpi_helpers.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,8 +15,8 @@ #define sleep(x) smpi_sleep(x) #define usleep(x) smpi_usleep(x) #else -#define sleep(x) (smpi_trace_set_call_location(__FILE__, __LINE__), smpi_sleep(x)) -#define usleep(x) (smpi_trace_set_call_location(__FILE__, __LINE__), smpi_usleep(x)) +#define sleep(x) (smpi_trace_set_call_location(__FILE__, __LINE__, "sleep"), smpi_sleep(x)) +#define usleep(x) (smpi_trace_set_call_location(__FILE__, __LINE__, "usleep"), smpi_usleep(x)) #endif #define gettimeofday(x, y) smpi_gettimeofday((x), 0) @@ -24,7 +24,7 @@ #ifndef TRACE_CALL_LOCATION /* Defined by smpicc on the command line */ #define nanosleep(x, y) smpi_nanosleep((x), (y)) #else -#define nanosleep(x) (smpi_trace_set_call_location(__FILE__, __LINE__), smpi_nanosleep(x)) +#define nanosleep(x) (smpi_trace_set_call_location(__FILE__, __LINE__, "nanosleep"), smpi_nanosleep(x)) #endif #define clock_gettime(x, y) smpi_clock_gettime((x), (y)) #endif @@ -41,4 +41,5 @@ #define exit(x) smpi_exit(x) +#define getpid smpi_getpid #endif diff --git a/include/smpi/smpi_helpers_internal.h b/include/smpi/smpi_helpers_internal.h index 53ca8a710d..4e40b053fc 100644 --- a/include/smpi/smpi_helpers_internal.h +++ b/include/smpi/smpi_helpers_internal.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,10 +12,17 @@ #include #include +#include #if _POSIX_TIMERS #include #endif +#if !defined(SMPI_NO_OVERRIDE_MALLOC) && !defined(__GLIBC__) +/* For musl libc, must be included before #defining calloc(). Testing if !defined(__GLIBC__) is a bit crude + * but I don't know a better way. */ +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -38,6 +45,8 @@ void* smpi_shared_malloc_intercept(size_t size, const char* file, int line); void* smpi_shared_calloc_intercept(size_t num_elm, size_t elem_size, const char* file, int line); void* smpi_shared_realloc_intercept(void* data, size_t size, const char* file, int line); void smpi_shared_free(void* data); + +pid_t smpi_getpid(); #ifdef __cplusplus [[noreturn]] // c++11 #else diff --git a/include/smpi/smpi_main.h b/include/smpi/smpi_main.h deleted file mode 100644 index 67d16be4f1..0000000000 --- a/include/smpi/smpi_main.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#define main smpi_windows_main__(int argc, char **argv);\ -int main(int argc, char **argv){\ -smpi_main(&smpi_windows_main__,argc,argv);\ -return 0;\ -}\ -int smpi_windows_main__ diff --git a/include/xbt.h b/include/xbt.h index 7540f592b7..0f6e5b8c04 100644 --- a/include/xbt.h +++ b/include/xbt.h @@ -1,6 +1,6 @@ /* xbt.h - Public interface to the xbt (SimGrid's toolbox) */ -/* Copyright (c) 2004-2022. The SimGrid Team. +/* Copyright (c) 2004-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -17,8 +17,6 @@ #include #include -#include - #include #include diff --git a/include/xbt/Extendable.hpp b/include/xbt/Extendable.hpp index 698e80c4f0..54adb3e65d 100644 --- a/include/xbt/Extendable.hpp +++ b/include/xbt/Extendable.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. +/* Copyright (c) 2015-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -7,14 +7,13 @@ #ifndef SIMGRID_XBT_LIB_HPP #define SIMGRID_XBT_LIB_HPP -#include "xbt/base.h" // XBT_ATTRIB_DEPRECATED_v334 #include #include #include +#include #include -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { template class Extension; template class Extendable; @@ -110,10 +109,8 @@ public: extensions_[0]=data; } template D* get_data() const { return static_cast(extensions_[0]); } - XBT_ATTRIB_DEPRECATED_v334("Please use typed template Extendable::get_data<>()") void* get_data() const - { - return get_data(); - } + template std::unique_ptr get_unique_data() { return std::unique_ptr(get_data()); } + // Convenience extension access when the type has an associated EXTENSION ID: template U* extension() const { return extension(U::EXTENSION_ID); } template void extension_set(U* p) { extension_set(U::EXTENSION_ID, p); } @@ -121,7 +118,6 @@ public: // Initialized with a first element, to save space for void* user data template std::vector> Extendable::deleters_{1}; -} -} +} // namespace simgrid::xbt #endif diff --git a/include/xbt/PropertyHolder.hpp b/include/xbt/PropertyHolder.hpp index d30beae6c4..623a35a5f6 100644 --- a/include/xbt/PropertyHolder.hpp +++ b/include/xbt/PropertyHolder.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,8 +10,7 @@ #include #include -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { /** @brief a PropertyHolder can be given a set of textual properties * @@ -32,7 +31,6 @@ public: template void set_properties(const Assoc& properties); }; -} // namespace xbt -} // namespace simgrid +} // namespace simgrid::xbt #endif diff --git a/include/xbt/asserts.h b/include/xbt/asserts.h index f0d023f883..455e30883a 100644 --- a/include/xbt/asserts.h +++ b/include/xbt/asserts.h @@ -1,6 +1,6 @@ /* xbt/asserts.h -- assertion mechanism */ -/* Copyright (c) 2005-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2005-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/xbt/asserts.hpp b/include/xbt/asserts.hpp index 84f647a047..ab9de25156 100644 --- a/include/xbt/asserts.hpp +++ b/include/xbt/asserts.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -27,7 +27,7 @@ #define _xbt_enforce_ARG1(cond) _xbt_enforce_ARGN((cond), "Assertion %s failed", #cond) #define _xbt_enforce_ARGN(cond, ...) \ do { \ - if (!(cond)) { \ + if (not(cond)) { \ throw simgrid::AssertionError(XBT_THROW_POINT, xbt::string_printf(__VA_ARGS__)); \ } \ } while (0) diff --git a/include/xbt/automaton.h b/include/xbt/automaton.h deleted file mode 100644 index cdd738a694..0000000000 --- a/include/xbt/automaton.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) 2011-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef XBT_AUTOMATON_H -#define XBT_AUTOMATON_H - -#include - -SG_BEGIN_DECL - -typedef struct xbt_automaton_state { - char* id; - int type; /* -1 = init, 0 = inter, 1 = final */ - xbt_dynar_t in; - xbt_dynar_t out; -} s_xbt_automaton_state; - -typedef struct xbt_automaton_state* xbt_automaton_state_t; -typedef const struct xbt_automaton_state* const_xbt_automaton_state_t; - -typedef struct xbt_automaton { - xbt_dynar_t propositional_symbols; - xbt_dynar_t transitions; - xbt_dynar_t states; - xbt_automaton_state_t current_state; -} s_xbt_automaton; - -typedef struct xbt_automaton* xbt_automaton_t; -typedef const struct xbt_automaton* const_xbt_automaton_t; - -typedef struct xbt_automaton_exp_label{ - enum{AUT_OR=0, AUT_AND=1, AUT_NOT=2, AUT_PREDICAT=3, AUT_ONE=4} type; - union{ - struct{ - struct xbt_automaton_exp_label* left_exp; - struct xbt_automaton_exp_label* right_exp; - }or_and; - struct xbt_automaton_exp_label* exp_not; - char* predicat; - }u; -} s_xbt_automaton_exp_label; - -typedef struct xbt_automaton_exp_label* xbt_automaton_exp_label_t; -typedef const struct xbt_automaton_exp_label* const_xbt_automaton_exp_label_t; - -typedef struct xbt_automaton_transition { - xbt_automaton_state_t src; - xbt_automaton_state_t dst; - xbt_automaton_exp_label_t label; -} s_xbt_automaton_transition; - -typedef struct xbt_automaton_transition* xbt_automaton_transition_t; -typedef const struct xbt_automaton_transition* const_xbt_automaton_transition_t; - -typedef struct xbt_automaton_propositional_symbol* xbt_automaton_propositional_symbol_t; -typedef const struct xbt_automaton_propositional_symbol* const_xbt_automaton_propositional_symbol_t; - -typedef int (*xbt_automaton_propositional_symbol_callback_type)(void*); -typedef void (*xbt_automaton_propositional_symbol_free_function_type)(void*); - -XBT_PUBLIC xbt_automaton_t xbt_automaton_new(void); -XBT_PUBLIC void xbt_automaton_load(xbt_automaton_t automaton, const char* file); -XBT_PUBLIC xbt_automaton_state_t xbt_automaton_state_new(const_xbt_automaton_t a, int type, const char* id); -XBT_PUBLIC xbt_automaton_transition_t xbt_automaton_transition_new(const_xbt_automaton_t a, xbt_automaton_state_t src, - xbt_automaton_state_t dst, - xbt_automaton_exp_label_t label); -XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_or(xbt_automaton_exp_label_t left, - xbt_automaton_exp_label_t right); -XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_and(xbt_automaton_exp_label_t left, - xbt_automaton_exp_label_t right); -XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_not(xbt_automaton_exp_label_t exp_not); -XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_predicat(const char* p); -XBT_PUBLIC xbt_automaton_exp_label_t xbt_automaton_exp_label_new_one(void); -XBT_PUBLIC xbt_dynar_t xbt_automaton_get_states(const_xbt_automaton_t a); -XBT_PUBLIC xbt_dynar_t xbt_automaton_get_transitions(const_xbt_automaton_t a); -XBT_PUBLIC xbt_automaton_transition_t xbt_automaton_get_transition(const_xbt_automaton_t a, - const_xbt_automaton_state_t src, - const_xbt_automaton_state_t dst); -XBT_PUBLIC xbt_automaton_state_t xbt_automaton_transition_get_source(const_xbt_automaton_transition_t t); -XBT_PUBLIC xbt_automaton_state_t xbt_automaton_transition_get_destination(const_xbt_automaton_transition_t t); -XBT_PUBLIC void xbt_automaton_transition_set_source(xbt_automaton_transition_t t, xbt_automaton_state_t src); -XBT_PUBLIC void xbt_automaton_transition_set_destination(xbt_automaton_transition_t t, xbt_automaton_state_t dst); -XBT_PUBLIC xbt_dynar_t xbt_automaton_state_get_out_transitions(const_xbt_automaton_state_t s); -XBT_PUBLIC xbt_dynar_t xbt_automaton_state_get_in_transitions(const_xbt_automaton_state_t s); -XBT_PUBLIC xbt_automaton_state_t xbt_automaton_state_exists(const_xbt_automaton_t a, const char* id); -XBT_PUBLIC void xbt_automaton_display(const_xbt_automaton_t a); -XBT_PUBLIC void xbt_automaton_exp_label_display(const_xbt_automaton_exp_label_t l); - -// xbt_automaton_propositional_symbol constructors: -XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new(const_xbt_automaton_t a, - const char* id, - int (*fct)(void)); -XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new_pointer(const_xbt_automaton_t a, - const char* id, - int* value); -XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new_callback( - const_xbt_automaton_t a, const char* id, xbt_automaton_propositional_symbol_callback_type callback, void* data, - xbt_automaton_propositional_symbol_free_function_type free_function); - -// xbt_automaton_propositional_symbol accessors: -XBT_PUBLIC xbt_automaton_propositional_symbol_callback_type -xbt_automaton_propositional_symbol_get_callback(const_xbt_automaton_propositional_symbol_t symbol); -XBT_PUBLIC void* xbt_automaton_propositional_symbol_get_data(const_xbt_automaton_propositional_symbol_t symbol); -XBT_PUBLIC const char* xbt_automaton_propositional_symbol_get_name(const_xbt_automaton_propositional_symbol_t symbol); - -// xbt_automaton_propositional_symbol methods! -XBT_PUBLIC int xbt_automaton_propositional_symbol_evaluate(const_xbt_automaton_propositional_symbol_t symbol); - -XBT_PUBLIC xbt_automaton_state_t xbt_automaton_get_current_state(const_xbt_automaton_t a); -XBT_PUBLIC int xbt_automaton_state_compare(const_xbt_automaton_state_t s1, const_xbt_automaton_state_t s2); -XBT_PUBLIC int xbt_automaton_propositional_symbols_compare_value(const_xbt_dynar_t s1, const_xbt_dynar_t s2); -XBT_PUBLIC int xbt_automaton_transition_compare(const_xbt_automaton_transition_t t1, - const_xbt_automaton_transition_t t2); -XBT_PUBLIC int xbt_automaton_exp_label_compare(const_xbt_automaton_exp_label_t l1, const_xbt_automaton_exp_label_t l2); -XBT_PUBLIC void xbt_automaton_state_free_voidp(void* s); -XBT_PUBLIC void xbt_automaton_state_free(xbt_automaton_state_t s); -XBT_PUBLIC void xbt_automaton_transition_free_voidp(void* t); -XBT_PUBLIC void xbt_automaton_exp_label_free_voidp(void* e); -XBT_PUBLIC void xbt_automaton_propositional_symbol_free_voidp(void* ps); -XBT_PUBLIC void xbt_automaton_free(xbt_automaton_t a); - -SG_END_DECL - -#endif diff --git a/include/xbt/automaton.hpp b/include/xbt/automaton.hpp deleted file mode 100644 index 8c4ac2e9b5..0000000000 --- a/include/xbt/automaton.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef XBT_AUTOMATON_HPP -#define XBT_AUTOMATON_HPP - -#include - -#include - -namespace simgrid { -namespace xbt { - -/** Add a proposition to an automaton (the C++ way) - * - * This API hides all the callback and dynamic allocation hell from - * the used which can use C++ style functors and lambda expressions. - */ -template xbt_automaton_propositional_symbol_t add_proposition(const_xbt_automaton_t a, const char* id, F f) -{ - auto* callback = new F(std::move(f)); - return xbt_automaton_propositional_symbol_new_callback( - a, id, [](auto* cb) -> int { return (*(F*)cb)(); }, callback, [](auto* cb) -> void { delete (F*)cb; }); -} - -} -} -#endif diff --git a/include/xbt/backtrace.hpp b/include/xbt/backtrace.hpp index 4e53a8fa63..c220965250 100644 --- a/include/xbt/backtrace.hpp +++ b/include/xbt/backtrace.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2005-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -17,8 +17,7 @@ SG_BEGIN_DECL XBT_PUBLIC void xbt_backtrace_display_current(); SG_END_DECL -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { class BacktraceImpl; /** A backtrace @@ -38,6 +37,5 @@ public: void display() const; }; -} -} +} // namespace simgrid::xbt #endif diff --git a/include/xbt/base.h b/include/xbt/base.h index c6b9787e6c..ceb0fb2be1 100644 --- a/include/xbt/base.h +++ b/include/xbt/base.h @@ -1,6 +1,6 @@ -/* xbt.h - Public interface to the xbt (simgrid's toolbox) */ +/* xbt.h - Public interface to the xbt (SimGrid's toolbox) */ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,19 +13,8 @@ # define _GNU_SOURCE #endif -/* On MinGW, stdio.h defines __MINGW_PRINTF_FORMAT and __MINGW_SCANF_FORMAT - which are the suitable format style (either gnu_printf or ms_printf) - depending on which version is available (__USE_MINGW_ANSI_STDIO): */ -#ifdef __MINGW32__ -# include - -#define XBT_ATTRIB_PRINTF(format_idx, arg_idx) \ - __attribute__((__format__(__MINGW_PRINTF_FORMAT, (format_idx), (arg_idx)))) -#define XBT_ATTRIB_SCANF(format_idx, arg_idx) __attribute__((__MINGW_SCANF_FORMAT(__scanf__, (format_idx), (arg_idx)))) -#else #define XBT_ATTRIB_PRINTF(format_idx, arg_idx) __attribute__((__format__(__printf__, (format_idx), (arg_idx)))) #define XBT_ATTRIB_SCANF(format_idx, arg_idx) __attribute__((__format__(__scanf__, (format_idx), (arg_idx)))) -#endif #if defined(__cplusplus) #if __cplusplus >= 201103L @@ -53,14 +42,12 @@ #define XBT_ATTRIB_DEPRECATED(mesg) __attribute__((deprecated(mesg))) #endif -#define XBT_ATTRIB_DEPRECATED_v333(mesg) \ - XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped after v3.32)") -#define XBT_ATTRIB_DEPRECATED_v334(mesg) \ - XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped after v3.33)") -#define XBT_ATTRIB_DEPRECATED_v335(mesg) \ - XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped after v3.34)") -#define XBT_ATTRIB_DEPRECATED_v336(mesg) \ - XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped after v3.35)") +#define XBT_ATTRIB_DEPRECATED_v338(mesg) \ + XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped after v3.37)") +#define XBT_ATTRIB_DEPRECATED_v339(mesg) \ + XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped after v3.38)") +#define XBT_ATTRIB_DEPRECATED_v340(mesg) \ + XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped after v3.39)") /* Work around https://github.com/microsoft/vscode-cpptools/issues/4503 */ #ifdef __INTELLISENSE__ @@ -75,12 +62,12 @@ # define XBT_ATTRIB_DESTRUCTOR(prio) __attribute__((__destructor__)) #endif -#ifndef XBT_ALWAYS_INLINE /* defined also in libsosp */ -# if defined(__GNUC__) -# define XBT_ALWAYS_INLINE inline __attribute__ ((always_inline)) -# else -# define XBT_ALWAYS_INLINE inline -# endif +#define XBT_ATTRIB_NOINLINE __attribute__((noinline)) + +#if defined(__GNUC__) +#define XBT_ALWAYS_INLINE inline __attribute__((always_inline)) +#else +#define XBT_ALWAYS_INLINE inline #endif /* Stringify argument. */ @@ -148,64 +135,27 @@ #define _XBT_STRINGIFY_A_22_(a, ...) #a, _XBT_IF_ONE_ARG(_XBT_STRINGIFY, _XBT_STRINGIFY_A_23_, __VA_ARGS__)(__VA_ARGS__) #define _XBT_STRINGIFY_A_23_(a, ...) #a, _XBT_IF_ONE_ARG(_XBT_STRINGIFY, _XBT_STRINGIFY_A_24_, __VA_ARGS__)(__VA_ARGS__) #define _XBT_STRINGIFY_A_24_(a, ...) #a, _XBT_IF_ONE_ARG(_XBT_STRINGIFY, _XBT_STRINGIFY_A_25_, __VA_ARGS__)(__VA_ARGS__) -#define _XBT_STRINGIFY_A_25_(...) error_maximum_size_of_XBT_STRINGIFY_ARGS_reached - -/* Handle import/export stuff - * - * Rationale of XBT_PUBLIC: +#define _XBT_STRINGIFY_A_25_(a, ...) #a, _XBT_IF_ONE_ARG(_XBT_STRINGIFY, _XBT_STRINGIFY_A_26_, __VA_ARGS__)(__VA_ARGS__) +#define _XBT_STRINGIFY_A_26_(a, ...) #a, _XBT_IF_ONE_ARG(_XBT_STRINGIFY, _XBT_STRINGIFY_A_27_, __VA_ARGS__)(__VA_ARGS__) +#define _XBT_STRINGIFY_A_27_(a, ...) #a, _XBT_IF_ONE_ARG(_XBT_STRINGIFY, _XBT_STRINGIFY_A_28_, __VA_ARGS__)(__VA_ARGS__) +#define _XBT_STRINGIFY_A_28_(a, ...) #a, _XBT_IF_ONE_ARG(_XBT_STRINGIFY, _XBT_STRINGIFY_A_29_, __VA_ARGS__)(__VA_ARGS__) +#define _XBT_STRINGIFY_A_29_(a, ...) #a, _XBT_IF_ONE_ARG(_XBT_STRINGIFY, _XBT_STRINGIFY_A_30_, __VA_ARGS__)(__VA_ARGS__) +#define _XBT_STRINGIFY_A_30_(...) error_maximum_size_of_XBT_STRINGIFY_ARGS_reached + +/* Rationale of XBT_PUBLIC: * * This is for library symbols visible from the application-land. * Basically, any symbols defined in the include/directory must be like this (plus some other globals). * - * UNIX coders should just think of it as a special way to say "extern". - * - * * If you build the DLL, define the DLL_EXPORT symbol so that all symbols actually get exported by this file. - * - * * If you link your application against the DLL or if you do a UNIX build, don't do anything special. This file - * will do the right thing for you by default. - * - * Rationale of XBT_EXPORT_NO_IMPORT: (windows-only) - * * Symbols which must be exported in the DLL, but not imported from it. - * - * * This is obviously useful for initialized globals (which cannot be extern or similar). - * * This is also used in the log mechanism where a macro creates the variable automatically. When the macro is - * called from within SimGrid, the symbol must be exported, but when called from within the client code, it must - * not try to retrieve the symbol from the DLL since it's not in there. - * - * Rationale of XBT_IMPORT_NO_EXPORT: (windows-only) - * * Symbols which must be imported from the DLL, but not explicitly exported from it. - * - * * The root log category is already exported, but not imported explicitly when creating a subcategory since we - * cannot import the parent category to deal with the fact that the parent may be in application space, not DLL - * space. + * Just think of it as a special way to say "extern". */ -/* Build the DLL */ -#if defined(DLL_EXPORT) -# define XBT_PUBLIC __declspec(dllexport) -# define XBT_EXPORT_NO_IMPORT __declspec(dllexport) -# define XBT_IMPORT_NO_EXPORT -# define XBT_PUBLIC_DATA extern __declspec(dllexport) -# define XBT_PRIVATE - -/* Link against the DLL */ -#elif (defined(_WIN32) && !defined(DLL_EXPORT)) -# define XBT_PUBLIC __declspec(dllimport) -# define XBT_EXPORT_NO_IMPORT -# define XBT_IMPORT_NO_EXPORT __declspec(dllimport) -# define XBT_PUBLIC_DATA extern __declspec(dllimport) -# define XBT_PRIVATE - -#elif defined(__ELF__) -# define XBT_PUBLIC __attribute__((visibility("default"))) -# define XBT_EXPORT_NO_IMPORT __attribute__((visibility("default"))) -# define XBT_IMPORT_NO_EXPORT __attribute__((visibility("default"))) +#if defined(__ELF__) +#define XBT_PUBLIC __attribute__((visibility("default"))) # define XBT_PUBLIC_DATA extern __attribute__((visibility("default"))) # define XBT_PRIVATE __attribute__((visibility("hidden"))) #else -# define XBT_PUBLIC /* public */ -# define XBT_EXPORT_NO_IMPORT -# define XBT_IMPORT_NO_EXPORT +#define XBT_PUBLIC /* public */ # define XBT_PUBLIC_DATA extern # define XBT_PRIVATE /** @private */ diff --git a/include/xbt/config.h b/include/xbt/config.h index f334866654..8d73be60c0 100644 --- a/include/xbt/config.h +++ b/include/xbt/config.h @@ -1,7 +1,7 @@ /* config - Dictionary where the type of each cell is provided. */ /* This is useful to build named structs, like option or property sets. */ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/xbt/config.hpp b/include/xbt/config.hpp index 59dfd0aee6..bb5ee91f36 100644 --- a/include/xbt/config.hpp +++ b/include/xbt/config.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,8 +22,7 @@ #include #include -namespace simgrid { -namespace config { +namespace simgrid::config { class Config; @@ -77,6 +76,10 @@ extern template XBT_PUBLIC double const& get_value(const std::string& na extern template XBT_PUBLIC bool const& get_value(const std::string& name); extern template XBT_PUBLIC std::string const& get_value(const std::string& name); +// ***** alias ***** + +XBT_PUBLIC void alias(const char* realname, std::initializer_list aliases); + // Register: /** Register a configuration flag @@ -88,7 +91,14 @@ extern template XBT_PUBLIC std::string const& get_value(const std:: */ template XBT_PUBLIC void declare_flag(const std::string& name, const std::string& description, T value, - std::function callback = std::function()); + std::function callback = nullptr); +template +void declare_flag(const std::string& name, std::initializer_list aliases, const std::string& description, + T value, std::function callback = nullptr) +{ + declare_flag(name, description, std::move(value), std::move(callback)); + alias(name.c_str(), aliases); +} extern template XBT_PUBLIC void declare_flag(const std::string& name, const std::string& description, int value, std::function callback); @@ -99,10 +109,6 @@ extern template XBT_PUBLIC void declare_flag(const std::string& name, const std: extern template XBT_PUBLIC void declare_flag(const std::string& name, const std::string& description, std::string value, std::function callback); -// ***** alias ***** - -XBT_PUBLIC void alias(const char* realname, std::initializer_list aliases); - /** Bind a variable to configuration flag * * @param value Bound variable @@ -133,7 +139,7 @@ void bind_flag(T& value, const char* name, std::initializer_list al */ // F is a checker, F : T& -> () template -typename std::enable_if_t()(std::declval()))>::value, void> +typename std::enable_if_t()(std::declval()))>, void> bind_flag(T& value, const char* name, const char* description, F callback) { declare_flag(name, description, value, std::function([&value, callback](const T& val) { @@ -143,7 +149,7 @@ bind_flag(T& value, const char* name, const char* description, F callback) } template -typename std::enable_if_t()(std::declval()))>::value, void> +typename std::enable_if_t()(std::declval()))>, void> bind_flag(T& value, const char* name, std::initializer_list aliases, const char* description, F callback) { bind_flag(value, name, description, std::move(callback)); @@ -151,8 +157,7 @@ bind_flag(T& value, const char* name, std::initializer_list aliases } template -typename std::enable_if_t()(std::declval()))>::value, - void> +typename std::enable_if_t()(std::declval()))>, void> bind_flag(std::string& value, const char* name, const char* description, const std::map>& valid_values, F callback) { @@ -167,15 +172,14 @@ bind_flag(std::string& value, const char* name, const char* description, if (val == "help") mesg += std::string("Possible values for option ") + name + ":\n"; else - mesg += std::string("Invalid value '") + val + "' for option " + name + ". Possible values:\n"; - for (auto const& kv : valid_values) - mesg += " - '" + kv.first + "': " + kv.second + (kv.first == value ? " <=== DEFAULT" : "") + "\n"; + mesg += "Invalid value '" + val + "' for option " + name + ". Possible values:\n"; + for (auto const& [v, descr] : valid_values) + mesg += " - '" + v + "': " + descr + (v == value ? " <=== DEFAULT" : "") + "\n"; xbt_die("%s", mesg.c_str()); })); } template -typename std::enable_if_t()(std::declval()))>::value, - void> +typename std::enable_if_t()(std::declval()))>, void> bind_flag(std::string& value, const char* name, std::initializer_list aliases, const char* description, const std::map>& valid_values, F callback) { @@ -192,7 +196,7 @@ bind_flag(std::string& value, const char* name, std::initializer_list bool template -typename std::enable_if_t()(std::declval()))>::value, void> +typename std::enable_if_t()(std::declval()))>, void> bind_flag(T& value, const char* name, const char* description, F callback) { declare_flag(name, description, value, std::function([&value, callback](const T& val) { @@ -254,6 +258,17 @@ public: /* A constructor accepting a map of valid values -> their description, * and producing an informative error message when an invalid value is passed, or when help is passed as a value. */ + Flag(const char* name, const char* desc, xbt::type_identity_t value, + const std::map>& valid_values) + : value_(value), name_(name) + { + simgrid::config::bind_flag(value_, name, desc, valid_values, [](const std::string&) {}); + } + + /* As earlier, a constructor accepting a map of valid values -> their description, + * and producing an informative error message when an invalid value is passed, or when help is passed as a value. + * But also take a callback that is invoked before the verification of parameter name validity. + */ template Flag(const char* name, const char* desc, xbt::type_identity_t value, const std::map>& valid_values, F callback) @@ -307,7 +322,6 @@ XBT_PUBLIC void finalize(); XBT_PUBLIC void show_aliases(); XBT_PUBLIC void help(); -} // namespace config -} // namespace simgrid +} // namespace simgrid::config #endif diff --git a/include/xbt/dict.h b/include/xbt/dict.h index 4dfbd4f27d..d5867aded3 100644 --- a/include/xbt/dict.h +++ b/include/xbt/dict.h @@ -1,6 +1,6 @@ /* xbt/dict.h -- api to a generic dictionary */ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/xbt/dynar.h b/include/xbt/dynar.h index 89d0f2f6b4..bd014f25b2 100644 --- a/include/xbt/dynar.h +++ b/include/xbt/dynar.h @@ -1,6 +1,6 @@ /* dynar - a generic dynamic array */ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/xbt/ex.h b/include/xbt/ex.h index a7b8d0e72b..f221afea87 100644 --- a/include/xbt/ex.h +++ b/include/xbt/ex.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2005-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,7 +11,6 @@ #include #include #include -#include /** @addtogroup XBT_ex_c * @brief Exceptions support (C) diff --git a/include/xbt/file.hpp b/include/xbt/file.hpp index f31364e569..afb262290b 100644 --- a/include/xbt/file.hpp +++ b/include/xbt/file.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,10 +7,16 @@ #define XBT_FILE_HPP #include +#include #include -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { + +void path_push(std::string const& str); +void path_pop(); +FILE* path_fopen(const std::string& name, const char* mode); +std::ifstream* path_ifsopen(const std::string& name); +std::string path_to_string(); class Path { public: @@ -31,6 +37,6 @@ public: private: std::string path_; }; -}} +} // namespace simgrid::xbt #endif /* XBT_FILE_HPP */ diff --git a/include/xbt/function_types.h b/include/xbt/function_types.h index 49f4754dee..16431a1c2a 100644 --- a/include/xbt/function_types.h +++ b/include/xbt/function_types.h @@ -1,6 +1,6 @@ /* function_type.h - classical types for pointer to function */ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,6 +22,9 @@ typedef int (*int_f_int_pvoid_t)(int, void*); typedef int (*int_f_pvoid_pvoid_t) (void *, void *); typedef int (*int_f_cpvoid_cpvoid_t) (const void *, const void *); +/** Prototype of an actor's main function + * + * The only difference with a classical main() in C is that the return type is void */ typedef void (*xbt_main_func_t)(int argc, char* argv[]); SG_END_DECL diff --git a/include/xbt/functional.hpp b/include/xbt/functional.hpp index 9509d49aa8..9d1b337c49 100644 --- a/include/xbt/functional.hpp +++ b/include/xbt/functional.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -23,8 +23,7 @@ #include #include -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { template class MainFunction { F code_; @@ -74,12 +73,12 @@ constexpr auto apply(F&& f, Tuple&& t, std::index_sequence) * @endcode **/ template -constexpr auto apply(F&& f, Tuple&& t) -> decltype( - simgrid::xbt::bits::apply(std::forward(f), std::forward(t), - std::make_index_sequence>::value>())) +constexpr auto apply(F&& f, Tuple&& t) + -> decltype(simgrid::xbt::bits::apply(std::forward(f), std::forward(t), + std::make_index_sequence>>())) { return simgrid::xbt::bits::apply(std::forward(f), std::forward(t), - std::make_index_sequence>::value>()); + std::make_index_sequence>>()); } template class Task; @@ -179,7 +178,7 @@ private: return code(std::forward(args)...); }, // Destroy: - std::is_trivially_destructible::value ? + std::is_trivially_destructible_v ? static_cast(nullptr) : [](TaskUnion& buffer) { auto* code = reinterpret_cast(&buffer); @@ -260,6 +259,5 @@ template auto make_task(F code, Args... args) -> Task(std::move(task)); } -} // namespace xbt -} // namespace simgrid +} // namespace simgrid::xbt #endif diff --git a/include/xbt/graph.h b/include/xbt/graph.h index e5fc1c8c3f..39982b3576 100644 --- a/include/xbt/graph.h +++ b/include/xbt/graph.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/xbt/log.h b/include/xbt/log.h index 423f28769d..49adae5a85 100644 --- a/include/xbt/log.h +++ b/include/xbt/log.h @@ -1,6 +1,6 @@ /* log - a generic logging facility in the spirit of log4j */ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -93,7 +93,7 @@ typedef enum { XBT_LOG_EXTERNAL_CATEGORY(catName); \ (void)_xbt_log_cat_init(&_XBT_LOGV(catName), xbt_log_priority_uninitialized); \ } \ - XBT_EXPORT_NO_IMPORT s_xbt_log_category_t _XBT_LOGV(catName) = { \ + s_xbt_log_category_t _XBT_LOGV(catName) = { \ &_XBT_LOGV(parent), \ NULL /* firstChild */, \ NULL /* nextSibling */, \ @@ -307,18 +307,7 @@ XBT_PUBLIC void xbt_log_init(int* argc, char** argv); XBT_PUBLIC void _xbt_log_event_log(xbt_log_event_t ev, const char* fmt, ...) XBT_ATTRIB_PRINTF(2, 3); XBT_PUBLIC int _xbt_log_cat_init(xbt_log_category_t category, e_xbt_log_priority_t priority); -#ifdef DLL_EXPORT -XBT_PUBLIC_DATA s_xbt_log_category_t _XBT_LOGV(XBT_LOG_ROOT_CAT); -#else -// If we `dllexport` the root log category, MinGW does not want us to take its address with the error: -// > initializer element is not constant -// When using auto-import, MinGW is happy. -// We should handle this for non-root log categories as well. extern s_xbt_log_category_t _XBT_LOGV(XBT_LOG_ROOT_CAT); -#endif - -extern xbt_log_appender_t xbt_log_default_appender; -extern xbt_log_layout_t xbt_log_default_layout; /* ********************** */ /* Public functions again */ diff --git a/include/xbt/log.hpp b/include/xbt/log.hpp index f71795f7d1..e2598edfad 100644 --- a/include/xbt/log.hpp +++ b/include/xbt/log.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,8 +9,7 @@ #include #include -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { /** Display information about an exception * @@ -23,7 +22,6 @@ XBT_PUBLIC void log_exception(e_xbt_log_priority_t priority, const char* context XBT_PUBLIC void install_exception_handler(); -} // namespace xbt -} // namespace simgrid +} // namespace simgrid::xbt -#endif \ No newline at end of file +#endif diff --git a/include/xbt/mallocator.h b/include/xbt/mallocator.h index b8652551ef..e9b4cf4eca 100644 --- a/include/xbt/mallocator.h +++ b/include/xbt/mallocator.h @@ -1,6 +1,6 @@ /* xbt/mallocator.h -- api to recycle allocated objects */ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -47,7 +47,7 @@ XBT_PUBLIC void xbt_mallocator_free(xbt_mallocator_t mallocator); XBT_PUBLIC void* xbt_mallocator_get(xbt_mallocator_t mallocator); XBT_PUBLIC void xbt_mallocator_release(xbt_mallocator_t mallocator, void* object); -XBT_PUBLIC void xbt_mallocator_initialization_is_done(int protect); +XBT_PUBLIC void xbt_mallocator_initialization_is_done(int need_protection); /** @} */ SG_END_DECL diff --git a/include/xbt/misc.h b/include/xbt/misc.h index 4b159a7b8d..0c45e62926 100644 --- a/include/xbt/misc.h +++ b/include/xbt/misc.h @@ -1,6 +1,6 @@ -/* xbt.h - Public interface to the xbt (simgrid's toolbox) */ +/* xbt.h - Public interface to the xbt (SimGrid's toolbox) */ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,10 +15,10 @@ SG_BEGIN_DECL /** Cache the size of a memory page for the current system. */ -XBT_PUBLIC_DATA int xbt_pagesize; +XBT_PUBLIC_DATA const int xbt_pagesize; /** Cache the number of bits of addresses inside a given page, log2(xbt_pagesize). */ -XBT_PUBLIC_DATA int xbt_pagebits; +XBT_PUBLIC_DATA const int xbt_pagebits; /** Helps ensuring that header version (SIMGRID_VERSION_MAJOR and friends) and dynamic library version do match. */ XBT_PUBLIC void sg_version_check(int lib_version_major, int lib_version_minor, int lib_version_patch); diff --git a/include/xbt/module.h b/include/xbt/module.h index fffd81ebc5..601f7f400b 100644 --- a/include/xbt/module.h +++ b/include/xbt/module.h @@ -1,6 +1,6 @@ /* module - modularize the code */ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,11 +8,18 @@ #ifndef XBT_MODULE_H #define XBT_MODULE_H -#include /* XBT_PUBLIC */ +// Deprecation warning on include (remove entire file with XBT_ATTRIB_DEPRECATED_v338) +#warning xbt/module.h is deprecated and will be removed after v3.37. + +#include +#include SG_BEGIN_DECL -XBT_PUBLIC void xbt_init(int* argc, char** argv); +XBT_ATTRIB_DEPRECATED_v338("Please use simgrid_init(&argc, argv) instead") static void xbt_init(int* argc, char** argv) +{ + simgrid_init(argc, argv); +} SG_END_DECL diff --git a/include/xbt/parmap.h b/include/xbt/parmap.h index c6d60df0ba..8fba478de9 100644 --- a/include/xbt/parmap.h +++ b/include/xbt/parmap.h @@ -1,6 +1,6 @@ /* A thread pool. */ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/include/xbt/parse_units.hpp b/include/xbt/parse_units.hpp index 0e82ae0163..1c8f6e8f85 100644 --- a/include/xbt/parse_units.hpp +++ b/include/xbt/parse_units.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/include/xbt/promise.hpp b/include/xbt/promise.hpp index 09ac8f017d..dc19907471 100644 --- a/include/xbt/promise.hpp +++ b/include/xbt/promise.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -17,8 +17,7 @@ #include #include -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { /** A value or an exception (or nothing) * @@ -126,7 +125,6 @@ template inline void set_promise(P& promise, F&& future) { fulfill_promise(promise, [&future] { return std::forward(future).get(); }); } -} -} +} // namespace simgrid::xbt #endif diff --git a/include/xbt/random.hpp b/include/xbt/random.hpp index 35d2809469..a5c4c7906f 100644 --- a/include/xbt/random.hpp +++ b/include/xbt/random.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,9 +12,7 @@ #include #include -namespace simgrid { -namespace xbt { -namespace random { +namespace simgrid::xbt::random { /** A random number generator. * @@ -162,8 +160,6 @@ double exponential(double lambda); * @param sd Standard deviation of the normal distribution */ double normal(double mean, double sd); -} // namespace random -} // namespace xbt -} // namespace simgrid +} // namespace simgrid::xbt::random #endif diff --git a/include/xbt/range.hpp b/include/xbt/range.hpp index e5fd1efa0c..47f021e6bf 100644 --- a/include/xbt/range.hpp +++ b/include/xbt/range.hpp @@ -1,5 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,8 +8,7 @@ #include -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { /** Describes a contiguous inclusive-exclusive [a,b) range of values */ template class Range { @@ -28,7 +26,6 @@ public: bool contain(T const& x) const { return begin_ <= x && end_ > x; } }; -} -} +} // namespace simgrid::xbt #endif diff --git a/include/xbt/replay.hpp b/include/xbt/replay.hpp index 6f16a6617c..e6da188839 100644 --- a/include/xbt/replay.hpp +++ b/include/xbt/replay.hpp @@ -1,6 +1,6 @@ /* xbt/replay.hpp -- Tools to parse a replay file */ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,8 +15,7 @@ #include #include -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { /* To split the file if a unique one is given (specific variable for the other case live in runner()) */ using ReplayAction = std::vector; @@ -26,8 +25,7 @@ using ReplayAction = std::vector; * xbt_replay_set_tracefile(). If trace_filename is not nullptr, then it's not shared and this trace file is for this * actor only */ XBT_PUBLIC int replay_runner(const char* actor_name, const char* trace_filename = nullptr); -} -} +} // namespace simgrid::xbt using action_fun = std::function; XBT_PUBLIC void xbt_replay_action_register(const char* action_name, const action_fun& function); diff --git a/include/xbt/signal.hpp b/include/xbt/signal.hpp index 4a16d1ebbd..70c477f6e6 100644 --- a/include/xbt/signal.hpp +++ b/include/xbt/signal.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,8 +10,7 @@ #include #include -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { template class signal; @@ -35,17 +34,14 @@ public: /** Fire that signal, invoking all callbacks */ R operator()(P... args) const { - for (auto const& handler : handlers_) - handler.second(args...); + for (auto const& [_, callback] : handlers_) + callback(args...); } /** Remove a callback */ void disconnect(unsigned int id) { handlers_.erase(id); } /** Remove all callbacks */ void disconnect_slots() { handlers_.clear(); } - /** Get the amount of callbacks */ - int get_slot_count() { return handlers_.size(); } }; -} -} +} // namespace simgrid::xbt #endif diff --git a/include/xbt/str.h b/include/xbt/str.h index 4030cf9eda..0d509b0c64 100644 --- a/include/xbt/str.h +++ b/include/xbt/str.h @@ -1,6 +1,6 @@ /* str.h - XBT string related functions. */ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/include/xbt/string.hpp b/include/xbt/string.hpp index a4624489fb..ff9d695d6e 100644 --- a/include/xbt/string.hpp +++ b/include/xbt/string.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,26 +6,13 @@ #ifndef SIMGRID_XBT_STRING_HPP #define SIMGRID_XBT_STRING_HPP -#include +#include "xbt/base.h" #include #include #include -#if SIMGRID_HAVE_MC - -#include -#include -#include -#include -#include - -#include - -#endif - -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { /** Create a C++ string from a C-style format * @@ -39,281 +26,5 @@ XBT_PUBLIC std::string string_printf(const char* fmt, ...) XBT_ATTRIB_PRINTF(1, */ XBT_PUBLIC std::string string_vprintf(const char* fmt, va_list ap) XBT_ATTRIB_PRINTF(1, 0); -#if SIMGRID_HAVE_MC - -/** POD structure representation of a string - */ -struct string_data { - char* data; - std::size_t len; -}; - -/** A std::string-like with well-known representation - * - * HACK, this is a (incomplete) replacement for `std::string`. - * It has a fixed POD representation (`simgrid::xbt::string_data`) - * which can be used to easily read the string content from another - * process. - * - * The internal representation of a `std::string` is private. - * We could add some code to read this for a given implementation. - * However, even if we focus on GNU libstdc++ with Itanium ABI - * GNU libstdc++ currently has two different ABIs - * - * * the pre-C++11 is a pointer to a ref-counted - * string-representation (with support for COW); - * - * * the [C++11-conforming implementation](https://gcc.gnu.org/gcc-5/changes.html) - * does not use refcouting/COW but has a small string optimization. - */ -class XBT_PUBLIC string { - static char NUL; - string_data str; - -public: - // Types - using size_type = std::size_t; - using reference = char&; - using const_reference = const char&; - using iterator = char*; - using const_iterator = const char*; - - // Dtor - ~string() - { - if (str.data != &NUL) - delete[] str.data; - } - - // Ctors - string(const char* s, size_t size) - { - if (size == 0) { - str.len = 0; - str.data = &NUL; - } else { - str.len = size; - str.data = new char[str.len + 1]; - std::copy_n(s, str.len, str.data); - str.data[str.len] = '\0'; - } - } - string() : string(&NUL, 0) {} - explicit string(const char* s) : string(s, strlen(s)) {} - string(string const& s) : string(s.c_str(), s.size()) {} - string(string&& s) noexcept : str(s.str) - { - s.str.len = 0; - s.str.data = &NUL; - } - explicit string(std::string const& s) : string(s.c_str(), s.size()) {} - - // Assign - void assign(const char* s, size_t size) - { - if (str.data != &NUL) { - delete[] str.data; - str.data = nullptr; - str.len = 0; - } - if (size != 0) { - str.len = size; - str.data = new char[str.len + 1]; - std::copy_n(s, str.len, str.data); - str.data[str.len] = '\0'; - } - } - - // Copy - string& operator=(const char* s) - { - assign(s, std::strlen(s)); - return *this; - } - string& operator=(string const& s) - { - if (this != &s) - assign(s.c_str(), s.size()); - return *this; - } - string& operator=(std::string const& s) - { - assign(s.c_str(), s.size()); - return *this; - } - - // Capacity - size_t size() const { return str.len; } - size_t length() const { return str.len; } - bool empty() const { return str.len == 0; } - void shrink_to_fit() { /* Being there, but doing nothing */} - - // Element access - char* data() { return str.data; } - const char* data() const { return str.data; } - char* c_str() { return str.data; } - const char* c_str() const { return str.data; }; - reference at(size_type i) - { - if (i >= size()) - throw std::out_of_range("Out of range"); - return data()[i]; - } - const_reference at(size_type i) const - { - if (i >= size()) - throw std::out_of_range("Out of range"); - return data()[i]; - } - reference operator[](size_type i) - { - return data()[i]; - } - const_reference operator[](size_type i) const - { - return data()[i]; - } - // Conversion - static const string_data& to_string_data(const string& s) { return s.str; } - operator std::string() const { return std::string(this->c_str(), this->size()); } - - // Iterators - iterator begin() { return data(); } - iterator end() { return data() + size(); } - const_iterator begin() const { return data(); } - const_iterator end() const { return data() + size(); } - const_iterator cbegin() const { return data(); } - const_iterator cend() const { return data() + size(); } - // (Missing, reverse iterators) - - // Operations - void clear() - { - str.len = 0; - str.data = &NUL; - } - - size_t copy(char* s, size_t len, size_t pos = 0) const - { - if (pos > str.len) - throw std::out_of_range(string_printf("xbt::string::copy with pos > size() (%zu > %zu)", pos, str.len)); - size_t count = std::min(len, str.len - pos); - std::copy_n(str.data + pos, count, s); - return count; - } - - bool equals(const char* data, std::size_t len) const - { - return this->size() == len - && std::memcmp(this->c_str(), data, len) == 0; - } - - bool operator==(string const& that) const - { - return this->equals(that.c_str(), that.size()); - } - bool operator==(std::string const& that) const - { - return this->equals(that.c_str(), that.size()); - } - bool operator==(const char* that) const - { - return this->equals(that, std::strlen(that)); - } - - template - bool operator!=(X const& that) const - { - return not (*this == that); - } - - // Compare: - int compare(const char* data, std::size_t len) const - { - size_t n = std::min(this->size(), len); - int res = memcmp(this->c_str(), data, n); - if (res != 0) - return res; - else if (this->size() == len) - return 0; - else if (this->size() < len) - return -1; - else - return 1; - } - int compare(string const& that) const - { - return this->compare(that.c_str(), that.size()); - } - int compare(std::string const& that) const - { - return this->compare(that.c_str(), that.size()); - } - int compare(const char* that) const - { - return this->compare(that, std::strlen(that)); - } - - // Define < <= >= > in term of compare(): - template - bool operator<(X const& that) const - { - return this->compare(that) < 0; - } - template - bool operator<=(X const& that) const - { - return this->compare(that) <= 0; - } - template - bool operator>(X const& that) const - { - return this->compare(that) > 0; - } - template - bool operator>=(X const& that) const - { - return this->compare(that) >= 0; - } -}; - -inline -bool operator==(std::string const& a, string const& b) -{ - return b == a; -} -inline -bool operator!=(std::string const& a, string const& b) -{ - return b != a; -} -inline -bool operator<(std::string const& a, string const& b) -{ - return b > a; -} -inline -bool operator<=(std::string const& a, string const& b) -{ - return b >= a; -} -inline -bool operator>(std::string const& a, string const& b) -{ - return b < a; -} -inline -bool operator>=(std::string const& a, string const& b) -{ - return b <= a; -} - -#else - -typedef std::string string; - -#endif -} -} - +} // namespace simgrid::xbt #endif diff --git a/include/xbt/sysdep.h b/include/xbt/sysdep.h index 280093dced..160fb7e396 100644 --- a/include/xbt/sysdep.h +++ b/include/xbt/sysdep.h @@ -2,7 +2,7 @@ /* no system header should be loaded out of this file so that we have only */ /* one file to check when porting to another OS */ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,7 +22,7 @@ SG_BEGIN_DECL #ifdef XBT_LOG_LOCALLY_DEFINE_XBT_CHANNEL -XBT_LOG_NEW_CATEGORY(xbt, "All XBT categories (simgrid toolbox)"); +XBT_LOG_NEW_CATEGORY(xbt, "All XBT categories (SimGrid toolbox)"); XBT_LOG_NEW_SUBCATEGORY(xbt_help, xbt, "Help messages"); #else XBT_LOG_EXTERNAL_CATEGORY(xbt); @@ -78,8 +78,7 @@ static XBT_ALWAYS_INLINE void *xbt_realloc(void *p, size_t s) { return res; } -/** @brief like free - @hideinitializer */ +/** @brief like free */ #define xbt_free(p) free(p) /*nothing specific to do here. A poor valgrind replacement? */ #ifdef __cplusplus diff --git a/include/xbt/system_error.hpp b/include/xbt/system_error.hpp index 198322e168..c94eaff884 100644 --- a/include/xbt/system_error.hpp +++ b/include/xbt/system_error.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. +/* Copyright (c) 2016-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -11,8 +11,7 @@ #ifndef SIMGRID_MC_SYSTEM_ERROR_HPP #define SIMGRID_MC_SYSTEM_ERROR_HPP -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { /** A `error_category` suitable to be used with `errno` * @@ -82,7 +81,6 @@ std::system_error errno_error(const char* what) return std::system_error(errno_code(), what); } -} -} +} // namespace simgrid::xbt #endif diff --git a/include/xbt/utility.hpp b/include/xbt/utility.hpp index 03458064d3..c35be72d7f 100644 --- a/include/xbt/utility.hpp +++ b/include/xbt/utility.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. +/* Copyright (c) 2016-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -25,10 +25,13 @@ constexpr std::array names{{_XBT_STRINGIFY_ARGS(__VA_ARGS__)}}; \ return names.at(static_cast(value)); \ } \ + static constexpr bool is_valid_##EnumType(int raw_value) \ + { \ + return raw_value >= 0 && raw_value < _XBT_COUNT_ARGS(__VA_ARGS__); \ + } \ enum class EnumType { __VA_ARGS__ } /* defined here to handle trailing semicolon */ -namespace simgrid { -namespace xbt { +namespace simgrid::xbt { /** @brief Replacement for C++20's std::type_identity_t */ @@ -76,6 +79,5 @@ template inline void intrusive_erase(List& list, Elem& list.erase(list.iterator_to(elem)); } -} -} +} // namespace simgrid::xbt #endif diff --git a/include/xbt/virtu.h b/include/xbt/virtu.h index db38c00466..53ccfaf1e9 100644 --- a/include/xbt/virtu.h +++ b/include/xbt/virtu.h @@ -1,6 +1,6 @@ /* virtu - virtualization layer for the logging to know about the actors */ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,29 +8,23 @@ #ifndef XBT_VIRTU_H #define XBT_VIRTU_H +#include #include -#ifdef __cplusplus -#include -#include - -namespace simgrid { -namespace xbt { - -/* Get the name of the UNIX process englobing the world */ -XBT_PUBLIC_DATA std::string binary_name; -/** Contains all the parameters we got from the command line (including argv[0]) */ -XBT_PUBLIC_DATA std::vector cmdline; - -} // namespace xbt -} // namespace simgrid -#endif +// Deprecation warning on include (remove entire file with XBT_ATTRIB_DEPRECATED_v338) +#warning xbt/virtu.h is deprecated and will be removed after v3.37. SG_BEGIN_DECL -XBT_PUBLIC const char* xbt_procname(void); +XBT_ATTRIB_DEPRECATED_v338("Please use sg_actor_self_get_name()") static const char* xbt_procname(void) +{ + return sg_actor_self_get_name(); +} -XBT_PUBLIC int xbt_getpid(void); +XBT_ATTRIB_DEPRECATED_v338("Please use sg_actor_self_get_pid()") static int xbt_getpid(void) +{ + return sg_actor_self_get_pid(); +}; SG_END_DECL diff --git a/include/xbt/xbt_os_time.h b/include/xbt/xbt_os_time.h index e0b9bd7981..9ebb2fbe6a 100644 --- a/include/xbt/xbt_os_time.h +++ b/include/xbt/xbt_os_time.h @@ -1,6 +1,6 @@ /* xbt/xbt_os_timer.h -- system dependency on time functions */ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/setup.py b/setup.py index 21877a1b07..241dd33b05 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL-2.1-only) which comes with this package. @@ -38,13 +38,7 @@ class CMakeBuild(build_ext): if not os.path.exists("MANIFEST.in"): raise RuntimeError( - "Please generate a MANIFEST.in file (configure simgrid, and copy it here if you build out of tree)") - - if platform.system() == "Windows": - cmake_version = LooseVersion( - re.search(r'version\s*([\d.]+)', out.decode()).group(1)) - if cmake_version < '3.1.0': - raise RuntimeError("CMake >= 3.1.0 is required on Windows") + "Please generate a MANIFEST.in file (configure SimGrid, and copy it here if you build out of tree)") for ext in self.extensions: self.build_extension(ext) @@ -56,7 +50,6 @@ class CMakeBuild(build_ext): cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, '-DPYTHON_EXECUTABLE=' + sys.executable, '-Denable_smpi=OFF', - '-Denable_java=OFF', '-Denable_python=ON', '-Dminimal-bindings=ON', '-Dpybind11_DIR=' + get_cmake_dir() @@ -65,15 +58,8 @@ class CMakeBuild(build_ext): cfg = 'Debug' if self.debug else 'Release' build_args = ['--config', cfg] - if platform.system() == "Windows": - cmake_args += [ - '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)] - if sys.maxsize > 2**32: - cmake_args += ['-A', 'x64'] - build_args += ['--', '/m'] - else: - cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] - build_args += ['--', '-j4'] + cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] + build_args += ['--', '-j4'] env = os.environ.copy() env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(env.get('CXXFLAGS', ''), @@ -88,7 +74,7 @@ class CMakeBuild(build_ext): setup( name='simgrid', - version='3.31.1', + version='3.35.1', author='Da SimGrid Team', author_email='simgrid-community@inria.fr', description='Toolkit for scalable simulation of distributed applications', @@ -114,12 +100,10 @@ setup( "License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)", "Operating System :: POSIX", "Operating System :: MacOS", - "Operating System :: Microsoft :: Windows", "Programming Language :: Python :: 3", "Programming Language :: C++", "Programming Language :: C", "Programming Language :: Fortran", - "Programming Language :: Java", "Topic :: System :: Distributed Computing", "Topic :: System :: Systems Administration", ], diff --git a/sonar-project.properties b/sonar-project.properties index 14f25573e0..a9d571e93a 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -4,7 +4,7 @@ sonar.organization=simgrid sonar.projectKey=simgrid_simgrid sonar.projectName=SimGrid -sonar.projectVersion=3.31.1 +sonar.projectVersion=3.35.1 sonar.links.homepage=https://simgrid.org sonar.links.issue=https://framagit.org/simgrid/simgrid/issues @@ -14,40 +14,10 @@ sonar.sources=src,examples,include,teshsuite # Disable some rules on some files -sonar.issue.ignore.multicriteria=j1,j2,j3,j4,jni1,jni2,c1,c2a,c2b,c3,c5a,c5b,c6a,c6b,c7,c8,c9,c10a,c10b,c10c,cex1a,cex1b,cex2a,cex2b,cex3,cex4,cxx17a,cxx17b,cxx17c,cxx17d,cxx17e,cxx17f,f1,p1,s1,s2,s3,s4,s5 - -# The Object.finalize() method should not be overridden -# But we need to clean the native memory with JNI -sonar.issue.ignore.multicriteria.j1.ruleKey=java:S1113 -sonar.issue.ignore.multicriteria.j1.resourceKey=**/*.java - -# Throwable.printStackTrace(...) should not be called -# But we don't have no better mechanism, and our Java apps are not rocket science -sonar.issue.ignore.multicriteria.j2.ruleKey=java:S1148 -sonar.issue.ignore.multicriteria.j2.resourceKey=**/*.java - -# Using command line arguments is security-sensitive -# But the authors of the applications using our library will be their only users, so there is no security concern -sonar.issue.ignore.multicriteria.j3.ruleKey=java:S4823 -sonar.issue.ignore.multicriteria.j3.resourceKey=**/*.java - -# Standard outputs should not be used directly to log anything -# But this file is used before SimGrid is initialized -sonar.issue.ignore.multicriteria.j4.ruleKey=java:S106 -sonar.issue.ignore.multicriteria.j4.resourceKey=src/bindings/java/org/simgrid/NativeLib.java - -# "reinterpret_cast" should not be used -# But this is exactly intended to store a pointer into a long -- what we do here -sonar.issue.ignore.multicriteria.jni1.ruleKey=cpp:S3630 -sonar.issue.ignore.multicriteria.jni1.resourceKey=src/bindings/java/*.cpp - -# Unused function parameters should be removed -# But JNI mandates these parameters -sonar.issue.ignore.multicriteria.jni2.ruleKey=cpp:S1172 -sonar.issue.ignore.multicriteria.jni2.resourceKey=src/bindings/java/*.cpp +sonar.issue.ignore.multicriteria=c1,c2a,c2b,c3,c5a,c5b,c6a,c6b,c7,c8,c9,c10a,c10b,c10c,cex1a,cex1b,cex2a,cex2b,cex3,cex4,f1,p1,s1,s2,s3,s4,s5 # Pointers should not be cast to integral types -# But we need that for jMSG, smpi and other places +# But we need that for smpi and other places sonar.issue.ignore.multicriteria.c1.ruleKey=cpp:S1767 sonar.issue.ignore.multicriteria.c1.resourceKey=**/*.cpp @@ -125,27 +95,6 @@ sonar.issue.ignore.multicriteria.cex3.resourceKey=examples/**/*.c sonar.issue.ignore.multicriteria.cex4.ruleKey=c:S995 sonar.issue.ignore.multicriteria.cex4.resourceKey=examples/**/*.c -# Ignore these C++17 rules in public headers, where we still support C++14 - -# C++17: Concise syntax should be used for concatenatable namespaces -sonar.issue.ignore.multicriteria.cxx17a.ruleKey=cpp:S5812 -sonar.issue.ignore.multicriteria.cxx17a.resourceKey=include/**/* -# C++17: "if","switch", and range-based for loop initializer should be used to reduce scope of variables -sonar.issue.ignore.multicriteria.cxx17b.ruleKey=cpp:S6004 -sonar.issue.ignore.multicriteria.cxx17b.resourceKey=include/**/*.hpp -# C++17: Structured binding should be used -sonar.issue.ignore.multicriteria.cxx17c.ruleKey=cpp:S6005 -sonar.issue.ignore.multicriteria.cxx17c.resourceKey=include/**/*.hpp -# C++17: "std::string_view" should be used to pass a read-only string to a function -sonar.issue.ignore.multicriteria.cxx17d.ruleKey=cpp:S6009 -sonar.issue.ignore.multicriteria.cxx17d.resourceKey=include/**/*.hpp -# C++17: Redundant class template arguments should not be used -sonar.issue.ignore.multicriteria.cxx17e.ruleKey=cpp:S6012 -sonar.issue.ignore.multicriteria.cxx17e.resourceKey=include/**/*.hpp -# C++17: The "_t" and "_v" version of type traits should be used instead of "::type" and "::value" -sonar.issue.ignore.multicriteria.cxx17f.ruleKey=cpp:S6020 -sonar.issue.ignore.multicriteria.cxx17f.resourceKey=include/**/*.hpp - # "reinterpret_cast" should not be used # But we need this to interface C and Fortran sonar.issue.ignore.multicriteria.f1.ruleKey=cpp:S3630 @@ -178,15 +127,13 @@ sonar.issue.ignore.multicriteria.s5.ruleKey=cpp:S995 sonar.issue.ignore.multicriteria.s5.resourceKey=src/smpi/bindings/*.cpp # Exclude some files from the analysis: -# - our unit tests -# - the tests that we borrowed elsewhere (MPICH and MBI) +# - the tests that we borrowed elsewhere (MPICH, MBI, McMini) # - Flex-generated files # - Collectives that we borrowed elsewhere (mpich, openMPI and other implems) # - the NAS, that are included in our examples # - The Catch2 library, that is included in our unit tests # - The xxHash library, used by the MC -# - MSG along with its examples and teshsuite -sonar.exclusions=src/include/catch.hpp,src/include/xxhash.hpp,src/*_unit.c*,teshsuite/smpi/mpich3-test/**,**/*_dtd.c,**/*_dtd.h,**/*yy.c,src/xbt/automaton/parserPromela.tab.*,src/smpi/colls/**/*,examples/smpi/NAS/*,examples/smpi/gemm/gemm.c,src/msg/**,include/msg/**,examples/deprecated/**,teshsuite/msg/** +sonar.exclusions=src/3rd-party/*,teshsuite/smpi/mpich3-test/**,teshsuite/smpi/MBI/**,teshsuite/mc/mcmini/**,**/*_dtd.c,**/*_dtd.h,**/*yy.c,src/smpi/colls/**/*,examples/smpi/NAS/*,examples/smpi/gemm/gemm.c # Exclude our examples from the duplication detection. # Examples are expected to be somehow repetitive @@ -206,26 +153,17 @@ sonar.cfamily.gcov.reportsPath=Testing/CoverageInfo # - examples in smpi/mc (coverage doesn't work with model checker) # - XML files # - Python files used to generate either simcalls or deployment files -# - Any java source code (it's deprecated now) -# - MSG (deprecated too) -sonar.coverage.exclusions=teshsuite/smpi/mpich3-test/**,teshsuite/smpi/MBI/**,examples/smpi/mc/**,**/*.xml,**/generate.py,**/*.java,src/bindings/java/**,src/msg/**,include/msg/**,examples/deprecated/**,teshsuite/msg/** +sonar.coverage.exclusions=teshsuite/smpi/mpich3-test/**,teshsuite/smpi/MBI/**,examples/smpi/mc/**,**/*.xml,**/generate.py, # Encoding of the source files sonar.sourceEncoding=UTF-8 # Version of the used prog languages -sonar.java.source=8 -sonar.java.binaries=CMakeFiles/simgrid-java_jar.dir,examples/deprecated/java -sonar.java.libraries= sonar.python.version=3 ### NOTE: the following properties are overridden by Jenkins configuration ### -#sonar.java.binaries #sonar.cfamily.build-wrapper-output #sonar.cfamily.gcov.reportsPath #sonar.python.coverage.reportPaths -#sonar.coverage.jacoco.xmlReportPaths #sonar.cfamily.threads -#sonar.cfamily.cache.enabled -#sonar.cfamily.cache.path diff --git a/src/include/catch.hpp b/src/3rd-party/catch.hpp similarity index 98% rename from src/include/catch.hpp rename to src/3rd-party/catch.hpp index 9c1c854fd5..9b309bddc6 100644 --- a/src/include/catch.hpp +++ b/src/3rd-party/catch.hpp @@ -1,9 +1,9 @@ /* - * Catch v2.13.5 - * Generated: 2021-04-10 23:43:17.560525 + * Catch v2.13.10 + * Generated: 2022-10-16 11:01:23.452308 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. + * Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,7 +15,7 @@ #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 5 +#define CATCH_VERSION_PATCH 10 #ifdef __clang__ # pragma clang system_header @@ -240,9 +240,6 @@ namespace Catch { // Visual C++ #if defined(_MSC_VER) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) - // Universal Windows platform does not support SEH // Or console colours (or console at all...) # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) @@ -251,13 +248,18 @@ namespace Catch { # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif +# if !defined(__clang__) // Handle Clang masquerading for msvc + // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ // _MSVC_TRADITIONAL == 0 means new conformant preprocessor // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(__clang__) // Handle Clang masquerading for msvc # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR # endif // MSVC_TRADITIONAL + +// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop` +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) # endif // __clang__ #endif // _MSC_VER @@ -326,7 +328,7 @@ namespace Catch { // Check if byte is available and usable # if __has_include() && defined(CATCH_CPP17_OR_GREATER) # include - # if __cpp_lib_byte > 0 + # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) # define CATCH_INTERNAL_CONFIG_CPP17_BYTE # endif # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) @@ -1010,34 +1012,34 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) #endif #endif @@ -1050,7 +1052,7 @@ struct AutoReg : NonCopyable { CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ static void TestName() #define INTERNAL_CATCH_TESTCASE( ... ) \ - INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ @@ -1072,7 +1074,7 @@ struct AutoReg : NonCopyable { CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ void TestName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ - INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ @@ -1113,18 +1115,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \ @@ -1162,18 +1164,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\ @@ -1204,7 +1206,7 @@ struct AutoReg : NonCopyable { static void TestFunc() #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \ - INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList ) + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList ) #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ @@ -1237,18 +1239,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\ @@ -1289,18 +1291,18 @@ struct AutoReg : NonCopyable { #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) #endif #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ - INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) + INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) #else #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ - INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) #endif #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \ @@ -1334,7 +1336,7 @@ struct AutoReg : NonCopyable { void TestName::test() #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \ - INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList ) + INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList ) // end catch_test_registry.h // start catch_capture.hpp @@ -3091,7 +3093,7 @@ namespace Detail { Approx operator-() const; template ::value>::type> - Approx operator()( T const& value ) { + Approx operator()( T const& value ) const { Approx approx( static_cast(value) ); approx.m_epsilon = m_epsilon; approx.m_margin = m_margin; @@ -4163,7 +4165,7 @@ namespace Generators { if (!m_predicate(m_generator.get())) { // It might happen that there are no values that pass the // filter. In that case we throw an exception. - auto has_initial_value = next(); + auto has_initial_value = nextImpl(); if (!has_initial_value) { Catch::throw_exception(GeneratorException("No valid value found in filtered generator")); } @@ -4175,6 +4177,11 @@ namespace Generators { } bool next() override { + return nextImpl(); + } + + private: + bool nextImpl() { bool success = m_generator.next(); if (!success) { return false; @@ -5458,6 +5465,8 @@ namespace Catch { } // namespace Catch // end catch_outlier_classification.hpp + +#include #endif // CATCH_CONFIG_ENABLE_BENCHMARKING #include @@ -6342,9 +6351,10 @@ namespace Catch { void writeTestCase(TestCaseNode const& testCaseNode); - void writeSection(std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode); + void writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail ); void writeAssertions(SectionNode const& sectionNode); void writeAssertion(AssertionStats const& stats); @@ -6879,7 +6889,7 @@ namespace Catch { } iters *= 2; } - throw optimized_away_error{}; + Catch::throw_exception(optimized_away_error{}); } } // namespace Detail } // namespace Benchmark @@ -6887,6 +6897,7 @@ namespace Catch { // end catch_run_for_at_least.hpp #include +#include namespace Catch { namespace Benchmark { @@ -7384,8 +7395,6 @@ namespace Catch { template struct ObjectStorage { - using TStorage = typename std::aligned_storage::value>::type; - ObjectStorage() : data() {} ObjectStorage(const ObjectStorage& other) @@ -7428,7 +7437,7 @@ namespace Catch { return *static_cast(static_cast(&data)); } - TStorage data; + struct { alignas(T) unsigned char data[sizeof(T)]; } data; }; } @@ -7938,7 +7947,7 @@ namespace Catch { #if defined(__i386__) || defined(__x86_64__) #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ #elif defined(__aarch64__) - #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #define CATCH_TRAP() __asm__(".inst 0xd43e0000") #endif #elif defined(CATCH_PLATFORM_IPHONE) @@ -10751,8 +10760,8 @@ namespace Catch { // If neither SEH nor signal handling is required, the handler impls // do not have to do anything, and can be empty. - FatalConditionHandler::engage_platform() {} - FatalConditionHandler::disengage_platform() {} + void FatalConditionHandler::engage_platform() {} + void FatalConditionHandler::disengage_platform() {} FatalConditionHandler::FatalConditionHandler() = default; FatalConditionHandler::~FatalConditionHandler() = default; @@ -13381,6 +13390,10 @@ namespace Catch { filename.erase(0, lastSlash); filename[0] = '#'; } + else + { + filename.insert(0, "#"); + } auto lastDot = filename.find_last_of('.'); if (lastDot != std::string::npos) { @@ -13543,7 +13556,7 @@ namespace Catch { // Handle list request if( Option listed = list( m_config ) ) - return static_cast( *listed ); + return (std::min) (MaxExitCode, static_cast(*listed)); TestGroup tests { m_config }; auto const totals = tests.execute(); @@ -15376,7 +15389,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 2, 13, 5, "", 0 ); + static Version version( 2, 13, 10, "", 0 ); return version; } @@ -16789,6 +16802,7 @@ CATCH_REGISTER_REPORTER("console", ConsoleReporter) #include #include #include +#include namespace Catch { @@ -16816,7 +16830,7 @@ namespace Catch { #else std::strftime(timeStamp, timeStampSize, fmt, timeInfo); #endif - return std::string(timeStamp); + return std::string(timeStamp, timeStampSize-1); } std::string fileNameTag(const std::vector &tags) { @@ -16827,6 +16841,17 @@ namespace Catch { return it->substr(1); return std::string(); } + + // Formats the duration in seconds to 3 decimal places. + // This is done because some genius defined Maven Surefire schema + // in a way that only accepts 3 decimal places, and tools like + // Jenkins use that schema for validation JUnit reporter output. + std::string formatDuration( double seconds ) { + ReusableStringStream rss; + rss << std::fixed << std::setprecision( 3 ) << seconds; + return rss.str(); + } + } // anonymous namespace JunitReporter::JunitReporter( ReporterConfig const& _config ) @@ -16896,7 +16921,7 @@ namespace Catch { if( m_config->showDurations() == ShowDurations::Never ) xml.writeAttribute( "time", "" ); else - xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "time", formatDuration( suiteTime ) ); xml.writeAttribute( "timestamp", getCurrentTimestamp() ); // Write properties if there are any @@ -16941,12 +16966,13 @@ namespace Catch { if ( !m_config->name().empty() ) className = m_config->name() + "." + className; - writeSection( className, "", rootSection ); + writeSection( className, "", rootSection, stats.testInfo.okToFail() ); } - void JunitReporter::writeSection( std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode ) { + void JunitReporter::writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode, + bool testOkToFail) { std::string name = trim( sectionNode.stats.sectionInfo.name ); if( !rootName.empty() ) name = rootName + '/' + name; @@ -16963,13 +16989,18 @@ namespace Catch { xml.writeAttribute( "classname", className ); xml.writeAttribute( "name", name ); } - xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) ); + xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) ); // This is not ideal, but it should be enough to mimic gtest's // junit output. // Ideally the JUnit reporter would also handle `skipTest` // events and write those out appropriately. xml.writeAttribute( "status", "run" ); + if (sectionNode.stats.assertions.failedButOk) { + xml.scopedElement("skipped") + .writeAttribute("message", "TEST_CASE tagged with !mayfail"); + } + writeAssertions( sectionNode ); if( !sectionNode.stdOut.empty() ) @@ -16979,9 +17010,9 @@ namespace Catch { } for( auto const& childNode : sectionNode.childSections ) if( className.empty() ) - writeSection( name, "", *childNode ); + writeSection( name, "", *childNode, testOkToFail ); else - writeSection( className, name, *childNode ); + writeSection( className, name, *childNode, testOkToFail ); } void JunitReporter::writeAssertions( SectionNode const& sectionNode ) { @@ -17493,12 +17524,20 @@ namespace Catch { #ifndef __OBJC__ +#ifndef CATCH_INTERNAL_CDECL +#ifdef _MSC_VER +#define CATCH_INTERNAL_CDECL __cdecl +#else +#define CATCH_INTERNAL_CDECL +#endif +#endif + #if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) // Standard C/C++ Win32 Unicode wmain entry point -extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { +extern "C" int CATCH_INTERNAL_CDECL wmain (int argc, wchar_t * argv[], wchar_t * []) { #else // Standard C/C++ main entry point -int main (int argc, char * argv[]) { +int CATCH_INTERNAL_CDECL main (int argc, char * argv[]) { #endif return Catch::Session().run( argc, argv ); @@ -17626,9 +17665,9 @@ int main (int argc, char * const argv[]) { #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) #define CATCH_BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) #define CATCH_BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) #endif // CATCH_CONFIG_ENABLE_BENCHMARKING // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required @@ -17730,9 +17769,9 @@ int main (int argc, char * const argv[]) { #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) #define BENCHMARK(...) \ - INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) + INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,)) #define BENCHMARK_ADVANCED(name) \ - INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____B_E_N_C_H____), name) + INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name) #endif // CATCH_CONFIG_ENABLE_BENCHMARKING using Catch::Detail::Approx; @@ -17779,8 +17818,8 @@ using Catch::Detail::Approx; #define CATCH_WARN( msg ) (void)(0) #define CATCH_CAPTURE( msg ) (void)(0) -#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) #define CATCH_SECTION( ... ) @@ -17789,7 +17828,7 @@ using Catch::Detail::Approx; #define CATCH_FAIL_CHECK( ... ) (void)(0) #define CATCH_SUCCEED( ... ) (void)(0) -#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) @@ -17812,8 +17851,8 @@ using Catch::Detail::Approx; #endif // "BDD-style" convenience wrappers -#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) #define CATCH_GIVEN( desc ) #define CATCH_AND_GIVEN( desc ) #define CATCH_WHEN( desc ) @@ -17861,10 +17900,10 @@ using Catch::Detail::Approx; #define INFO( msg ) (void)(0) #define UNSCOPED_INFO( msg ) (void)(0) #define WARN( msg ) (void)(0) -#define CAPTURE( msg ) (void)(0) +#define CAPTURE( ... ) (void)(0) -#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) -#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #define METHOD_AS_TEST_CASE( method, ... ) #define REGISTER_TEST_CASE( Function, ... ) (void)(0) #define SECTION( ... ) @@ -17872,7 +17911,7 @@ using Catch::Detail::Approx; #define FAIL( ... ) (void)(0) #define FAIL_CHECK( ... ) (void)(0) #define SUCCEED( ... ) (void)(0) -#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ )) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) @@ -17902,8 +17941,8 @@ using Catch::Detail::Approx; #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) // "BDD-style" convenience wrappers -#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) ) -#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className ) #define GIVEN( desc ) #define AND_GIVEN( desc ) diff --git a/src/bindings/java/JavaContext.cpp b/src/bindings/java/JavaContext.cpp deleted file mode 100644 index a9ea0728ed..0000000000 --- a/src/bindings/java/JavaContext.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* Context switching within the JVM. */ - -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "JavaContext.hpp" -#include "jxbt_utilities.hpp" -#include "simgrid/Exception.hpp" -#include "src/kernel/actor/ActorImpl.hpp" - -#include -#include - -extern JavaVM* __java_vm; - -XBT_LOG_NEW_DEFAULT_CATEGORY(java, "MSG for Java(TM)"); - -namespace simgrid::kernel::context { - -JavaContextFactory::JavaContextFactory() : ContextFactory() -{ - xbt_assert(xbt::binary_name == "java"); -} - -JavaContextFactory::~JavaContextFactory()=default; - -Context* JavaContextFactory::create_context(std::function&& code, actor::ActorImpl* actor) -{ - return this->new_context(std::move(code), actor); -} - -void JavaContextFactory::run_all(std::vector const& actors) -{ - SerialThreadContext::run_all(actors); -} - -JavaContext::JavaContext(std::function&& code, actor::ActorImpl* actor) - : SerialThreadContext(std::move(code), actor, false /* not maestro */) -{ - /* ThreadContext already does all we need */ -} - -void JavaContext::start_hook() -{ - Context::set_current(this); // We need to attach it also for maestro, in contrary to our ancestor - - //Attach the thread to the JVM - JNIEnv *env; - xbt_assert(__java_vm->AttachCurrentThread((void**)&env, nullptr) == JNI_OK, - "The thread could not be attached to the JVM"); - this->jenv_ = env; -} - -void JavaContext::stop() -{ - this->get_actor()->cleanup_from_self(); - - /* Unregister the thread from the JVM */ - JNIEnv* env = this->jenv_; - env->DeleteGlobalRef(this->jprocess_); - jint error = __java_vm->DetachCurrentThread(); - if (error != JNI_OK) { - /* This is probably a Java thread, ie an actor not created from the XML (and thus from the C++), - * but from Java with something like new Process().start(). - * - * We should not even try to detach such threads. Instead, we throw a Java exception that will raise up - * until run_jprocess(), IIUC. - */ - jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed"); - XBT_DEBUG("Cannot detach the current thread"); - } - - simgrid::ForcefulKillException::do_throw(); // clean RAII variables with the dedicated exception -} - -} // namespace simgrid::kernel::context diff --git a/src/bindings/java/JavaContext.hpp b/src/bindings/java/JavaContext.hpp deleted file mode 100644 index 52598c626d..0000000000 --- a/src/bindings/java/JavaContext.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* Context switching within the JVM. */ - -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_JAVA_JAVA_CONTEXT_HPP -#define SIMGRID_JAVA_JAVA_CONTEXT_HPP - -#include -#include - -#include "src/kernel/context/ContextThread.hpp" - -#include "jmsg.hpp" - -namespace simgrid::kernel::context { - -class JavaContext; -class JavacontextFactory; - -class JavaContext : public SerialThreadContext { -public: - // The java process instance bound with the msg process structure: - jobject jprocess_ = nullptr; - // JNI interface pointer associated to this thread: - JNIEnv* jenv_ = nullptr; - - friend class JavaContextFactory; - JavaContext(std::function&& code, actor::ActorImpl* actor); - - void start_hook() override; - void stop() override; -}; - -class JavaContextFactory : public ContextFactory { -public: - JavaContextFactory(); - ~JavaContextFactory() override; - Context* create_context(std::function&& code, actor::ActorImpl* actor) override; - void run_all(std::vector const& actors) override; -}; - -XBT_PRIVATE ContextFactory* java_factory(); -XBT_PRIVATE void java_main_jprocess(jobject process); - -} // namespace simgrid::kernel::context - -#endif /* SIMGRID_JAVA_JAVA_CONTEXT_HPP */ diff --git a/src/bindings/java/MANIFEST.in b/src/bindings/java/MANIFEST.in deleted file mode 100644 index bb1ca2beb4..0000000000 --- a/src/bindings/java/MANIFEST.in +++ /dev/null @@ -1,3 +0,0 @@ -Built-By: Da SimGrid team -Main-Class: org.simgrid.msg.Msg -Class-Path: . diff --git a/src/bindings/java/jmsg.cpp b/src/bindings/java/jmsg.cpp deleted file mode 100644 index bcf7c86635..0000000000 --- a/src/bindings/java/jmsg.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include -#include -#include - -#include "simgrid/Exception.hpp" -#include "simgrid/plugins/energy.h" -#include "simgrid/plugins/file_system.h" -#include "simgrid/plugins/live_migration.h" -#include "simgrid/plugins/load.h" - -#include "simgrid/s4u/Actor.hpp" -#include "simgrid/s4u/Host.hpp" - -#include "jmsg.hpp" -#include "jmsg_as.hpp" -#include "jmsg_host.h" -#include "jmsg_process.h" -#include "jmsg_task.h" -#include "jxbt_utilities.hpp" - -#include "JavaContext.hpp" - -/* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */ -#ifndef JNIEXPORT -#define JNIEXPORT -#endif -#ifndef JNICALL -#define JNICALL -#endif -/* end of eclipse-mandated pimple */ - -int JAVA_HOST_LEVEL = -1; - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java); - -JavaVM *__java_vm = nullptr; - -JNIEnv *get_current_thread_env() -{ - using simgrid::kernel::context::JavaContext; - const JavaContext* ctx = static_cast(simgrid::kernel::context::Context::self()); - if (ctx) - return ctx->jenv_; - else - return nullptr; -} - -void jmsg_throw_status(JNIEnv *env, msg_error_t status) { - switch (status) { - case MSG_TIMEOUT: - jxbt_throw_time_out_failure(env, ""); - break; - case MSG_TRANSFER_FAILURE: - jxbt_throw_transfer_failure(env, ""); - break; - case MSG_HOST_FAILURE: - jxbt_throw_host_failure(env, ""); - break; - case MSG_TASK_CANCELED: - jxbt_throw_task_cancelled(env, ""); - break; - default: - xbt_die("undefined message failed (please see jmsg_throw_status function in jmsg.cpp)"); - } -} - -/*************************************************************************************** - * Unsortable functions * - ***************************************************************************************/ - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Msg_getClock(JNIEnv*, jclass) -{ - return (jdouble)simgrid_get_clock(); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_init(JNIEnv* env, jclass, jobjectArray jargs) -{ - env->GetJavaVM(&__java_vm); - - simgrid::kernel::context::ContextFactory::initializer = []() { - XBT_INFO("Using regular java threads."); - return new simgrid::kernel::context::JavaContextFactory(); - }; - const _jthrowable* exc = env->ExceptionOccurred(); - if (exc) { - env->ExceptionClear(); - } - - setlocale(LC_NUMERIC,"C"); - - int argc = 1; - if (jargs) - argc += static_cast(env->GetArrayLength(jargs)); - xbt_assert(argc > 0); - - // Need a static storage because the XBT layer saves the arguments in xbt::binary_name and xbt::cmdline. - static std::vector args; - args.reserve(argc); - - args.emplace_back("java"); - for (int index = 1; index < argc; index++) { - auto jval = (jstring)env->GetObjectArrayElement(jargs, index - 1); - jstring_wrapper tmp(env, jval); - args.emplace_back(tmp.value); - } - - std::unique_ptr argv(new char*[argc + 1]); - std::transform(begin(args), end(args), argv.get(), [](std::string& s) { return &s.front(); }); - argv[argc] = nullptr; - - int argc2 = argc; - MSG_init(&argc2, argv.get()); - xbt_assert(argc2 <= argc); - - for (int index = 1; index < argc2; index++) - env->SetObjectArrayElement(jargs, index - 1, (jstring)env->NewStringUTF(argv[index])); - - sg_vm_live_migration_plugin_init(); - JAVA_HOST_LEVEL = simgrid::s4u::Host::extension_create(nullptr); -} - -JNIEXPORT void JNICALL JNICALL Java_org_simgrid_msg_Msg_run(JNIEnv* env, jclass) -{ - /* Run everything */ - XBT_DEBUG("Ready to run"); - simgrid_run(); - XBT_DEBUG("Done running"); - XBT_INFO("Terminating the simulation..."); - /* Cleanup java hosts */ - sg_host_t* hosts = sg_host_list(); - size_t host_count = sg_host_count(); - for (size_t index = 0; index < host_count - 1; index++) { - auto jhost = (jobject)hosts[index]->extension(JAVA_HOST_LEVEL); - if (jhost) - jhost_unref(env, jhost); - } - xbt_free(hosts); - - /* Display the status of remaining threads. None should survive, but who knows */ - jclass clsProcess = jxbt_get_class(env, "org/simgrid/msg/Process"); - jmethodID idDebug = jxbt_get_static_jmethod(env, clsProcess, "debugAllThreads", "()V"); - xbt_assert(idDebug != nullptr, "Method Process.debugAllThreads() not found..."); - env->CallStaticVoidMethod(clsProcess, idDebug); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_createEnvironment(JNIEnv* env, jclass, jstring jplatformFile) -{ - jstring_wrapper platformFile(env, jplatformFile); - simgrid_load_platform(platformFile); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Msg_environmentGetRoutingRoot(JNIEnv* env, jclass) -{ - sg_netzone_t as = sg_zone_get_root(); - jobject jas = jnetzone_new_instance(env); - if (not jas) { - jxbt_throw_jni(env, "java As instantiation failed"); - return nullptr; - } - jas = jnetzone_ref(env, jas); - if (not jas) { - jxbt_throw_jni(env, "new global ref allocation failed"); - return nullptr; - } - jnetzone_bind(jas, as, env); - - return (jobject) jas; -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_debug(JNIEnv* env, jclass, jstring js) -{ - jstring_wrapper s(env, js); - XBT_DEBUG("%s", s.value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_verb(JNIEnv* env, jclass, jstring js) -{ - jstring_wrapper s(env, js); - XBT_VERB("%s", s.value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_info(JNIEnv* env, jclass, jstring js) -{ - jstring_wrapper s(env, js); - XBT_INFO("%s", s.value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_warn(JNIEnv* env, jclass, jstring js) -{ - jstring_wrapper s(env, js); - XBT_WARN("%s", s.value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_error(JNIEnv* env, jclass, jstring js) -{ - jstring_wrapper s(env, js); - XBT_ERROR("%s", s.value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_critical(JNIEnv* env, jclass, jstring js) -{ - jstring_wrapper s(env, js); - XBT_CRITICAL("%s", s.value); -} - -static void java_main(int argc, char* argv[]); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_deployApplication(JNIEnv* env, jclass, jstring jdeploymentFile) -{ - jstring_wrapper deploymentFile(env, jdeploymentFile); - - simgrid_register_default(java_main); - simgrid_load_deployment(deploymentFile); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_energyInit() { - sg_host_energy_plugin_init(); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_loadInit() { - sg_host_load_plugin_init(); -} -/** Run a Java org.simgrid.msg.Process - * - * If needed, this waits for the process starting time. - * Then it calls the Process.run() method. - */ -static void run_jprocess(JNIEnv *env, jobject jprocess) -{ - // wait for the process's start time - jfieldID jprocess_field_Process_startTime = jxbt_get_sfield(env, "org/simgrid/msg/Process", "startTime", "D"); - jdouble startTime = env->GetDoubleField(jprocess, jprocess_field_Process_startTime); - if (startTime > simgrid_get_clock()) - simgrid::s4u::this_actor::sleep_for(startTime - simgrid_get_clock()); - - //Execution of the "run" method. - jmethodID id = jxbt_get_smethod(env, "org/simgrid/msg/Process", "run", "()V"); - xbt_assert((id != nullptr), "Method Process.run() not found..."); - - env->CallVoidMethod(jprocess, id); - if (env->ExceptionOccurred()) { - XBT_DEBUG("Something went wrong in this Java actor, forget about it."); - env->ExceptionClear(); - xbt_assert(__java_vm->DetachCurrentThread() == JNI_OK, "Cannot detach failing thread"); - simgrid::ForcefulKillException::do_throw(); - } -} - -/** Create a Java org.simgrid.msg.Process with the arguments and run it */ -static void java_main(int argc, char* argv[]) -{ - JNIEnv *env = get_current_thread_env(); - auto* context = static_cast(simgrid::kernel::context::Context::self()); - - //Change the "." in class name for "/". - std::string arg0 = argv[0]; - std::replace(begin(arg0), end(arg0), '.', '/'); - jclass class_Process = env->FindClass(arg0.c_str()); - //Retrieve the methodID for the constructor - xbt_assert((class_Process != nullptr), "Class not found (%s). The deployment file must use the fully qualified class name, including the package. The case is important.", argv[0]); - jmethodID constructor_Process = env->GetMethodID(class_Process, "", "(Lorg/simgrid/msg/Host;Ljava/lang/String;[Ljava/lang/String;)V"); - xbt_assert((constructor_Process != nullptr), "Constructor not found for class %s. Is there a (Host, String ,String[]) constructor in your class ?", argv[0]); - - //Retrieve the name of the process. - jstring jname = env->NewStringUTF(argv[0]); - //Build the arguments - auto args = static_cast( - env->NewObjectArray(argc - 1, env->FindClass("java/lang/String"), env->NewStringUTF(""))); - for (int i = 1; i < argc; i++) - env->SetObjectArrayElement(args,i - 1, env->NewStringUTF(argv[i])); - //Retrieve the host for the process. - jstring jhostName = env->NewStringUTF(simgrid::s4u::Host::current()->get_cname()); - jobject jhost = Java_org_simgrid_msg_Host_getByName(env, nullptr, jhostName); - //creates the process - jobject jprocess = env->NewObject(class_Process, constructor_Process, jhost, jname, args); - xbt_assert((jprocess != nullptr), "Process allocation failed."); - jprocess = env->NewGlobalRef(jprocess); - //bind the process to the context - const_sg_actor_t actor = sg_actor_self(); - - context->jprocess_ = jprocess; - /* sets the PID and the PPID of the process */ - env->SetIntField(jprocess, jprocess_field_Process_pid, static_cast(actor->get_pid())); - env->SetIntField(jprocess, jprocess_field_Process_ppid, static_cast(actor->get_ppid())); - jprocess_bind(jprocess, actor, env); - - run_jprocess(env, context->jprocess_); -} - -namespace simgrid::kernel::context { - -/** Run the Java org.simgrid.msg.Process */ -void java_main_jprocess(jobject jprocess) -{ - JNIEnv *env = get_current_thread_env(); - auto* context = static_cast(Context::self()); - context->jprocess_ = jprocess; - jprocess_bind(context->jprocess_, sg_actor_self(), env); - - run_jprocess(env, context->jprocess_); -} -} // namespace simgrid::kernel::context diff --git a/src/bindings/java/jmsg.hpp b/src/bindings/java/jmsg.hpp deleted file mode 100644 index 49fb4c90dd..0000000000 --- a/src/bindings/java/jmsg.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* Java Wrappers to the MSG API. */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef JMSG_HPP -#define JMSG_HPP -#include -#include -#include - -extern "C" { - -/* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */ -#ifndef JNIEXPORT -#define JNIEXPORT -#endif -#ifndef JNICALL -#define JNICALL -#endif -/* end of eclipse-mandated pimple */ - -extern int JAVA_HOST_LEVEL; - -JNIEnv* get_current_thread_env(); -/** - * This function throws the correct exception according to the status provided. - */ -void jmsg_throw_status(JNIEnv* env, msg_error_t status); - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Msg_getClock(JNIEnv* env, jclass cls); -JNIEXPORT void JNICALL JNICALL Java_org_simgrid_msg_Msg_run(JNIEnv* env, jclass cls); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_init(JNIEnv* env, jclass cls, jobjectArray jargs); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_energyInit(); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_liveMigrationInit(); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_fileSystemInit(); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_loadInit(); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_debug(JNIEnv* env, jclass cls, jstring jargs); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_verb(JNIEnv* env, jclass cls, jstring jargs); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_info(JNIEnv* env, jclass cls, jstring jargs); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_warn(JNIEnv* env, jclass cls, jstring jargs); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_error(JNIEnv* env, jclass cls, jstring jargs); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_critical(JNIEnv* env, jclass cls, jstring jargs); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_createEnvironment(JNIEnv* env, jclass cls, jstring jplatformFile); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Msg_environmentGetRoutingRoot(JNIEnv* env, jclass cls); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_deployApplication(JNIEnv* env, jclass cls, jstring jdeploymentFile); -} -#endif diff --git a/src/bindings/java/jmsg_as.cpp b/src/bindings/java/jmsg_as.cpp deleted file mode 100644 index 32719ea775..0000000000 --- a/src/bindings/java/jmsg_as.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* Java bindings of the NetZones. */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/kernel/routing/NetZoneImpl.hpp" -#include "simgrid/s4u/Host.hpp" -#include "simgrid/s4u/NetZone.hpp" - -#include "jmsg.hpp" -#include "jmsg_as.hpp" -#include "jmsg_host.h" -#include "jxbt_utilities.hpp" - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java); - -static jmethodID jas_method_As_constructor; -static jfieldID jas_field_As_bind; - -jobject jnetzone_new_instance(JNIEnv* env) -{ - jclass cls = jxbt_get_class(env, "org/simgrid/msg/As"); - return env->NewObject(cls, jas_method_As_constructor); -} - -jobject jnetzone_ref(JNIEnv* env, jobject jas) -{ - return env->NewGlobalRef(jas); -} - -void jnetzone_unref(JNIEnv* env, jobject jas) -{ - env->DeleteGlobalRef(jas); -} - -void jnetzone_bind(jobject jas, simgrid::s4u::NetZone* netzone, JNIEnv* env) -{ - env->SetLongField(jas, jas_field_As_bind, (jlong)(uintptr_t)(netzone)); -} - -simgrid::s4u::NetZone* jnetzone_get_native(JNIEnv* env, jobject jas) -{ - return (simgrid::s4u::NetZone*)(uintptr_t)env->GetLongField(jas, jas_field_As_bind); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_As_nativeInit(JNIEnv* env, jclass cls) -{ - jclass class_As = env->FindClass("org/simgrid/msg/As"); - jas_method_As_constructor = env->GetMethodID(class_As, "", "()V"); - jas_field_As_bind = jxbt_get_jfield(env,class_As, "bind", "J"); - xbt_assert(class_As && jas_method_As_constructor && jas_field_As_bind, - "Native initialization of msg/AS failed. Please report that bug"); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_As_getName(JNIEnv * env, jobject jas) { - const simgrid::s4u::NetZone* as = jnetzone_get_native(env, jas); - return env->NewStringUTF(as->get_cname()); -} - -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_As_getSons(JNIEnv * env, jobject jas) { - int index = 0; - jobjectArray jtable; - const simgrid::s4u::NetZone* self_as = jnetzone_get_native(env, jas); - - jclass cls = env->FindClass("org/simgrid/msg/As"); - - if (not cls) - return nullptr; - - jtable = env->NewObjectArray(static_cast(self_as->get_children().size()), cls, nullptr); - - if (not jtable) { - jxbt_throw_jni(env, "Hosts table allocation failed"); - return nullptr; - } - - for (auto const& tmp_as : self_as->get_children()) { - jobject tmp_jas = jnetzone_new_instance(env); - if (not tmp_jas) { - jxbt_throw_jni(env, "java As instantiation failed"); - return nullptr; - } - tmp_jas = jnetzone_ref(env, tmp_jas); - if (not tmp_jas) { - jxbt_throw_jni(env, "new global ref allocation failed"); - return nullptr; - } - jnetzone_bind(tmp_jas, tmp_as, env); - - env->SetObjectArrayElement(jtable, index, tmp_jas); - index++; - } - return jtable; -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_As_getProperty(JNIEnv *env, jobject jas, jobject jname) { - const simgrid::s4u::NetZone* as = jnetzone_get_native(env, jas); - - if (not as) { - jxbt_throw_notbound(env, "as", jas); - return nullptr; - } - jstring_wrapper name(env, static_cast(jname)); - - const char* property = sg_zone_get_property_value(as, name); - if (not property) { - return nullptr; - } - - jobject jproperty = env->NewStringUTF(property); - - return jproperty; -} - -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_As_getHosts(JNIEnv * env, jobject jas) -{ - jobjectArray jtable; - jobject jhost; - jstring jname; - const simgrid::s4u::NetZone* as = jnetzone_get_native(env, jas); - - jclass cls = jxbt_get_class(env, "org/simgrid/msg/Host"); - if (not cls) - return nullptr; - - std::vector table = as->get_all_hosts(); - - jtable = env->NewObjectArray(static_cast(table.size()), cls, nullptr); - - if (not jtable) { - jxbt_throw_jni(env, "Hosts table allocation failed"); - return nullptr; - } - - int index = 0; - for (auto const& host : table) { - jhost = static_cast(host->extension(JAVA_HOST_LEVEL)); - if (not jhost) { - jname = env->NewStringUTF(host->get_cname()); - - jhost = Java_org_simgrid_msg_Host_getByName(env, cls, jname); - - env->ReleaseStringUTFChars(static_cast(jname), host->get_cname()); - } - - env->SetObjectArrayElement(jtable, index, jhost); - index++; - } - return jtable; -} diff --git a/src/bindings/java/jmsg_as.hpp b/src/bindings/java/jmsg_as.hpp deleted file mode 100644 index 90eb543498..0000000000 --- a/src/bindings/java/jmsg_as.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/* Functions related to the java As instances. */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef JMSG_AS_HPP -#define JMSG_AS_HPP -#include "simgrid/zone.h" -#include - -extern "C" { - -/* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */ -#ifndef JNIEXPORT -#define JNIEXPORT -#endif -#ifndef JNICALL -#define JNICALL -#endif -/* end of eclipse-mandated pimple */ - -jobject jnetzone_new_instance(JNIEnv* env); -jobject jnetzone_ref(JNIEnv* env, jobject jnetzone); -void jnetzone_unref(JNIEnv* env, jobject jnetzone); -void jnetzone_bind(jobject jas, msg_netzone_t as, JNIEnv* env); -simgrid::s4u::NetZone* jnetzone_get_native(JNIEnv* env, jobject jnetzone); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_As_nativeInit(JNIEnv* env, jclass cls); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_As_getName(JNIEnv* env, jobject jas); -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_As_getSons(JNIEnv* env, jobject jnetzone); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_As_getProperty(JNIEnv* env, jobject jhost, jobject jname); -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_As_getHosts(JNIEnv* env, jobject jnetzone); -} -#endif diff --git a/src/bindings/java/jmsg_comm.cpp b/src/bindings/java/jmsg_comm.cpp deleted file mode 100644 index 0eaa12d63f..0000000000 --- a/src/bindings/java/jmsg_comm.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* Java bindings to the Comm API */ - -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "jmsg_comm.h" -#include "jmsg.hpp" -#include "jxbt_utilities.hpp" - -#include - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java); - -static jfieldID jcomm_field_Comm_bind; -static jfieldID jcomm_field_Comm_finished; -static jfieldID jcomm_field_Comm_receiving; -static jfieldID jtask_field_Comm_task; -static jfieldID jcomm_field_Comm_taskBind; - -void jcomm_bind_task(JNIEnv *env, jobject jcomm) { - const_msg_comm_t comm = (msg_comm_t)(uintptr_t)env->GetLongField(jcomm, jcomm_field_Comm_bind); - //test if we are receiving or sending a task. - jboolean jreceiving = env->GetBooleanField(jcomm, jcomm_field_Comm_receiving); - if (jreceiving == JNI_TRUE) { - //bind the task object. - msg_task_t task = MSG_comm_get_task(comm); - xbt_assert(task != nullptr, "Task is nullptr"); - auto jtask_global = static_cast(MSG_task_get_data(task)); - //case where the data has already been retrieved - if (jtask_global == nullptr) { - return; - } - - //Make sure the data will be correctly gc. - jobject jtask_local = env->NewLocalRef(jtask_global); - env->DeleteGlobalRef(jtask_global); - - env->SetObjectField(jcomm, jtask_field_Comm_task, jtask_local); - - MSG_task_set_data(task, nullptr); - } -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_nativeInit(JNIEnv *env, jclass cls) { - jclass jfield_class_Comm = env->FindClass("org/simgrid/msg/Comm"); - xbt_assert(jfield_class_Comm, "Native initialization of msg/Comm failed. Please report that bug"); - - jcomm_field_Comm_bind = jxbt_get_jfield(env, jfield_class_Comm, "bind", "J"); - jcomm_field_Comm_taskBind = jxbt_get_jfield(env, jfield_class_Comm, "taskBind", "J"); - jcomm_field_Comm_receiving = jxbt_get_jfield(env, jfield_class_Comm, "receiving", "Z"); - jtask_field_Comm_task = jxbt_get_jfield(env, jfield_class_Comm, "task", "Lorg/simgrid/msg/Task;"); - jcomm_field_Comm_finished = jxbt_get_jfield(env, jfield_class_Comm, "finished", "Z"); - xbt_assert(jcomm_field_Comm_bind && jcomm_field_Comm_taskBind && jcomm_field_Comm_receiving && - jtask_field_Comm_task && jcomm_field_Comm_finished, - "Native initialization of msg/Comm failed. Please report that bug"); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_nativeFinalize(JNIEnv *env, jobject jcomm) { - msg_task_t *task_received; - - task_received = (msg_task_t*) (uintptr_t) env->GetLongField(jcomm, jcomm_field_Comm_taskBind); - delete task_received; - - const_msg_comm_t comm = (msg_comm_t)(uintptr_t)env->GetLongField(jcomm, jcomm_field_Comm_bind); - MSG_comm_destroy(comm); -} - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Comm_test(JNIEnv *env, jobject jcomm) { - msg_comm_t comm; - comm = (msg_comm_t) (uintptr_t) env->GetLongField(jcomm, jcomm_field_Comm_bind); - - jboolean finished = env->GetBooleanField(jcomm, jcomm_field_Comm_finished); - if (finished == JNI_TRUE) { - return JNI_TRUE; - } - - if (not comm) { - jxbt_throw_null(env, "comm is null"); - return JNI_FALSE; - } - - if (MSG_comm_test(comm)) { - msg_error_t status = MSG_comm_get_status(comm); - if (status == MSG_OK) { - jcomm_bind_task(env,jcomm); - return JNI_TRUE; - } else { - //send the correct exception - jmsg_throw_status(env,status); - } - } - return JNI_FALSE; -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_waitCompletion(JNIEnv *env, jobject jcomm, jdouble timeout) { - auto comm = (msg_comm_t)(uintptr_t)env->GetLongField(jcomm, jcomm_field_Comm_bind); - if (not comm) { - jxbt_throw_null(env, "comm is null"); - return; - } - - jboolean finished = env->GetBooleanField(jcomm, jcomm_field_Comm_finished); - if (finished == JNI_TRUE) { - return; - } - - msg_error_t status; - status = MSG_comm_wait(comm, timeout); - env->SetBooleanField(jcomm, jcomm_field_Comm_finished, JNI_TRUE); - if (status == MSG_OK) { - jcomm_bind_task(env,jcomm); - } else { - jmsg_throw_status(env,status); - } -} - -static msg_comm_t* jarray_to_commArray(JNIEnv *env, jobjectArray jcomms, /* OUT */ int *count) -{ - *count = env->GetArrayLength(jcomms); - auto* comms = new msg_comm_t[*count]; - - for (int i=0; i < *count; i++) { - jobject jcomm = env->GetObjectArrayElement(jcomms, i); - if (env->ExceptionOccurred()) - break; - - comms[i] = (msg_comm_t) (uintptr_t) env->GetLongField(jcomm, jcomm_field_Comm_bind); - if (not comms[i]) { - jxbt_throw_null(env, std::string("comm at rank ") + std::to_string(i) + " is null"); - return nullptr; - } - - env->DeleteLocalRef(jcomm); // reduce the load on the garbage collector: we don't need that object anymore - } - return comms; -} -JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_waitAll(JNIEnv *env, jclass cls, jobjectArray jcomms, jdouble timeout) -{ - int count; - msg_comm_t* comms = jarray_to_commArray(env, jcomms, &count); - if (not comms) - return; - - MSG_comm_waitall(comms, count, timeout); - delete[] comms; -} -JNIEXPORT int JNICALL Java_org_simgrid_msg_Comm_waitAny(JNIEnv *env, jclass cls, jobjectArray jcomms) -{ - int count; - msg_comm_t* comms = jarray_to_commArray(env, jcomms, &count); - if (not comms) - return -1; - xbt_dynar_t dyn = xbt_dynar_new(sizeof(msg_comm_t),nullptr); - for (int i=0; i - -SG_BEGIN_DECL - -/* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */ -#ifndef JNIEXPORT -#define JNIEXPORT -#endif -#ifndef JNICALL -#define JNICALL -#endif -/* end of eclipse-mandated pimple */ - -/** This function binds the task associated with the communication to the java communication object. */ -void jcomm_bind_task(JNIEnv *env, jobject jcomm); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_nativeInit(JNIEnv *env, jclass cls); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_nativeFinalize(JNIEnv *env, jobject jcomm); - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Comm_test(JNIEnv *env, jobject jcomm); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_waitCompletion(JNIEnv *env, jobject jcomm, jdouble timeout); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_waitAll(JNIEnv *env, jclass cls, jobjectArray jcomms, jdouble timeout); -JNIEXPORT int JNICALL Java_org_simgrid_msg_Comm_waitAny(JNIEnv *env, jclass cls, jobjectArray jcomms); - -SG_END_DECL -#endif diff --git a/src/bindings/java/jmsg_host.cpp b/src/bindings/java/jmsg_host.cpp deleted file mode 100644 index 025d17d021..0000000000 --- a/src/bindings/java/jmsg_host.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/* Functions related to the java host instances. */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/Exception.hpp" -#include "simgrid/plugins/energy.h" -#include "simgrid/plugins/load.h" -#include "simgrid/s4u/Host.hpp" - -#include "JavaContext.hpp" -#include "jmsg.hpp" -#include "jmsg_host.h" -#include "jxbt_utilities.hpp" - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java); - -static jmethodID jhost_method_Host_constructor; -static jfieldID jhost_field_Host_bind; -static jfieldID jhost_field_Host_name; - -jobject jhost_new_instance(JNIEnv * env) { - jclass cls = jxbt_get_class(env, "org/simgrid/msg/Host"); - return env->NewObject(cls, jhost_method_Host_constructor); -} - -jobject jhost_ref(JNIEnv * env, jobject jhost) { - return env->NewGlobalRef(jhost); -} - -void jhost_unref(JNIEnv * env, jobject jhost) { - env->DeleteGlobalRef(jhost); -} - -void jhost_bind(jobject jhost, msg_host_t host, JNIEnv * env) { - env->SetLongField(jhost, jhost_field_Host_bind, (jlong) (uintptr_t) (host)); -} - -msg_host_t jhost_get_native(JNIEnv * env, jobject jhost) { - return (msg_host_t) (uintptr_t) env->GetLongField(jhost, jhost_field_Host_bind); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_nativeInit(JNIEnv *env, jclass cls) { - jclass class_Host = env->FindClass("org/simgrid/msg/Host"); - jhost_method_Host_constructor = env->GetMethodID(class_Host, "", "()V"); - jhost_field_Host_bind = jxbt_get_jfield(env,class_Host, "bind", "J"); - jhost_field_Host_name = jxbt_get_jfield(env, class_Host, "name", "Ljava/lang/String;"); - xbt_assert(class_Host && jhost_field_Host_name && jhost_method_Host_constructor && jhost_field_Host_bind, - "Native initialization of msg/Host failed. Please report that bug"); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Host_getByName(JNIEnv* env, jclass cls, jstring jname) -{ - /* get the C string from the java string */ - if (jname == nullptr) { - jxbt_throw_null(env, "No host can have a null name"); - return nullptr; - } - jstring_wrapper name(env, jname); - /* get the host by name (the hosts are created during the grid resolution) */ - sg_host_t host = sg_host_by_name(name); - - if (not host) { /* invalid name */ - jxbt_throw_host_not_found(env, name); - return nullptr; - } - - if (not host->extension(JAVA_HOST_LEVEL)) { /* native host not associated yet with java host */ - /* Instantiate a new java host */ - jobject jhost = jhost_new_instance(env); - - if (not jhost) { - jxbt_throw_jni(env, "java host instantiation failed"); - return nullptr; - } - - /* get a global reference to the newly created host */ - jhost = jhost_ref(env, jhost); - - if (not jhost) { - jxbt_throw_jni(env, "new global ref allocation failed"); - return nullptr; - } - /* Sets the java host name */ - env->SetObjectField(jhost, jhost_field_Host_name, jname); - /* bind the java host and the native host */ - jhost_bind(jhost, host, env); - - /* the native host data field is set with the global reference to the java host returned by this function */ - host->extension_set(JAVA_HOST_LEVEL, jhost); - } - - /* return the global reference to the java host instance */ - return (jobject) host->extension(JAVA_HOST_LEVEL); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Host_currentHost(JNIEnv * env, jclass cls) { - jobject jhost; - - sg_host_t host = sg_host_self(); - - if (not host->extension(JAVA_HOST_LEVEL)) { - /* the native host not yet associated with the java host instance */ - - /* instantiate a new java host instance */ - jhost = jhost_new_instance(env); - - if (not jhost) { - jxbt_throw_jni(env, "java host instantiation failed"); - return nullptr; - } - - /* get a global reference to the newly created host */ - jhost = jhost_ref(env, jhost); - - if (not jhost) { - jxbt_throw_jni(env, "global ref allocation failed"); - return nullptr; - } - /* Sets the host name */ - jobject jname = env->NewStringUTF(host->get_cname()); - env->SetObjectField(jhost, jhost_field_Host_name, jname); - /* Bind & store it */ - jhost_bind(jhost, host, env); - host->extension_set(JAVA_HOST_LEVEL, jhost); - } else { - jhost = (jobject) host->extension(JAVA_HOST_LEVEL); - } - - return jhost; -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_on(JNIEnv *env, jobject jhost) { - sg_host_t host = jhost_get_native(env, jhost); - sg_host_turn_on(host); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_off(JNIEnv *env, jobject jhost) { - sg_host_t host = jhost_get_native(env, jhost); - if (not simgrid::ForcefulKillException::try_n_catch([host]() { sg_host_turn_off(host); })) - jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Host turned off"); -} - -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Host_getCount(JNIEnv * env, jclass cls) { - return (jint)sg_host_count(); -} - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getSpeed(JNIEnv * env, jobject jhost) { - const_sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return -1; - } - - return (jdouble)sg_host_get_speed(host); -} - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCoreNumber(JNIEnv * env, jobject jhost) { - const_sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return -1; - } - - return (jdouble)sg_host_core_count(host); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Host_getProperty(JNIEnv *env, jobject jhost, jobject jname) { - const_sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return nullptr; - } - jstring_wrapper name(env, (jstring)jname); - - const char* property = sg_host_get_property_value(host, name); - if (not property) { - return nullptr; - } - - jobject jproperty = env->NewStringUTF(property); - - return jproperty; -} - -JNIEXPORT void JNICALL -Java_org_simgrid_msg_Host_setProperty(JNIEnv *env, jobject jhost, jobject jname, jobject jvalue) { - sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return; - } - jstring_wrapper name(env, (jstring)jname); - jstring_wrapper value_java(env, (jstring)jvalue); - const char* value = xbt_strdup(value_java); - - sg_host_set_property_value(host, name, value); -} - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Host_isOn(JNIEnv * env, jobject jhost) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return 0; - } - - return (jboolean)sg_host_is_on(host); -} - -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_Host_all(JNIEnv * env, jclass cls_arg) -{ - sg_host_t* table = sg_host_list(); - int count = sg_host_count(); - - jclass cls = jxbt_get_class(env, "org/simgrid/msg/Host"); - if (not cls) - return nullptr; - - jobjectArray jtable = env->NewObjectArray((jsize)count, cls, nullptr); - - if (not jtable) { - jxbt_throw_jni(env, "Hosts table allocation failed"); - return nullptr; - } - - for (int index = 0; index < count; index++) { - auto jhost = static_cast(table[index]->extension(JAVA_HOST_LEVEL)); - - if (not jhost) { - jstring jname = env->NewStringUTF(table[index]->get_cname()); - jhost = Java_org_simgrid_msg_Host_getByName(env, cls_arg, jname); - } - - env->SetObjectArrayElement(jtable, index, jhost); - } - xbt_free(table); - return jtable; -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_setAsyncMailbox(JNIEnv * env, jclass cls_arg, jobject jname) -{ - jstring_wrapper name(env, (jstring)jname); - sg_mailbox_set_receiver(name); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_updateAllEnergyConsumptions(JNIEnv* env, jclass cls) -{ - sg_host_energy_update_all(); -} - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getConsumedEnergy (JNIEnv *env, jobject jhost) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return 0; - } - - return sg_host_get_consumed_energy(host); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_setPstate(JNIEnv* env, jobject jhost, jint pstate) -{ - sg_host_t host = jhost_get_native(env, jhost); - sg_host_set_pstate(host, pstate); -} -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Host_getPstate(JNIEnv* env, jobject jhost) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - return sg_host_get_pstate(host); -} -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Host_getPstatesCount(JNIEnv* env, jobject jhost) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - return sg_host_get_nb_pstates(host); -} -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCurrentPowerPeak(JNIEnv* env, jobject jhost) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - return sg_host_get_speed(host); -} -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getPowerPeakAt(JNIEnv* env, jobject jhost, jint pstate) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - return sg_host_get_pstate_speed(host, pstate); -} - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getLoad(JNIEnv* env, jobject jhost) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - return sg_host_get_load(host); -} - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCurrentLoad (JNIEnv *env, jobject jhost) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return 0; - } - - return sg_host_get_current_load(host); -} - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getComputedFlops (JNIEnv *env, jobject jhost) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return 0; - } - - return sg_host_get_computed_flops(host); -} - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getAvgLoad (JNIEnv *env, jobject jhost) -{ - const_sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return 0; - } - - return sg_host_get_avg_load(host); -} diff --git a/src/bindings/java/jmsg_host.h b/src/bindings/java/jmsg_host.h deleted file mode 100644 index a885ee2535..0000000000 --- a/src/bindings/java/jmsg_host.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Functions related to the java host instances. */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef MSG_JHOST_H -#define MSG_JHOST_H - -#include "simgrid/host.h" -#include "simgrid/plugins/file_system.h" -#include - -SG_BEGIN_DECL - -/* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */ -#ifndef JNIEXPORT -#define JNIEXPORT -#endif -#ifndef JNICALL -#define JNICALL -#endif -/* end of eclipse-mandated pimple */ - -/** Returns a new java instance of a host. */ -jobject jhost_new_instance(JNIEnv * env); - -/** Take a ref onto the java instance (to prevent its collection) */ -jobject jhost_ref(JNIEnv * env, jobject jhost); - -/** Release a ref onto the java instance */ -void jhost_unref(JNIEnv * env, jobject jhost); - -/** Binds a native instance to a java instance. */ -void jhost_bind(jobject jhost, sg_host_t host, JNIEnv* env); - -/** Extracts the native instance associated to a java instance. */ -sg_host_t jhost_get_native(JNIEnv* env, jobject jhost); - -/** Initialize the native world, called from the Java world at startup */ -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_nativeInit(JNIEnv *env, jclass cls); - -/* Implement the Java API */ - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Host_getByName(JNIEnv* env, jclass cls, jstring jname); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Host_currentHost(JNIEnv* env, jclass cls); -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Host_getCount (JNIEnv *env, jclass cls); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_on(JNIEnv* env, jobject jhost); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_off(JNIEnv* env, jobject jhost); -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Host_isOn(JNIEnv* env, jobject jhost); -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getSpeed (JNIEnv *env, jobject jhost); -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCoreNumber (JNIEnv *env, jobject jhost); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Host_getProperty(JNIEnv *env, jobject jhost, jobject jname); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_setProperty(JNIEnv *env, jobject jhost, jobject jname, jobject jvalue); -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_Host_all(JNIEnv *env, jclass cls); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_setAsyncMailbox(JNIEnv * env, jclass cls_arg, jobject jname); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_updateAllEnergyConsumptions(JNIEnv* env, jclass cls); -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getConsumedEnergy (JNIEnv *env, jobject jhost); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_setPstate(JNIEnv* env, jobject jhost, jint pstate); -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Host_getPstate(JNIEnv* env, jobject jhost); -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Host_getPstatesCount(JNIEnv* env, jobject jhost); -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCurrentPowerPeak(JNIEnv* env, jobject jhost); -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getPowerPeakAt(JNIEnv* env, jobject jhost, jint pstate); -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getLoad(JNIEnv* env, jobject jhost); - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCurrentLoad(JNIEnv *env, jobject jhost); -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getAvgLoad(JNIEnv *env, jobject jhost); -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getComputedFlops (JNIEnv *env, jobject jhost); -SG_END_DECL -#endif diff --git a/src/bindings/java/jmsg_process.cpp b/src/bindings/java/jmsg_process.cpp deleted file mode 100644 index ffbf7ff7c8..0000000000 --- a/src/bindings/java/jmsg_process.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/* Functions related to the java process instances. */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "jmsg_process.h" - -#include "JavaContext.hpp" -#include "jmsg.hpp" -#include "jmsg_host.h" -#include "jxbt_utilities.hpp" -#include "simgrid/Exception.hpp" -#include "simgrid/s4u/Actor.hpp" -#include "src/kernel/actor/ActorImpl.hpp" - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java); - -jfieldID jprocess_field_Process_bind; -jfieldID jprocess_field_Process_host; -jfieldID jprocess_field_Process_killTime; -jfieldID jprocess_field_Process_name; -jfieldID jprocess_field_Process_pid; -jfieldID jprocess_field_Process_ppid; - -jobject jprocess_from_native(const_sg_actor_t actor) -{ - const simgrid::kernel::context::JavaContext* context = - static_cast(actor->get_impl()->context_.get()); - return context->jprocess_; -} - -jobject jprocess_ref(jobject jprocess, JNIEnv* env) -{ - return env->NewGlobalRef(jprocess); -} - -void jprocess_unref(jobject jprocess, JNIEnv* env) -{ - env->DeleteGlobalRef(jprocess); -} - -sg_actor_t jprocess_to_native(jobject jprocess, JNIEnv* env) -{ - return (sg_actor_t)(intptr_t)env->GetLongField(jprocess, jprocess_field_Process_bind); -} - -void jprocess_bind(jobject jprocess, const_sg_actor_t actor, JNIEnv* env) -{ - env->SetLongField(jprocess, jprocess_field_Process_bind, (intptr_t)actor); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_nativeInit(JNIEnv *env, jclass cls) { - jclass jprocess_class_Process = env->FindClass("org/simgrid/msg/Process"); - xbt_assert(jprocess_class_Process, "Native initialization of msg/Process failed. Please report that bug"); - - jprocess_field_Process_name = jxbt_get_jfield(env, jprocess_class_Process, "name", "Ljava/lang/String;"); - jprocess_field_Process_bind = jxbt_get_jfield(env, jprocess_class_Process, "bind", "J"); - jprocess_field_Process_pid = jxbt_get_jfield(env, jprocess_class_Process, "pid", "I"); - jprocess_field_Process_ppid = jxbt_get_jfield(env, jprocess_class_Process, "ppid", "I"); - jprocess_field_Process_host = jxbt_get_jfield(env, jprocess_class_Process, "host", "Lorg/simgrid/msg/Host;"); - jprocess_field_Process_killTime = jxbt_get_jfield(env, jprocess_class_Process, "killTime", "D"); - xbt_assert(jprocess_field_Process_name && jprocess_field_Process_pid && jprocess_field_Process_ppid && - jprocess_field_Process_host, - "Native initialization of msg/Process failed. Please report that bug"); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_create(JNIEnv* env, jobject jprocess_arg, jobject jhost) -{ - /* create a global java process instance */ - jobject jprocess = jprocess_ref(jprocess_arg, env); - - /* Actually build the MSG process */ - auto jname = (jstring)env->GetObjectField(jprocess, jprocess_field_Process_name); - const char* name = env->GetStringUTFChars(jname, nullptr); - auto actor_code = [jprocess]() { simgrid::kernel::context::java_main_jprocess(jprocess); }; - auto self = simgrid::kernel::actor::ActorImpl::self(); - sg_host_t host = jhost_get_native(env, jhost); - auto* actor = simgrid::kernel::actor::simcall_answered([name, actor_code, host, self] { - return simgrid::kernel::actor::ActorImpl::create(std::move(name), std::move(actor_code), nullptr, host, self).get(); - }); - sg_actor_yield(); - - env->ReleaseStringUTFChars(jname, name); - - /* Retrieve the kill time from the actor */ - actor->get_ciface()->set_kill_time((double)env->GetDoubleField(jprocess, jprocess_field_Process_killTime)); - - /* sets the PID and the PPID of the actor */ - env->SetIntField(jprocess, jprocess_field_Process_pid, (jint)actor->get_ciface()->get_pid()); - env->SetIntField(jprocess, jprocess_field_Process_ppid, (jint)actor->get_ciface()->get_ppid()); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_daemonize(JNIEnv* env, jobject jprocess) -{ - sg_actor_t actor = jprocess_to_native(jprocess, env); - - if (not actor) { - jxbt_throw_notbound(env, "process", jprocess); - return; - } - - actor->daemonize(); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_killAll(JNIEnv* env, jclass cls) -{ - sg_actor_kill_all(); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_fromPID(JNIEnv * env, jclass cls, jint pid) -{ - auto const* actor = sg_actor_by_pid(pid); - - if (not actor) { - jxbt_throw_process_not_found(env, std::string("PID = ") + std::to_string(static_cast(pid))); - return nullptr; - } - - jobject jprocess = jprocess_from_native(actor); - - if (not jprocess) { - jxbt_throw_jni(env, "get process failed"); - return nullptr; - } - - return jprocess; -} - -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Process_nativeGetPID(JNIEnv* env, jobject jprocess) -{ - const_sg_actor_t actor = jprocess_to_native(jprocess, env); - return sg_actor_get_pid(actor); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getProperty(JNIEnv *env, jobject jprocess, jobject jname) { - const_sg_actor_t actor = jprocess_to_native(jprocess, env); - - if (not actor) { - jxbt_throw_notbound(env, "process", jprocess); - return nullptr; - } - jstring_wrapper name(env, (jstring)jname); - - const char* property = actor->get_property(name); - if (not property) - return nullptr; - - jobject jproperty = env->NewStringUTF(property); - - return jproperty; -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getCurrentProcess(JNIEnv * env, jclass cls) -{ - jobject jprocess = jprocess_from_native(sg_actor_self()); - if (not jprocess) - jxbt_throw_jni(env, xbt_strdup("SIMIX_process_get_jprocess() failed")); - - return jprocess; -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_suspend(JNIEnv * env, jobject jprocess) -{ - sg_actor_t actor = jprocess_to_native(jprocess, env); - - if (not actor) { - jxbt_throw_notbound(env, "process", jprocess); - return; - } - - /* suspend the process */ - actor->suspend(); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_resume(JNIEnv * env, jobject jprocess) -{ - sg_actor_t actor = jprocess_to_native(jprocess, env); - - if (not actor) { - jxbt_throw_notbound(env, "process", jprocess); - return; - } - - /* resume the process */ - actor->resume(); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_setAutoRestart(JNIEnv* env, jobject jprocess, - jboolean jauto_restart) -{ - sg_actor_t actor = jprocess_to_native(jprocess, env); - if (not actor) { - jxbt_throw_notbound(env, "process", jprocess); - return; - } - - actor->set_auto_restart(jauto_restart == JNI_TRUE); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_restart (JNIEnv *env, jobject jprocess) { - sg_actor_t actor = jprocess_to_native(jprocess, env); - - if (not actor) { - jxbt_throw_notbound(env, "process", jprocess); - return; - } - - actor->restart(); -} - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Process_isSuspended(JNIEnv * env, jobject jprocess) -{ - sg_actor_t actor = jprocess_to_native(jprocess, env); - - if (not actor) { - jxbt_throw_notbound(env, "process", jprocess); - return 0; - } - - /* true is the actor is suspended, false otherwise */ - return (jboolean)actor->is_suspended(); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_sleep(JNIEnv *env, jclass cls, jlong jmillis, jint jnanos) - { - double time = ((double)jmillis) / 1000 + ((double)jnanos) / 1000000000; - msg_error_t rv = MSG_OK; - if (not simgrid::ForcefulKillException::try_n_catch([&time]() { simgrid::s4u::this_actor::sleep_for(time); })) { - rv = MSG_HOST_FAILURE; - } - if (rv != MSG_OK) { - jmsg_throw_status(env, rv); - } -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_waitFor(JNIEnv * env, jobject jprocess, jdouble jseconds) -{ - msg_error_t rv = MSG_OK; - if (not simgrid::ForcefulKillException::try_n_catch( - [&jseconds]() { simgrid::s4u::this_actor::sleep_for((double)jseconds); })) { - rv = MSG_HOST_FAILURE; - jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed"); - } - if (env->ExceptionOccurred()) - return; - if (rv != MSG_OK) { - XBT_DEBUG("Status NOK"); - jmsg_throw_status(env,rv); - } -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_kill(JNIEnv * env, jobject jprocess) -{ - /* get the native instances from the java ones */ - sg_actor_t actor = jprocess_to_native(jprocess, env); - if (not actor) { - jxbt_throw_notbound(env, "process", jprocess); - return; - } - if (not simgrid::ForcefulKillException::try_n_catch([&actor]() { actor->kill(); })) { - jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed"); - } -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_migrate(JNIEnv * env, jobject jprocess, jobject jhost) -{ - sg_actor_t actor = jprocess_to_native(jprocess, env); - - if (not actor) { - jxbt_throw_notbound(env, "process", jprocess); - return; - } - - sg_host_t host = jhost_get_native(env, jhost); - - if (not host) { - jxbt_throw_notbound(env, "host", jhost); - return; - } - - /* change the host of the actor */ - actor->set_host(host); - - /* change the host java side */ - env->SetObjectField(jprocess, jprocess_field_Process_host, jhost); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_yield(JNIEnv* env, jclass cls) -{ - simgrid::s4u::this_actor::yield(); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_setKillTime (JNIEnv *env , jobject jprocess, jdouble jkilltime) { - jprocess_to_native(jprocess, env)->set_kill_time((double)jkilltime); -} - -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Process_getCount(JNIEnv * env, jclass cls) { - return (jint)sg_actor_count(); -} diff --git a/src/bindings/java/jmsg_process.h b/src/bindings/java/jmsg_process.h deleted file mode 100644 index 489f9c2234..0000000000 --- a/src/bindings/java/jmsg_process.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Functions related to the java process instances. */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef MSG_JPROCESS_H -#define MSG_JPROCESS_H - -#include "simgrid/actor.h" -#include - -SG_BEGIN_DECL; - -/* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */ -#ifndef JNIEXPORT -#define JNIEXPORT -#endif -#ifndef JNICALL -#define JNICALL -#endif -/* end of eclipse-mandated pimple */ - -// Cached java fields accessed by the rest of the code -extern jfieldID jprocess_field_Process_pid; -extern jfieldID jprocess_field_Process_ppid; - -/** Take a ref onto the java instance (to prevent its collection) */ -jobject jprocess_ref(jobject jprocess, JNIEnv* env); - -/** Release a ref onto the java instance */ -void jprocess_unref(jobject jprocess, JNIEnv* env); - -/** Binds a native instance to a java instance. */ -void jprocess_bind(jobject jprocess, const_sg_actor_t process, JNIEnv* env); - -/** Extract the java instance from the native one */ -jobject jprocess_from_native(const_sg_actor_t process); - -/** Extract the native instance from the java one */ -sg_actor_t jprocess_to_native(jobject jprocess, JNIEnv* env); - -/** Initialize the native world, called from the Java world at startup */ -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_nativeInit(JNIEnv *env, jclass cls); - -/* Implement the Java API */ - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_create(JNIEnv* env, jobject jprocess_arg, jobject jhostname); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_daemonize(JNIEnv* env, jobject jprocess); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_killAll(JNIEnv* env, jclass cls); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_fromPID(JNIEnv* env, jclass cls, jint pid); -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Process_nativeGetPID(JNIEnv* env, jobject jprocess); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getProperty(JNIEnv* env, jobject jprocess, jobject jname); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getCurrentProcess(JNIEnv* env, jclass cls); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_suspend(JNIEnv* env, jobject jprocess); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_resume(JNIEnv* env, jobject jprocess); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_setAutoRestart(JNIEnv* env, jobject jprocess, jboolean jauto_restart); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_restart(JNIEnv* env, jobject jprocess); -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Process_isSuspended(JNIEnv* env, jobject jprocess); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_sleep(JNIEnv* env, jclass cls, jlong jmillis, jint jnanos); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_waitFor(JNIEnv* env, jobject jprocess, jdouble jseconds); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_kill(JNIEnv* env, jobject jprocess); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_migrate(JNIEnv* env, jobject jprocess, jobject jhost); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_yield(JNIEnv* env, jclass cls); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_setKillTime(JNIEnv* env, jobject jprocess, jdouble jkilltime); -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Process_getCount(JNIEnv * env, jclass cls); - -SG_END_DECL; -#endif diff --git a/src/bindings/java/jmsg_synchro.cpp b/src/bindings/java/jmsg_synchro.cpp deleted file mode 100644 index 92ba1cc418..0000000000 --- a/src/bindings/java/jmsg_synchro.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* Java bindings of the Synchronization API. */ - -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "jmsg_synchro.h" -#include "jmsg.hpp" -#include "jxbt_utilities.hpp" -#include "simgrid/Exception.hpp" -#include "simgrid/mutex.h" -#include "simgrid/semaphore.h" - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java); - -static jfieldID jsynchro_field_Mutex_bind; - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_nativeInit(JNIEnv *env, jclass cls) { - jsynchro_field_Mutex_bind = jxbt_get_sfield(env, "org/simgrid/msg/Mutex", "bind", "J"); - xbt_assert(jsynchro_field_Mutex_bind, "Native initialization of msg/Mutex failed. Please report that bug"); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_init(JNIEnv * env, jobject obj) { - sg_mutex_t mutex = sg_mutex_init(); - - env->SetLongField(obj, jsynchro_field_Mutex_bind, (jlong)(uintptr_t)(mutex)); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_acquire(JNIEnv * env, jobject obj) { - auto mutex = (sg_mutex_t)(uintptr_t)env->GetLongField(obj, jsynchro_field_Mutex_bind); - sg_mutex_lock(mutex); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_release(JNIEnv * env, jobject obj) { - sg_mutex_t mutex; - - mutex = (sg_mutex_t)(uintptr_t)env->GetLongField(obj, jsynchro_field_Mutex_bind); - sg_mutex_unlock(mutex); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_nativeFinalize(JNIEnv * env, jobject obj) { - const_sg_mutex_t mutex = (sg_mutex_t)(uintptr_t)env->GetLongField(obj, jsynchro_field_Mutex_bind); - sg_mutex_destroy(mutex); -} - -static jfieldID jsynchro_field_Semaphore_bind; - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_nativeInit(JNIEnv *env, jclass cls) { - jsynchro_field_Semaphore_bind = jxbt_get_sfield(env, "org/simgrid/msg/Semaphore", "bind", "J"); - xbt_assert(jsynchro_field_Semaphore_bind, "Native initialization of msg/Semaphore failed. Please report that bug"); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_init(JNIEnv * env, jobject obj, jint capacity) { - sg_sem_t sem = sg_sem_init((int)capacity); - - env->SetLongField(obj, jsynchro_field_Semaphore_bind, (jlong)(uintptr_t)(sem)); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_acquire(JNIEnv * env, jobject obj, jdouble timeout) { - sg_sem_t sem; - - sem = (sg_sem_t)(uintptr_t)env->GetLongField(obj, jsynchro_field_Semaphore_bind); - msg_error_t res = sg_sem_acquire_timeout(sem, (double)timeout) == 0 ? MSG_OK : MSG_TIMEOUT; - if (res != MSG_OK) { - jmsg_throw_status(env, res); - } -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_release(JNIEnv * env, jobject obj) { - sg_sem_t sem; - - sem = (sg_sem_t)(uintptr_t)env->GetLongField(obj, jsynchro_field_Semaphore_bind); - sg_sem_release(sem); -} - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Semaphore_wouldBlock(JNIEnv * env, jobject obj) { - sg_sem_t sem; - - sem = (sg_sem_t)(uintptr_t)env->GetLongField(obj, jsynchro_field_Semaphore_bind); - int res = sg_sem_would_block(sem); - return (jboolean) res; -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_nativeFinalize(JNIEnv * env, jobject obj) { - const_sg_sem_t sem; - - sem = (sg_sem_t)(uintptr_t)env->GetLongField(obj, jsynchro_field_Semaphore_bind); - sg_sem_destroy(sem); -} diff --git a/src/bindings/java/jmsg_synchro.h b/src/bindings/java/jmsg_synchro.h deleted file mode 100644 index 35641e4049..0000000000 --- a/src/bindings/java/jmsg_synchro.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Java bindings of the Synchronization API. */ - -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef MSG_JSYNCHRO_H -#define MSG_JSYNCHRO_H - -#include "xbt/base.h" -#include - -SG_BEGIN_DECL - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_nativeInit(JNIEnv *env, jclass cls); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_init(JNIEnv * env, jobject obj); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_acquire(JNIEnv * env, jobject obj); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_release(JNIEnv * env, jobject obj); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Mutex_nativeFinalize(JNIEnv * env, jobject obj); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_nativeInit(JNIEnv *env, jclass cls); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_init(JNIEnv * env, jobject obj, jint capacity); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_acquire(JNIEnv * env, jobject obj, jdouble timeout); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_release(JNIEnv * env, jobject obj); -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Semaphore_wouldBlock(JNIEnv * env, jobject obj); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Semaphore_nativeFinalize(JNIEnv * env, jobject obj); - -SG_END_DECL -#endif diff --git a/src/bindings/java/jmsg_task.cpp b/src/bindings/java/jmsg_task.cpp deleted file mode 100644 index d5686e2238..0000000000 --- a/src/bindings/java/jmsg_task.cpp +++ /dev/null @@ -1,501 +0,0 @@ -/* Functions related to the java task instances. */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/Exception.hpp" -#include "simgrid/s4u/Host.hpp" - -#include "jmsg.hpp" -#include "jmsg_host.h" -#include "jmsg_process.h" -#include "jmsg_task.h" -#include "jxbt_utilities.hpp" - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java); - -static jmethodID jtask_method_Comm_constructor; - -static jfieldID jtask_field_Task_bind; -static jfieldID jtask_field_Task_name; -static jfieldID jtask_field_Task_messageSize; -static jfieldID jtask_field_Comm_bind; -static jfieldID jtask_field_Comm_taskBind; -static jfieldID jtask_field_Comm_receiving; - -void jtask_bind(jobject jtask, msg_task_t task, JNIEnv * env) -{ - env->SetLongField(jtask, jtask_field_Task_bind, (intptr_t)task); -} - -msg_task_t jtask_to_native(jobject jtask, JNIEnv* env) -{ - return (msg_task_t)(intptr_t)env->GetLongField(jtask, jtask_field_Task_bind); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_nativeInit(JNIEnv *env, jclass cls) { - jclass jtask_class_Comm = env->FindClass("org/simgrid/msg/Comm"); - jclass jtask_class_Task = env->FindClass("org/simgrid/msg/Task"); - xbt_assert(jtask_class_Comm && jtask_class_Task, - "Native initialization of msg/Comm or msg/Task failed. Please report that bug"); - - jtask_method_Comm_constructor = env->GetMethodID(jtask_class_Comm, "", "()V"); - jtask_field_Task_bind = jxbt_get_jfield(env, jtask_class_Task, "bind", "J"); - jtask_field_Task_name = jxbt_get_jfield(env, jtask_class_Task, "name", "Ljava/lang/String;"); - jtask_field_Task_messageSize = jxbt_get_jfield(env, jtask_class_Task, "messageSize", "D"); - jtask_field_Comm_bind = jxbt_get_jfield(env, jtask_class_Comm, "bind", "J"); - jtask_field_Comm_taskBind = jxbt_get_jfield(env, jtask_class_Comm, "taskBind", "J"); - jtask_field_Comm_receiving = jxbt_get_jfield(env, jtask_class_Comm, "receiving", "Z"); - xbt_assert(jtask_field_Task_bind && jtask_field_Comm_bind && jtask_field_Comm_taskBind && - jtask_field_Comm_receiving && jtask_method_Comm_constructor, - "Native initialization of msg/Task failed. Please report that bug"); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_create(JNIEnv * env, jobject jtask, jstring jname, - jdouble jflopsAmount, jdouble jbytesAmount) -{ - jstring_wrapper task_name(env, jname); - msg_task_t task = MSG_task_create(task_name, jflopsAmount, jbytesAmount, jtask); - - /* bind & store the task */ - jtask_bind(jtask, task, env); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_parallelCreate(JNIEnv * env, jobject jtask, jstring jname, - jobjectArray jhosts, jdoubleArray jcomputeDurations_arg, - jdoubleArray jmessageSizes_arg) -{ - int host_count = env->GetArrayLength(jhosts); - - jdouble* jcomputeDurations = env->GetDoubleArrayElements(jcomputeDurations_arg, nullptr); - auto* hosts = new msg_host_t[host_count]; - auto* computeDurations = new double[host_count]; - for (int index = 0; index < host_count; index++) { - jobject jhost = env->GetObjectArrayElement(jhosts, index); - hosts[index] = jhost_get_native(env, jhost); - computeDurations[index] = jcomputeDurations[index]; - } - env->ReleaseDoubleArrayElements(jcomputeDurations_arg, jcomputeDurations, 0); - - jdouble* jmessageSizes = env->GetDoubleArrayElements(jmessageSizes_arg, nullptr); - auto* messageSizes = new double[host_count * host_count]; - for (int index = 0; index < host_count * host_count; index++) { - messageSizes[index] = jmessageSizes[index]; - } - env->ReleaseDoubleArrayElements(jmessageSizes_arg, jmessageSizes, 0); - - /* get the C string from the java string */ - jstring_wrapper name(env, jname); - msg_task_t task = MSG_parallel_task_create(name, host_count, hosts, computeDurations, messageSizes, jtask); - - /* associate the java task object and the native task */ - jtask_bind(jtask, task, env); - - delete[] hosts; - delete[] computeDurations; - delete[] messageSizes; -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_cancel(JNIEnv * env, jobject jtask) -{ - msg_task_t ptask = jtask_to_native(jtask, env); - - if (not ptask) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - - msg_error_t rv = MSG_task_cancel(ptask); - xbt_assert(rv == MSG_OK, "MSG_task_cancel() unexpectedly failed with error code %d. Please report this bug", rv); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_execute(JNIEnv * env, jobject jtask) -{ - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - msg_error_t rv; - if (not simgrid::ForcefulKillException::try_n_catch([&rv, &task]() { rv = MSG_task_execute(task); })) { - jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed"); - } - - if (env->ExceptionOccurred()) - return; - if (rv != MSG_OK) { - jmsg_throw_status(env, rv); - } -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setBound(JNIEnv * env, jobject jtask, jdouble bound) -{ - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - MSG_task_set_bound(task, bound); -} - -JNIEXPORT jstring JNICALL Java_org_simgrid_msg_Task_getName(JNIEnv * env, jobject jtask) { - const_msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return nullptr; - } - - return env->NewStringUTF(MSG_task_get_name(task)); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_getSender(JNIEnv * env, jobject jtask) { - const_msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return nullptr; - } - - auto const* process = MSG_task_get_sender(task); - if (process == nullptr) { - return nullptr; - } - return (jobject)jprocess_from_native(process); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_getSource(JNIEnv * env, jobject jtask) -{ - const_msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return nullptr; - } - - auto const* host = MSG_task_get_source(task); - if (host == nullptr) { - return nullptr; - } - if (not host->extension(JAVA_HOST_LEVEL)) { - jxbt_throw_jni(env, "MSG_task_get_source() failed"); - return nullptr; - } - - return (jobject) host->extension(JAVA_HOST_LEVEL); -} - -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Task_getFlopsAmount(JNIEnv * env, jobject jtask) -{ - const_msg_task_t ptask = jtask_to_native(jtask, env); - - if (not ptask) { - jxbt_throw_notbound(env, "task", jtask); - return -1; - } - return (jdouble)MSG_task_get_flops_amount(ptask); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setName(JNIEnv *env, jobject jtask, jobject jname) { - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - jstring_wrapper name(env, static_cast(jname)); - - env->SetObjectField(jtask, jtask_field_Task_name, jname); - MSG_task_set_name(task, name); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setPriority(JNIEnv * env, jobject jtask, jdouble priority) -{ - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - MSG_task_set_priority(task, priority); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setFlopsAmount (JNIEnv *env, jobject jtask, jdouble computationAmount) -{ - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - MSG_task_set_flops_amount(task, computationAmount); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setBytesAmount (JNIEnv *env, jobject jtask, jdouble dataSize) -{ - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - env->SetDoubleField(jtask, jtask_field_Task_messageSize, dataSize); - MSG_task_set_bytes_amount(task, dataSize); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_sendBounded(JNIEnv * env,jobject jtask, jstring jalias, - jdouble jtimeout,jdouble maxrate) -{ - msg_task_t task = jtask_to_native(jtask, env); - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - - /* Add a global ref into the Ctask so that the receiver can use it */ - MSG_task_set_data(task, env->NewGlobalRef(jtask)); - - jstring_wrapper alias(env, jalias); - msg_error_t res = MSG_task_send_with_timeout_bounded(task, alias, jtimeout, maxrate); - - if (res != MSG_OK) - jmsg_throw_status(env, res); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_receive(JNIEnv* env, jclass cls, jstring jalias, jdouble jtimeout) -{ - msg_task_t task = nullptr; - - jstring_wrapper alias(env, jalias); - msg_error_t rv; - if (not simgrid::ForcefulKillException::try_n_catch( - [&rv, &task, &alias, &jtimeout]() { rv = MSG_task_receive_with_timeout(&task, alias, (double)jtimeout); })) { - jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed"); - } - if (env->ExceptionOccurred()) - return nullptr; - if (rv != MSG_OK) { - jmsg_throw_status(env, rv); - return nullptr; - } - auto jtask_global = (jobject)MSG_task_get_data(task); - - /* Convert the global ref into a local ref so that the JVM can free the stuff */ - jobject jtask_local = env->NewLocalRef(jtask_global); - env->DeleteGlobalRef(jtask_global); - MSG_task_set_data(task, nullptr); - - return (jobject) jtask_local; -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_irecv(JNIEnv * env, jclass cls, jstring jmailbox) { - jclass comm_class = env->FindClass("org/simgrid/msg/Comm"); - if (not comm_class) - return nullptr; - - //pointer to store the task object pointer. - auto* task = new msg_task_t(nullptr); - /* There should be a cache here */ - - jobject jcomm = env->NewObject(comm_class, jtask_method_Comm_constructor); - if (not jcomm) { - jxbt_throw_jni(env, "Can't create a Comm object."); - return nullptr; - } - - jstring_wrapper mailbox(env, jmailbox); - msg_comm_t comm = MSG_task_irecv(task, mailbox); - - env->SetLongField(jcomm, jtask_field_Comm_bind, (jlong) (uintptr_t)(comm)); - env->SetLongField(jcomm, jtask_field_Comm_taskBind, (jlong) (uintptr_t)(task)); - env->SetBooleanField(jcomm, jtask_field_Comm_receiving, JNI_TRUE); - - return jcomm; -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_receiveBounded(JNIEnv* env, jclass cls, jstring jalias, - jdouble jtimeout, jdouble rate) -{ - msg_task_t task = nullptr; - - jstring_wrapper alias(env, jalias); - msg_error_t res = MSG_task_receive_with_timeout_bounded(&task, alias, jtimeout, rate); - if (env->ExceptionOccurred()) - return nullptr; - if (res != MSG_OK) { - jmsg_throw_status(env, res); - return nullptr; - } - auto jtask_global = (jobject)MSG_task_get_data(task); - - /* Convert the global ref into a local ref so that the JVM can free the stuff */ - jobject jtask_local = env->NewLocalRef(jtask_global); - env->DeleteGlobalRef(jtask_global); - MSG_task_set_data(task, nullptr); - - return (jobject) jtask_local; -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_irecvBounded(JNIEnv * env, jclass cls, jstring jmailbox, - jdouble rate) -{ - jclass comm_class = env->FindClass("org/simgrid/msg/Comm"); - if (not comm_class) - return nullptr; - - // pointer to store the task object pointer. - auto* task = new msg_task_t(nullptr); - - jobject jcomm = env->NewObject(comm_class, jtask_method_Comm_constructor); - if (not jcomm) { - jxbt_throw_jni(env, "Can't create a Comm object."); - return nullptr; - } - - jstring_wrapper mailbox(env, jmailbox); - msg_comm_t comm = MSG_task_irecv_bounded(task, mailbox, rate); - - env->SetLongField(jcomm, jtask_field_Comm_bind, (jlong) (uintptr_t)(comm)); - env->SetLongField(jcomm, jtask_field_Comm_taskBind, (jlong) (uintptr_t)(task)); - env->SetBooleanField(jcomm, jtask_field_Comm_receiving, JNI_TRUE); - - return jcomm; -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_isend(JNIEnv *env, jobject jtask, jstring jmailbox) -{ - msg_comm_t comm; - - jclass comm_class = env->FindClass("org/simgrid/msg/Comm"); - - if (not comm_class) - return nullptr; - - jobject jcomm = env->NewObject(comm_class, jtask_method_Comm_constructor); - jstring_wrapper mailbox(env, jmailbox); - - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - env->DeleteLocalRef(jcomm); - jxbt_throw_notbound(env, "task", jtask); - return nullptr; - } - - MSG_task_set_data(task, env->NewGlobalRef(jtask)); - comm = MSG_task_isend(task,mailbox); - - env->SetLongField(jcomm, jtask_field_Comm_bind, (jlong) (uintptr_t)(comm)); - env->SetLongField(jcomm, jtask_field_Comm_taskBind, (jlong) (uintptr_t)(nullptr)); - env->SetBooleanField(jcomm, jtask_field_Comm_receiving, JNI_FALSE); - - return jcomm; -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_isendBounded(JNIEnv *env, jobject jtask, jstring jmailbox, - jdouble maxrate) -{ - msg_task_t task; - jobject jcomm; - msg_comm_t comm; - - jclass comm_class = env->FindClass("org/simgrid/msg/Comm"); - if (not comm_class) - return nullptr; - - jcomm = env->NewObject(comm_class, jtask_method_Comm_constructor); - jstring_wrapper mailbox(env, jmailbox); - - task = jtask_to_native(jtask, env); - - if (not task) { - env->DeleteLocalRef(jcomm); - jxbt_throw_notbound(env, "task", jtask); - return nullptr; - } - - MSG_task_set_data(task, env->NewGlobalRef(jtask)); - comm = MSG_task_isend_bounded(task,mailbox,maxrate); - - env->SetLongField(jcomm, jtask_field_Comm_bind, (jlong) (uintptr_t)(comm)); - env->SetLongField(jcomm, jtask_field_Comm_taskBind, (jlong) (uintptr_t)(nullptr)); - env->SetBooleanField(jcomm, jtask_field_Comm_receiving, JNI_FALSE); - - return jcomm; -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_nativeFinalize(JNIEnv * env, jobject jtask) -{ - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - - MSG_task_destroy(task); -} - -static void msg_task_cancel_on_failed_dsend(void*t) { - auto task = (msg_task_t)t; - JNIEnv* env = get_current_thread_env(); - if (env) { - auto jtask_global = (jobject)MSG_task_get_data(task); - /* Destroy the global ref so that the JVM can free the stuff */ - env->DeleteGlobalRef(jtask_global); - /* Don't free the C data here, to avoid a race condition with the GC also sometimes doing so. - * A rare memleak is seen as preferable to a rare "free(): invalid pointer" failure that - * proves really hard to debug. - */ - } - MSG_task_set_data(task, nullptr); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_dsend(JNIEnv * env, jobject jtask, jstring jalias) -{ - jstring_wrapper alias(env, jalias); - - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - - /* Pass a global ref to the Jtask into the Ctask so that the receiver can use it */ - MSG_task_set_data(task, env->NewGlobalRef(jtask)); - MSG_task_dsend(task, alias, msg_task_cancel_on_failed_dsend); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_dsendBounded(JNIEnv * env, jobject jtask, jstring jalias, - jdouble maxrate) -{ - jstring_wrapper alias(env, jalias); - - msg_task_t task = jtask_to_native(jtask, env); - - if (not task) { - jxbt_throw_notbound(env, "task", jtask); - return; - } - - /* Pass a global ref to the Jtask into the Ctask so that the receiver can use it */ - MSG_task_set_data(task, env->NewGlobalRef(jtask)); - MSG_task_dsend_bounded(task, alias, msg_task_cancel_on_failed_dsend, maxrate); -} - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Task_listen(JNIEnv * env, jclass cls, jstring jalias) -{ - jstring_wrapper alias(env, jalias); - return (jboolean)MSG_task_listen(alias); -} - -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Task_listenFrom(JNIEnv * env, jclass cls, jstring jalias) -{ - jstring_wrapper alias(env, jalias); - return (jint)MSG_task_listen_from(alias); -} diff --git a/src/bindings/java/jmsg_task.h b/src/bindings/java/jmsg_task.h deleted file mode 100644 index 9384815f84..0000000000 --- a/src/bindings/java/jmsg_task.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Functions related to the java task instances. */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef MSG_JTASK_H -#define MSG_JTASK_H - -#include -#include "simgrid/msg.h" - -SG_BEGIN_DECL - -/** Binds a native instance to a java instance. */ -void jtask_bind(jobject jtask, msg_task_t task, JNIEnv * env); - -/** Extract the native instance from the java one */ -msg_task_t jtask_to_native(jobject jtask, JNIEnv* env); - -/** Initialize the native world, called from the Java world at startup */ -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_nativeInit(JNIEnv* env, jclass cls); - -/* Implement the Java API */ - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_create(JNIEnv* env, jobject jtask, jstring jname, - jdouble jcomputeDuration, jdouble jmessageSize); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_nativeFinalize(JNIEnv* env, jobject jtask); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_parallelCreate(JNIEnv* env, jobject jtask, jstring jname, - jobjectArray jhosts, jdoubleArray jcomputeDurations_arg, - jdoubleArray jmessageSizes); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_cancel(JNIEnv* env, jobject jtask); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_execute(JNIEnv* env, jobject jtask); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setBound(JNIEnv* env, jobject jtask, jdouble bound); -JNIEXPORT jstring JNICALL Java_org_simgrid_msg_Task_getName(JNIEnv* env, jobject jtask); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setName(JNIEnv* env, jobject jtask, jobject jname); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_getSender(JNIEnv* env, jobject jtask); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_getSource(JNIEnv* env, jobject jtask); -JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Task_getFlopsAmount(JNIEnv* env, jobject jtask); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setPriority(JNIEnv* env, jobject jtask, jdouble prioriy); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setFlopsAmount(JNIEnv* env, jobject jtask, jdouble computationAmount); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setBytesAmount(JNIEnv* env, jobject jtask, jdouble dataSize); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_sendBounded(JNIEnv* env, jobject jtask, jstring jalias, - jdouble jtimeout, jdouble maxrate); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_receive(JNIEnv* env, jclass cls, jstring jalias, jdouble jtimeout); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_irecv(JNIEnv* env, jclass cls, jstring jmailbox); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_receiveBounded(JNIEnv* env, jclass cls, jstring jalias, - jdouble jtimeout, jdouble rate); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_irecvBounded(JNIEnv* env, jclass cls, jstring jmailbox, - jdouble rate); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_isend(JNIEnv* env, jobject jtask, jstring jmailbox); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Task_isendBounded(JNIEnv* env, jobject jtask, jstring jmailbox, - jdouble maxrate); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_dsend(JNIEnv* env, jobject jtask, jstring jalias); -JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_dsendBounded(JNIEnv* env, jobject jtask, jstring jalias, - jdouble maxrate); -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Task_listen(JNIEnv* env, jclass cls, jstring jalias); -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Task_listenFromHost(JNIEnv* env, jclass cls, jstring jalias, jobject jhost); -JNIEXPORT jint JNICALL Java_org_simgrid_msg_Task_listenFrom(JNIEnv* env, jclass cls, jstring jalias); - -SG_END_DECL -#endif diff --git a/src/bindings/java/jmsg_vm.cpp b/src/bindings/java/jmsg_vm.cpp deleted file mode 100644 index 48cd4abe7b..0000000000 --- a/src/bindings/java/jmsg_vm.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* Functions related to the Virtual Machines. */ - -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "jmsg_vm.h" -#include "jmsg_host.h" -#include "jxbt_utilities.hpp" -#include "simgrid/Exception.hpp" -#include "simgrid/plugins/live_migration.h" -#include "src/kernel/resource/VirtualMachineImpl.hpp" - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java); - -extern int JAVA_HOST_LEVEL; -static jfieldID jvm_field_bind; - -void jvm_bind(JNIEnv* env, jobject jvm, sg_vm_t vm) -{ - env->SetLongField(jvm, jvm_field_bind, (intptr_t)vm); -} - -sg_vm_t jvm_get_native(JNIEnv* env, jobject jvm) -{ - return (sg_vm_t)(intptr_t)env->GetLongField(jvm, jvm_field_bind); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_nativeInit(JNIEnv *env, jclass cls) -{ - jclass jprocess_class_VM = env->FindClass("org/simgrid/msg/VM"); - jvm_field_bind = jxbt_get_jfield(env, jprocess_class_VM, "bind", "J"); - xbt_assert(jvm_field_bind, "Native initialization of msg/VM failed. Please report that bug"); -} - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isCreated(JNIEnv* env, jobject jvm) -{ - const_sg_vm_t vm = jvm_get_native(env, jvm); - return sg_vm_is_created(vm); -} - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isRunning(JNIEnv* env, jobject jvm) -{ - const_sg_vm_t vm = jvm_get_native(env, jvm); - return sg_vm_is_running(vm); -} - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isMigrating(JNIEnv* env, jobject jvm) -{ - const_sg_vm_t vm = jvm_get_native(env, jvm); - return sg_vm_is_migrating(vm); -} - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isSuspended(JNIEnv* env, jobject jvm) -{ - const_sg_vm_t vm = jvm_get_native(env, jvm); - return sg_vm_is_suspended(vm); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_setBound(JNIEnv *env, jobject jvm, jdouble bound) -{ - sg_vm_t vm = jvm_get_native(env, jvm); - sg_vm_set_bound(vm, bound); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_create(JNIEnv* env, jobject jVm, jobject jHost, jstring jname, - jint coreAmount, jint jramsize, jint jmig_netspeed, - jint jdp_intensity) -{ - sg_host_t host = jhost_get_native(env, jHost); - - jstring_wrapper name(env, jname); - sg_vm_t vm = sg_vm_create_migratable(host, name, static_cast(coreAmount), static_cast(jramsize), - static_cast(jmig_netspeed), static_cast(jdp_intensity)); - - jvm_bind(env, jVm, vm); - jVm = env->NewGlobalRef(jVm); - // We use the extension level of the host, even if that's somehow disturbing - vm->extension_set(JAVA_HOST_LEVEL, jVm); -} - -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_VM_all(JNIEnv* env, jclass cls_arg) -{ - sg_host_t* hosts = sg_host_list(); - size_t host_count = sg_host_count(); - std::vector vms; - - for (size_t i = 0; i < host_count; i++) { - const auto* vm = dynamic_cast(hosts[i]); - if (vm != nullptr && vm->get_state() != simgrid::s4u::VirtualMachine::State::DESTROYED) { - auto jvm = static_cast(vm->extension(JAVA_HOST_LEVEL)); - vms.push_back(jvm); - } - } - xbt_free(hosts); - - vms.shrink_to_fit(); - int count = vms.size(); - - jclass cls = jxbt_get_class(env, "org/simgrid/msg/VM"); - if (not cls) - return nullptr; - - jobjectArray jtable = env->NewObjectArray((jsize)count, cls, nullptr); - if (not jtable) { - jxbt_throw_jni(env, "Hosts table allocation failed"); - return nullptr; - } - - for (int index = 0; index < count; index++) { - jobject jhost = vms.at(index); - env->SetObjectArrayElement(jtable, index, jhost); - } - return jtable; -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_nativeFinalize(JNIEnv *env, jobject jvm) -{ - sg_vm_t vm = jvm_get_native(env, jvm); - sg_vm_destroy(vm); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_start(JNIEnv *env, jobject jvm) -{ - sg_vm_t vm = jvm_get_native(env, jvm); - sg_vm_start(vm); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_shutdown(JNIEnv *env, jobject jvm) -{ - sg_vm_t vm = jvm_get_native(env, jvm); - if (vm) - sg_vm_shutdown(vm); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_destroy(JNIEnv* env, jobject jvm) -{ - sg_vm_t vm = jvm_get_native(env, jvm); - if (vm) { - sg_vm_destroy(vm); - auto* vmList = &simgrid::kernel::resource::VirtualMachineImpl::allVms_; - vmList->erase(std::remove(vmList->begin(), vmList->end(), vm), vmList->end()); - } -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_nativeMigration(JNIEnv* env, jobject jvm, jobject jhost) -{ - sg_vm_t vm = jvm_get_native(env, jvm); - sg_host_t host = jhost_get_native(env, jhost); - if (not simgrid::ForcefulKillException::try_n_catch([&vm, &host]() { sg_vm_migrate(vm, host); })) { - XBT_VERB("Caught exception during migration"); - jxbt_throw_host_failure(env, " during migration"); - } -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_suspend(JNIEnv *env, jobject jvm) -{ - sg_vm_t vm = jvm_get_native(env, jvm); - sg_vm_suspend(vm); -} - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_resume(JNIEnv *env, jobject jvm) -{ - sg_vm_t vm = jvm_get_native(env, jvm); - sg_vm_resume(vm); -} - -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_VM_getVMByName(JNIEnv* env, jclass cls, jstring jname) -{ - /* get the C string from the java string */ - if (jname == nullptr) { - jxbt_throw_null(env, "No VM can have a null name"); - return nullptr; - } - jstring_wrapper name(env, jname); - /* get the VM by name (VMs are just special hosts, unfortunately) */ - auto const* host = sg_host_by_name(name); - - if (not host) { /* invalid name */ - jxbt_throw_host_not_found(env, name); - return nullptr; - } - - return static_cast(host->extension(JAVA_HOST_LEVEL)); -} diff --git a/src/bindings/java/jmsg_vm.h b/src/bindings/java/jmsg_vm.h deleted file mode 100644 index 977cb5436b..0000000000 --- a/src/bindings/java/jmsg_vm.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Functions related to the Virtual Machines. */ - -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef MSG_VM_H -#define MSG_VM_H - -#include "simgrid/host.h" -#include "simgrid/vm.h" -#include - -SG_BEGIN_DECL - -/* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */ -#ifndef JNIEXPORT -#define JNIEXPORT -#endif -#ifndef JNICALL -#define JNICALL -#endif -/* end of eclipse-mandated pimple */ - -void jvm_bind(JNIEnv* env, jobject jvm, sg_vm_t vm); -sg_vm_t jvm_get_native(JNIEnv* env, jobject jvm); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_nativeInit(JNIEnv* env, jclass cls); - -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_VM_all(JNIEnv* env, jclass cls_arg); - -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isCreated(JNIEnv* env, jobject jvm); -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isRunning(JNIEnv* env, jobject jvm); -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isMigrating(JNIEnv* env, jobject jvm); -JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isSuspended(JNIEnv* env, jobject jvm); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_setBound(JNIEnv* env, jobject jvm, jdouble bound); - -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_create(JNIEnv* env, jobject jvm, jobject jhost, jstring jname, - jint coreAmount, jint jramsize, jint dprate, jint mig_netspeed); -JNIEXPORT jobject JNICALL Java_org_simgrid_msg_VM_getVMByName(JNIEnv* env, jclass cls, jstring jname); -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_nativeFinalize(JNIEnv* env, jobject jvm); -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_start(JNIEnv* env, jobject jvm); -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_nativeMigration(JNIEnv* env, jobject jvm, jobject jhost); -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_suspend(JNIEnv* env, jobject jvm); -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_resume(JNIEnv* env, jobject jvm); -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_shutdown(JNIEnv* env, jobject jvm); -JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_destroy(JNIEnv* env, jobject jvm); - -SG_END_DECL - -#endif diff --git a/src/bindings/java/jtrace.cpp b/src/bindings/java/jtrace.cpp deleted file mode 100644 index bcfa76854b..0000000000 --- a/src/bindings/java/jtrace.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* Java bindings of the Trace API. */ - -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "jtrace.h" -#include "jxbt_utilities.hpp" -#include "simgrid/instr.h" - -/* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */ -#ifndef JNIEXPORT -#define JNIEXPORT -#endif -#ifndef JNICALL -#define JNICALL -#endif -/* end of eclipse-mandated pimple */ - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostStateDeclare(JNIEnv * env, jclass cls, jstring js) -{ - jstring_wrapper s(env, js); - TRACE_host_state_declare(s); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostStateDeclareValue (JNIEnv *env, jclass cls, jstring js_state, - jstring js_value, jstring js_color) -{ - jstring_wrapper state(env, js_state); - jstring_wrapper value(env, js_value); - jstring_wrapper color(env, js_color); - - TRACE_host_state_declare_value(state, value, color); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostSetState (JNIEnv *env, jclass cls, jstring js_host, - jstring js_state, jstring js_value) -{ - jstring_wrapper host(env, js_host); - jstring_wrapper state(env, js_state); - jstring_wrapper value(env, js_value); - - TRACE_host_set_state(host, state, value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostPushState (JNIEnv *env, jclass cls, jstring js_host, - jstring js_state, jstring js_value) -{ - jstring_wrapper host(env, js_host); - jstring_wrapper state(env, js_state); - jstring_wrapper value(env, js_value); - - TRACE_host_push_state(host, state, value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostPopState (JNIEnv *env, jclass cls, jstring js_host, - jstring js_state) -{ - jstring_wrapper host(env, js_host); - jstring_wrapper state(env, js_state); - - TRACE_host_pop_state(host, state); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostVariableDeclare(JNIEnv* env, jclass cls, jstring js_variable) -{ - jstring_wrapper variable(env, js_variable); - simgrid::instr::declare_host_variable(variable); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostVariableSet(JNIEnv* env, jclass cls, jstring js_host, - jstring js_variable, jdouble value) -{ - jstring_wrapper host(env, js_host); - jstring_wrapper variable(env, js_variable); - - simgrid::instr::set_host_variable(host, variable, value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostVariableAdd(JNIEnv* env, jclass cls, jstring js_host, - jstring js_variable, jdouble value) -{ - jstring_wrapper host(env, js_host); - jstring_wrapper variable(env, js_variable); - - simgrid::instr::add_host_variable(host, variable, value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostVariableSub(JNIEnv* env, jclass cls, jstring js_host, - jstring js_variable, jdouble value) -{ - jstring_wrapper host(env, js_host); - jstring_wrapper variable(env, js_variable); - - simgrid::instr::sub_host_variable(host, variable, value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_vmVariableDeclare(JNIEnv* env, jclass cls, jstring js_variable) -{ - jstring_wrapper variable(env, js_variable); - simgrid::instr::declare_vm_variable(variable); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_vmVariableSet(JNIEnv* env, jclass cls, jstring js_vm, - jstring js_variable, jdouble value) -{ - jstring_wrapper vm(env, js_vm); - jstring_wrapper variable(env, js_variable); - - simgrid::instr::set_vm_variable(vm, variable, value); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkVariableDeclare (JNIEnv *env, jclass cls, jstring jvar) { - jstring_wrapper variable(env, jvar); - simgrid::instr::declare_link_variable(variable); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkVariableDeclareWithColor (JNIEnv *env, jclass cls, jstring jvar, jstring jcolor) { - jstring_wrapper variable(env, jvar); - jstring_wrapper color(env, jcolor); - simgrid::instr::declare_link_variable(variable, color); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkVariableSet (JNIEnv *env, jclass cls, jstring jlink, jstring jvar, jdouble jvalue) { - jstring_wrapper link(env, jlink); - jstring_wrapper variable(env, jvar); - simgrid::instr::set_link_variable(link, variable, jvalue); -} - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkSrcDstVariableSet - (JNIEnv *env, jclass cls, jstring jsrc, jstring jdst, jstring jvar, jdouble jval) -{ - jstring_wrapper src(env, jsrc); - jstring_wrapper dst(env, jdst); - - jstring_wrapper variable(env, jvar); - simgrid::instr::set_link_variable(src, dst, variable, jval); -} diff --git a/src/bindings/java/jtrace.h b/src/bindings/java/jtrace.h deleted file mode 100644 index 626d40d1d3..0000000000 --- a/src/bindings/java/jtrace.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Java bindings of the Trace API. */ - -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -/* Header for class org_simgrid_trace_Trace */ - -#ifndef Included_org_simgrid_trace_Trace -#define Included_org_simgrid_trace_Trace - -/* Shut up some errors in eclipse online compiler. I wish such a pimple wouldn't be needed */ -#ifndef JNIEXPORT -#define JNIEXPORT -#endif -#ifndef JNICALL -#define JNICALL -#endif -/* end of eclipse-mandated pimple */ - -#ifdef __cplusplus -extern "C" { -#endif -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostVariableDeclare (JNIEnv *env, jclass cls, jstring jvar); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_vmVariableDeclare (JNIEnv *env, jclass cls, jstring jvar); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostVariableDeclareWithColor (JNIEnv *env, jclass cls, jstring jvar, - jstring jcolor); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostVariableSet (JNIEnv *env, jclass cls, jstring js_host, - jstring jvar, jdouble value); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_vmVariableSet (JNIEnv *env, jclass cls, jstring js_wn, - jstring jvar, jdouble value); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostVariableAdd (JNIEnv *env, jclass cls, jstring js_host, - jstring jvar, jdouble value); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostVariableSub (JNIEnv *env, jclass cls, jstring js_host, - jstring jvar, jdouble value); -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_trace_Trace_getHostVariablesName (JNIEnv *env, jclass cls); - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkVariableDeclare (JNIEnv *env, jclass cls, jstring jvar); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkVariableDeclareWithColor (JNIEnv *env, jclass cls, jstring jvar, - jstring jcolor); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkVariableSet (JNIEnv *env, jclass cls, jstring jlink, - jstring jvar, jdouble jvalue); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkVariableAdd (JNIEnv *env, jclass cls, jstring jlink, - jstring jvar, jdouble jvalue); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkVariableSub (JNIEnv *env, jclass cls, jstring jlink, - jstring jvar, jdouble jvalue); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_linkSrcDstVariableSet (JNIEnv *env, jclass cls, jstring jsrc, - jstring jdst, jstring jvar, jdouble jvalue); -JNIEXPORT jobjectArray JNICALL Java_org_simgrid_trace_Trace_getLinkVariablesName (JNIEnv *env, jclass cls); - -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostStateDeclare(JNIEnv * env, jclass cls, jstring js); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostStateDeclareValue (JNIEnv *env, jclass cls, jstring js_state, - jstring js_value, jstring js_color); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostSetState (JNIEnv *env, jclass cls, jstring js_host, - jstring js_state, jstring js_value); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostPushState (JNIEnv *env, jclass cls, jstring js_host, - jstring js_state, jstring js_value); -JNIEXPORT void JNICALL Java_org_simgrid_trace_Trace_hostPopState (JNIEnv *env, jclass cls, jstring js_host, - jstring js_state); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/bindings/java/jxbt_utilities.cpp b/src/bindings/java/jxbt_utilities.cpp deleted file mode 100644 index c2597b0fee..0000000000 --- a/src/bindings/java/jxbt_utilities.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* Various JNI helper functions */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "jxbt_utilities.hpp" -#include "xbt/string.hpp" -#include "xbt/sysdep.h" - -jclass jxbt_get_class(JNIEnv * env, const char *name) -{ - jclass cls = env->FindClass(name); - if (not cls) { - jxbt_throw_jni(env, std::string("Class ") + name + " not found"); - return nullptr; - } - - return cls; -} - -jmethodID jxbt_get_jmethod(JNIEnv * env, jclass cls, const char *name, const char *signature) -{ - if (not cls) - return nullptr; - - jmethodID id = env->GetMethodID(cls, name, signature); - if (not id) { - jmethodID tostr_id = env->GetMethodID(cls, "getName", "()Ljava/lang/String;"); - auto jclassname = (jstring)env->CallObjectMethod(cls, tostr_id, nullptr); - jstring_wrapper classname(env, jclassname); - auto msg = std::string("Cannot find method") + name + "(" + signature + ") in " + classname.value; - - jxbt_throw_jni(env, msg); - return nullptr; - } - - return id; -} - -jmethodID jxbt_get_static_jmethod(JNIEnv * env, jclass cls, const char *name, const char *signature) -{ - if (not cls) - return nullptr; - - jmethodID id = env->GetStaticMethodID(cls, name, signature); - if (not id) { - jmethodID tostr_id = env->GetMethodID(cls, "getName", "()Ljava/lang/String;"); - auto jclassname = (jstring)env->CallObjectMethod(cls, tostr_id, nullptr); - jstring_wrapper classname(env, jclassname); - auto msg = std::string("Cannot find static method") + name + "(" + signature + ") in " + classname.value; - - jxbt_throw_jni(env, msg); - return nullptr; - } - - return id; -} - -jmethodID jxbt_get_static_smethod(JNIEnv * env, const char *classname, const char *name, const char *signature) -{ - jclass cls = jxbt_get_class(env, classname); - if (not cls) - return nullptr; - - jmethodID id = env->GetStaticMethodID(cls, name, signature); - if (not id) { - jxbt_throw_jni(env, std::string("Cannot find static method") + name + "(" + signature + ") in " + classname); - return nullptr; - } - return id; -} - -jmethodID jxbt_get_smethod(JNIEnv * env, const char *classname, const char *name, const char *signature) -{ - jclass cls = jxbt_get_class(env, classname); - if (not cls) - return nullptr; - - jmethodID id = env->GetMethodID(cls, name, signature); - if (not id) { - jxbt_throw_jni(env, std::string("Cannot find method") + name + "(" + signature + ") in " + classname); - return nullptr; - } - return id; -} - -jfieldID jxbt_get_jfield(JNIEnv * env, jclass cls, const char *name, const char *signature) -{ - if (not cls) - return nullptr; - - jfieldID id = env->GetFieldID(cls, name, signature); - if (not id) { - jmethodID getname_id = env->GetMethodID(cls, "getName", "()Ljava/lang/String;"); - auto jclassname = (jstring)env->CallObjectMethod(cls, getname_id, nullptr); - const char* classname = env->GetStringUTFChars(jclassname, nullptr); - - env->ReleaseStringUTFChars(jclassname, classname); - - jxbt_throw_jni(env, std::string("Cannot find field") + signature + " " + name + " in " + classname); - - return nullptr; - } - - return id; -} - -jfieldID jxbt_get_sfield(JNIEnv * env, const char *classname, const char *name, const char *signature) -{ - jclass cls = jxbt_get_class(env, classname); - if (not cls) - return nullptr; - - jfieldID id = env->GetFieldID(cls, name, signature); - if (not id) { - jxbt_throw_jni(env, std::string("Cannot find field") + signature + " " + name + " in " + classname); - return nullptr; - } - - return id; -} - -void jxbt_throw_by_name(JNIEnv* env, const char* name, const std::string& msg) -{ - jclass cls = env->FindClass(name); - - xbt_assert(cls, "%s (Plus severe error: class %s not found)\n", msg.c_str(), name); - - env->ThrowNew(cls, msg.c_str()); -} - -void jxbt_throw_jni(JNIEnv* env, const std::string& msg) -{ - jxbt_throw_by_name(env, "org/simgrid/msg/JniException", "Internal or JNI error: " + msg); -} - -void jxbt_throw_notbound(JNIEnv* env, const std::string& kind, void* pointer) -{ - jxbt_throw_by_name(env, "org/simgrid/msg/JniException", - simgrid::xbt::string_printf("Internal error: %s %p not bound", kind.c_str(), pointer)); -} - -void jxbt_throw_null(JNIEnv* env, const std::string& msg) -{ - jxbt_throw_by_name(env, "java/lang/NullPointerException", msg); -} - -void jxbt_throw_illegal(JNIEnv* env, const std::string& msg) -{ - jxbt_throw_by_name(env, "java/lang/IllegalArgumentException", msg); -} - -void jxbt_throw_host_not_found(JNIEnv* env, const std::string& invalid_name) -{ - jxbt_throw_by_name(env, "org/simgrid/msg/HostNotFoundException", "No such host: " + invalid_name); -} - -void jxbt_throw_process_not_found(JNIEnv* env, const std::string& invalid_name) -{ - jxbt_throw_by_name(env, "org/simgrid/msg/ProcessNotFoundException", "No such process: " + invalid_name); -} - -void jxbt_throw_transfer_failure(JNIEnv* env, const std::string& details) -{ - jxbt_throw_by_name(env, "org/simgrid/msg/TransferFailureException", details); -} - -void jxbt_throw_host_failure(JNIEnv* env, const std::string& details) -{ - jxbt_throw_by_name(env, "org/simgrid/msg/HostFailureException", "Host Failure" + details); -} - -void jxbt_throw_time_out_failure(JNIEnv* env, const std::string& details) -{ - jxbt_throw_by_name(env, "org/simgrid/msg/TimeoutException", details); -} - -void jxbt_throw_task_cancelled(JNIEnv* env, const std::string& details) -{ - jxbt_throw_by_name(env, "org/simgrid/msg/TaskCancelledException", details); -} diff --git a/src/bindings/java/jxbt_utilities.hpp b/src/bindings/java/jxbt_utilities.hpp deleted file mode 100644 index 63988babbf..0000000000 --- a/src/bindings/java/jxbt_utilities.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* Various JNI helper functions */ - -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef JXBT_UTILITIES_HPP -#define JXBT_UTILITIES_HPP - -#include -#include -#include - -/* Search a class and throw an exception if not found */ -jclass jxbt_get_class(JNIEnv* env, const char* name); - -/* Search a method in a class and throw an exception if not found(it's ok to to pass a NULL class: it's a noop) */ -jmethodID jxbt_get_jmethod(JNIEnv* env, jclass cls, const char* name, const char* signature); - -/* Like the jxbt_get_class() but get a static method */ -jmethodID jxbt_get_static_jmethod(JNIEnv* env, jclass cls, const char* name, const char* signature); - -/* Search a field in a class and throw an exception if not found (it's ok to to pass a NULL class: it's a noop) */ -jfieldID jxbt_get_jfield(JNIEnv* env, jclass cls, const char* name, const char* signature); - -/* Search a method in a class and throw an exception if not found (it's ok to to pass a NULL class: it's a noop) */ -jmethodID jxbt_get_smethod(JNIEnv* env, const char* classname, const char* name, const char* signature); - -/* Like the jxbt_get_smethod() but get a static method */ -jmethodID jxbt_get_static_smethod(JNIEnv* env, const char* classname, const char* name, const char* signature); - -/* Search a field in a class and throw an exception if not found (it's ok to to pass a NULL class: it's a noop) */ -jfieldID jxbt_get_sfield(JNIEnv* env, const char* classname, const char* name, const char* signature); - -/* Throws an exception according to its name */ -void jxbt_throw_by_name(JNIEnv* env, const char* name, const std::string& msg); -/** Thrown on internal error of this layer, or on problem with JNI */ -void jxbt_throw_jni(JNIEnv* env, const std::string& msg); -/** Thrown when using an object not bound to a native one where it should, or reverse (kinda JNI issue) */ -void jxbt_throw_notbound(JNIEnv* env, const std::string& kind, void* pointer); -/** Thrown if NULL gets used */ -void jxbt_throw_null(JNIEnv* env, const std::string& msg); - -/** Thrown on illegal arguments */ -void jxbt_throw_illegal(JNIEnv* env, const std::string& msg); -/** Thrown when looking for a host from name does not lead to anything */ -void jxbt_throw_host_not_found(JNIEnv* env, const std::string& invalid_name); -/** Thrown when looking for a host from name does not lead to anything */ -void jxbt_throw_process_not_found(JNIEnv* env, const std::string& invalid_name); -/** Thrown when a transfer failure occurs while Sending task */ -void jxbt_throw_transfer_failure(JNIEnv* env, const std::string& detail); -/** Thrown when a host failure occurs while Sending a task*/ -void jxbt_throw_host_failure(JNIEnv* env, const std::string& details); -/** Thrown when a timeout occurs while Sending a task */ -void jxbt_throw_time_out_failure(JNIEnv* env, const std::string& details); -/**Thrown when a task is canceled */ -void jxbt_throw_task_cancelled(JNIEnv* env, const std::string& details); - -class jstring_wrapper { - JNIEnv* env_ = nullptr; - jstring jstr_ = nullptr; - -public: - const char* value = nullptr; - - jstring_wrapper(JNIEnv* env, jstring jstr) : env_(env), jstr_(jstr) - { - if (jstr != nullptr) - value = env_->GetStringUTFChars(jstr_, nullptr); - } - void reset(JNIEnv* env, jstring jstr) - { - if (jstr_ != nullptr) - env_->ReleaseStringUTFChars(jstr_, value); - env_ = env; - jstr_ = jstr; - if (jstr != nullptr) - value = env_->GetStringUTFChars(jstr_, nullptr); - } - ~jstring_wrapper() - { - if (jstr_ != nullptr) - env_->ReleaseStringUTFChars(jstr_, value); - } - operator const char*() const { return value; } - operator const std::string() const { return std::string(value); } -}; - -#endif diff --git a/src/bindings/java/org/simgrid/NativeLib.java b/src/bindings/java/org/simgrid/NativeLib.java deleted file mode 100644 index 5d2b646406..0000000000 --- a/src/bindings/java/org/simgrid/NativeLib.java +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.stream.Stream; - -/** Helper class loading the native functions of SimGrid that we use for downcalls - * - * Almost all org.simgrid.msg.* classes contain a static block (thus executed when the class is loaded) - * containing a call to this. - */ -public final class NativeLib { - private static final boolean WINDOWS_OS = System.getProperty("os.name").toLowerCase().startsWith("win"); - private static boolean isNativeInited = false; - private static Path tempDir = null; // where the embeeded libraries are unpacked before loading them - - /** A static-only "class" don't need no constructor */ - private NativeLib() { - throw new IllegalAccessError("Utility class"); - } - - /** Hidden debug main() function - * - * It is not the Main-Class defined in src/bindings/java/MANIFEST.in (org.simgrid.msg.Msg is), - * so it won't get executed by default. But that's helpful to debug linkage errors, if you - * know that it exists. It's used by cmake during the configure, to inform the user. - */ - public static void main(String[] args) { - System.out.println("This jarfile searches the native code under: " +getPath()); - } - - /** Main function loading all the native classes that we need */ - public static void nativeInit() { - if (isNativeInited) - return; - - if (WINDOWS_OS) - NativeLib.nativeInit("winpthread-1"); - - NativeLib.nativeInit("simgrid"); - NativeLib.nativeInit("simgrid-java"); - isNativeInited = true; - } - - /** Helper function trying to load one requested library */ - public static void nativeInit(String name) { - Throwable cause = null; - try { - /* Prefer the version of the library bundled into the jar file and use it */ - if (loadLibAsStream(name)) - return; - } catch (UnsatisfiedLinkError|SecurityException|IOException e) { - cause = e; - } - - /* If not found, try to see if we can find a version on disk */ - try { - System.loadLibrary(name); - return; - } catch (UnsatisfiedLinkError systemException) { /* don't care */ } - - System.err.println("\nCannot load the bindings to the "+name+" library in path "+getPath()+" and no usable SimGrid installation found on disk."); - if (cause != null) { - if (cause.getMessage().contains("libcgraph.so")) - System.err.println("HINT: Try to install the libcgraph package (sudo apt-get install libcgraph)."); - else if (cause.getMessage().contains("libboost_context.so")) - System.err.println("HINT: Try to install the boost-context package (sudo apt-get install libboost-context-dev)."); - else - System.err.println("Try to install the missing dependencies, if any. Read carefully the following error message."); - - System.err.println(); - cause.printStackTrace(); - } else { - System.err.println("This jar file does not seem to fit your system, and no usable SimGrid installation found on disk for "+name+"."); - } - System.exit(1); - } - - /** Try to extract the library from the jarfile before loading it */ - private static boolean loadLibAsStream (String name) throws IOException, UnsatisfiedLinkError { - String path = NativeLib.getPath(); - - // We must write the lib onto the disk before loading it -- stupid operating systems - if (tempDir == null) { - final String tempPrefix = "simgrid-java-"; - - if (WINDOWS_OS) { - // The cleanup at exit fails on Windows where it is impossible to delete files which are still in - // use. Try to remove stale temporary files from previous executions, and limit disk usage. - Path tmpdir = (new File(System.getProperty("java.io.tmpdir"))).toPath(); - try (Stream paths = Files.find(tmpdir, 1, - (Path p, java.nio.file.attribute.BasicFileAttributes a) -> - a.isDirectory() && !p.equals(tmpdir) && - p.getFileName().toString().startsWith(tempPrefix))) { - paths.map(Path::toFile) - .map(FileCleaner::new) - .forEach(FileCleaner::run); - - } - } - - tempDir = Files.createTempDirectory(tempPrefix); - // don't leak the files on disk, but remove it on JVM shutdown - Runtime.getRuntime().addShutdownHook(new Thread(new FileCleaner(tempDir.toFile()))); - } - - /* For each possible filename of the given library on all possible OSes, try it */ - for (String filename : new String[] - { name, - "lib"+name+".so", /* linux */ - name+".dll", "lib"+name+".dll", /* windows (pure and mingw) */ - "lib"+name+".dylib" /* macOS */}) { - - File fileOut = new File(tempDir.toFile(), filename); - try ( // Try-with-resources. These stream will be autoclosed when needed. - InputStream in = NativeLib.class.getClassLoader().getResourceAsStream(path+filename); - ) { - if (in != null) { - /* copy the library in position */ - Files.copy(in, fileOut.toPath()); - - /* load that library */ - System.load(fileOut.getAbsolutePath()); - - /* It loaded! we're good */ - return true; - } - } - } - - /* No suitable name found */ - return false; - } - - /** Find where to search for the library in the jar -- keep it aligned with where cmake puts it! */ - private static String getPath() { - // Inspiration: https://github.com/xerial/snappy-java/blob/develop/src/main/java/org/xerial/snappy/OSInfo.java - String prefix = "NATIVE"; - String os = System.getProperty("os.name"); - String arch = System.getProperty("os.arch"); - - if (arch.matches("^i[3-6]86$")) - arch = "x86"; - else if ("x86_64".equalsIgnoreCase(arch) || "AMD64".equalsIgnoreCase(arch)) - arch = "amd64"; - - if (os.toLowerCase().startsWith("win")) { - os = "Windows"; - } else if (os.contains("OS X")) { - os = "Darwin"; - } - os = os.replace(' ', '_'); - arch = arch.replace(' ', '_'); - - return prefix + "/" + os + "/" + arch + "/"; - } - - /** A hackish mechanism used to remove the file containing our library when the JVM shuts down */ - private static class FileCleaner implements Runnable { - private File dir; - public FileCleaner(File dir) { - this.dir = dir; - } - @Override - public void run() { - try (Stream paths = Files.walk(dir.toPath())) { - paths.sorted(java.util.Comparator.reverseOrder()) - .map(java.nio.file.Path::toFile) - //.peek(System.err::println) // Prints what gets removed - .forEach(java.io.File::delete); - } catch(Exception e) { - System.err.println("Error while cleaning temporary file " + dir.getAbsolutePath() + - ": " + e.getCause()); - e.printStackTrace(); - } - } - } -} diff --git a/src/bindings/java/org/simgrid/msg/As.java b/src/bindings/java/org/simgrid/msg/As.java deleted file mode 100644 index 06e81c2694..0000000000 --- a/src/bindings/java/org/simgrid/msg/As.java +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -public class As { - - private long bind; - - protected As() {} - - @Override - public String toString (){ - return this.getName(); - } - public native String getName(); - - public native As[] getSons(); - - public native String getProperty(String name); - - public native Host[] getHosts(); - - /** - * Class initializer, to initialize various JNI stuff - */ - public static native void nativeInit(); - static { - nativeInit(); - } -} diff --git a/src/bindings/java/org/simgrid/msg/Comm.java b/src/bindings/java/org/simgrid/msg/Comm.java deleted file mode 100644 index d73d042097..0000000000 --- a/src/bindings/java/org/simgrid/msg/Comm.java +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** Communication action, representing an ongoing communication between processes. */ -public class Comm { - /** Indicates if the communication is a receiving communication */ - protected boolean receiving; - /** Indicates if the communication is finished */ - protected boolean finished = false; - /** - * Represents the bind between the java comm and the - * native C comm. You must never access it, since it is - * automatically set. - */ - private long bind = 0; - /** Represents the bind for the task object pointer. Don't touch it. */ - private long taskBind = 0; - /** Task associated with the comm. Beware, it can be null */ - protected Task task = null; - /** - * Protected constructor, used by Comm factories - * in Task. - */ - protected Comm() { - - } - /** - * Destroy the C communication object, when the GC reclaims the java part. - * @deprecated (from Java9 onwards) - */ - @Deprecated @Override - protected void finalize() throws Throwable{ - nativeFinalize(); - } - protected native void nativeFinalize(); - /** - * Returns if the communication is finished or not. - * If the communication has finished and there was an error, - * raise an exception. - */ - public native boolean test() throws TransferFailureException, HostFailureException, TimeoutException ; - /** Wait infinitely for the completion of the communication (infinite timeout) */ - public void waitCompletion() throws TransferFailureException, HostFailureException, TimeoutException { - waitCompletion(-1); - } - /** - * Wait for the completion of the communication. - * Throws an exception if there were an error in the communication. - * @param timeout Time before giving up (infinite time if negative) - */ - public native void waitCompletion(double timeout) throws TransferFailureException, HostFailureException, TimeoutException; - - /** Wait all of the communications */ - public static native void waitAll(Comm[] comms, double timeout) throws TransferFailureException, HostFailureException, TimeoutException; - /** Wait all of the communications, with no maximal delay */ - public static void waitAll(Comm[] comms) throws TransferFailureException, HostFailureException, TimeoutException { - waitAll(comms, -1.); - } - /** Wait any of the communications, and return the rank of the terminating comm */ - public static native int waitAny(Comm[] comms) throws TransferFailureException, HostFailureException, TimeoutException; - /** - * Returns the task associated with the communication. - * if the communication isn't finished yet, will return null. - */ - public Task getTask() { - return task; - } - - /** Class initializer, to initialize various JNI stuff */ - public static native void nativeInit(); - static { - org.simgrid.NativeLib.nativeInit(); - nativeInit(); - } -} diff --git a/src/bindings/java/org/simgrid/msg/Host.java b/src/bindings/java/org/simgrid/msg/Host.java deleted file mode 100644 index 866d537ada..0000000000 --- a/src/bindings/java/org/simgrid/msg/Host.java +++ /dev/null @@ -1,168 +0,0 @@ -/* Bindings to the MSG hosts */ - -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** - * A host object represents a location (any possible place) where a process may run. - * Thus it is represented as a physical resource with computing capabilities, some - * mailboxes to enable running process to communicate with remote ones, and some private - * data that can be only accessed by local process. An instance of this class is always - * bound with the corresponding native host. All the native hosts are automatically created - * during the call of the method Msg.createEnvironment(). This method take as parameter a - * platform file which describes all elements of the platform (host, link, root..). - * You cannot create a host yourself. - * - * The best way to get a host instance is to call the static method - * Host.getByName(). - * - * For example to get the instance of the host. If your platform - * file description contains a host named "Jacquelin" : - * - * \verbatim -Host jacquelin; - -try { - jacquelin = Host.getByName("Jacquelin"); -} catch(HostNotFoundException e) { - System.err.println(e.toString()); -} -... -\endverbatim - * - */ -public class Host { - - /** - * This attribute represents a bind between a java host object and - * a native host. Even if this attribute is public you must never - * access to it. It is set automatically during the call of the - * static method Host.getByName(). - * - * @see Host.getByName(). - */ - private long bind; - protected String name; - - /** User data. */ - private Object data; - protected Host() { - this.bind = 0; - this.data = null; - } - - @Override - public String toString (){ - return this.name; - } - - /** - * This static method gets a host instance associated with a native - * host of your platform. This is the best way to get a java host object. - * - * @param name The name of the host to get. - * - * @return The host object with the given name. - * @exception HostNotFoundException if the name of the host is not valid. - */ - public static native Host getByName(String name) throws HostNotFoundException; - /** Counts the installed hosts. */ - public static native int getCount(); - - /** Returns the host of the current process. */ - public static native Host currentHost(); - - /** Returns all hosts of the installed platform. */ - public static native Host[] all(); - - /** - * This static method sets a mailbox to receive in asynchronous mode. - * - * All messages sent to this mailbox will be transferred to - * the receiver without waiting for the receive call. - * The receive call will still be necessary to use the received data. - * If there is a need to receive some messages asynchronously, and some not, - * two different mailboxes should be used. - * - * @param mailboxName The name of the mailbox - */ - public static native void setAsyncMailbox(String mailboxName); - - public String getName() { - return name; - } - - public void setData(Object data) { - this.data = data; - } - - public Object getData() { - return this.data; - } - /** Returns true if the host has an associated data object. */ - public boolean hasData() { - return null != this.data; - } - - /** Starts the host if it is off */ - public native void on(); - /** Stops the host if it is on */ - public native void off() throws ProcessKilledError; - - /** - * This method returns the speed of the processor of a host (in flops), - * regardless of the current load of the machine. - */ - public native double getSpeed(); - public native double getCoreNumber(); - - public native String getProperty(String name); - public native void setProperty(String name, String value); - /** Tests if a host is up and running. */ - public native boolean isOn(); - - /** After this call, sg_host_get_consumed_energy() will not interrupt your process - * (until after the next clock update). - */ - public static native void updateAllEnergyConsumptions(); - /** Returns the amount of Joules consumed by that host so far - * - * Please note that since the consumption is lazily updated, it may require a simcall to update it. - * The result is that the actor requesting this value will be interrupted, - * the value will be updated in kernel mode before returning the control to the requesting actor. - */ - public native double getConsumedEnergy(); - - /** Returns the current load of the host, as a ratio = achieved_flops / (core_current_speed * core_amount) - * - * See simgrid::plugin::HostLoad::get_current_load() for the full documentation. - */ - public native double getCurrentLoad(); - /** Returns the number of flops computed of the host since the beginning of the simulation */ - public native double getComputedFlops(); - /** Returns the average load of the host as a ratio since the beginning of the simulation*/ - public native double getAvgLoad(); - - /** Returns the current pstate */ - public native int getPstate(); - /** Changes the current pstate */ - public native void setPstate(int pstate); - public native int getPstatesCount(); - /** Returns the speed of the processor (in flop/s) at the current pstate. See also @ref plugin_energy. */ - public native double getCurrentPowerPeak(); - /** Returns the speed of the processor (in flop/s) at a given pstate. See also @ref plugin_energy. */ - public native double getPowerPeakAt(int pstate); - - /** Returns the current computation load (in flops per second) */ - public native double getLoad(); - - /** Class initializer, to initialize various JNI stuff */ - private static native void nativeInit(); - static { - nativeInit(); - } -} diff --git a/src/bindings/java/org/simgrid/msg/HostFailureException.java b/src/bindings/java/org/simgrid/msg/HostFailureException.java deleted file mode 100644 index 39bee14454..0000000000 --- a/src/bindings/java/org/simgrid/msg/HostFailureException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** This exception is raised when the host on which you are running has just been rebooted. */ -public class HostFailureException extends MsgException { - private static final long serialVersionUID = 1L; - - /** Constructs an HostFailureException without a detail message. */ - public HostFailureException() { - super(); - } - /** Constructs an HostFailureException with a detail message. */ - public HostFailureException(String s) { - super(s); - } -} diff --git a/src/bindings/java/org/simgrid/msg/HostNotFoundException.java b/src/bindings/java/org/simgrid/msg/HostNotFoundException.java deleted file mode 100644 index 24602844b7..0000000000 --- a/src/bindings/java/org/simgrid/msg/HostNotFoundException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** This exception is raised when looking for a non-existing host. */ -public class HostNotFoundException extends MsgException { - private static final long serialVersionUID = 1L; - - /** Constructs an HostNotFoundException without a detail message. */ - public HostNotFoundException() { - super(); - } - /** Constructs an HostNotFoundException with a detail message. */ - public HostNotFoundException(String s) { - super(s); - } -} diff --git a/src/bindings/java/org/simgrid/msg/JniException.java b/src/bindings/java/org/simgrid/msg/JniException.java deleted file mode 100644 index 2a3541ad8c..0000000000 --- a/src/bindings/java/org/simgrid/msg/JniException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* This exception is raised when there is a problem within the bindings (in JNI). */ - -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** - * Exception raised when there is a problem within the bindings (in JNI). - * - * That's a RuntimeException: I guess nobody wants to survive a JNI error in SimGrid - */ -public class JniException extends RuntimeException { - private static final long serialVersionUID = 1L; - - - /** Constructs an JniException without a detail message. */ - public JniException() { - super(); - } - /** Constructs an JniException with a detail message. */ - public JniException(String s) { - super(s); - } - public JniException(String string, Exception e) { - super(string,e); - } -} diff --git a/src/bindings/java/org/simgrid/msg/Msg.java b/src/bindings/java/org/simgrid/msg/Msg.java deleted file mode 100644 index bc7de74b50..0000000000 --- a/src/bindings/java/org/simgrid/msg/Msg.java +++ /dev/null @@ -1,91 +0,0 @@ -/* JNI interface to C code for MSG. */ - -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -public final class Msg { - - /** Retrieves the simulation time */ - public static final native double getClock(); - /** Issue a debug logging message. */ - public static final native void debug(String msg); - /** Issue a verbose logging message. */ - public static final native void verb(String msg); - /** Issue an information logging message */ - public static final native void info(String msg); - /** Issue a warning logging message. */ - public static final native void warn(String msg); - /** Issue an error logging message. */ - public static final native void error(String msg); - /** Issue a critical logging message. */ - public static final native void critical(String s); - - private Msg() { - throw new IllegalAccessError("Utility class"); - } - - /********************************************************************************* - * Deployment and initialization related functions * - *********************************************************************************/ - - /** Initialize a MSG simulation. - * - * @param args The arguments of the command line of the simulation. - */ - public static final native void init(String[]args); - - /** Tell the kernel that you want to use the energy plugin */ - public static final native void energyInit(); - - /** Tell the kernel that you want to use the filesystem plugin. */ - public static final native void fileSystemInit(); - - /** Initializes the HostLoad plugin. - * - * The HostLoad plugin provides an API to get the current load of each host. - */ - public static final native void loadInit(); - - /** Run the MSG simulation. - * - * After the simulation, you can freely retrieve the information that you want.. - * In particular, retrieving the status of a process or the current date is perfectly ok. - */ - public static final native void run() ; - - /** Create the simulation environment by parsing a platform file. */ - public static final native void createEnvironment(String platformFile); - - public static final native As environmentGetRoutingRoot(); - - /** Starts your processes by parsing a deployment file. */ - public static final native void deployApplication(String deploymentFile); - - /** Example launcher. You can use it or provide your own launcher, as you wish - * @param args - */ - public static void main(String[]args) { - /* initialize the MSG simulation. Must be done before anything else (even logging). */ - Msg.init(args); - - if (args.length < 2) { - Msg.info("Usage: Msg platform_file deployment_file"); - System.exit(1); - } - - /* Load the platform and deploy the application */ - Msg.createEnvironment(args[0]); - Msg.deployApplication(args[1]); - /* Execute the simulation */ - Msg.run(); - } - - /* Class initializer, to initialize various JNI stuff */ - static { - org.simgrid.NativeLib.nativeInit(); - } -} diff --git a/src/bindings/java/org/simgrid/msg/MsgException.java b/src/bindings/java/org/simgrid/msg/MsgException.java deleted file mode 100644 index 21a4f896da..0000000000 --- a/src/bindings/java/org/simgrid/msg/MsgException.java +++ /dev/null @@ -1,22 +0,0 @@ -/* This exception is an abstract class grouping all MSG-related exceptions */ - -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** This exception is an abstract class grouping all MSG-related exceptions */ -public abstract class MsgException extends Exception { - private static final long serialVersionUID = 1L; - - /** Constructs an MsgException without a detail message. */ - protected MsgException() { - super(); - } - /** Constructs an MsgException with a detail message. */ - protected MsgException(String msg) { - super(msg); - } -} diff --git a/src/bindings/java/org/simgrid/msg/Mutex.java b/src/bindings/java/org/simgrid/msg/Mutex.java deleted file mode 100644 index 42fb368615..0000000000 --- a/src/bindings/java/org/simgrid/msg/Mutex.java +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; -/** A mutex implemented on top of SimGrid synchronization mechanisms. - * You can use it exactly the same way that you use the mutexes, - * but to handle the interactions between the processes within the simulation. - * - * Don't mix simgrid synchronization with Java native one, or it will deadlock! - */ -public class Mutex { - private long bind; // The C object -- don't touch it - - public Mutex() { - init(); - } - - /** @deprecated (from Java9 onwards) */ - @Deprecated @Override - protected void finalize() throws Throwable { - nativeFinalize(); - } - private native void nativeFinalize(); - private native void init(); - public native void acquire(); - public native void release(); - - /** Class initializer, to initialize various JNI stuff */ - public static native void nativeInit(); - static { - org.simgrid.NativeLib.nativeInit(); - nativeInit(); - } -} - - diff --git a/src/bindings/java/org/simgrid/msg/Process.java b/src/bindings/java/org/simgrid/msg/Process.java deleted file mode 100644 index 66eb168f86..0000000000 --- a/src/bindings/java/org/simgrid/msg/Process.java +++ /dev/null @@ -1,338 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -import java.util.ArrayList; -import java.util.Arrays; - -/** - * A process may be defined as a code, with some private data, executing - * in a location (host). All the process used by your simulation must be - * declared in the deployment file (XML format). - * To create your own process you must inherit your own process from this - * class and override the method "main()". For example if you want to use - * a process named Worker proceed as it : - * - * (1) import the class Process of the package simgrid.msg - * import simgrid.msg.Process; - * - * public class Worker extends simgrid.msg.Process { - * - * (2) Override the method function - * - * \verbatim - * public void main(String[] args) { - * System.out.println("Hello MSG"); - * } - * \endverbatim - * } - * The name of your process must be declared in the deployment file of your simulation. - * For the example, for the previous process Worker this file must contains a line : - * <process host="Maxims" function="Worker"/>, where Maxims is the host of the process - * Worker. All the process of your simulation are automatically launched and managed by Msg. - * A process use tasks to simulate communications or computations with another process. - * For more information see Task. For more information on host concept - * see Host. - * - */ - -public abstract class Process implements Runnable { - /** - * This attribute represents a bind between a java process object and - * a native process. Even if this attribute is public you must never - * access to it. It is set automatically during the build of the object. - */ - private long bind = 0; - /** Indicates if the process is started */ - - /** Time at which the process should be created */ - protected double startTime = 0; - /** Time at which the process should be killed */ - private double killTime = -1; // Used from the C world - - private String name = null; - - private int pid = -1; - private int ppid = -1; - private Host host = null; - - /** The arguments of the method function of the process. */ - private ArrayList args = new ArrayList<>(); - - /** - * Constructs a new process from the name of a host and his name. The method - * function of the process doesn't have argument. - * - * @param hostname Where to create the process. - * @param name The name of the process. - * - * @exception HostNotFoundException if no host with this name exists. - * - * - */ - protected Process(String hostname, String name) throws HostNotFoundException { - this(Host.getByName(hostname), name, null); - } - /** - * Constructs a new process from the name of a host and his name. The arguments - * of the method function of the process are specified by the parameter args. - * - * @param hostname Where to create the process. - * @param name The name of the process. - * @param args The arguments of the main function of the process. - * - * @exception HostNotFoundException if no host with this name exists. - * - */ - protected Process(String hostname, String name, String[] args) throws HostNotFoundException { - this(Host.getByName(hostname), name, args); - } - /** - * Constructs a new process from a host and his name. The method function of the - * process doesn't have argument. - * - * @param host Where to create the process. - * @param name The name of the process. - * - */ - protected Process(Host host, String name) { - this(host, name, null); - } - /** - * Constructs a new process from a host and his name, the arguments of here method function are - * specified by the parameter args. - * - * @param host Where to create the process. - * @param name The name of the process. - * @param argsParam The arguments of main method of the process. - */ - protected Process(Host host, String name, String[]argsParam) - { - if (host == null) - throw new IllegalArgumentException("Cannot create a process on the null host"); - if (name == null) - throw new IllegalArgumentException("Process name cannot be null"); - - this.host = host; - this.name = name; - - this.args = new ArrayList<>(); - if (null != argsParam) - this.args.addAll(Arrays.asList(argsParam)); - } - /** - * Constructs a new process from a host and his name, the arguments of here method function are - * specified by the parameter args. - * - * @param host Where to create the process. - * @param name The name of the process. - * @param args The arguments of main method of the process. - * @param startTime Start time of the process - * @param killTime Kill time of the process - * - */ - protected Process(Host host, String name, String[]args, double startTime, double killTime) { - this(host, name, args); - this.startTime = startTime; - this.killTime = killTime; - } - /** - * The native method to create an MSG process. - * @param host where to create the process. - */ - protected native void create(Host host); - - /** - * This method kills all running process of the simulation. - */ - public static native void killAll(); - - /** Simply kills the receiving process. - * - * SimGrid sometimes have issues when you kill processes that are currently communicating and such. We are working on it to fix the issues. - */ - public native void kill(); - public static void kill(Process p) { - p.kill(); - } - - /** Suspends the process. See {@link #resume()} to resume it afterward */ - public native void suspend(); - /** Resume a process that was suspended by {@link #suspend()}. */ - public native void resume(); - /** Tests if a process is suspended. - * - * @see suspend() - * @see resume() - */ - public native boolean isSuspended(); - - /** Yield the current process. All other processes that are ready at the same timestamp will be executed first */ - public static native void yield(); - - /** - * Specify whether the process should restart when its host restarts after a failure - * - * A process naturally stops when its host stops. It starts again only if autoRestart is set to true. - * Otherwise, it just disappears when the host stops. - */ - public native void setAutoRestart(boolean autoRestart); - /** Restarts the process from the beginning */ - public native void restart(); - /** - * Returns the name of the process - */ - public String getName() { - return this.name; - } - /** - * Returns the host of the process. - * @return The host instance of the process. - */ - public Host getHost() { - return this.host; - } - /** - * This static method gets a process from a PID. - * - * @param pid The process identifier of the process to get. - * - * @return The process with the specified PID. - */ - public static native Process fromPID(int pid); - /** - * This method returns the PID of the process. - * - * @return The PID of the process. - * - */ - public int getPID() { - if (pid == -1) // Don't traverse the JNI barrier if you already have the answer - pid = nativeGetPID(); - return pid; - } - // This should not be used: the PID is supposed to be initialized from the C directly when the actor is created, - // but this sometimes fail, so let's play nasty but safe here. - private native int nativeGetPID(); - /** - * This method returns the PID of the parent of a process. - * - * @return The PID of the parent of the process. - * - */ - public int getPPID() { - return ppid; - } - /** - * Returns the value of a given process property. - */ - public native String getProperty(String name); - - /** - * Set the kill time of the process - * @param killTime the time when the process is killed - */ - public native void setKillTime(double killTime); - - /** - * This static method returns the currently running process. - * - * @return The current process. - * - */ - public static native Process getCurrentProcess(); - /** - * Migrates a process to another host. - * - * @param host The host where to migrate the process. - * - */ - public native void migrate(Host host); - /** - * Makes the current process sleep until millis milliseconds have elapsed. - * You should note that unlike "waitFor" which takes seconds (as usual in SimGrid), this method takes milliseconds (as usual for sleep() in Java). - * - * @param millis the length of time to sleep in milliseconds. - */ - public static void sleep(long millis) throws HostFailureException { - sleep(millis,0); - } - /** - * Makes the current process sleep until millis milliseconds and nanos nanoseconds - * have elapsed. - * Unlike {@link #waitFor(double)} which takes seconds, this method takes - * milliseconds and nanoseconds. - * Overloads Thread.sleep. - * @param millis the length of time to sleep in milliseconds. - * @param nanos additional nanoseconds to sleep. - */ - public static native void sleep(long millis, int nanos) throws HostFailureException; - /** - * Makes the current process sleep until time seconds have elapsed. - * @param seconds The time the current process must sleep. - */ - public native void waitFor(double seconds) throws HostFailureException; - /** - * This method actually creates and run the process. - * It is a noop if the process is already launched. - */ - public final void start() { - if (bind == 0) - create(host); - } - - /** This method runs the process. It calls the method function that you must overwrite. */ - @Override - public void run() { - - try { - String[] argsArray = new String[this.args.size()]; - this.args.toArray(argsArray); - - this.main(argsArray); - } - catch(MsgException e) { - e.printStackTrace(); - Msg.info("Unexpected behavior. Stopping now"); - System.exit(1); - } - /* Let the ProcessKilledError (that we'd get if the process is forcefully killed) flow back to the caller */ - } - - /** - * The main function of the process (to implement by the user). - * - * @param args - * @throws MsgException - */ - public abstract void main(String[]args) throws MsgException; - - /** Stops the execution of the current actor */ - public void exit() { - this.kill(); - } - /** - * Class initializer, to initialize various JNI stuff - */ - private static native void nativeInit(); - static { - org.simgrid.NativeLib.nativeInit(); - nativeInit(); - } - /** - * This static method returns the current amount of processes running - * - * @return The count of the running processes - */ - public static native int getCount(); - - public static void debugAllThreads() { - // Search remaining threads that are not main nor daemon - for (Thread t : Thread.getAllStackTraces().keySet()) - if (! t.isDaemon() && !t.getName().equals("main")) - System.err.println("Thread "+t.getName()+" is still running! Please report that bug"); - } -} diff --git a/src/bindings/java/org/simgrid/msg/ProcessKilledError.java b/src/bindings/java/org/simgrid/msg/ProcessKilledError.java deleted file mode 100644 index 8f76d01fa8..0000000000 --- a/src/bindings/java/org/simgrid/msg/ProcessKilledError.java +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** Used internally to interrupt the user code when the process gets killed. - * - * @beginrst - * You can catch it for cleanups or to debug, but DO NOT BLOCK IT, or your simulation will segfault! - * - * .. code-block:: java - * - * try { - * getHost().off(); - * } catch (ProcessKilledError e) { - * e.printStackTrace(); - * throw e; - * } - * - * @endrst - */ - -public class ProcessKilledError extends Error { - private static final long serialVersionUID = 1L; - public ProcessKilledError(String s) { - super(s); - } -} diff --git a/src/bindings/java/org/simgrid/msg/ProcessNotFoundException.java b/src/bindings/java/org/simgrid/msg/ProcessNotFoundException.java deleted file mode 100644 index 2e1b30c7c1..0000000000 --- a/src/bindings/java/org/simgrid/msg/ProcessNotFoundException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** Exception raised when looking for a non-existing process. */ -public class ProcessNotFoundException extends MsgException { - private static final long serialVersionUID = 1L; - - /** Constructs an ProcessNotFoundException without a detail message. */ - public ProcessNotFoundException() { - super(); - } - /** Constructs an ProcessNotFoundException with a detail message. */ - public ProcessNotFoundException(String s) { - super(s); - } -} diff --git a/src/bindings/java/org/simgrid/msg/Semaphore.java b/src/bindings/java/org/simgrid/msg/Semaphore.java deleted file mode 100644 index 4ab3543267..0000000000 --- a/src/bindings/java/org/simgrid/msg/Semaphore.java +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; -/** A semaphore implemented on top of SimGrid synchronization mechanisms. - * You can use it exactly the same way that you use classical semaphores - * but to handle the interactions between the processes within the simulation. - * - */ - -public class Semaphore { - private long bind; // The C object -- don't touch it - /** - * Semaphore capacity, defined when the semaphore is created. At most capacity - * process can acquire this semaphore at the same time. - */ - protected final int capacity; - /** - * Creates a new semaphore with the given capacity. At most capacity - * process can acquire this semaphore at the same time. - */ - public Semaphore(int capacity) { - init(capacity); - this.capacity = capacity; - } - /** The native implementation of semaphore initialization - */ - private native void init(int capacity); - - - /** Locks on the semaphore object until the provided timeout expires - * @exception TimeoutException if the timeout expired before - * the semaphore could be acquired. - * @param timeout the duration of the lock - */ - public native void acquire(double timeout) throws TimeoutException; - /** Locks on the semaphore object with no timeout - */ - public void acquire() { - try { - acquire(-1); - } catch (TimeoutException e) { - e.printStackTrace(); // This should not happen. - assert false ; - } - } - /** Releases the semaphore object - */ - public native void release(); - /** returns a boolean indicating it this semaphore would block at this very specific time - * - * Note that the returned value may be wrong right after the - * function call, when you try to use it... But that's a - * classical semaphore issue, and SimGrid's semaphores are not - * different to usual ones here. - */ - public native boolean wouldBlock(); - - /** Returns the semaphore capacity - */ - public int getCapacity(){ - return this.capacity; - } - - - /** - * Deletes this semaphore when the GC reclaims it - * @deprecated (from Java9 onwards) - */ - @Deprecated @Override - protected void finalize() throws Throwable { - nativeFinalize(); - } - private native void nativeFinalize(); - /** - * Class initializer, to initialize various JNI stuff - */ - public static native void nativeInit(); - static { - org.simgrid.NativeLib.nativeInit(); - nativeInit(); - } -} diff --git a/src/bindings/java/org/simgrid/msg/Task.java b/src/bindings/java/org/simgrid/msg/Task.java deleted file mode 100644 index b291e7762a..0000000000 --- a/src/bindings/java/org/simgrid/msg/Task.java +++ /dev/null @@ -1,347 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** - * A task is either something to compute somewhere, or something to exchange between two hosts (or both). - * It is defined by a computing amount and a message size. - * - */ -public class Task { - /** - * This attribute represents a bind between a java task object and - * a native task. Even if this attribute is public you must never - * access to it. It is set automatically during the build of the object. - */ - private long bind = 0; - /** - * Task name - */ - protected String name; - - private double messageSize; - - /** Default constructor (all fields to 0 or null) */ - public Task() { - create(null, 0, 0); - this.messageSize = 0; - } - - /* * * * - * * Constructors * * - * * * */ - /** - * Construct a new task with the specified processing amount and amount - * of data needed. - * - * @param name Task's name - * - * @param flopsAmount A value of the processing amount (in flop) needed to process the task. - * If 0, then it cannot be executed with the execute() method. - * This value has to be ≥ 0. - * - * @param bytesAmount A value of amount of data (in bytes) needed to transfer this task. - * If 0, then it cannot be transferred with the get() and put() methods. - * This value has to be ≥ 0. - */ - public Task(String name, double flopsAmount, double bytesAmount) { - if (flopsAmount<0) - throw new IllegalArgumentException("Task flopsAmount (" + flopsAmount + ") cannot be negative"); - if (bytesAmount<0) - throw new IllegalArgumentException("Task bytesAmount (" + bytesAmount + ") cannot be negative"); - - create(name, flopsAmount, bytesAmount); - - this.name = name; - this.messageSize = bytesAmount; - } - /** - * Construct a new parallel task with the specified processing amount and amount for each host - * implied. - * - * @param name The name of the parallel task. - * @param hosts The list of hosts implied by the parallel task. - * @param flopsAmount The amount of operations to be performed by each host of hosts. - * flopsAmount[i] is the total number of operations that have to be - * performed on hosts[i]. - * @param bytesAmount A matrix describing the amount of data to exchange between hosts. The - * length of this array must be hosts.length * hosts.length. It is actually - * used as a matrix with the lines being the source and the columns being - * the destination of the communications. - */ - public Task(String name, Host[]hosts, double[]flopsAmount, double[]bytesAmount) { - if (flopsAmount == null) - throw new IllegalArgumentException("Parallel task flops amounts is null"); - if (bytesAmount == null) - throw new IllegalArgumentException("Parallel task bytes amounts is null"); - if (hosts == null) - throw new IllegalArgumentException("Host list is null"); - if (name == null) - throw new IllegalArgumentException("Parallel task name is null"); - - parallelCreate(name, hosts, flopsAmount, bytesAmount); - this.name = name; - } - - /** - * The natively implemented method to create a MSG task. - * - * @param name The name of the task. - * @param flopsAmount A value of the processing amount (in flop) needed - * to process the task. If 0, then it cannot be executed - * with the execute() method. This value has to be >= 0. - * @param bytesAmount A value of amount of data (in bytes) needed to transfer - * this task. If 0, then it cannot be transferred this task. - * If 0, then it cannot be transferred with the get() and put() - * methods. This value has to be >= 0. - * @exception IllegalArgumentException if compute duration <0 or message size <0 - */ - private final native void create(String name, - double flopsAmount, - double bytesAmount); - /** - * The natively implemented method to create a MSG parallel task. - * - * @param name The name of the parallel task. - * @param hosts The list of hosts implied by the parallel task. - * @param flopsAmount The total number of operations that have to be performed - * on the hosts. - * @param bytesAmount An array of doubles - * - */ - private final native void parallelCreate(String name, - Host[]hosts, - double[]flopsAmount, - double[]bytesAmount); - /* * * * - * * Getters / Setters * * - * * * */ - /** Gets the name of the task */ - public String getName() { - return name; - } - - /** Gets the sender of the task (or null if not sent yet) */ - public native Process getSender(); - - /** Gets the source of the task (or null if not sent yet). */ - public native Host getSource(); - - /** Gets the remaining amount of flops to execute in this task - * - * If it's ongoing, you get the exact amount at the present time. If it's already done, it's 0. - */ - public native double getFlopsAmount(); - /** - * Sets the name of the task - * @param name the new task name - */ - public native void setName(String name); - /** - * This method sets the priority of the computation of the task. - * The priority doesn't affect the transfer rate. For example a - * priority of 2 will make the task receive two times more cpu than - * the other ones. - * - * @param priority The new priority of the task. - */ - public native void setPriority(double priority); - - /** Set the computation amount needed to process the task - * - * Warning if the execution is already started and ongoing, this call does nothing. - * @param flopsAmount the amount of computation needed to process the task - */ - public native void setFlopsAmount(double flopsAmount); - /** - * Set the amount of bytes to exchange the task - * - * Warning if the communication is already started and ongoing, this call does nothing. - * @param bytesAmount the size of the task - */ - public native void setBytesAmount(double bytesAmount); - /* * * * - * * Computation-related * * - * * * */ - /** - * Executes a task on the location on which the current process is running. - * - * @throws HostFailureException - * @throws TaskCancelledException - */ - public native void execute() throws HostFailureException,TaskCancelledException; - - /** Changes the maximum CPU utilization of a computation task. Unit is flops/s. */ - public native void setBound(double bound); - - /** Cancels a task. */ - public native void cancel(); - - /** - * Deletes a task once the garbage collector reclaims it - * @deprecated (from Java9 onwards) - */ - @Deprecated @Override - protected void finalize() throws Throwable{ - nativeFinalize(); - bind=0; // to avoid segfaults if the impossible happens yet again making this task surviving its finalize() - } - protected native void nativeFinalize(); - /* * * * - * * Communication-related * * - * * * */ - - /** Send the task asynchronously on the specified mailbox, - * with no way to retrieve whether the communication succeeded or not - * - */ - public native void dsendBounded(String mailbox, double maxrate); - - - /** Send the task asynchronously on the specified mailbox, - * with no way to retrieve whether the communication succeeded or not - * - */ - public native void dsend(String mailbox); - - /** - * Sends the task on the specified mailbox - * - * @param mailbox where to send the message - * @throws TimeoutException - * @throws HostFailureException - * @throws TransferFailureException - */ - public void send(String mailbox) throws TransferFailureException, HostFailureException, TimeoutException { - send(mailbox, -1); - } - - /** - * Sends the task on the specified mailbox (wait at most \a timeout seconds) - * - * @param mailbox where to send the message - * @param timeout - * @throws TimeoutException - * @throws HostFailureException - * @throws TransferFailureException - */ - public void send(String mailbox, double timeout) throws TransferFailureException, HostFailureException, TimeoutException { - sendBounded(mailbox, timeout, -1); - } - - /** Sends the task on the specified mailbox (capping the sending rate to \a maxrate) - * - * @param mailbox where to send the message - * @param maxrate - * @throws TransferFailureException - * @throws HostFailureException - * @throws TimeoutException - */ - public void sendBounded(String mailbox, double maxrate) throws TransferFailureException, HostFailureException, TimeoutException { - sendBounded(mailbox, -1, maxrate); - } - - - /** Sends the task on the specified mailbox (capping the sending rate to \a maxrate) with a timeout - * - * @param mailbox where to send the message - * @param timeout - * @param maxrate - * @throws TransferFailureException - * @throws HostFailureException - * @throws TimeoutException - */ - public native void sendBounded(String mailbox, double timeout, double maxrate) throws TransferFailureException, HostFailureException, TimeoutException; - - - /** - * Sends the task on the mailbox asynchronously - */ - public native Comm isend(String mailbox); - - /** - * Sends the task on the mailbox asynchronously (capping the sending rate to \a maxrate) - */ - public native Comm isendBounded(String mailbox, double maxrate); - - - /** - * Starts listening for receiving a task from an asynchronous communication - * @param mailbox - * @return a Comm handler - */ - public static native Comm irecv(String mailbox); - - /** - * Retrieves next task on the mailbox identified by the specified alias - * - * @param mailbox - * @return a Task - */ - - public static Task receive(String mailbox) throws TransferFailureException, HostFailureException, TimeoutException { - return receive(mailbox, -1.0); - } - - /** - * Retrieves next task on the mailbox identified by the specified alias (wait at most \a timeout seconds) - * - * @param mailbox - * @param timeout - * @return a Task - */ - public static native Task receive(String mailbox, double timeout) throws TransferFailureException, HostFailureException, TimeoutException; - - /** - * Starts listening for receiving a task from an asynchronous communication with a capped rate - * @param mailbox - * @return a Comm handler - */ - public static native Comm irecvBounded(String mailbox, double rate); - /** - * Retrieves next task from the mailbox identified by the specified name with a capped rate - * - * @param mailbox - * @return a Task - */ - - public static Task receiveBounded(String mailbox, double rate) throws TransferFailureException, HostFailureException, TimeoutException { - return receiveBounded(mailbox, -1.0, rate); - } - - /** - * Retrieves next task on the mailbox identified by the specified name (wait at most \a timeout seconds) with a capped rate - * - * @param mailbox - * @param timeout - * @return a Task - */ - public static native Task receiveBounded(String mailbox, double timeout, double rate) throws TransferFailureException, HostFailureException, TimeoutException; - - - - /** - * Tests whether there is a pending communication on the mailbox identified by the specified alias, and who sent it - */ - public static native int listenFrom(String mailbox); - /** - * Listen whether there is a task waiting (either for a send or a recv) on the mailbox identified by the specified alias - */ - public static native boolean listen(String mailbox); - - /** - * Class initializer, to initialize various JNI stuff - */ - public static native void nativeInit(); - static { - org.simgrid.NativeLib.nativeInit(); - nativeInit(); - } - - public double getMessageSize() { - return this.messageSize; - } -} diff --git a/src/bindings/java/org/simgrid/msg/TaskCancelledException.java b/src/bindings/java/org/simgrid/msg/TaskCancelledException.java deleted file mode 100644 index 3b55a08d8f..0000000000 --- a/src/bindings/java/org/simgrid/msg/TaskCancelledException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** Exception raised when a task is cancelled. */ -public class TaskCancelledException extends MsgException { - private static final long serialVersionUID = 1L; - - /** Constructs an TaskCancelledException without a detail message. */ - public TaskCancelledException() { - super(); - } - /** Constructs an TaskCancelledException with a detail message. */ - public TaskCancelledException(String s) { - super(s); - } -} diff --git a/src/bindings/java/org/simgrid/msg/TimeoutException.java b/src/bindings/java/org/simgrid/msg/TimeoutException.java deleted file mode 100644 index 732d697df5..0000000000 --- a/src/bindings/java/org/simgrid/msg/TimeoutException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** Exception raised when sending a task timeouts */ -public class TimeoutException extends MsgException { - private static final long serialVersionUID = 1L; - - /** Constructs an TimeoutFailureException without a detail message. */ - public TimeoutException() { - super(); - } - /** Constructs an TransferFailureException with a detail message. */ - public TimeoutException(String s) { - super(s); - } -} diff --git a/src/bindings/java/org/simgrid/msg/TransferFailureException.java b/src/bindings/java/org/simgrid/msg/TransferFailureException.java deleted file mode 100644 index 53b8d9756b..0000000000 --- a/src/bindings/java/org/simgrid/msg/TransferFailureException.java +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -/** Exception raised if sending a task fails */ -public class TransferFailureException extends MsgException { - private static final long serialVersionUID = 1L; - - /** Constructs an TransferFailureException without a detail message. */ - public TransferFailureException() { - super(); - } - /** - * Constructs an TransferFailureException with a detail message. - * - * @param s the detail message. - */ - public TransferFailureException(String s) { - super(s); - } -} diff --git a/src/bindings/java/org/simgrid/msg/VM.java b/src/bindings/java/org/simgrid/msg/VM.java deleted file mode 100644 index a53f40694b..0000000000 --- a/src/bindings/java/org/simgrid/msg/VM.java +++ /dev/null @@ -1,158 +0,0 @@ -/* Java bindings of the s4u::VirtualMachine */ - -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.msg; - -public class VM extends Host { - // No need to declare a new bind variable: we use the one inherited from the super class Host - - private Host currentHost; - private int coreAmount = 1; - - /** - * Create a `basic` VM : 1 core and 1GB of RAM. - * @param host Host node - * @param name name of the machine - */ - public VM(Host host, String name) { - this(host,name, /*coreAmount*/1, 1024, 0, 0); - } - - /** - * Create a VM without useless values (for humans) - * @param host Host node - * @param name name of the machine - * @param coreAmount the amount of cores of the VM - */ - public VM(Host host, String name, int coreAmount) { - this(host,name, coreAmount, 1024, 0, 0); - } - - /** - * Create a VM with 1 core - * @param host Host node - * @param name name of the machine - * @param ramSize size of the RAM that should be allocated (in MBytes) - * @param migNetSpeed (network bandwidth allocated for migrations in MB/s, if you don't know put zero ;)) - * @param dpIntensity (dirty page percentage according to migNetSpeed, [0-100], if you don't know put zero ;)) - */ - public VM(Host host, String name, int ramSize, int migNetSpeed, int dpIntensity){ - this(host, name, /*coreAmount*/1, ramSize, migNetSpeed, dpIntensity); - } - - /** - * Create a VM - * @param host Host node - * @param name name of the machine - * @param coreAmount the amount of cores of the VM - * @param ramSize size of the RAM that should be allocated (in MBytes) - * @param migNetSpeed (network bandwidth allocated for migrations in MB/s, if you don't know put zero ;)) - * @param dpIntensity (dirty page percentage according to migNetSpeed, [0-100], if you don't know put zero ;)) - */ - public VM(Host host, String name, int coreAmount, int ramSize, int migNetSpeed, int dpIntensity){ - super(); - super.name = name; - this.currentHost = host; - this.coreAmount = coreAmount; - create(host, name, coreAmount, ramSize, migNetSpeed, dpIntensity); - } - - /** Retrieve the list of all existing VMs */ - public static native VM[] all(); - - /** Retrieve a VM from its name */ - public static native VM getVMByName(String name); - - /** - * Make sure that the GC also destroys the C object - * @deprecated (from Java9 onwards) - */ - @Deprecated @Override - protected void finalize() throws Throwable { - nativeFinalize(); - } - private native void nativeFinalize(); - - /** Returns whether the given VM is currently suspended */ - public native boolean isCreated(); - - /** Returns whether the given VM is currently running */ - public native boolean isRunning(); - - /** Returns whether the given VM is currently running */ - public native boolean isMigrating(); - - /** Returns whether the given VM is currently suspended */ - public native boolean isSuspended(); - - /** Returns the amount of virtual CPUs provided */ - public int getCoreAmount() { - return coreAmount; - } - - /** - * Natively implemented method create the VM. - * @param ramSize size of the RAM that should be allocated (in MB) - * @param migNetSpeed (network bandwidth allocated for migrations in MB/s, if you don't know put zero ;)) - * @param dpIntensity (dirty page intensity, a percentage of migNetSpeed [0-100], if you don't know put zero ;)) - */ - private native void create(Host host, String name, int coreAmount, int ramSize, int migNetSpeed, int dpIntensity); - - /** - * Set a CPU bound for a given VM. - * @param bound in flops/s - */ - public native void setBound(double bound); - - /** start the VM */ - public native void start(); - - /** - * Immediately kills all processes within the given VM. - * - * No extra delay occurs. If you want to simulate this too, you want to use a MSG_process_sleep() - */ - public native void shutdown(); - - /** Shutdown and unref the VM. */ - public native void destroy(); - - /** Change the host on which all processes are running - * (pre-copy is implemented) - */ - public void migrate(Host destination) throws HostFailureException{ - try { - this.nativeMigration(destination); - } catch (Exception e){ - Msg.info("Migration of VM "+this.getName()+" to "+destination.getName()+" is impossible ("+e.getMessage()+")"); - throw new HostFailureException(e.getMessage()); - } - // If the migration correctly returned, then we should change the currentHost value. - this.currentHost = destination; - } - private native void nativeMigration(Host destination) throws MsgException; - - /** Immediately suspend the execution of all processes within the given VM - * - * No suspension cost occurs. If you want to simulate this too, you want to use a @ref File.write() before or - * after, depending on the exact semantic of VM suspend to you. - */ - public native void suspend(); - - /** Immediately resumes the execution of all processes within the given VM - * - * No resume cost occurs. If you want to simulate this too, you want to use a @ref File.read() before or after, - * depending on the exact semantic of VM resume to you. - */ - public native void resume(); - - /** Class initializer (for JNI), don't do it yourself */ - private static native void nativeInit(); - static { - nativeInit(); - } -} diff --git a/src/bindings/java/org/simgrid/trace/Trace.java b/src/bindings/java/org/simgrid/trace/Trace.java deleted file mode 100644 index 19e22548c8..0000000000 --- a/src/bindings/java/org/simgrid/trace/Trace.java +++ /dev/null @@ -1,309 +0,0 @@ -/* JNI interface to C code for the TRACES part of SimGrid. */ - -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -package org.simgrid.trace; - -import org.simgrid.NativeLib; - -public final class Trace { - /* Statically load the library which contains all native functions used in here */ - static { - NativeLib.nativeInit(); - } - - private Trace() { - throw new IllegalStateException("Utility class \"Trace\""); - } - - // TODO complete the binding of the tracing API - - /** - * Declare a new user variable associated to hosts with a color. - * - * @param variable - * @param color - */ - public static final native void hostVariableDeclareWithColor (String variable, String color); - - /** - * Add a value to a variable of a host. - * - * @param host - * @param variable - * @param value - */ - public static final native void hostVariableAdd (String host, String variable, double value); - - /** - * Subtract a value from a variable of a host. - * - * @param host - * @param variable - * @param value - */ - public static final native void hostVariableSub (String host, String variable, double value); - - /** - * Set the value of a variable of a host at a given timestamp. - * - * @param time - * @param host - * @param variable - * @param value - */ - public static final native void hostVariableSetWithTime (double time, String host, String variable, double value); - - /** - * Add a value to a variable of a host at a given timestamp. - * - * @param time - * @param host - * @param variable - * @param value - */ - public static final native void hostVariableAddWithTime (double time, String host, String variable, double value); - - /** - * Subtract a value from a variable of a host at a given timestamp. - * - * @param time - * @param host - * @param variable - * @param value - */ - public static final native void hostVariableSubWithTime (double time, String host, String variable, double value); - - /** - * Get declared user host variables. - * - */ - public static final native String[] getHostVariablesName (); - - /** - * Declare a new user variable associated to links. - * - * @param variable - */ - public static final native void linkVariableDeclare (String variable); - - /** - * Declare a new user variable associated to links with a color. - * @param variable - * @param color - */ - public static final native void linkVariableDeclareWithColor (String variable, String color); - - /** - * Set the value of a variable of a link. - * - * @param link - * @param variable - * @param value - */ - public static final native void linkVariableSet (String link, String variable, double value); - - /** - * Add a value to a variable of a link. - * - * @param link - * @param variable - * @param value - */ - public static final native void linkVariableAdd (String link, String variable, double value); - - /** - * Subtract a value from a variable of a link. - * - * @param link - * @param variable - * @param value - */ - public static final native void linkVariableSub (String link, String variable, double value); - - /** - * Set the value of a variable of a link at a given timestamp. - * - * @param time - * @param link - * @param variable - * @param value - */ - public static final native void linkVariableSetWithTime (double time, String link, String variable, double value); - - /** - * Add a value to a variable of a link at a given timestamp. - * - * @param time - * @param link - * @param variable - * @param value - */ - public static final native void linkVariableAddWithTime (double time, String link, String variable, double value); - - /** - * Subtract a value from a variable of a link at a given timestamp. - * - * @param time - * @param link - * @param variable - * @param value - */ - public static final native void linkVariableSubWithTime (double time, String link, String variable, double value); - - /** - * Set the value of the variable present in the links connecting source and destination. - * - * @param src - * @param dst - * @param variable - * @param value - */ - public static final native void linkSrcDstVariableSet (String src, String dst, String variable, double value); - - /** - * Add a value to the variable present in the links connecting source and destination. - * - * @param src - * @param dst - * @param variable - * @param value - */ - public static final native void linkSrcDstVariableAdd (String src, String dst, String variable, double value); - - /** - * Subtract a value from the variable present in the links connecting source and destination. - * - * @param src - * @param dst - * @param variable - * @param value - */ - public static final native void linkSrcDstVariableSub (String src, String dst, String variable, double value); - - /** - * Set the value of the variable present in the links connecting source and destination at a given timestamp. - * - * @param time - * @param src - * @param dst - * @param variable - * @param value - */ - public static final native void linkSrcDstVariableSetWithTime (double time, String src, String dst, String variable, double value); - - /** - * Add a value to the variable present in the links connecting source and destination at a given timestamp. - * - * @param time - * @param src - * @param dst - * @param variable - * @param value - */ - public static final native void linkSrcdstVariableAddWithTime (double time, String src, String dst, String variable, double value); - - /** - * Subtract a value from the variable present in the links connecting source and destination at a given timestamp. - * - * @param time - * @param src - * @param dst - * @param variable - * @param value - */ - public static final native void linkSrcDstVariableSubWithTime (double time, String src, String dst, String variable, double value); - - /** - * Get declared user link variables. - */ - public static final native String[] getLinkVariablesName (); - - - /* **** ******** WARNINGS ************** ***** */ - /* Only the following routines have been */ - /* JNI implemented - Adrien May, 22nd */ - /* **** ******************************** ***** */ - - /** - * Declare a user state that will be associated to hosts. - * A user host state can be used to trace application states. - * - * @param name The name of the new state to be declared. - */ - public static final native void hostStateDeclare(String name); - - /** - * Declare a new value for a user state associated to hosts. - * The color needs to be a string with three numbers separated by spaces in the range [0,1]. - * A light-gray color can be specified using "0.7 0.7 0.7" as color. - * - * @param state The name of the new state to be declared. - * @param value The name of the value - * @param color The color of the value - */ - public static final native void hostStateDeclareValue (String state, String value, String color); - - /** - * Set the user state to the given value. - * (the queue is totally flushed and reinitialized with the given state). - * - * @param host The name of the host to be considered. - * @param state The name of the state previously declared. - * @param value The new value of the state. - */ - public static final native void hostSetState (String host, String state, String value); - - /** - * Push a new value for a state of a given host. - * - * @param host The name of the host to be considered. - * @param state The name of the state previously declared. - * @param value The value to be pushed. - */ - public static final native void hostPushState (String host, String state, String value); - - /** - * Pop the last value of a state of a given host. - * - * @param host The name of the host to be considered. - * @param state The name of the state to be popped. - */ - public static final native void hostPopState (String host, String state); - - /** - * Declare a new user variable associated to hosts. - * - * @param variable - */ - public static final native void hostVariableDeclare (String variable); - - /** - * Set the value of a variable of a host. - * - * @param host - * @param variable - * @param value - */ - public static final native void hostVariableSet (String host, String variable, double value); - - /** - * Declare a new user variable associated to VMs. - * - * @param variable - */ - public static final native void vmVariableDeclare (String variable); - - /** - * Set the value of a variable of a VM. - * - * @param vm - * @param variable - * @param value - */ - public static final native void vmVariableSet (String vm, String variable, double value); -} diff --git a/src/bindings/python/simgrid_python.cpp b/src/bindings/python/simgrid_python.cpp index e1c42ed8b4..d00494965a 100644 --- a/src/bindings/python/simgrid_python.cpp +++ b/src/bindings/python/simgrid_python.cpp @@ -1,30 +1,18 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifdef _WIN32 -#warning Try to work around https://bugs.python.org/issue11566 -#define _hypot hypot -#endif - -#if defined(__GNUG__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-value" -#endif - #include // Must come before our own stuff #include #include -#if defined(__GNUG__) -#pragma GCC diagnostic pop -#endif - #include "simgrid/kernel/ProfileBuilder.hpp" #include "simgrid/kernel/routing/NetPoint.hpp" +#include "simgrid/plugins/load.h" #include +#include #include #include #include @@ -32,11 +20,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -45,20 +35,34 @@ #include namespace py = pybind11; +using simgrid::s4u::Activity; +using simgrid::s4u::ActivityPtr; +using simgrid::s4u::ActivitySet; +using simgrid::s4u::ActivitySetPtr; using simgrid::s4u::Actor; using simgrid::s4u::ActorPtr; using simgrid::s4u::Barrier; using simgrid::s4u::BarrierPtr; using simgrid::s4u::Comm; using simgrid::s4u::CommPtr; +using simgrid::s4u::CommTask; +using simgrid::s4u::CommTaskPtr; +using simgrid::s4u::Disk; using simgrid::s4u::Engine; +using simgrid::s4u::ExecTask; +using simgrid::s4u::ExecTaskPtr; using simgrid::s4u::Host; +using simgrid::s4u::Io; +using simgrid::s4u::IoTask; +using simgrid::s4u::IoTaskPtr; using simgrid::s4u::Link; using simgrid::s4u::Mailbox; using simgrid::s4u::Mutex; using simgrid::s4u::MutexPtr; using simgrid::s4u::Semaphore; using simgrid::s4u::SemaphorePtr; +using simgrid::s4u::Task; +using simgrid::s4u::TaskPtr; XBT_LOG_NEW_DEFAULT_CATEGORY(python, "python"); @@ -72,15 +76,6 @@ std::string get_simgrid_version() sg_version_get(&major, &minor, &patch); return simgrid::xbt::string_printf("%i.%i.%i", major, minor, patch); } - -/** @brief Wrap for mailbox::get_async */ -class PyGetAsync { - std::unique_ptr data = std::make_unique(); - -public: - PyObject** get() const { return data.get(); } -}; - } // namespace PYBIND11_DECLARE_HOLDER_TYPE(T, boost::intrusive_ptr) @@ -123,14 +118,12 @@ PYBIND11_MODULE(simgrid, m) py::call_guard()) .def("exec_async", py::overload_cast(&simgrid::s4u::this_actor::exec_async), py::call_guard()) - .def("parallel_execute", &simgrid::s4u::this_actor::parallel_execute, - py::call_guard(), + .def("parallel_execute", &simgrid::s4u::this_actor::parallel_execute, py::call_guard(), "Run a parallel task (requires the 'ptask_L07' model)") .def("exec_init", py::overload_cast&, const std::vector&, - const std::vector&> (&simgrid::s4u::this_actor::exec_init), - py::call_guard(), - "Initiate a parallel task (requires the 'ptask_L07' model)") + const std::vector&>(&simgrid::s4u::this_actor::exec_init), + py::call_guard(), "Initiate a parallel task (requires the 'ptask_L07' model)") .def("get_host", &simgrid::s4u::this_actor::get_host, "Retrieves host on which the current actor is located") .def("set_host", &simgrid::s4u::this_actor::set_host, py::call_guard(), "Moves the current actor to another host.", py::arg("dest")) @@ -146,19 +139,19 @@ PYBIND11_MODULE(simgrid, m) .def("exit", &simgrid::s4u::this_actor::exit, py::call_guard(), "kill the current actor") .def( "on_exit", - [](py::object cb) { - py::function fun = py::reinterpret_borrow(cb); - fun.inc_ref(); // FIXME: why is this needed for tests like actor-kill and actor-lifetime? - simgrid::s4u::this_actor::on_exit([fun](bool failed) { - py::gil_scoped_acquire py_context; // need a new context for callback + [](py::object fun) { + fun.inc_ref(); // keep alive after return + const py::gil_scoped_release gil_release; + simgrid::s4u::this_actor::on_exit([fun_p = fun.ptr()](bool failed) { + const py::gil_scoped_acquire py_context; // need a new context for callback try { + const auto fun = py::reinterpret_borrow(fun_p); fun(failed); } catch (const py::error_already_set& e) { xbt_die("Error while executing the on_exit lambda: %s", e.what()); } }); }, - py::call_guard(), "Define a lambda to be called when the actor ends. It takes a bool parameter indicating whether the actor " "was killed. If False, the actor finished peacefully.") .def("get_pid", &simgrid::s4u::this_actor::get_pid, "Retrieves PID of the current actor") @@ -175,54 +168,16 @@ PYBIND11_MODULE(simgrid, m) return new simgrid::s4u::Engine(&argc, argv.data()); }), "The constructor should take the parameters from the command line, as is ") - .def_static("get_clock", - []() // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx( - PyExc_DeprecationWarning, - "get_clock() is deprecated and will be dropped after v3.33, use `Engine.clock` instead.", 1); - return Engine::get_clock(); - }) .def_property_readonly_static( "clock", [](py::object /* self */) { return Engine::get_clock(); }, "The simulation time, ie the amount of simulated seconds since the simulation start.") .def_property_readonly_static( "instance", [](py::object /* self */) { return Engine::get_instance(); }, "Retrieve the simulation engine") - .def("get_all_hosts", - [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx(PyExc_DeprecationWarning, - "get_all_hosts() is deprecated and will be dropped after v3.33, use all_hosts instead.", 1); - return self.attr("all_hosts"); - }) - .def("host_by_name", &Engine::host_by_name_or_null, py::call_guard(), + .def("host_by_name", &Engine::host_by_name_or_null, "Retrieve a host by its name, or None if it does not exist in the platform.") .def_property_readonly("all_hosts", &Engine::get_all_hosts, "Returns the list of all hosts found in the platform") - .def("get_all_links", - [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx(PyExc_DeprecationWarning, - "get_all_links() is deprecated and will be dropped after v3.33, use all_links instead.", 1); - return self.attr("all_links"); - }) .def_property_readonly("all_links", &Engine::get_all_links, "Returns the list of all links found in the platform") - .def("get_all_netpoints", - [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx( - PyExc_DeprecationWarning, - "get_all_netpoints() is deprecated and will be dropped after v3.33, use all_netpoints instead.", 1); - return self.attr("all_netpoints"); - }) .def_property_readonly("all_netpoints", &Engine::get_all_netpoints) - .def("get_netzone_root", - [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx(PyExc_DeprecationWarning, - "get_netzone_root() is deprecated and will be dropped after v3.3, use netzone_root instead.", - 1); - return self.attr("netzone_root"); - }) .def_property_readonly("netzone_root", &Engine::get_netzone_root, "Retrieve the root netzone, containing all others.") .def("netpoint_by_name", &Engine::netpoint_by_name_or_null) @@ -231,10 +186,8 @@ PYBIND11_MODULE(simgrid, m) "Change one of SimGrid's configurations") .def("load_platform", &Engine::load_platform, "Load a platform file describing the environment") .def("load_deployment", &Engine::load_deployment, "Load a deployment file and launch the actors that it contains") - .def("mailbox_by_name_or_create", &Engine::mailbox_by_name_or_create, - py::call_guard(), - py::arg("name"), - "Find a mailbox from its name or create one if it does not exist") + .def("mailbox_by_name_or_create", &Engine::mailbox_by_name_or_create, py::call_guard(), + py::arg("name"), "Find a mailbox from its name or create one if it does not exist") .def("run", &Engine::run, py::call_guard(), "Run the simulation until its end") .def("run_until", py::overload_cast(&Engine::run_until, py::const_), py::call_guard(), "Run the simulation until the given date", @@ -242,15 +195,18 @@ PYBIND11_MODULE(simgrid, m) .def( "register_actor", [](Engine* e, const std::string& name, py::object fun_or_class) { - e->register_actor(name, [fun_or_class](std::vector args) { - py::gil_scoped_acquire py_context; + fun_or_class.inc_ref(); // keep alive after return + const py::gil_scoped_release gil_release; + e->register_actor(name, [fun_or_class_p = fun_or_class.ptr()](std::vector args) { + const py::gil_scoped_acquire py_context; try { /* Convert the std::vector into a py::tuple */ py::tuple params(args.size() - 1); for (size_t i = 1; i < args.size(); i++) params[i - 1] = py::cast(args[i]); - py::object res = fun_or_class(*params); + const auto fun_or_class = py::reinterpret_borrow(fun_or_class_p); + py::object res = fun_or_class(*params); /* If I was passed a class, I just built an instance, so I need to call it now */ if (py::isinstance(res)) res(); @@ -263,7 +219,8 @@ PYBIND11_MODULE(simgrid, m) } }); }, - "Registers the main function of an actor"); + "Registers the main function of an actor") + .def("set_log_control", [](Engine*, const std::string& settings) { xbt_log_control_set(settings.c_str()); }); /* Class Netzone */ py::class_> netzone( @@ -279,10 +236,21 @@ PYBIND11_MODULE(simgrid, m) .def_static("create_empty_zone", &simgrid::s4u::create_empty_zone, "Creates a zone of type Empty") .def_static("create_wifi_zone", &simgrid::s4u::create_wifi_zone, "Creates a zone of type Wi-Fi") .def("add_route", - py::overload_cast&, bool>(&simgrid::s4u::NetZone::add_route), - "Add a route between 2 netpoints") + "Add a route between 2 hosts") + .def("add_route", + py::overload_cast&>(&simgrid::s4u::NetZone::add_route), + "Add a route between 2 hosts") + .def("add_route", + py::overload_cast&, bool>(&simgrid::s4u::NetZone::add_route), + "Add a route between 2 netzones. The gateway of each zone gets used.") + .def("add_route", + py::overload_cast&>(&simgrid::s4u::NetZone::add_route), + "Add a route between 2 netzones. The gateway of each zone gets used.") .def("create_host", py::overload_cast(&simgrid::s4u::NetZone::create_host), "Creates a host") .def("create_host", @@ -314,23 +282,22 @@ PYBIND11_MODULE(simgrid, m) .def("create_router", &simgrid::s4u::NetZone::create_router, "Create a router") .def("set_parent", &simgrid::s4u::NetZone::set_parent, "Set the parent of this zone") .def("set_property", &simgrid::s4u::NetZone::set_property, "Add a property to this zone") - .def("get_netpoint", - [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx(PyExc_DeprecationWarning, - "get_netpoint() is deprecated and will be dropped after v3.33, use netpoint instead.", 1); - return self.attr("netpoint"); - }) + .def("set_gateway", py::overload_cast(&simgrid::s4u::NetZone::set_gateway), + "Specify the gateway of this zone, to be used for inter-zone routes") + .def("set_gateway", py::overload_cast(&simgrid::s4u::NetZone::set_gateway), + "Specify the gateway of this zone, to be used for inter-zone routes") .def_property_readonly("netpoint", &simgrid::s4u::NetZone::get_netpoint, "Retrieve the netpoint associated to this zone") .def("seal", &simgrid::s4u::NetZone::seal, "Seal this NetZone") - .def_property_readonly( - "name", [](const simgrid::s4u::NetZone* self) { return self->get_name(); }, - "The name of this network zone (read-only property)."); + .def_property_readonly("name", &simgrid::s4u::NetZone::get_name, + "The name of this network zone (read-only property).") + .def( + "__repr__", [](const simgrid::s4u::NetZone net) { return "NetZone(" + net.get_name() + ")"; }, + "Textual representation of the NetZone"); /* Class ClusterCallbacks */ py::class_(m, "ClusterCallbacks", "Callbacks used to create cluster zones") - .def(py::init&, + .def(py::init&, const std::function&, const std::function&>()); @@ -393,49 +360,14 @@ PYBIND11_MODULE(simgrid, m) " \"\"\"\n\n" "The second function parameter is the periodicity: the time to wait after the last event to start again over " "the list. Set it to -1 to not loop over.") - .def("get_pstate_count", - [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx( - PyExc_DeprecationWarning, - "get_pstate_count() is deprecated and will be dropped after v3.33, use pstate_count instead.", 1); - return self.attr("pstate_count"); - }) .def_property_readonly("pstate_count", &Host::get_pstate_count, "Retrieve the count of defined pstate levels") - .def("get_pstate_speed", - [](py::object self, int state) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx( - PyExc_DeprecationWarning, - "get_pstate_speed() is deprecated and will be dropped after v3.33, use pstate_speed instead.", 1); - return self.attr("pstate_speed")(state); - }) - .def("pstate_speed", &Host::get_pstate_speed, py::call_guard(), - "Retrieve the maximal speed at the given pstate") - .def("get_netpoint", - [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx(PyExc_DeprecationWarning, - "get_netpoint() is deprecated and will be dropped after v3.33, use netpoint instead.", 1); - return self.attr("netpoint"); - }) + .def("pstate_speed", &Host::get_pstate_speed, "Retrieve the maximal speed at the given pstate") .def_property_readonly("netpoint", &Host::get_netpoint, "Retrieve the netpoint associated to this zone") + .def_property_readonly("disks", &Host::get_disks, "The list of disks on this host (read-only).") .def("get_disks", &Host::get_disks, "Retrieve the list of disks in this host") - .def("set_core_count", - [](py::object self, double count) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx(PyExc_DeprecationWarning, - "set_core_count() is deprecated and will be dropped after v3.33, use core_count instead.", - 1); - self.attr("core_count")(count); - }) - .def_property( - "core_count", &Host::get_core_count, - [](Host* h, int count) { - py::gil_scoped_release gil_guard; - return h->set_core_count(count); - }, - "Manage the number of cores in the CPU") + .def_property("core_count", &Host::get_core_count, + py::cpp_function(&Host::set_core_count, py::call_guard()), + "Manage the number of cores in the CPU") .def("set_coordinates", &Host::set_coordinates, py::call_guard(), "Set the coordinates of this host") .def("set_sharing_policy", &simgrid::s4u::Host::set_sharing_policy, py::call_guard(), @@ -446,21 +378,14 @@ PYBIND11_MODULE(simgrid, m) py::overload_cast(&Host::create_disk), py::call_guard(), "Create a disk") .def("seal", &Host::seal, py::call_guard(), "Seal this host") - .def_property( - "pstate", &Host::get_pstate, - [](Host* h, int i) { - py::gil_scoped_release gil_guard; - h->set_pstate(i); - }, - "The current pstate (read/write property).") + .def("turn_off", &Host::turn_off, py::call_guard(), "Turn off this host") + .def("turn_on", &Host::turn_on, py::call_guard(), "Turn on this host") + .def_property("pstate", &Host::get_pstate, + py::cpp_function(&Host::set_pstate, py::call_guard()), + "The current pstate (read/write property).") .def_static("current", &Host::current, py::call_guard(), - "Retrieves the host on which the running actor is located.") - .def_property_readonly( - "name", - [](const Host* self) { - return std::string(self->get_name().c_str()); // Convert from xbt::string because of MC - }, - "The name of this host (read-only property).") + "Retrieves the host on which the running actor is located.") + .def_property_readonly("name", &Host::get_name, "The name of this host (read-only property).") .def_property_readonly("load", &Host::get_load, "Returns the current computation load (in flops per second), NOT taking the external load " "into account. This is the currently achieved speed (read-only property).") @@ -475,22 +400,47 @@ PYBIND11_MODULE(simgrid, m) .def_static( "on_creation_cb", [](py::object cb) { - Host::on_creation_cb([cb](Host& h) { - py::function fun = py::reinterpret_borrow(cb); - py::gil_scoped_acquire py_context; // need a new context for callback + cb.inc_ref(); // keep alive after return + const py::gil_scoped_release gil_release; + Host::on_creation_cb([cb_p = cb.ptr()](Host& h) { + const py::gil_scoped_acquire py_context; // need a new context for callback try { + const auto fun = py::reinterpret_borrow(cb_p); fun(&h); } catch (const py::error_already_set& e) { xbt_die("Error while executing the on_creation lambda : %s", e.what()); } }); }, - py::call_guard(), ""); + "") + .def( + "__repr__", [](const Host* h) { return "Host(" + h->get_name() + ")"; }, + "Textual representation of the Host."); + + m.def("sg_host_load_plugin_init", [host]() { + sg_host_load_plugin_init(); + + static_cast>>(host) + .def( + "reset_load", [](const Host* h) { sg_host_load_reset(h); }, py::call_guard(), + "Reset counters of the host load plugin for this host.") + .def_property_readonly( + "current_load", [](const Host* h) { return sg_host_get_current_load(h); }, "Current load of the host.") + .def_property_readonly( + "avg_load", [](const Host* h) { return sg_host_get_avg_load(h); }, "Average load of the host.") + .def_property_readonly( + "idle_time", [](const Host* h) { return sg_host_get_idle_time(h); }, "Idle time of the host") + .def_property_readonly( + "total_idle_time", [](const Host* h) { return sg_host_get_total_idle_time(h); }, + "Total idle time of the host.") + .def_property_readonly( + "computed_flops", [](const Host* h) { return sg_host_get_computed_flops(h); }, + "Computed flops of the host."); + }); py::enum_(host, "SharingPolicy") .value("NONLINEAR", simgrid::s4u::Host::SharingPolicy::NONLINEAR) - .value("LINEAR", simgrid::s4u::Host::SharingPolicy::LINEAR) - .export_values(); + .value("LINEAR", simgrid::s4u::Host::SharingPolicy::LINEAR); /* Class Disk */ py::class_> disk( @@ -507,18 +457,17 @@ PYBIND11_MODULE(simgrid, m) "Set sharing policy for this disk", py::arg("op"), py::arg("policy"), py::arg("cb") = simgrid::s4u::NonLinearResourceCb()) .def("seal", &simgrid::s4u::Disk::seal, py::call_guard(), "Seal this disk") - .def_property_readonly( - "name", [](const simgrid::s4u::Disk* self) { return self->get_name(); }, - "The name of this disk (read-only property)."); + .def_property_readonly("name", &simgrid::s4u::Disk::get_name, "The name of this disk (read-only property).") + .def( + "__repr__", [](const Disk* d) { return "Disk(" + d->get_name() + ")"; }, + "Textual representation of the Disk"); py::enum_(disk, "SharingPolicy") .value("NONLINEAR", simgrid::s4u::Disk::SharingPolicy::NONLINEAR) - .value("LINEAR", simgrid::s4u::Disk::SharingPolicy::LINEAR) - .export_values(); + .value("LINEAR", simgrid::s4u::Disk::SharingPolicy::LINEAR); py::enum_(disk, "Operation") .value("READ", simgrid::s4u::Disk::Operation::READ) .value("WRITE", simgrid::s4u::Disk::Operation::WRITE) - .value("READWRITE", simgrid::s4u::Disk::Operation::READWRITE) - .export_values(); + .value("READWRITE", simgrid::s4u::Disk::Operation::READWRITE); /* Class NetPoint */ py::class_> @@ -602,23 +551,25 @@ PYBIND11_MODULE(simgrid, m) "Set level of communication speed of given host on this Wi-Fi link") .def_static("by_name", &Link::by_name, "Retrieves a Link from its name, or dies") .def("seal", &Link::seal, py::call_guard(), "Seal this link") - .def_property_readonly( - "name", - [](const Link* self) { - return std::string(self->get_name().c_str()); // Convert from xbt::string because of MC - }, - "The name of this link") + .def_property_readonly("name", &Link::get_name, "The name of this link") .def_property_readonly("bandwidth", &Link::get_bandwidth, "The bandwidth (in bytes per second) (read-only property).") - .def_property_readonly("latency", &Link::get_latency, "The latency (in seconds) (read-only property)."); - + .def_property_readonly("latency", &Link::get_latency, "The latency (in seconds) (read-only property).") + .def( + "__repr__", [](const Link* l) { return "Link(" + l->get_name() + ")"; }, + "Textual representation of the Link"); py::enum_(link, "SharingPolicy") - .value("NONLINEAR", Link::SharingPolicy::NONLINEAR) - .value("WIFI", Link::SharingPolicy::WIFI) - .value("SPLITDUPLEX", Link::SharingPolicy::SPLITDUPLEX) - .value("SHARED", Link::SharingPolicy::SHARED) - .value("FATPIPE", Link::SharingPolicy::FATPIPE) - .export_values(); + .value("NONLINEAR", Link::SharingPolicy::NONLINEAR, + "This policy takes a callback that specifies the maximal capacity as a function of the number of usage. " + "See the examples with 'degradation' in their name.") + .value("WIFI", Link::SharingPolicy::WIFI, "Pseudo-sharing policy requesting wifi-specific sharing.") + .value("SPLITDUPLEX", Link::SharingPolicy::SPLITDUPLEX, + "Each link is split in 2, UP and DOWN, one per direction. These links are SHARED.") + .value("SHARED", Link::SharingPolicy::SHARED, + "The bandwidth is shared between all comms using that link, regardless of their direction.") + .value("FATPIPE", Link::SharingPolicy::FATPIPE, + "Each comm can use the link fully, with no sharing (only a maximum). This is intended to represent the " + "backbone links that cannot be saturated by concurrent links, but have a maximal bandwidth."); /* Class LinkInRoute */ py::class_ linkinroute(m, "LinkInRoute", "Abstraction to add link in routes"); @@ -627,234 +578,158 @@ PYBIND11_MODULE(simgrid, m) py::enum_(linkinroute, "Direction") .value("UP", simgrid::s4u::LinkInRoute::Direction::UP) .value("DOWN", simgrid::s4u::LinkInRoute::Direction::DOWN) - .value("NONE", simgrid::s4u::LinkInRoute::Direction::NONE) - .export_values(); + .value("NONE", simgrid::s4u::LinkInRoute::Direction::NONE); /* Class Split-Duplex Link */ py::class_>( m, "SplitDuplexLink", "Network split-duplex link") - .def("get_link_up", - [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx(PyExc_DeprecationWarning, - "get_link_up() is deprecated and will be dropped after v3.33, use link_up instead.", 1); - return self.attr("link_up"); - }) .def_property_readonly("link_up", &simgrid::s4u::SplitDuplexLink::get_link_up, "Get link direction up") - .def("get_link_down", - [](py::object self) // XBT_ATTRIB_DEPRECATED_v334 - { - PyErr_WarnEx(PyExc_DeprecationWarning, - "get_link_down() is deprecated and will be dropped after v3.33, use link_down instead.", 1); - return self.attr("link_down"); - }) .def_property_readonly("link_down", &simgrid::s4u::SplitDuplexLink::get_link_down, "Get link direction down"); /* Class Mailbox */ py::class_>( m, "Mailbox", "Mailbox. See the C++ documentation for details.") .def( - "__str__", [](const Mailbox* self) { return std::string("Mailbox(") + self->get_cname() + ")"; }, - "Textual representation of the Mailbox`") - .def_static("by_name", &Mailbox::by_name, - py::call_guard(), - py::arg("name"), + "__repr__", [](const Mailbox* self) { return "Mailbox(" + self->get_name() + ")"; }, + "Textual representation of the Mailbox") + .def_static("by_name", &Mailbox::by_name, py::call_guard(), py::arg("name"), "Retrieve a Mailbox from its name") - .def_property_readonly( - "name", - [](const Mailbox* self) { - return std::string(self->get_name().c_str()); // Convert from xbt::string because of MC - }, - "The name of that mailbox (read-only property).") - .def_property_readonly("ready", &Mailbox::ready, py::call_guard(), + .def_property_readonly("name", &Mailbox::get_name, "The name of that mailbox (read-only property).") + .def_property_readonly("ready", &Mailbox::ready, "Check if there is a communication ready to be consumed from a mailbox.") .def( "put", [](Mailbox* self, py::object data, uint64_t size, double timeout) { - data.inc_ref(); - self->put(data.ptr(), size, timeout); + auto* data_ptr = data.inc_ref().ptr(); + const py::gil_scoped_release gil_release; + self->put(data_ptr, size, timeout); }, - py::call_guard(), "Blocking data transmission with a timeout") + "Blocking data transmission with a timeout") .def( "put", [](Mailbox* self, py::object data, uint64_t size) { - data.inc_ref(); - self->put(data.ptr(), size); + auto* data_ptr = data.inc_ref().ptr(); + const py::gil_scoped_release gil_release; + self->put(data_ptr, size); }, - py::call_guard(), "Blocking data transmission") + "Blocking data transmission") .def( "put_async", [](Mailbox* self, py::object data, uint64_t size) { - data.inc_ref(); - return self->put_async(data.ptr(), size); + auto* data_ptr = data.inc_ref().ptr(); + const py::gil_scoped_release gil_release; + return self->put_async(data_ptr, size); }, - py::call_guard(), "Non-blocking data transmission") + "Non-blocking data transmission") .def( "put_init", [](Mailbox* self, py::object data, uint64_t size) { - data.inc_ref(); - return self->put_init(data.ptr(), size); + auto* data_ptr = data.inc_ref().ptr(); + const py::gil_scoped_release gil_release; + return self->put_init(data_ptr, size); }, - py::call_guard(), "Creates (but don’t start) a data transmission to that mailbox.") .def( - "get", - [](Mailbox* self) { - py::object data = py::reinterpret_steal(self->get()); - // data.dec_ref(); // FIXME: why does it break python-actor-create? - return data; - }, + "get", [](Mailbox* self) { return py::reinterpret_steal(self->get()); }, py::call_guard(), "Blocking data reception") .def( - "get_async", - [](Mailbox* self) -> std::tuple { - PyGetAsync wrap; - auto comm = self->get_async(wrap.get()); - return std::make_tuple(std::move(comm), std::move(wrap)); - }, + "get_async", [](Mailbox* self) -> CommPtr { return self->get_async(); }, py::call_guard(), "Non-blocking data reception. Use data.get() to get the python object after the communication has finished") - .def( - "set_receiver", [](Mailbox* self, ActorPtr actor) { self->set_receiver(actor); }, - py::call_guard(), "Sets the actor as permanent receiver"); + .def("set_receiver", &Mailbox::set_receiver, py::call_guard(), + "Sets the actor as permanent receiver"); - /* Class PyGetAsync */ - py::class_(m, "PyGetAsync", "Wrapper for async get communications") - .def(py::init<>()) - .def( - "get", [](const PyGetAsync* self) { return py::reinterpret_steal(*(self->get())); }, - "Get python object after async communication in receiver side"); + /* class Activity */ + py::class_(m, "Activity", "Activity. See the C++ documentation for details."); /* Class Comm */ - py::class_(m, "Comm", "Communication. See the C++ documentation for details.") - .def_property_readonly("dst_data_size", &Comm::get_dst_data_size, - py::call_guard(), + py::class_(m, "Comm", "Communication. See the C++ documentation for details.") + .def_property_readonly("dst_data_size", &Comm::get_dst_data_size, py::call_guard(), "Retrieve the size of the received data.") - .def_property_readonly("mailbox", &Comm::get_mailbox, - py::call_guard(), + .def_property_readonly("mailbox", &Comm::get_mailbox, py::call_guard(), "Retrieve the mailbox on which this comm acts.") - .def_property_readonly("sender", &Comm::get_sender, - py::call_guard()) - .def_property_readonly("state_str", [](const Comm* self){ return std::string(self->get_state_str()); }, - py::call_guard(), + .def_property_readonly("sender", &Comm::get_sender, py::call_guard()) + .def_property_readonly("state_str", &Comm::get_state_str, py::call_guard(), "Retrieve the Comm state as string") - .def_property_readonly("remaining", &Comm::get_remaining, - py::call_guard(), + .def_property_readonly("remaining", &Comm::get_remaining, py::call_guard(), "Remaining amount of work that this Comm entails") - .def_property_readonly("start_time", &Comm::get_start_time, - py::call_guard(), + .def_property_readonly("start_time", &Comm::get_start_time, py::call_guard(), "Time at which this Comm started") - .def_property_readonly("finish_time", &Comm::get_finish_time, - py::call_guard(), + .def_property_readonly("finish_time", &Comm::get_finish_time, py::call_guard(), "Time at which this Comm finished") - .def("set_payload_size", &Comm::set_payload_size, py::call_guard(), - py::arg("bytes"), + .def_property_readonly("is_suspended", &Comm::is_suspended, py::call_guard(), + "Whether this Comm is suspended") + .def("set_payload_size", &Comm::set_payload_size, py::call_guard(), py::arg("bytes"), "Specify the amount of bytes which exchange should be simulated.") - .def("set_rate", &Comm::set_rate, py::call_guard(), - py::arg("rate"), + .def("set_rate", &Comm::set_rate, py::call_guard(), py::arg("rate"), "Sets the maximal communication rate (in byte/sec). Must be done before start") - .def("cancel", [](Comm* self){ return self->cancel(); }, - py::call_guard(), py::return_value_policy::reference_internal, - "Cancel the activity.") - .def("start", [](Comm* self){ return self->start(); }, - py::call_guard(), py::return_value_policy::reference_internal, + .def("cancel", &Comm::cancel, py::call_guard(), + py::return_value_policy::reference_internal, "Cancel the activity.") + .def("start", &Comm::start, py::call_guard(), py::return_value_policy::reference_internal, "Starts a previously created activity. This function is optional: you can call wait() even if you didn't " "call start()") - .def("suspend", [](Comm* self){ return self->suspend(); }, - py::call_guard(), py::return_value_policy::reference_internal, - "Suspend the activity.") - .def("resume", [](Comm* self){ return self->resume(); }, - py::call_guard(), py::return_value_policy::reference_internal, - "Resume the activity.") + .def("suspend", &Comm::suspend, py::call_guard(), + py::return_value_policy::reference_internal, "Suspend the activity.") + .def("resume", &Comm::resume, py::call_guard(), + py::return_value_policy::reference_internal, "Resume the activity.") .def("test", &Comm::test, py::call_guard(), "Test whether the communication is terminated.") .def("wait", &Comm::wait, py::call_guard(), "Block until the completion of that communication.") - .def("wait_for", &Comm::wait_for, py::call_guard(), - py::arg("timeout"), + .def("wait_for", &Comm::wait_for, py::call_guard(), py::arg("timeout"), "Block until the completion of that communication, or raises TimeoutException after the specified timeout.") - .def("wait_until", &Comm::wait_until, py::call_guard(), - py::arg("time_limit"), + .def("wait_until", &Comm::wait_until, py::call_guard(), py::arg("time_limit"), "Block until the completion of that communication, or raises TimeoutException after the specified time.") - .def("detach", [](Comm* self) { return self->detach(); }, - py::return_value_policy::reference_internal, + .def( + "get_payload", + [](const Comm* self) { return py::reinterpret_steal((PyObject*)self->get_payload()); }, + py::call_guard(), + "Retrieve the message's payload of a get_async. You cannot call this until after the comm termination.") + .def("detach", py::overload_cast<>(&Comm::detach), py::return_value_policy::reference_internal, py::call_guard(), "Start the comm, and ignore its result. It can be completely forgotten after that.") - .def_static("sendto", &Comm::sendto, py::call_guard(), - py::arg("from"), py::arg("to"), py::arg("simulated_size_in_bytes"), - "Do a blocking communication between two arbitrary hosts.") + .def_static("sendto", &Comm::sendto, py::call_guard(), py::arg("from"), py::arg("to"), + py::arg("simulated_size_in_bytes"), "Do a blocking communication between two arbitrary hosts.") .def_static("sendto_init", py::overload_cast(&Comm::sendto_init), - py::call_guard(), - py::arg("from"), py::arg("to"), + py::call_guard(), py::arg("from"), py::arg("to"), "Creates a communication between the two given hosts, bypassing the mailbox mechanism.") - .def_static("sendto_async", &Comm::sendto_async, py::call_guard(), - py::arg("from"), py::arg("to"), py::arg("simulated_size_in_bytes"), + .def_static("sendto_async", &Comm::sendto_async, py::call_guard(), py::arg("from"), + py::arg("to"), py::arg("simulated_size_in_bytes"), "Do a blocking communication between two arbitrary hosts.\n\nThis initializes a communication that " "completely bypass the mailbox and actors mechanism. There is really no limit on the hosts involved. " - "In particular, the actor does not have to be on one of the involved hosts.") - .def_static("test_any", &Comm::test_any, - py::call_guard(), - py::arg("comms"), - "take a vector s4u::CommPtr and return the rank of the first finished one (or -1 if none is done)") - .def_static("wait_all", &Comm::wait_all, py::call_guard(), - py::arg("comms"), - "Block until the completion of all communications in the list.") - .def_static("wait_all_for", &Comm::wait_all_for, py::call_guard(), - py::arg("comms"), py::arg("timeout"), - "Block until the completion of all communications in the list, or raises TimeoutException after " - "the specified timeout.") - .def_static("wait_any", &Comm::wait_any, - py::call_guard(), - py::arg("comms"), - "Block until the completion of any communication in the list and return the index of the " - "terminated one.") - .def_static("wait_any_for", &Comm::wait_any_for, - py::call_guard(), - py::arg("comms"), py::arg("timeout"), - "Block until the completion of any communication in the list and return the index of the terminated " - "one, or -1 if a timeout occurred."); + "In particular, the actor does not have to be on one of the involved hosts."); /* Class Io */ - py::class_(m, "Io", "I/O activities. See the C++ documentation for details.") + py::class_(m, "Io", + "I/O activities. See the C++ documentation for details.") .def("test", &simgrid::s4u::Io::test, py::call_guard(), "Test whether the I/O is terminated.") .def("wait", &simgrid::s4u::Io::wait, py::call_guard(), - "Block until the completion of that I/O operation") - .def_static( - "wait_any_for", &simgrid::s4u::Io::wait_any_for, py::call_guard(), - "Block until the completion of any I/O in the list (or timeout) and return the index of the terminated one.") - .def_static("wait_any", &simgrid::s4u::Io::wait_any, py::call_guard(), - "Block until the completion of any I/O in the list and return the index of the terminated one."); + "Block until the completion of that I/O operation"); /* Class Exec */ - py::class_(m, "Exec", "Execution. See the C++ documentation for details.") - .def_property_readonly( - "remaining", - [](simgrid::s4u::ExecPtr self) { - py::gil_scoped_release gil_guard; - return self->get_remaining(); - }, - "Amount of flops that remain to be computed until completion (read-only property).") - .def_property_readonly( - "remaining_ratio", - [](simgrid::s4u::ExecPtr self) { - py::gil_scoped_release gil_guard; - return self->get_remaining_ratio(); - }, - "Amount of work remaining until completion from 0 (completely done) to 1 (nothing done " - "yet) (read-only property).") + py::class_(m, "Exec", + "Execution. See the C++ documentation for details.") + .def_property_readonly("remaining", &simgrid::s4u::Exec::get_remaining, py::call_guard(), + "Amount of flops that remain to be computed until completion (read-only property).") + .def_property_readonly("remaining_ratio", &simgrid::s4u::Exec::get_remaining_ratio, + py::call_guard(), + "Amount of work remaining until completion from 0 (completely done) to 1 (nothing done " + "yet) (read-only property).") .def_property("host", &simgrid::s4u::Exec::get_host, &simgrid::s4u::Exec::set_host, "Host on which this execution runs. Only the first host is returned for parallel executions. " "Changing this value migrates the execution.") + .def_property_readonly("is_suspended", &simgrid::s4u::Exec::is_suspended, + py::call_guard(), "Whether this Exec is suspended") .def("test", &simgrid::s4u::Exec::test, py::call_guard(), "Test whether the execution is terminated.") .def("cancel", &simgrid::s4u::Exec::cancel, py::call_guard(), "Cancel that execution.") .def("start", &simgrid::s4u::Exec::start, py::call_guard(), "Start that execution.") .def("suspend", &simgrid::s4u::Exec::suspend, py::call_guard(), "Suspend that execution.") + .def("resume", &simgrid::s4u::Exec::resume, py::call_guard(), "Resume that execution.") .def("wait", &simgrid::s4u::Exec::wait, py::call_guard(), "Block until the completion of that execution.") - .def("wait_for", &simgrid::s4u::Exec::wait_for, py::call_guard(), - py::arg("timeout"), + .def("wait_for", &simgrid::s4u::Exec::wait_for, py::call_guard(), py::arg("timeout"), "Block until the completion of that activity, or raises TimeoutException after the specified timeout."); /* Class Semaphore */ @@ -868,34 +743,35 @@ PYBIND11_MODULE(simgrid, m) .def("acquire_timeout", &Semaphore::acquire_timeout, py::call_guard(), py::arg("timeout"), "Acquire on the semaphore object with no timeout. Blocks until the semaphore is acquired or return " "true if it has not been acquired after the specified timeout.") - .def("release", &Semaphore::release, py::call_guard(), - "Release the semaphore.") + .def("release", &Semaphore::release, py::call_guard(), "Release the semaphore.") .def_property_readonly("capacity", &Semaphore::get_capacity, py::call_guard(), "Get the semaphore capacity.") .def_property_readonly("would_block", &Semaphore::would_block, py::call_guard(), "Check whether trying to acquire the semaphore would block (in other word, checks whether " "this semaphore has capacity).") // Allow semaphores to be automatically acquired/released with a context manager: `with semaphore: ...` - .def("__enter__", [](Semaphore* self){ self->acquire(); }, py::call_guard()) - .def("__exit__", [](Semaphore* self){ self->release(); }, py::call_guard()); + .def("__enter__", &Semaphore::acquire, py::call_guard()) + .def("__exit__", + [](Semaphore* self, const py::object&, const py::object&, const py::object&) { self->release(); }); /* Class Mutex */ py::class_(m, "Mutex", "A classical mutex, but blocking in the simulation world." "See the C++ documentation for details.") - .def(py::init<>(&Mutex::create), py::call_guard(), "Mutex constructor.") + .def(py::init<>(&Mutex::create), py::call_guard(), + "Mutex constructor (pass True as a parameter to get a recursive Mutex).", py::arg("recursive") = false) .def("lock", &Mutex::lock, py::call_guard(), "Block until the mutex is acquired.") .def("try_lock", &Mutex::try_lock, py::call_guard(), "Try to acquire the mutex. Return true if the mutex was acquired, false otherwise.") .def("unlock", &Mutex::unlock, py::call_guard(), "Release the mutex.") // Allow mutexes to be automatically acquired/released with a context manager: `with mutex: ...` - .def("__enter__", [](Mutex* self){ self->lock(); }, py::call_guard()) - .def("__exit__", [](Mutex* self, const py::object&, const py::object&, const py::object&) { self->unlock(); }, + .def("__enter__", &Mutex::lock, py::call_guard()) + .def( + "__exit__", [](Mutex* self, const py::object&, const py::object&, const py::object&) { self->unlock(); }, py::call_guard()); /* Class Barrier */ - py::class_(m, "Barrier", - "A classical barrier, but blocking in the simulation world.") + py::class_(m, "Barrier", "A classical barrier, but blocking in the simulation world.") .def(py::init<>(&Barrier::create), py::call_guard(), py::arg("expected_actors"), "Barrier constructor.") .def("wait", &Barrier::wait, py::call_guard(), @@ -908,12 +784,15 @@ PYBIND11_MODULE(simgrid, m) "application. See the C++ documentation for details.") .def( "create", - [](py::str name, Host* h, py::object fun, py::args args) { - fun.inc_ref(); // FIXME: why is this needed for tests like exec-async, exec-dvfs and exec-remote? - args.inc_ref(); // FIXME: why is this needed for tests like actor-migrate? - return simgrid::s4u::Actor::create(name, h, [fun, args]() { - py::gil_scoped_acquire py_context; + [](const std::string& name, Host* h, py::object fun, py::args args) { + fun.inc_ref(); // keep alive after return + args.inc_ref(); // keep alive after return + const py::gil_scoped_release gil_release; + return simgrid::s4u::Actor::create(name, h, [fun_p = fun.ptr(), args_p = args.ptr()]() { + const py::gil_scoped_acquire py_context; try { + const auto fun = py::reinterpret_borrow(fun_p); + const auto args = py::reinterpret_borrow(args_p); fun(*args); } catch (const py::error_already_set& ex) { if (ex.matches(pyForcefulKillEx)) { @@ -924,14 +803,9 @@ PYBIND11_MODULE(simgrid, m) } }); }, - py::call_guard(), "Create an actor from a function or an object. See the :ref:`example `.") .def_property( - "host", &Actor::get_host, - [](Actor* a, Host* h) { - py::gil_scoped_release gil_guard; - a->set_host(h); - }, + "host", &Actor::get_host, py::cpp_function(&Actor::set_host, py::call_guard()), "The host on which this actor is located. Changing this value migrates the actor.\n\n" "If the actor is currently blocked on an execution activity, the activity is also migrated to the new host. " "If it’s blocked on another kind of activity, an error is raised as the mandated code is not written yet. " @@ -960,5 +834,142 @@ PYBIND11_MODULE(simgrid, m) "Suspend that actor, that is blocked until resume()ed by another actor.") .def("resume", &Actor::resume, py::call_guard(), "Resume that actor, that was previously suspend()ed.") - .def_static("kill_all", &Actor::kill_all, py::call_guard(), "Kill all actors but the caller."); + .def_static("kill_all", &Actor::kill_all, py::call_guard(), + "Kill all actors but the caller.") + .def( + "__repr__", [](const ActorPtr a) { return "Actor(" + a->get_name() + ")"; }, + "Textual representation of the Actor"); + + /* Enum Class IoOpType */ + py::enum_(m, "IoOpType") + .value("READ", simgrid::s4u::Io::OpType::READ) + .value("WRITE", simgrid::s4u::Io::OpType::WRITE); + + /* Class Task */ + py::class_(m, "Task", "Task. See the C++ documentation for details.") + .def_static( + "on_start_cb", + [](py::object cb) { + cb.inc_ref(); // keep alive after return + const py::gil_scoped_release gil_release; + Task::on_start_cb([cb_p = cb.ptr()](Task* op) { + const py::gil_scoped_acquire py_context; // need a new context for callback + py::reinterpret_borrow(cb_p)(op); + }); + }, + "Add a callback called when each task starts.") + .def_static( + "on_completion_cb", + [](py::object cb) { + cb.inc_ref(); // keep alive after return + const py::gil_scoped_release gil_release; + Task::on_completion_cb([cb_p = cb.ptr()](Task* op) { + const py::gil_scoped_acquire py_context; // need a new context for callback + py::reinterpret_borrow(cb_p)(op); + }); + }, + "Add a callback called when each task ends.") + .def_property_readonly("name", &Task::get_name, "The name of this task (read-only).") + .def_property_readonly("successors", &Task::get_successors, "The successors of this task (read-only).") + .def_property("amount", &Task::get_amount, &Task::set_amount, "The amount of work to do for this task.") + .def( + "get_count", [](const TaskPtr t) { return t->get_count("instance_0"); }, + "The execution count of this task instance_0.") + .def( + "get_count", [](const TaskPtr t, const std::string& instance) { return t->get_count(instance); }, + "The execution count of this task instance.") + .def("enqueue_firings", py::overload_cast(&Task::enqueue_firings), py::call_guard(), + py::arg("n"), "Enqueue firings for this task.") + .def("add_successor", py::overload_cast(&Task::add_successor), py::call_guard(), + py::arg("op"), "Add a successor to this task.") + .def("remove_successor", py::overload_cast(&Task::remove_successor), + py::call_guard(), py::arg("op"), "Remove a successor of this task.") + .def("remove_all_successors", &Task::remove_all_successors, py::call_guard(), + "Remove all successors of this task.") + .def("on_this_start_cb", py::overload_cast&>(&Task::on_this_start_cb), + py::arg("func"), "Add a callback called when this task starts.") + .def("on_this_completion_cb", py::overload_cast&>(&Task::on_this_completion_cb), + py::arg("func"), "Add a callback called when this task ends.") + .def( + "__repr__", [](const TaskPtr op) { return "Task(" + op->get_name() + ")"; }, + "Textual representation of the Task"); + + /* Class CommTask */ + py::class_(m, "CommTask", "Communication Task. See the C++ documentation for details.") + .def_static("init", py::overload_cast(&CommTask::init), + py::call_guard(), py::arg("name"), "CommTask constructor") + .def_static("init", py::overload_cast(&CommTask::init), + py::call_guard(), py::arg("name"), py::arg("bytes"), py::arg("source"), + py::arg("destination"), "CommTask constructor") + .def_property("source", &CommTask::get_source, &CommTask::set_source, "The source of the communication.") + .def_property("destination", &CommTask::get_destination, &CommTask::set_destination, + "The destination of the communication.") + .def_property("bytes", &CommTask::get_bytes, &CommTask::set_bytes, "The amount of bytes to send.") + .def( + "__repr__", [](const CommTaskPtr c) { return "CommTask(" + c->get_name() + ")"; }, + "Textual representation of the CommTask"); + + /* Class ExecTask */ + py::class_(m, "ExecTask", "Execution Task. See the C++ documentation for details.") + .def_static("init", py::overload_cast(&ExecTask::init), + py::call_guard(), py::arg("name"), "ExecTask constructor") + .def_static("init", py::overload_cast(&ExecTask::init), + py::call_guard(), py::arg("name"), py::arg("flops"), py::arg("host"), + "CommTask constructor.") + .def_property("host", &ExecTask::get_host, &ExecTask::set_host, "The host of the execution.") + .def_property("flops", &ExecTask::get_flops, &ExecTask::set_flops, "The amount of flops to execute.") + .def( + "__repr__", [](const ExecTaskPtr e) { return "ExecTask(" + e->get_name() + ")"; }, + "Textual representation of the ExecTask"); + + /* Class IoTask */ + py::class_(m, "IoTask", "IO Task. See the C++ documentation for details.") + .def_static("init", py::overload_cast(&IoTask::init), + py::call_guard(), py::arg("name"), "IoTask constructor") + .def_static("init", py::overload_cast(&IoTask::init), + py::call_guard(), py::arg("name"), py::arg("bytes"), py::arg("disk"), + py::arg("type"), "IoTask constructor.") + .def_property("disk", &IoTask::get_disk, &IoTask::set_disk, "The disk of the IO.") + .def_property("bytes", &IoTask::get_bytes, &IoTask::set_bytes, "The amount of bytes to process.") + .def_property("type", &IoTask::get_bytes, &IoTask::set_bytes, "The type of IO.") + .def( + "__repr__", [](const IoTaskPtr io) { return "IoTask(" + io->get_name() + ")"; }, + "Textual representation of the IoTask"); + + /* Class ActivitySet */ + py::class_(m, "ActivitySet", "ActivitySet. See the C++ documentation for details.") + .def(py::init([](std::vector activities) { + auto* ret = new ActivitySet(); + for (auto a : activities) + ret->push(a); + return ActivitySetPtr(ret); + }), + "The constructor should take the parameters from the command line, as is ") + .def(py::init([]() { return ActivitySetPtr(new ActivitySet()); }), + "The constructor should take the parameters from the command line, as is ") + + .def("push", &ActivitySet::push, py::call_guard(), py::arg("activity"), + "Add an activity to the set") + .def("erase", &ActivitySet::erase, py::call_guard(), py::arg("activity"), + "Remove that activity from the set") + .def_property_readonly("size", &ActivitySet::size, "Count of activities in the set") + .def("empty", &ActivitySet::empty, "Returns whether the set is empty") + .def("has_failed_activities", &ActivitySet::has_failed_activities, + "Returns whether there is any failed activities") + .def("get_failed_activity", &ActivitySet::get_failed_activity, "Returns a failed activity from the set, or None") + + .def("wait_all_for", &ActivitySet::wait_all_for, py::call_guard(), py::arg("timeout"), + "Wait for the completion of all activities in the set, but not longer than the provided timeout") + .def("wait_all", &ActivitySet::wait_all, py::call_guard(), + "Wait for the completion of all activities in the set, endlessly") + .def("test_any", &ActivitySet::test_any, py::call_guard(), + "Returns the first terminated activity if any, or None if no activity is terminated") + .def("wait_any_for", &ActivitySet::wait_any_for, py::call_guard(), py::arg("timeout"), + "Wait for the completion of one activity in the set, but not longer than the provided timeout") + .def("wait_any", &ActivitySet::wait_any, py::call_guard(), + "Wait for the completion of one activity in the set, endlessly") + + .def( + "__repr__", [](const ActivitySetPtr as) { return "ActivitySet([...])"; }, + "Textual representation of the ActivitySet"); } diff --git a/src/dag/dax_dtd.c b/src/dag/dax_dtd.c index 6be8241db0..3ba8d5c45a 100644 --- a/src/dag/dax_dtd.c +++ b/src/dag/dax_dtd.c @@ -1821,14 +1821,7 @@ const char* *dax__statenames=NULL; * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ -#if defined(_WIN32) -# ifndef __STRICT_ANSI__ -# include -# include -# endif -#else -# include -#endif +#include #endif #ifndef YY_EXTRA_TYPE diff --git a/src/dag/loaders.cpp b/src/dag/loaders.cpp index c6d288db6b..09591b1e83 100644 --- a/src/dag/loaders.cpp +++ b/src/dag/loaders.cpp @@ -1,5 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,6 +6,8 @@ #include "src/internal_config.h" #include #include +#include +#include #include #include #include @@ -19,6 +20,16 @@ #include "dax_dtd.h" #include "dax_dtd.c" +#if SIMGRID_HAVE_JSON +// Disable implicit conversions. See https://github.com/nlohmann/json#implicit-conversions +#ifdef JSON_USE_IMPLICIT_CONVERSIONS +#undef JSON_USE_IMPLICIT_CONVERSIONS +#endif +#define JSON_USE_IMPLICIT_CONVERSIONS 0 +#include +#include +#endif + #if HAVE_GRAPHVIZ #include #endif @@ -33,16 +44,16 @@ static void uniq_transfer_task_name(simgrid::s4u::Comm* comm) std::string new_name = parent->get_name() + "_" + comm->get_name() + "_" + child->get_name(); - comm->set_name(new_name)->vetoable_start(); + comm->set_name(new_name)->start(); } static bool check_for_cycle(const std::vector& dag) { std::vector current; - for (const auto& a : dag) - if (dynamic_cast(a.get()) != nullptr && a->has_no_successor()) - current.push_back(a); + std::copy_if(begin(dag), end(dag), back_inserter(current), [](const auto& a) { + return dynamic_cast(a.get()) != nullptr && a->has_no_successor(); + }); while (not current.empty()) { std::vector next; @@ -79,6 +90,81 @@ static std::map> jobs; static std::map> files; static ExecPtr current_job; +/** @brief loads a JSON file describing a DAG + * + * See https://github.com/wfcommons/wfformat for more details. We support wfformat 1.4. + */ +std::vector create_DAG_from_json(const std::string& filename) +{ +#if SIMGRID_HAVE_JSON + std::ifstream f(filename); + auto data = nlohmann::json::parse(f); + std::vector dag = {}; + std::map, std::less<>> successors = {}; + std::map comms_destinations = {}; + ActivityPtr current; + + for (auto const& task: data["workflow"]["tasks"]) { + if (task["type"] == "compute") { + current = + Exec::init()->set_name(task["name"].get())->set_flops_amount(task["runtimeInSeconds"].get()); + if (task.contains("machine")) + dynamic_cast(current.get()) + ->set_host(simgrid::s4u::Engine::get_instance()->host_by_name(task["machine"].get())); + } + else if (task["type"] == "transfer"){ + current = Comm::sendto_init() + ->set_name(task["name"].get()) + ->set_payload_size(task["writtenBytes"].get()); + if (task.contains("machine")) + comms_destinations[current] = + simgrid::s4u::Engine::get_instance()->host_by_name(task["machine"].get()); + if (task["parents"].size() == 1) { + ActivityPtr parent_activity; + for (auto const& activity: dag) { + if (activity->get_name() == task["parents"][0]) { + parent_activity = activity; + break; + } + } + if (dynamic_cast(parent_activity.get()) != nullptr) + dynamic_cast(current.get())->set_source(dynamic_cast(parent_activity.get())->get_host()); + else if (dynamic_cast(parent_activity.get()) != nullptr) + dynamic_cast(current.get())->set_source(dynamic_cast(parent_activity.get())->get_destination()); + } + } else if (XBT_LOG_ISENABLED(dag_parsing, xbt_log_priority_debug)) { + std::stringstream ss; + ss << task["type"]; + XBT_DEBUG("Task type \"%s\" not supported.", ss.str().c_str()); + } + + dag.push_back(current); + for (auto const& parent : task["parents"]) + successors[parent.get()].push_back(current); + } + // Assign successors + for (auto const& [parent, successors_list] : successors) + for (auto const& activity: dag) + if (activity->get_name() == parent) { + for (auto const& successor: successors_list) + activity->add_successor(successor); + break; + } + // Assign destinations of Comms (if done before successors are assigned there is a bug) + for (auto const& [comm, destination]: comms_destinations) + dynamic_cast(comm.get())->set_destination(destination); + + // Start only Activities with dependencies solved + for (auto const& activity: dag) { + if (dynamic_cast(activity.get()) != nullptr && activity->dependencies_solved()) + activity->start(); + } + return dag; +#else + xbt_die("JSON support was not compiled in, probably because nlohmann/json was not found. Please install " + "nlohmann-json3-dev and recompile SimGrid to use this feature."); +#endif +} /** @brief loads a DAX file describing a DAG * * See https://confluence.pegasus.isi.edu/display/pegasus/WorkflowGenerator for more details. @@ -92,12 +178,12 @@ std::vector create_DAG_from_DAX(const std::string& filename) dax_lineno = 1; auto root_task = Exec::init()->set_name("root")->set_flops_amount(0); - root_task->vetoable_start(); + root_task->start(); result.push_back(root_task); auto end_task = Exec::init()->set_name("end")->set_flops_amount(0); - end_task->vetoable_start(); + end_task->start(); xbt_assert(dax_lex() == 0, "Parse error in %s: %s", filename.c_str(), dax__parse_err_msg()); dax__delete_buffer(input_buffer); @@ -198,7 +284,7 @@ std::vector create_DAG_from_dot(const std::string& filename) if (activities.find(name) == activities.end()) { XBT_DEBUG("See ", name.c_str(), amount); - act = Exec::init()->set_name(name)->set_flops_amount(amount)->vetoable_start(); + act = Exec::init()->set_name(name)->set_flops_amount(amount)->start(); activities.try_emplace(name, act); if (name != "root" && name != "end") dag.push_back(act); @@ -208,12 +294,12 @@ std::vector create_DAG_from_dot(const std::string& filename) } /*Check if 'root' and 'end' nodes have been explicitly declared. If not, create them. */ if (activities.find("root") == activities.end()) - root = Exec::init()->set_name("root")->set_flops_amount(0)->vetoable_start(); + root = Exec::init()->set_name("root")->set_flops_amount(0)->start(); else root = activities.at("root"); if (activities.find("end") == activities.end()) - end = Exec::init()->set_name("end")->set_flops_amount(0)->vetoable_start(); + end = Exec::init()->set_name("end")->set_flops_amount(0)->start(); else end = activities.at("end"); @@ -238,7 +324,7 @@ std::vector create_DAG_from_dot(const std::string& filename) std::string name = std::string(src_name) + "->" + dst_name; XBT_DEBUG("See ", name.c_str(), size); if (activities.find(name) == activities.end()) { - act = Comm::sendto_init()->set_name(name)->set_payload_size(size)->vetoable_start(); + act = Comm::sendto_init()->set_name(name)->set_payload_size(size)->start(); src->add_successor(act); act->add_successor(dst); activities.try_emplace(name, act); @@ -295,7 +381,7 @@ std::vector create_DAG_from_dot(const std::string& filename) void STag_dax__adag() { try { - double version = std::stod(std::string(A_dax__adag_version)); + double version = std::stod(A_dax__adag_version); xbt_assert(version == 2.1, "Expected version 2.1 in tag, got %f. Fix the parser or your file", version); } catch (const std::invalid_argument&) { throw std::invalid_argument(std::string("Parse error: ") + A_dax__adag_version + " is not a double"); @@ -305,12 +391,12 @@ void STag_dax__adag() void STag_dax__job() { try { - double runtime = std::stod(std::string(A_dax__job_runtime)); + double runtime = std::stod(A_dax__job_runtime); std::string name = std::string(A_dax__job_id) + "@" + A_dax__job_name; runtime *= 4200000000.; /* Assume that timings were done on a 4.2GFlops machine. I mean, why not? */ XBT_DEBUG("See ", A_dax__job_id, A_dax__job_runtime, runtime); - simgrid::s4u::current_job = simgrid::s4u::Exec::init()->set_name(name)->set_flops_amount(runtime)->vetoable_start(); + simgrid::s4u::current_job = simgrid::s4u::Exec::init()->set_name(name)->set_flops_amount(runtime)->start(); simgrid::s4u::jobs.try_emplace(A_dax__job_id, simgrid::s4u::current_job); simgrid::s4u::result.push_back(simgrid::s4u::current_job); } catch (const std::invalid_argument&) { @@ -322,7 +408,7 @@ void STag_dax__uses() { double size; try { - size = std::stod(std::string(A_dax__uses_size)); + size = std::stod(A_dax__uses_size); } catch (const std::invalid_argument&) { throw std::invalid_argument(std::string("Parse error: ") + A_dax__uses_size + " is not a double"); } @@ -357,7 +443,7 @@ void STag_dax__child() if (job != simgrid::s4u::jobs.end()) { current_child = job->second; } else { - throw std::out_of_range(std::string("Parse error on line ") + std::to_string(dax_lineno) + + throw std::out_of_range("Parse error on line " + std::to_string(dax_lineno) + ": Asked to add dependencies to the non-existent " + A_dax__child_ref + "task"); } } @@ -375,9 +461,9 @@ void STag_dax__parent() parent->add_successor(current_child); XBT_DEBUG("Control-flow dependency from %s to %s", current_child->get_cname(), parent->get_cname()); } else { - throw std::out_of_range(std::string("Parse error on line ") + std::to_string(dax_lineno) + - ": Asked to add a dependency from " + current_child->get_name() + " to " + - A_dax__parent_ref + ", but " + A_dax__parent_ref + " does not exist"); + throw std::out_of_range("Parse error on line " + std::to_string(dax_lineno) + ": Asked to add a dependency from " + + current_child->get_name() + " to " + A_dax__parent_ref + ", but " + A_dax__parent_ref + + " does not exist"); } } diff --git a/src/include/xbt/mmalloc.h b/src/include/xbt/mmalloc.h deleted file mode 100644 index f2b85acfbd..0000000000 --- a/src/include/xbt/mmalloc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. - This file was then part of the GNU C Library. */ - -#ifndef SIMGRID_MMALLOC_H -#define SIMGRID_MMALLOC_H - -#include "src/internal_config.h" - -#include /* for NULL */ -#include /* for size_t */ - -#include "xbt/dict.h" -#include "xbt/dynar.h" - -SG_BEGIN_DECL - -/* Datatype representing a separate heap. The whole point of the mmalloc module is to allow several such heaps in the - * process. It thus works by redefining all the classical memory management functions (malloc and friends) with an - * extra first argument: the heap in which the memory is to be taken. - * - * The heap structure itself is an opaque object that shouldn't be messed with. - */ -typedef struct mdesc s_xbt_mheap_t; -typedef s_xbt_mheap_t* xbt_mheap_t; - -#if HAVE_MMALLOC -/* Allocate SIZE bytes of memory (and memset it to 0). */ -XBT_PUBLIC void* mmalloc(xbt_mheap_t md, size_t size); - -/* Allocate SIZE bytes of memory (and don't mess with it) */ -void* mmalloc_no_memset(xbt_mheap_t mdp, size_t size); - -/* Re-allocate the previously allocated block in void*, making the new block SIZE bytes long. */ -XBT_PUBLIC void* mrealloc(xbt_mheap_t md, void* ptr, size_t size); - -/* Free a block allocated by `mmalloc', `mrealloc' or `mcalloc'. */ -XBT_PUBLIC void mfree(xbt_mheap_t md, void* ptr); - -#define XBT_MHEAP_OPTION_MEMSET 1 - -XBT_PUBLIC xbt_mheap_t xbt_mheap_new(void* baseaddr, int options); - -XBT_PUBLIC void xbt_mheap_destroy_no_free(xbt_mheap_t md); - -XBT_PUBLIC void* xbt_mheap_destroy(xbt_mheap_t md); - -/* To get the heap used when using the legacy version malloc/free/realloc and such */ -xbt_mheap_t mmalloc_get_current_heap(void); - -#endif -SG_END_DECL - -#endif /* SIMGRID_MMALLOC_H */ diff --git a/src/include/xbt/xbt_modinter.h b/src/include/xbt/xbt_modinter.h deleted file mode 100644 index 254f554448..0000000000 --- a/src/include/xbt/xbt_modinter.h +++ /dev/null @@ -1,30 +0,0 @@ -/* xbt_modinter - How to init/exit the XBT modules */ - -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef XBT_MODINTER_H -#define XBT_MODINTER_H -#include "xbt/misc.h" -#include "xbt/mmalloc.h" - -SG_BEGIN_DECL - -/* Modules definitions */ - -void xbt_log_preinit(void); -void xbt_log_postexit(void); - -void xbt_dict_preinit(void); -void xbt_dict_postexit(void); - -xbt_mheap_t mmalloc_preinit(void); -void mmalloc_postexit(void); - -extern int xbt_initialized; - -SG_END_DECL - -#endif diff --git a/src/include/xxhash.hpp b/src/include/xxhash.hpp deleted file mode 100644 index 14d43efa19..0000000000 --- a/src/include/xxhash.hpp +++ /dev/null @@ -1,725 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include - -#include - -/* -xxHash - Extremely Fast Hash algorithm -Header File -Copyright (C) 2012-2018, Yann Collet. -Copyright (C) 2017-2018, Piotr Pliszka. -All rights reserved. - -BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: -* Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -You can contact the author at : -- xxHash source repository : https://github.com/Cyan4973/xxHash -- xxHash C++ port repository : https://github.com/RedSpah/xxhash_cpp -*/ - -/* ************************************* -* Tuning parameters -***************************************/ -/*!XXH_FORCE_MEMORY_ACCESS : -* By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. -* Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. -* The below switch allow to select different access method for improved performance. -* Method 0 (default) : use `memcpy()`. Safe and portable. -* Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). -* This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. -* Method 2 : direct access. This method doesn't depend on compiler but violate C standard. -* It can generate buggy code on targets which do not support unaligned memory accesses. -* But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) -* See http://stackoverflow.com/a/32095106/646947 for details. -* Prefer these methods in priority order (0 > 1 > 2) -*/ -#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define XXH_FORCE_MEMORY_ACCESS 2 -# elif defined(__INTEL_COMPILER) || (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) -# define XXH_FORCE_MEMORY_ACCESS 1 -# endif -#endif - - -/*!XXH_FORCE_NATIVE_FORMAT : -* By default, xxHash library provides endian-independent Hash values, based on little-endian convention. -* Results are therefore identical for little-endian and big-endian CPU. -* This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. -* Should endian-independence be of no importance for your application, you may set the #define below to 1, -* to improve speed for Big-endian CPU. -* This option has no impact on Little_Endian CPU. -*/ -#if !defined(XXH_FORCE_NATIVE_FORMAT) || (XXH_FORCE_NATIVE_FORMAT == 0) /* can be defined externally */ -# define XXH_FORCE_NATIVE_FORMAT 0 -# define XXH_CPU_LITTLE_ENDIAN 1 -#endif - - -/*!XXH_FORCE_ALIGN_CHECK : -* This is a minor performance trick, only useful with lots of very small keys. -* It means : check for aligned/unaligned input. -* The check costs one initial branch per hash; -* set it to 0 when the input is guaranteed to be aligned, -* or when alignment doesn't matter for performance. -*/ -#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ -# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_FORCE_ALIGN_CHECK 0 -# else -# define XXH_FORCE_ALIGN_CHECK 1 -# endif -#endif - -/*!XXH_CPU_LITTLE_ENDIAN : -* This is a CPU endian detection macro, will be -* automatically set to 1 (little endian) if XXH_FORCE_NATIVE_FORMAT -* is left undefined, XXH_FORCE_NATIVE_FORMAT is defined to 0, or if an x86/x86_64 compiler macro is defined. -* If left undefined, endianness will be determined at runtime, at the cost of a slight one-time overhead -* and a larger overhead due to get_endian() not being constexpr. -*/ -#ifndef XXH_CPU_LITTLE_ENDIAN -# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_CPU_LITTLE_ENDIAN 1 -# endif -#endif - -/* ************************************* -* Compiler Specific Options -***************************************/ -#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -namespace xxh -{ - /* ************************************* - * Version - ***************************************/ - constexpr int cpp_version_major = 0; - constexpr int cpp_version_minor = 6; - constexpr int cpp_version_release = 5; - constexpr uint32_t version_number() { return cpp_version_major * 10000 + cpp_version_minor * 100 + cpp_version_release; } - - namespace hash_t_impl - { - /* ************************************* - * Basic Types - Detail - ***************************************/ - - using _hash32_underlying = uint32_t; - using _hash64_underlying = uint64_t; - - template - struct hash_type { using type = void; }; - template <> - struct hash_type<32> { using type = _hash32_underlying; }; - template <> - struct hash_type<64> { using type = _hash64_underlying; }; - } - - /* ************************************* - * Basic Types - Public - ***************************************/ - - template - using hash_t = typename hash_t_impl::hash_type::type; - using hash32_t = hash_t<32>; - using hash64_t = hash_t<64>; - - /* ************************************* - * Bit Functions - Public - ***************************************/ - - namespace bit_ops - { - /* **************************************** - * Intrinsics and Bit Operations - ******************************************/ - -#if defined(_MSC_VER) - inline uint32_t rotl32(uint32_t x, int32_t r) { return _rotl(x, r); } - inline uint64_t rotl64(uint64_t x, int32_t r) { return _rotl64(x, r); } -#else - inline uint32_t rotl32(uint32_t x, int32_t r) { return ((x << r) | (x >> (32 - r))); } - inline uint64_t rotl64(uint64_t x, int32_t r) { return ((x << r) | (x >> (64 - r))); } -#endif - -#if defined(_MSC_VER) /* Visual Studio */ - inline uint32_t swap32(uint32_t x) { return _byteswap_ulong(x); } - inline uint64_t swap64(uint64_t x) { return _byteswap_uint64(x); } -#elif XXH_GCC_VERSION >= 403 - inline uint32_t swap32(uint32_t x) { return __builtin_bswap32(x); } - inline uint64_t swap64(uint64_t x) { return __builtin_bswap64(x); } -#else - inline uint32_t swap32(uint32_t x) { return ((x << 24) & 0xff000000) | ((x << 8) & 0x00ff0000) | ((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff); } - inline uint64_t swap64(uint64_t x) { return ((x << 56) & 0xff00000000000000ULL) | ((x << 40) & 0x00ff000000000000ULL) | ((x << 24) & 0x0000ff0000000000ULL) | ((x << 8) & 0x000000ff00000000ULL) | ((x >> 8) & 0x00000000ff000000ULL) | ((x >> 24) & 0x0000000000ff0000ULL) | ((x >> 40) & 0x000000000000ff00ULL) | ((x >> 56) & 0x00000000000000ffULL); } -#endif - template - inline hash_t rotl(hash_t n, int32_t r) {}; - - template <> - inline hash_t<32> rotl<32>(hash_t<32> n, int32_t r) - { - return rotl32(n, r); - }; - - template <> - inline hash_t<64> rotl<64>(hash_t<64> n, int32_t r) - { - return rotl64(n, r); - }; - - template - inline hash_t swap(hash_t n) {}; - - template <> - inline hash_t<32> swap<32>(hash_t<32> n) - { - return swap32(n); - }; - - template <> - inline hash_t<64> swap<64>(hash_t<64> n) - { - return swap64(n); - }; - } - - /* ************************************* - * Memory Functions - Public - ***************************************/ - - enum class alignment : uint8_t { aligned, unaligned }; - enum class endianness : uint8_t { big_endian = 0, little_endian = 1, unspecified = 2 }; - - namespace mem_ops - { - /* ************************************* - * Memory Access - ***************************************/ -#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) - - /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ - template - inline hash_t read_unaligned(const void* memPtr) { return *(const hash_t*)memPtr; } - -#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) - - /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ - /* currently only defined for gcc and icc */ - template - using unalign = union { hash_t uval; } __attribute((packed)); - - template - inline hash_t read_unaligned(const void* memPtr) { return ((const unalign*)memPtr)->uval; } -#else - - /* portable and safe solution. Generally efficient. - * see : http://stackoverflow.com/a/32095106/646947 - */ - template - inline hash_t read_unaligned(const void* memPtr) - { - hash_t val; - memcpy(&val, memPtr, sizeof(val)); - return val; - } - -#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ - - inline hash_t<32> read32(const void* memPtr) { return read_unaligned<32>(memPtr); } - inline hash_t<64> read64(const void* memPtr) { return read_unaligned<64>(memPtr); } - - /* ************************************* - * Architecture Macros - ***************************************/ - - /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ - -#ifndef XXH_CPU_LITTLE_ENDIAN - - inline endianness get_endian(endianness endian) - { - static struct _dummy_t - { - std::array endian_lookup = { endianness::big_endian, endianness::little_endian, endianness::unspecified }; - const int g_one = 1; - _dummy_t() - { - endian_lookup[2] = static_cast(*(const char*)(&g_one)); - } - } _dummy; - - return _dummy.endian_lookup[(uint8_t)endian]; - } - - inline bool is_little_endian() - { - return get_endian(endianness::unspecified) == endianness::little_endian; - } - -#else - constexpr endianness get_endian(endianness endian) - { - constexpr std::array endian_lookup = {{ endianness::big_endian, endianness::little_endian, (XXH_CPU_LITTLE_ENDIAN) ? endianness::little_endian : endianness::big_endian }}; - return endian_lookup[static_cast(endian)]; - } - - constexpr bool is_little_endian() - { - return get_endian(endianness::unspecified) == endianness::little_endian; - } - -#endif - - - - /* *************************** - * Memory reads - *****************************/ - - - template - inline hash_t readLE_align(const void* ptr, endianness endian, alignment align) - { - if (align == alignment::unaligned) - { - return endian == endianness::little_endian ? read_unaligned(ptr) : bit_ops::swap(read_unaligned(ptr)); - } - else - { - return endian == endianness::little_endian ? *reinterpret_cast*>(ptr) : bit_ops::swap(*reinterpret_cast*>(ptr)); - } - } - - template - inline hash_t readLE(const void* ptr, endianness endian) - { - return readLE_align(ptr, endian, alignment::unaligned); - } - - template - inline hash_t readBE(const void* ptr) - { - return is_little_endian() ? bit_ops::swap(read_unaligned(ptr)) : read_unaligned(ptr); - } - - template - inline alignment get_alignment(const void* input) - { - return ((XXH_FORCE_ALIGN_CHECK) && ((reinterpret_cast(input) & ((N / 8) - 1)) == 0)) ? xxh::alignment::aligned : xxh::alignment::unaligned; - } - } - - /* ******************************************************************* - * Hash functions - *********************************************************************/ - - namespace detail - { - /* ******************************************************************* - * Hash functions - Implementation - *********************************************************************/ - - constexpr static std::array primes32 = {{ 2654435761U, 2246822519U, 3266489917U, 668265263U, 374761393U }}; - constexpr static std::array primes64 = {{ 11400714785074694791ULL, 14029467366897019727ULL, 1609587929392839161ULL, 9650029242287828579ULL, 2870177450012600261ULL }}; - - template - constexpr hash_t PRIME(int32_t n) {}; - - template <> - constexpr hash32_t PRIME<32>(int32_t n) - { - return primes32[n - 1]; - } - - template <> - constexpr hash64_t PRIME<64>(int32_t n) - { - return primes64[n - 1]; - } - - template - inline hash_t round(hash_t seed, hash_t input) - { - seed += input * PRIME(2); - seed = bit_ops::rotl(seed, ((N == 32) ? 13 : 31)); - seed *= PRIME(1); - return seed; - } - - inline hash64_t mergeRound64(hash64_t acc, hash64_t val) - { - val = round<64>(0, val); - acc ^= val; - acc = acc * PRIME<64>(1) + PRIME<64>(4); - return acc; - } - - template - inline void endian_align_sub_mergeround( -#if __cplusplus < 201703L - __attribute__((unused)) -#else - [[maybe_unused]] -#endif - hash_t& hash_ret, hash_t v1, hash_t v2, hash_t v3, hash_t v4) {}; - - template <> - inline void endian_align_sub_mergeround<64>(hash_t<64>& hash_ret, hash_t<64> v1, hash_t<64> v2, hash_t<64> v3, hash_t<64> v4) - { - hash_ret = mergeRound64(hash_ret, v1); - hash_ret = mergeRound64(hash_ret, v2); - hash_ret = mergeRound64(hash_ret, v3); - hash_ret = mergeRound64(hash_ret, v4); - } - - template - inline hash_t endian_align_sub_ending(hash_t hash_ret, const uint8_t* p, const uint8_t* bEnd, xxh::endianness endian, xxh::alignment align) {}; - - template <> - inline hash_t<32> endian_align_sub_ending<32>(hash_t<32> hash_ret, const uint8_t* p, const uint8_t* bEnd, xxh::endianness endian, xxh::alignment align) - { - while ((p + 4) <= bEnd) - { - hash_ret += mem_ops::readLE_align<32>(p, endian, align) * PRIME<32>(3); - hash_ret = bit_ops::rotl<32>(hash_ret, 17) * PRIME<32>(4); - p += 4; - } - - while (p < bEnd) - { - hash_ret += (*p) * PRIME<32>(5); - hash_ret = bit_ops::rotl<32>(hash_ret, 11) * PRIME<32>(1); - p++; - } - - hash_ret ^= hash_ret >> 15; - hash_ret *= PRIME<32>(2); - hash_ret ^= hash_ret >> 13; - hash_ret *= PRIME<32>(3); - hash_ret ^= hash_ret >> 16; - - return hash_ret; - } - - template <> - inline hash_t<64> endian_align_sub_ending<64>(hash_t<64> hash_ret, const uint8_t* p, const uint8_t* bEnd, xxh::endianness endian, xxh::alignment align) - { - while (p + 8 <= bEnd) - { - const hash64_t k1 = round<64>(0, mem_ops::readLE_align<64>(p, endian, align)); - hash_ret ^= k1; - hash_ret = bit_ops::rotl<64>(hash_ret, 27) * PRIME<64>(1) + PRIME<64>(4); - p += 8; - } - - if (p + 4 <= bEnd) - { - hash_ret ^= static_cast(mem_ops::readLE_align<32>(p, endian, align)) * PRIME<64>(1); - hash_ret = bit_ops::rotl<64>(hash_ret, 23) * PRIME<64>(2) + PRIME<64>(3); - p += 4; - } - - while (p < bEnd) - { - hash_ret ^= (*p) * PRIME<64>(5); - hash_ret = bit_ops::rotl<64>(hash_ret, 11) * PRIME<64>(1); - p++; - } - - hash_ret ^= hash_ret >> 33; - hash_ret *= PRIME<64>(2); - hash_ret ^= hash_ret >> 29; - hash_ret *= PRIME<64>(3); - hash_ret ^= hash_ret >> 32; - - return hash_ret; - } - - template - inline hash_t endian_align(const void* input, size_t len, hash_t seed, xxh::endianness endian, xxh::alignment align) - { - static_assert(!(N != 32 && N != 64), "You can only call endian_align in 32 or 64 bit mode."); - - const uint8_t* p = static_cast(input); - const uint8_t* bEnd = p + len; - hash_t hash_ret; - - if (len >= (N / 2)) - { - const uint8_t* const limit = bEnd - (N / 2); - hash_t v1 = seed + PRIME(1) + PRIME(2); - hash_t v2 = seed + PRIME(2); - hash_t v3 = seed + 0; - hash_t v4 = seed - PRIME(1); - - do - { - v1 = round(v1, mem_ops::readLE_align(p, endian, align)); p += (N / 8); - v2 = round(v2, mem_ops::readLE_align(p, endian, align)); p += (N / 8); - v3 = round(v3, mem_ops::readLE_align(p, endian, align)); p += (N / 8); - v4 = round(v4, mem_ops::readLE_align(p, endian, align)); p += (N / 8); - } while (p <= limit); - - hash_ret = bit_ops::rotl(v1, 1) + bit_ops::rotl(v2, 7) + bit_ops::rotl(v3, 12) + bit_ops::rotl(v4, 18); - - endian_align_sub_mergeround(hash_ret, v1, v2, v3, v4); - } - else { hash_ret = seed + PRIME(5); } - - hash_ret += static_cast>(len); - - return endian_align_sub_ending(hash_ret, p, bEnd, endian, align); - } - } - - template - hash_t xxhash(const void* input, size_t len, hash_t seed = 0, endianness endian = endianness::unspecified) - { - static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode."); - return detail::endian_align(input, len, seed, mem_ops::get_endian(endian), mem_ops::get_alignment(input)); - } - - template - hash_t xxhash(const std::basic_string& input, hash_t seed = 0, endianness endian = endianness::unspecified) - { - static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode."); - return detail::endian_align(static_cast(input.data()), input.length() * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment(static_cast(input.data()))); - } - - template - hash_t xxhash(ContiguousIterator begin, ContiguousIterator end, hash_t seed = 0, endianness endian = endianness::unspecified) - { - static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode."); - using T = typename std::decay_t; - return detail::endian_align(static_cast(&*begin), (end - begin) * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment(static_cast(&*begin))); - } - - template - hash_t xxhash(const std::vector& input, hash_t seed = 0, endianness endian = endianness::unspecified) - { - static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode."); - return detail::endian_align(static_cast(input.data()), input.size() * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment(static_cast(input.data()))); - } - - template - hash_t xxhash(const std::array& input, hash_t seed = 0, endianness endian = endianness::unspecified) - { - static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode."); - return detail::endian_align(static_cast(input.data()), AN * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment(static_cast(input.data()))); - } - - template - hash_t xxhash(const std::initializer_list& input, hash_t seed = 0, endianness endian = endianness::unspecified) - { - static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode."); - return detail::endian_align(static_cast(input.begin()), input.size() * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment(static_cast(input.begin()))); - } - - - /* ******************************************************************* - * Hash streaming - *********************************************************************/ - enum class error_code : uint8_t { ok = 0, error }; - - template - class hash_state_t - { - uint64_t total_len = 0; - hash_t v1 = 0, v2 = 0, v3 = 0, v4 = 0; - std::array, 4> mem = {{ 0,0,0,0 }}; - uint32_t memsize = 0; - - inline error_code _update_impl(const void* input, size_t length, endianness endian) - { - const uint8_t* p = reinterpret_cast(input); - const uint8_t* const bEnd = p + length; - - if (!input) { return xxh::error_code::error; } - - total_len += length; - - if (memsize + length < (N / 2)) - { /* fill in tmp buffer */ - memcpy(reinterpret_cast(mem.data()) + memsize, input, length); - memsize += static_cast(length); - return error_code::ok; - } - - if (memsize) - { /* some data left from previous update */ - memcpy(reinterpret_cast(mem.data()) + memsize, input, (N / 2) - memsize); - - const hash_t* ptr = mem.data(); - v1 = detail::round(v1, mem_ops::readLE(ptr, endian)); ptr++; - v2 = detail::round(v2, mem_ops::readLE(ptr, endian)); ptr++; - v3 = detail::round(v3, mem_ops::readLE(ptr, endian)); ptr++; - v4 = detail::round(v4, mem_ops::readLE(ptr, endian)); - - p += (N / 2) - memsize; - memsize = 0; - } - - if (p <= bEnd - (N / 2)) - { - const uint8_t* const limit = bEnd - (N / 2); - - do - { - v1 = detail::round(v1, mem_ops::readLE(p, endian)); p += (N / 8); - v2 = detail::round(v2, mem_ops::readLE(p, endian)); p += (N / 8); - v3 = detail::round(v3, mem_ops::readLE(p, endian)); p += (N / 8); - v4 = detail::round(v4, mem_ops::readLE(p, endian)); p += (N / 8); - } while (p <= limit); - } - - if (p < bEnd) - { - memcpy(mem.data(), p, static_cast(bEnd - p)); - memsize = static_cast(bEnd - p); - } - - return error_code::ok; - } - - inline hash_t _digest_impl(endianness endian) const - { - const uint8_t* p = reinterpret_cast(mem.data()); - const uint8_t* const bEnd = reinterpret_cast(mem.data()) + memsize; - hash_t hash_ret; - - if (total_len > (N / 2)) - { - hash_ret = bit_ops::rotl(v1, 1) + bit_ops::rotl(v2, 7) + bit_ops::rotl(v3, 12) + bit_ops::rotl(v4, 18); - - detail::endian_align_sub_mergeround(hash_ret, v1, v2, v3, v4); - } - else { hash_ret = v3 + detail::PRIME(5); } - - hash_ret += static_cast>(total_len); - - return detail::endian_align_sub_ending(hash_ret, p, bEnd, endian, alignment::unaligned); - } - - public: - hash_state_t(hash_t seed = 0) - { - static_assert(!(N != 32 && N != 64), "You can only stream hashing in 32 or 64 bit mode."); - v1 = seed + detail::PRIME(1) + detail::PRIME(2); - v2 = seed + detail::PRIME(2); - v3 = seed + 0; - v4 = seed - detail::PRIME(1); - }; - - hash_state_t operator=(hash_state_t& other) - { - memcpy(this, other, sizeof(hash_state_t)); - } - - error_code reset(hash_t seed = 0) - { - memset(this, 0, sizeof(hash_state_t)); - v1 = seed + detail::PRIME(1) + detail::PRIME(2); - v2 = seed + detail::PRIME(2); - v3 = seed + 0; - v4 = seed - detail::PRIME(1); - return error_code::ok; - } - - error_code update(const void* input, size_t length, endianness endian = endianness::unspecified) - { - return _update_impl(input, length, mem_ops::get_endian(endian)); - } - - template - error_code update(const std::basic_string& input, endianness endian = endianness::unspecified) - { - return _update_impl(static_cast(input.data()), input.length() * sizeof(T), mem_ops::get_endian(endian)); - } - - template - error_code update(ContiguousIterator begin, ContiguousIterator end, endianness endian = endianness::unspecified) - { - using T = typename std::decay_t; - return _update_impl(static_cast(&*begin), (end - begin) * sizeof(T), mem_ops::get_endian(endian)); - } - - template - error_code update(const std::vector& input, endianness endian = endianness::unspecified) - { - return _update_impl(static_cast(input.data()), input.size() * sizeof(T), mem_ops::get_endian(endian)); - } - - template - error_code update(const std::array& input, endianness endian = endianness::unspecified) - { - return _update_impl(static_cast(input.data()), AN * sizeof(T), mem_ops::get_endian(endian)); - } - - template - error_code update(const std::initializer_list& input, endianness endian = endianness::unspecified) - { - return _update_impl(static_cast(input.begin()), input.size() * sizeof(T), mem_ops::get_endian(endian)); - } - - hash_t digest(endianness endian = endianness::unspecified) - { - return _digest_impl(mem_ops::get_endian(endian)); - } - }; - - using hash_state32_t = hash_state_t<32>; - using hash_state64_t = hash_state_t<64>; - - - /* ******************************************************************* - * Canonical - *********************************************************************/ - - template - struct canonical_t - { - std::array digest;\ - - - - canonical_t(hash_t hash) - { - if (mem_ops::is_little_endian()) { hash = bit_ops::swap(hash); } - memcpy(digest.data(), &hash, sizeof(canonical_t)); - } - - hash_t get_hash() const - { - return mem_ops::readBE(&digest); - } - }; - - using canonical32_t = canonical_t<32>; - using canonical64_t = canonical_t<64>; -} diff --git a/src/instr/instr_config.cpp b/src/instr/instr_config.cpp index e989fd457e..c13fdffc99 100644 --- a/src/instr/instr_config.cpp +++ b/src/instr/instr_config.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,9 +11,6 @@ #include "xbt/xbt_os_time.h" #include -#ifdef WIN32 -#include // _mkdir -#endif #include #include @@ -23,7 +20,7 @@ XBT_LOG_NEW_CATEGORY(instr, "Logging the behavior of the tracing system (used fo XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_config, instr, "Configuration"); std::ofstream tracing_file; -std::map tracing_files; // TI specific +static std::map tracing_files; // TI specific constexpr char OPT_TRACING_BASIC[] = "tracing/basic"; constexpr char OPT_TRACING_COMMENT_FILE[] = "tracing/comment-file"; @@ -209,7 +206,7 @@ void TRACE_help() namespace simgrid::instr { static bool trace_active = false; TraceFormat trace_format = TraceFormat::Paje; -int trace_precision; +static int trace_precision; /************* * Callbacks * @@ -276,11 +273,7 @@ static void on_container_creation_ti(const Container& c) if (not simgrid::config::get_value("tracing/smpi/format/ti-one-file") || ti_unique_file == nullptr) { std::string folder_name = simgrid::config::get_value("tracing/filename") + "_files"; std::string filename = folder_name + "/" + std::to_string(prefix) + "_" + c.get_name() + ".txt"; -#ifdef WIN32 - _mkdir(folder_name.c_str()); -#else - mkdir(folder_name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); -#endif + mkdir(folder_name.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); ti_unique_file = new std::ofstream(filename.c_str(), std::ofstream::out); xbt_assert(not ti_unique_file->fail(), "Tracefile %s could not be opened for writing", filename.c_str()); tracing_file << filename << '\n'; diff --git a/src/instr/instr_interface.cpp b/src/instr/instr_interface.cpp index 73de1d2b71..e444c0c367 100644 --- a/src/instr/instr_interface.cpp +++ b/src/instr/instr_interface.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -17,11 +17,11 @@ enum class InstrUserVariable { DECLARE, SET, ADD, SUB }; XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_api, instr, "API"); -std::set> created_categories; -std::set> declared_marks; -std::set> user_host_variables; -std::set> user_vm_variables; -std::set> user_link_variables; +static std::set> created_categories; +static std::set> declared_marks; +static std::set> user_host_variables; +static std::set> user_vm_variables; +static std::set> user_link_variables; static void instr_user_variable(double time, const std::string& resource, const std::string& variable_name, const std::string& parent_type, double value, InstrUserVariable what, @@ -312,7 +312,7 @@ void declare_tracing_category(const std::string& name, const std::string& color) double blue = simgrid::xbt::random::uniform_real(0.0, std::nextafter(1.0, 2.0)); final_color = std::to_string(red) + " " + std::to_string(green) + " " + std::to_string(blue); } else { - final_color = std::string(color); + final_color = color; } XBT_DEBUG("CAT,declare %s, \"%s\" \"%s\"", name.c_str(), color.c_str(), final_color.c_str()); @@ -332,248 +332,6 @@ const std::set>& get_tracing_categories() } // namespace simgrid::instr -static xbt_dynar_t instr_set_to_dynar(const std::set>& filter) // XBT_ATTRIB_DEPRECATED_v334 -{ - if (not TRACE_is_enabled() || not TRACE_needs_platform()) - return nullptr; - - xbt_dynar_t ret = xbt_dynar_new (sizeof(char*), &xbt_free_ref); - for (auto const& name : filter) - xbt_dynar_push_as(ret, char*, xbt_strdup(name.c_str())); - - return ret; -} - -void TRACE_category(const char* category) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::declare_tracing_category(category); -} - -void TRACE_category_with_color(const char* category, const char* color) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::declare_tracing_category(category, color); -} - -xbt_dynar_t TRACE_get_categories() // XBT_ATTRIB_DEPRECATED_v334 -{ - if (not TRACE_is_enabled() || not TRACE_categorized()) - return nullptr; - return instr_set_to_dynar(created_categories); -} - -void TRACE_declare_mark(const char* mark_type) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::declare_mark(mark_type); -} - -void TRACE_declare_mark_value_with_color(const char* mark_type, const char* mark_value, - const char* mark_color) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::declare_mark_value(mark_type, mark_value, mark_color); -} - -void TRACE_declare_mark_value(const char* mark_type, const char* mark_value) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::declare_mark_value(mark_type, mark_value); -} - -void TRACE_mark(const char* mark_type, const char* mark_value) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::mark(mark_type, mark_value); -} - -xbt_dynar_t TRACE_get_marks() // XBT_ATTRIB_DEPRECATED_v334 -{ - if (not TRACE_is_enabled()) - return nullptr; - - return instr_set_to_dynar(declared_marks); -} - -int TRACE_platform_graph_export_graphviz(const char* filename) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::platform_graph_export_graphviz(filename); - return 1; -} - -void TRACE_vm_variable_declare(const char* variable) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(0, "", variable, "VM", 0, InstrUserVariable::DECLARE, "", &user_vm_variables); -} -void TRACE_vm_variable_declare_with_color(const char* variable, const char* color) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(0, "", variable, "VM", 0, InstrUserVariable::DECLARE, color, &user_vm_variables); -} - -void TRACE_vm_variable_set(const char* vm, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(simgrid_get_clock(), vm, variable, "VM", value, InstrUserVariable::SET, "", &user_vm_variables); -} - -void TRACE_vm_variable_add(const char* vm, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(simgrid_get_clock(), vm, variable, "VM", value, InstrUserVariable::ADD, "", &user_vm_variables); -} -void TRACE_vm_variable_sub(const char* vm, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(simgrid_get_clock(), vm, variable, "VM", value, InstrUserVariable::SUB, "", &user_vm_variables); -} - -void TRACE_vm_variable_set_with_time(double time, const char* vm, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(time, vm, variable, "VM", value, InstrUserVariable::SET, "", &user_vm_variables); -} - -void TRACE_vm_variable_add_with_time(double time, const char* vm, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(time, vm, variable, "VM", value, InstrUserVariable::ADD, "", &user_vm_variables); -} -void TRACE_vm_variable_sub_with_time(double time, const char* vm, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(time, vm, variable, "VM", value, InstrUserVariable::SUB, "", &user_vm_variables); -} - -void TRACE_host_variable_declare(const char* variable) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::declare_host_variable(variable); -} - -void TRACE_host_variable_declare_with_color(const char* variable, const char* color) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::declare_host_variable(variable, color); -} - -void TRACE_host_variable_set(const char* host, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(simgrid_get_clock(), host, variable, "HOST", value, InstrUserVariable::SET, "", - &user_host_variables); -} - -void TRACE_host_variable_add(const char* host, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(simgrid_get_clock(), host, variable, "HOST", value, InstrUserVariable::ADD, "", - &user_host_variables); -} - -void TRACE_host_variable_sub(const char* host, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(simgrid_get_clock(), host, variable, "HOST", value, InstrUserVariable::SUB, "", - &user_host_variables); -} - -void TRACE_host_variable_set_with_time(double time, const char* host, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(time, host, variable, "HOST", value, InstrUserVariable::SET, "", &user_host_variables); -} - -void TRACE_host_variable_add_with_time(double time, const char* host, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(time, host, variable, "HOST", value, InstrUserVariable::ADD, "", &user_host_variables); -} - -void TRACE_host_variable_sub_with_time(double time, const char* host, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(time, host, variable, "HOST", value, InstrUserVariable::SUB, "", &user_host_variables); -} - -xbt_dynar_t TRACE_get_host_variables() // XBT_ATTRIB_DEPRECATED_v334 -{ - return instr_set_to_dynar(user_host_variables); -} - -void TRACE_link_variable_declare(const char* variable) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::declare_link_variable(variable); -} - -void TRACE_link_variable_declare_with_color(const char* variable, const char* color) // XBT_ATTRIB_DEPRECATED_v334 -{ - simgrid::instr::declare_link_variable(variable, color); -} - -void TRACE_link_variable_set(const char* link, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(simgrid_get_clock(), link, variable, "LINK", value, InstrUserVariable::SET, "", - &user_link_variables); -} - -void TRACE_link_variable_add(const char* link, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(simgrid_get_clock(), link, variable, "LINK", value, InstrUserVariable::ADD, "", - &user_link_variables); -} - -void TRACE_link_variable_sub(const char* link, const char* variable, double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(simgrid_get_clock(), link, variable, "LINK", value, InstrUserVariable::SUB, "", - &user_link_variables); -} - -void TRACE_link_variable_set_with_time(double time, const char* link, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(time, link, variable, "LINK", value, InstrUserVariable::SET, "", &user_link_variables); -} - -void TRACE_link_variable_add_with_time(double time, const char* link, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(time, link, variable, "LINK", value, InstrUserVariable::ADD, "", &user_link_variables); -} - -void TRACE_link_variable_sub_with_time(double time, const char* link, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_variable(time, link, variable, "LINK", value, InstrUserVariable::SUB, "", &user_link_variables); -} - -void TRACE_link_srcdst_variable_set(const char* src, const char* dst, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_srcdst_variable(simgrid_get_clock(), src, dst, variable, value, InstrUserVariable::SET); -} - -void TRACE_link_srcdst_variable_add(const char* src, const char* dst, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_srcdst_variable(simgrid_get_clock(), src, dst, variable, value, InstrUserVariable::ADD); -} - -void TRACE_link_srcdst_variable_sub(const char* src, const char* dst, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_srcdst_variable(simgrid_get_clock(), src, dst, variable, value, InstrUserVariable::SUB); -} - -void TRACE_link_srcdst_variable_set_with_time(double time, const char* src, const char* dst, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_srcdst_variable(time, src, dst, variable, value, InstrUserVariable::SET); -} - -void TRACE_link_srcdst_variable_add_with_time(double time, const char* src, const char* dst, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_srcdst_variable(time, src, dst, variable, value, InstrUserVariable::ADD); -} - -void TRACE_link_srcdst_variable_sub_with_time(double time, const char* src, const char* dst, const char* variable, - double value) // XBT_ATTRIB_DEPRECATED_v334 -{ - instr_user_srcdst_variable(time, src, dst, variable, value, InstrUserVariable::SUB); -} - -xbt_dynar_t TRACE_get_link_variables() // XBT_ATTRIB_DEPRECATED_v334 -{ - return instr_set_to_dynar(user_link_variables); -} - /** @ingroup TRACE_user_variables * @brief Declare a new user state associated to hosts. * diff --git a/src/instr/instr_paje_containers.cpp b/src/instr/instr_paje_containers.cpp index f53a60866c..5ebe79a08a 100644 --- a/src/instr/instr_paje_containers.cpp +++ b/src/instr/instr_paje_containers.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -20,7 +20,7 @@ NetZoneContainer::NetZoneContainer(const std::string& name, unsigned int level, { xbt_assert(s4u::Engine::get_instance()->netpoint_by_name_or_null(get_name()), "Element '%s' not found", get_cname()); if (parent_) { - std::string type_name = std::string("L") + std::to_string(level); + std::string type_name = "L" + std::to_string(level); type_ = parent_->type_->by_name_or_create(type_name); parent_->children_.try_emplace(get_name(), this); on_creation(*this); diff --git a/src/instr/instr_paje_containers.hpp b/src/instr/instr_paje_containers.hpp index a4a4fe088a..957d4981ef 100644 --- a/src/instr/instr_paje_containers.hpp +++ b/src/instr/instr_paje_containers.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/instr/instr_paje_events.cpp b/src/instr/instr_paje_events.cpp index e4bfcb3019..f908770f1f 100644 --- a/src/instr/instr_paje_events.cpp +++ b/src/instr/instr_paje_events.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,7 +6,6 @@ #include "src/instr/instr_private.hpp" #include "src/instr/instr_smpi.hpp" #include "src/smpi/include/private.hpp" -#include "src/surf/surf_interface.hpp" #include "xbt/ex.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_paje_events, instr, "Paje tracing event system (events)"); diff --git a/src/instr/instr_paje_events.hpp b/src/instr/instr_paje_events.hpp index d182088913..ed12cd6236 100644 --- a/src/instr/instr_paje_events.hpp +++ b/src/instr/instr_paje_events.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/instr/instr_paje_header.cpp b/src/instr/instr_paje_header.cpp index 44092c26dc..d69e4ddf15 100644 --- a/src/instr/instr_paje_header.cpp +++ b/src/instr/instr_paje_header.cpp @@ -1,14 +1,13 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "simgrid/Exception.hpp" #include "simgrid/version.h" #include "src/instr/instr_private.hpp" #include "src/smpi/include/private.hpp" -#include "xbt/virtu.h" /* xbt::cmdline */ +#include +#include extern std::ofstream tracing_file; namespace simgrid::instr::paje { @@ -18,7 +17,7 @@ void dump_generator_version() tracing_file << "#This file was generated using SimGrid-" << SIMGRID_VERSION_MAJOR << "." << SIMGRID_VERSION_MINOR << "." << SIMGRID_VERSION_PATCH << '\n'; tracing_file << "#["; - for (auto const& str : simgrid::xbt::cmdline) { + for (auto const& str : simgrid::s4u::Engine::get_instance()->get_cmdline()) { tracing_file << str << " "; } tracing_file << "]\n"; @@ -34,11 +33,9 @@ void dump_comment_file(const std::string& filename) throw TracingError(XBT_THROW_POINT, xbt::string_printf("Comment file %s could not be opened for reading.", filename.c_str())); - while (not fs.eof()) { - std::string line; - std::getline(fs, line); + std::string line; + while (std::getline(fs, line)) tracing_file << "# " << line; - } fs.close(); } diff --git a/src/instr/instr_paje_trace.cpp b/src/instr/instr_paje_trace.cpp index 46431388a3..abf4956af2 100644 --- a/src/instr/instr_paje_trace.cpp +++ b/src/instr/instr_paje_trace.cpp @@ -1,13 +1,13 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "simgrid/Exception.hpp" -#include "simgrid/sg_config.hpp" #include "src/instr/instr_private.hpp" #include "src/instr/instr_smpi.hpp" +#include "src/simgrid/sg_config.hpp" #include "src/smpi/include/private.hpp" #include diff --git a/src/instr/instr_paje_types.cpp b/src/instr/instr_paje_types.cpp index d5658efb7d..1e4c912f2e 100644 --- a/src/instr/instr_paje_types.cpp +++ b/src/instr/instr_paje_types.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ void VariableType::instr_event(double now, double delta, const char* resource, d // create a key considering the resource and variable, and check if key exists in the global map: // if it doesn't, set the variable to zero. if (static std::set> platform_variables; - platform_variables.emplace(std::string(resource) + get_name()).second) + platform_variables.emplace(resource + get_name()).second) set_event(now, 0); add_event(now, value); diff --git a/src/instr/instr_paje_types.hpp b/src/instr/instr_paje_types.hpp index ac914dbcd5..bdb16d4819 100644 --- a/src/instr/instr_paje_types.hpp +++ b/src/instr/instr_paje_types.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/instr/instr_paje_values.hpp b/src/instr/instr_paje_values.hpp index 045a829615..b080129af5 100644 --- a/src/instr/instr_paje_values.hpp +++ b/src/instr/instr_paje_values.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/instr/instr_platform.cpp b/src/instr/instr_platform.cpp index 0db7a143c4..f7cbcc9dca 100644 --- a/src/instr/instr_platform.cpp +++ b/src/instr/instr_platform.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,9 +14,9 @@ #include #include "src/instr/instr_private.hpp" +#include "src/kernel/activity/ExecImpl.hpp" #include "src/kernel/resource/CpuImpl.hpp" #include "src/kernel/resource/NetworkModel.hpp" -#include "src/surf/surf_interface.hpp" #include @@ -24,7 +24,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_routing, instr, "Tracing platform hierarch std::string instr_pid(simgrid::s4u::Actor const& proc) { - return std::string(proc.get_name()) + "-" + std::to_string(proc.get_pid()); + return proc.get_name() + "-" + std::to_string(proc.get_pid()); } static simgrid::instr::Container* lowestCommonAncestor(const simgrid::instr::Container* a1, @@ -142,10 +142,10 @@ static void recursiveNewVariableType(const std::string& new_typename, const std: simgrid::instr::Type* root) { if (root->get_name() == "HOST" || root->get_name() == "VM") - root->by_name_or_create(std::string("p") + new_typename, color); + root->by_name_or_create("p" + new_typename, color); if (root->get_name() == "LINK") - root->by_name_or_create(std::string("b") + new_typename, color); + root->by_name_or_create("b" + new_typename, color); for (auto const& [_, child] : root->get_children()) { recursiveNewVariableType(new_typename, color, child.get()); @@ -348,6 +348,15 @@ static void on_host_creation(s4u::Host const& host) root->get_type()->by_name_or_create("MIGRATE_LINK", mpi, mpi); mpi->by_name_or_create("MIGRATE_STATE"); } + + if (TRACE_actor_is_enabled()) { + auto* host_type = container->get_type(); + auto* state = host_type->by_name_or_create("HOST_STATE"); + state->set_calling_container(container); + state->add_entity_value("receive", "1 0 0"); + state->add_entity_value("send", "0 0 1"); + state->add_entity_value("execute", "0 1 1"); + } } static void on_action_state_change(kernel::resource::Action const& action, @@ -363,12 +372,17 @@ static void on_action_state_change(kernel::resource::Action const& action, resource_set_utilization("HOST", "speed_used", cpu->get_cname(), action.get_category(), value, action.get_last_update(), simgrid_get_clock() - action.get_last_update()); - if (const auto* link = dynamic_cast(resource)) + else if (const auto* link = dynamic_cast(resource)) resource_set_utilization("LINK", "bandwidth_used", link->get_cname(), action.get_category(), value, action.get_last_update(), simgrid_get_clock() - action.get_last_update()); } } +static void on_activity_suspend_resume(s4u::Activity const& activity) +{ + on_action_state_change(*activity.get_impl()->model_action_, /*ignored*/ kernel::resource::Action::State::STARTED); +} + static void on_platform_created() { currentContainer.clear(); @@ -450,9 +464,11 @@ void define_callbacks() s4u::Link::on_bandwidth_change_cb([](s4u::Link const& link) { Container::by_name(link.get_name()) ->get_variable("bandwidth") - ->set_event(simgrid_get_clock(), sg_bandwidth_factor * link.get_bandwidth()); + ->set_event( + simgrid_get_clock(), + static_cast(link.get_impl()->get_model())->get_bandwidth_factor() * + link.get_bandwidth()); }); - s4u::NetZone::on_seal_cb([](s4u::NetZone const& /*netzone*/) { currentContainer.pop_back(); }); kernel::routing::NetPoint::on_creation.connect([](kernel::routing::NetPoint const& netpoint) { if (netpoint.is_router()) new RouterContainer(netpoint.get_name(), currentContainer.back()); @@ -461,14 +477,15 @@ void define_callbacks() s4u::NetZone::on_creation_cb(on_netzone_creation); - kernel::resource::CpuAction::on_state_change.connect(on_action_state_change); + s4u::Host::on_exec_state_change_cb(on_action_state_change); s4u::Link::on_communication_state_change_cb(on_action_state_change); + s4u::Exec::on_suspend_cb(on_activity_suspend_resume); + s4u::Exec::on_resume_cb(on_activity_suspend_resume); if (TRACE_actor_is_enabled()) { s4u::Actor::on_creation_cb(on_actor_creation); s4u::Actor::on_destruction_cb([](s4u::Actor const& actor) { - auto container = Container::by_name_or_null(instr_pid(actor)); - if (container != nullptr) + if (auto* container = Container::by_name_or_null(instr_pid(actor))) container->remove_from_parent(); }); s4u::Actor::on_suspend_cb([](s4u::Actor const& actor) { @@ -481,11 +498,38 @@ void define_callbacks() }); s4u::Actor::on_wake_up_cb( [](s4u::Actor const& actor) { Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->pop_event(); }); - s4u::Exec::on_start_cb([](s4u::Exec const&) { - Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->push_event("execute"); + + s4u::Exec::on_start_cb([](s4u::Exec const& e) { + std::string pid = instr_pid(*s4u::Actor::self()); + if (pid == "-0") //Exec is launched directly by Maestro, use the host as container + Container::by_name(e.get_host()->get_name())->get_state("HOST_STATE")->push_event("execute"); + else + Container::by_name(pid)->get_state("ACTOR_STATE")->push_event("execute"); }); - s4u::Activity::on_completion_cb([](const s4u::Activity&) { - Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->pop_event(); + + s4u::Exec::on_completion_cb([](const s4u::Exec& e) { + std::string pid = instr_pid(*s4u::Actor::self()); + if (pid == "-0") //Exec is launched directly by Maestro, use the host as container + Container::by_name(e.get_host()->get_name())->get_state("HOST_STATE")->pop_event(); + else + Container::by_name(pid)->get_state("ACTOR_STATE")->pop_event(); + }); + + s4u::Comm::on_completion_cb([](const s4u::Comm& c) { + if (c.get_sender()) { + Container::by_name(instr_pid(*c.get_sender()))->get_state("ACTOR_STATE")->pop_event(); + Container::by_name(instr_pid(*c.get_receiver()))->get_state("ACTOR_STATE")->pop_event(); + } else { + Container::by_name(c.get_source()->get_name())->get_state("HOST_STATE")->pop_event(); + Container::by_name(c.get_destination()->get_name())->get_state("HOST_STATE")->pop_event(); + } + }); + s4u::Comm::on_start_cb([](s4u::Comm const& c) { + std::string pid = instr_pid(*s4u::Actor::self()); + if (pid == "-0") { //Comm is launched directly by Maestro, use the host as container + Container::by_name(c.get_source()->get_name())->get_state("HOST_STATE")->push_event("start"); + Container::by_name(c.get_destination()->get_name())->get_state("HOST_STATE")->push_event("start"); + } }); s4u::Comm::on_send_cb([](s4u::Comm const&) { Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->push_event("send"); @@ -498,14 +542,12 @@ void define_callbacks() if (TRACE_smpi_is_enabled() && TRACE_smpi_is_computing()) { s4u::Exec::on_start_cb([](s4u::Exec const& exec) { - Container::by_name(std::string("rank-") + std::to_string(s4u::Actor::self()->get_pid())) + Container::by_name("rank-" + std::to_string(s4u::Actor::self()->get_pid())) ->get_state("MPI_STATE") ->push_event("computing", new CpuTIData("compute", exec.get_cost())); }); - s4u::Activity::on_completion_cb([](const s4u::Activity&) { - Container::by_name(std::string("rank-") + std::to_string(s4u::Actor::self()->get_pid())) - ->get_state("MPI_STATE") - ->pop_event(); + s4u::Exec::on_completion_cb([](const s4u::Exec&) { + Container::by_name("rank-" + std::to_string(s4u::Actor::self()->get_pid()))->get_state("MPI_STATE")->pop_event(); }); } diff --git a/src/instr/instr_private.hpp b/src/instr/instr_private.hpp index e3116555c8..091bbccb9e 100644 --- a/src/instr/instr_private.hpp +++ b/src/instr/instr_private.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -40,7 +40,6 @@ void dump_header(bool basic, bool display_sizes); */ enum class TraceFormat { Paje, /*TimeIndependent*/ Ti }; extern TraceFormat trace_format; -extern int trace_precision; extern double last_timestamp_to_dump; void init(); @@ -68,20 +67,20 @@ public: // NoOpTI: init, finalize, test, wait, barrier class NoOpTIData : public TIData { - explicit NoOpTIData(const std::string&, double); // disallow this constructor inherited from TIData - public: using TIData::TIData; + explicit NoOpTIData(const std::string&, double) = delete; // disallow this constructor inherited from TIData + std::string print() override { return get_name(); } std::string display_size() override { return "NA"; } }; // CPuTI: compute, sleep (+ waitAny and waitall out of laziness) class CpuTIData : public TIData { - explicit CpuTIData(const std::string&); // disallow this constructor inherited from TIData - public: using TIData::TIData; + explicit CpuTIData(const std::string&) = delete; // disallow this constructor inherited from TIData + std::string print() override { std::stringstream stream; @@ -233,12 +232,6 @@ public: XBT_PRIVATE std::string instr_pid(simgrid::s4u::Actor const& proc); -extern XBT_PRIVATE std::set> created_categories; -extern XBT_PRIVATE std::set> declared_marks; -extern XBT_PRIVATE std::set> user_host_variables; -extern XBT_PRIVATE std::set> user_vm_variables; -extern XBT_PRIVATE std::set> user_link_variables; - /* from instr_config.c */ XBT_PRIVATE bool TRACE_needs_platform(); XBT_PRIVATE bool TRACE_is_enabled(); diff --git a/src/instr/instr_resource_utilization.cpp b/src/instr/instr_resource_utilization.cpp index 3b8a2f97ab..8af9cc2dbb 100644 --- a/src/instr/instr_resource_utilization.cpp +++ b/src/instr/instr_resource_utilization.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/instr/instr_smpi.hpp b/src/instr/instr_smpi.hpp index ec09a78133..d0633285e8 100644 --- a/src/instr/instr_smpi.hpp +++ b/src/instr/instr_smpi.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -24,6 +24,7 @@ XBT_PRIVATE void TRACE_smpi_init(aid_t pid, const std::string& calling_func); class smpi_trace_call_location_t { public: + std::string func_call; std::string filename; int linenumber = 0; @@ -35,6 +36,8 @@ public: return previous_filename + ':' + std::to_string(previous_linenumber) + ':' + filename + ':' + std::to_string(linenumber); } + + std::string get_call_location() const { return filename + ":" + std::to_string(linenumber) + ":" + func_call + "()"; } }; #endif diff --git a/src/internal_config.h.in b/src/internal_config.h.in index 2479af4c45..59761d5c5b 100644 --- a/src/internal_config.h.in +++ b/src/internal_config.h.in @@ -3,7 +3,7 @@ /* Warning: The file internal_config.h is AUTOMATICALLY GENERATED by Cmake. * Edit the template instead: src/internal_config.h.in */ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -48,6 +48,7 @@ /* Variables for the raw contexts (to select the right assembly code) */ #cmakedefine01 SIMGRID_PROCESSOR_i686 #cmakedefine01 SIMGRID_PROCESSOR_x86_64 +#cmakedefine01 SIMGRID_PROCESSOR_arm64 /* Variables for the SysV contexts */ @sg_makecontext_stack_addr@ @@ -58,8 +59,6 @@ #define PTH_STACKGROWTH @PTH_STACKGROWTH@ /* MC variables */ -/* Did we compile mmalloc in? */ -#cmakedefine01 HAVE_MMALLOC /* process_vm_readv: transfer data between process address spaces */ #cmakedefine01 HAVE_PROCESS_VM_READV @@ -81,12 +80,8 @@ /* Other function checks */ /* Function dlfunc */ #cmakedefine01 HAVE_DLFUNC -/* Function mmap */ -#cmakedefine01 HAVE_MMAP /* Function mremap */ #cmakedefine01 HAVE_MREMAP -/* Function sysconf */ -#cmakedefine01 HAVE_SYSCONF /* Function vasprintf */ #cmakedefine01 HAVE_VASPRINTF @@ -96,3 +91,5 @@ /* The boost_stacktrace_backtrace library */ #cmakedefine01 HAVE_BOOST_STACKTRACE_BACKTRACE /* preferred */ #cmakedefine01 HAVE_BOOST_STACKTRACE_ADDR2LINE /* fallback */ +/* Whether the ns-3 library has GetNextEventTime */ +#cmakedefine01 SIMGRID_HAVE_NS3_GetNextEventTime diff --git a/src/kernel/EngineImpl.cpp b/src/kernel/EngineImpl.cpp index 00d0f16557..8b7b60a0cd 100644 --- a/src/kernel/EngineImpl.cpp +++ b/src/kernel/EngineImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,28 +8,28 @@ #include #include #include -#include -#include "mc/mc.h" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" #include "src/kernel/resource/profile/Profile.hpp" +#include "src/kernel/xml/platf.hpp" +#include "src/mc/mc.h" +#include "src/mc/mc_config.hpp" #include "src/mc/mc_record.hpp" #include "src/mc/mc_replay.hpp" +#include "src/simgrid/math_utils.h" +#include "src/simgrid/sg_config.hpp" #include "src/smpi/include/smpi_actor.hpp" -#include "src/surf/xml/platf.hpp" -#include "xbt/module.h" -#include "xbt/xbt_modinter.h" /* whether initialization was already done */ - -#include -#ifndef _WIN32 -#include -#endif /* _WIN32 */ #if SIMGRID_HAVE_MC #include "src/mc/remote/AppSide.hpp" #endif +#include "xbt/log.hpp" + +#include +#include + XBT_LOG_NEW_DEFAULT_CATEGORY(ker_engine, "Logging specific to Engine (kernel)"); namespace simgrid::kernel { @@ -68,7 +68,7 @@ static inline std::string contexts_list() } static config::Flag context_factory_name("contexts/factory", - (std::string("Possible values: ") + contexts_list()).c_str(), + ("Possible values: " + contexts_list()).c_str(), context_factories.begin()->first); } // namespace simgrid::kernel @@ -85,7 +85,6 @@ XBT_ATTRIB_NORETURN static void inthandler(int) exit(1); } -#ifndef _WIN32 static void segvhandler(int signum, siginfo_t* siginfo, void* /*context*/) { if ((siginfo->si_signo == SIGSEGV && siginfo->si_code == SEGV_ACCERR) || siginfo->si_signo == SIGBUS) { @@ -102,7 +101,7 @@ static void segvhandler(int signum, siginfo_t* siginfo, void* /*context*/) "If you think you've found a bug in SimGrid, please report it along with a\n" "Minimal Working Example (MWE) reproducing your problem and a full backtrace\n" "of the fault captured with gdb or valgrind.\n", - simgrid::kernel::context::stack_size / 1024); + simgrid::kernel::context::Context::stack_size / 1024); } else if (siginfo->si_signo == SIGSEGV) { fprintf(stderr, "Segmentation fault.\n"); #if HAVE_SMPI @@ -118,45 +117,31 @@ static void segvhandler(int signum, siginfo_t* siginfo, void* /*context*/) std::raise(signum); } -/** - * Install signal handler for SIGSEGV. Check that nobody has already installed - * its own handler. For example, the Java VM does this. - */ -static void install_segvhandler() +static void install_signal_handlers() { - stack_t old_stack; + /* Install signal handler for SIGINT */ + std::signal(SIGINT, inthandler); - if (simgrid::kernel::context::Context::install_sigsegv_stack(&old_stack, true) == -1) { + /* Install signal handler for SIGSEGV */ + if (simgrid::kernel::context::Context::install_sigsegv_stack(true) == -1) { XBT_WARN("Failed to register alternate signal stack: %s", strerror(errno)); return; } - if (not(old_stack.ss_flags & SS_DISABLE)) { - XBT_DEBUG("An alternate stack was already installed (sp=%p, size=%zu, flags=%x). Restore it.", old_stack.ss_sp, - old_stack.ss_size, (unsigned)old_stack.ss_flags); - sigaltstack(&old_stack, nullptr); - } struct sigaction action; - struct sigaction old_action; action.sa_sigaction = &segvhandler; action.sa_flags = SA_ONSTACK | SA_RESETHAND | SA_SIGINFO; sigemptyset(&action.sa_mask); /* Linux tend to raise only SIGSEGV where other systems also raise SIGBUS on severe error */ for (int sig : {SIGSEGV, SIGBUS}) { - if (sigaction(sig, &action, &old_action) == -1) { + if (sigaction(sig, &action, nullptr) == -1) XBT_WARN("Failed to register signal handler for signal %d: %s", sig, strerror(errno)); - continue; - } - if ((old_action.sa_flags & SA_SIGINFO) || old_action.sa_handler != SIG_DFL) { - XBT_DEBUG("A signal handler was already installed for signal %d (%p). Restore it.", sig, - (old_action.sa_flags & SA_SIGINFO) ? (void*)old_action.sa_sigaction : (void*)old_action.sa_handler); - sigaction(sig, &old_action, nullptr); - } } } -#endif /* _WIN32 */ +static simgrid::config::Flag cfg_dbg_clean_atexit{ + "debug/clean-atexit", "Whether to cleanup SimGrid at exit. Disable it if your code segfaults after its end.", true}; namespace simgrid::kernel { @@ -170,6 +155,9 @@ EngineImpl::~EngineImpl() for (auto const& [_, mailbox] : mailboxes_) delete mailbox; + for (auto const& [_, queue] : mqueues_) + delete queue; + /* Kill all actors (but maestro) */ maestro_->kill_all(); run_all_actors(); @@ -178,10 +166,6 @@ EngineImpl::~EngineImpl() delete maestro_; delete context_factory_; - /* Free the remaining data structures */ -#if SIMGRID_HAVE_MC - xbt_dynar_free(&actors_vector_); -#endif /* clear models before freeing handle, network models can use external callback defined in the handle */ models_prio_.clear(); } @@ -195,29 +179,25 @@ void EngineImpl::initialize(int* argc, char** argv) // The communication initialization is done ASAP, as we need to get some init parameters from the MC for different // layers. But instance_ needs to be created, as we send the address of some of its fields to the MC that wants to // read them directly. - simgrid::mc::AppSide::initialize(actors_vector_); + simgrid::mc::AppSide::get(); // To ensure that it's initialized #endif - if (xbt_initialized == 0) { - xbt_init(argc, argv); + if (static bool inited = false; not inited) { + inited = true; + xbt_log_init(argc, argv); + + simgrid::xbt::install_exception_handler(); sg_config_init(argc, argv); } - instance_->context_mod_init(); - - /* Prepare to display some more info when dying on Ctrl-C pressing */ - std::signal(SIGINT, inthandler); + cmdline_.assign(argv, argv + *argc); -#ifndef _WIN32 - install_segvhandler(); -#endif + instance_->context_mod_init(); - /* register a function to be called by SURF after the environment creation */ - sg_platf_init(); - s4u::Engine::on_platform_created_cb([this]() { this->presolve(); }); + install_signal_handlers(); - if (config::get_value("debug/clean-atexit")) + if (cfg_dbg_clean_atexit) atexit(shutdown); } @@ -242,11 +222,6 @@ void EngineImpl::context_mod_init() const } #endif - /* select the context factory to use to create the contexts */ - if (context::ContextFactory::initializer) { // Give Java a chance to hijack the factory mechanism - instance_->set_context_factory(context::ContextFactory::initializer()); - return; - } /* use the factory specified by --cfg=contexts/factory:value */ for (auto const& [factory_name, factory] : context_factories) if (context_factory_name == factory_name) { @@ -272,7 +247,7 @@ void EngineImpl::context_mod_init() const XBT_ERROR(" (boost was disabled at compilation time on this machine -- check configure logs for details. Did you " "install the libboost-context-dev package?)"); #endif - XBT_ERROR(" thread: slow portability layer using pthreads as provided by gcc"); + XBT_ERROR(" thread: slow portability layer using standard threads as provided by libstdc"); xbt_die("Please use a valid factory."); } } @@ -306,7 +281,7 @@ void EngineImpl::shutdown() } tmgr_finalize(); - sg_platf_exit(); + sg_platf_parser_finalize(); delete instance_; instance_ = nullptr; @@ -328,9 +303,6 @@ void EngineImpl::load_platform(const std::string& platf) { double start = xbt_os_time(); if (boost::algorithm::ends_with(platf, ".so") || boost::algorithm::ends_with(platf, ".dylib")) { -#ifdef _WIN32 - xbt_die("loading platform through shared library isn't supported on windows"); -#else void* handle = dlopen(platf.c_str(), RTLD_LAZY); xbt_assert(handle, "Impossible to open platform file: %s", platf.c_str()); platf_handle_ = std::unique_ptr>(handle, dlclose); @@ -339,7 +311,6 @@ void EngineImpl::load_platform(const std::string& platf) const char* dlsym_error = dlerror(); xbt_assert(not dlsym_error, "Error: %s", dlsym_error); callable(*simgrid::s4u::Engine::get_instance()); -#endif /* _WIN32 */ } else { parse_platform_file(platf); } @@ -350,12 +321,11 @@ void EngineImpl::load_platform(const std::string& platf) void EngineImpl::load_deployment(const std::string& file) const { - sg_platf_exit(); - sg_platf_init(); + sg_platf_parser_finalize(); - surf_parse_open(file); - surf_parse(); - surf_parse_close(); + simgrid_parse_open(file); + simgrid_parse(false); + simgrid_parse_close(); } void EngineImpl::register_function(const std::string& name, const actor::ActorCodeFactory& code) @@ -381,7 +351,7 @@ void EngineImpl::add_model(std::shared_ptr model, const std::ve models_prio_[model_name] = std::move(model); } -/** Wake up all actors waiting for a Surf action to finish */ +/** Wake up all actors waiting for an action to finish */ void EngineImpl::handle_ended_actions() const { for (auto const& model : models_) { @@ -389,24 +359,27 @@ void EngineImpl::handle_ended_actions() const while (auto* action = model->extract_failed_action()) { XBT_DEBUG(" Handling Action %p", action); if (action->get_activity() != nullptr) { // Skip vcpu actions + activity::ActivityImplPtr activity(action->get_activity()); // Action failures are not automatically reported when the action is started by maestro (as in SimDAG) - if (action->get_activity()->get_actor() == maestro_) - action->get_activity()->get_iface()->complete(s4u::Activity::State::FAILED); + if (activity->get_actor() == maestro_) + activity->get_iface()->complete(s4u::Activity::State::FAILED); - activity::ActivityImplPtr(action->get_activity())->post(); + activity->finish(); } } XBT_DEBUG("Handling the terminated actions (if any)"); while (auto* action = model->extract_done_action()) { XBT_DEBUG(" Handling Action %p", action); if (action->get_activity() != nullptr) { + activity::ActivityImplPtr activity(action->get_activity()); + // Action termination are not automatically reported when the action is started by maestro (as in SimDAG) - action->get_activity()->set_finish_time(action->get_finish_time()); + activity->set_finish_time(action->get_finish_time()); - if (action->get_activity()->get_actor() == maestro_) - action->get_activity()->get_iface()->complete(s4u::Activity::State::FINISHED); + if (activity->get_actor() == maestro_) + activity->get_iface()->complete(s4u::Activity::State::FINISHED); - activity::ActivityImplPtr(action->get_activity())->post(); + activity->finish(); } } } @@ -483,6 +456,9 @@ void EngineImpl::display_all_actor_status() const if (boost::dynamic_pointer_cast(actor->waiting_synchro_) != nullptr) synchro_description = "communication"; + if (boost::dynamic_pointer_cast(actor->waiting_synchro_) != nullptr) + synchro_description = "message"; + if (boost::dynamic_pointer_cast(actor->waiting_synchro_) != nullptr) synchro_description = "sleeping"; @@ -492,36 +468,19 @@ void EngineImpl::display_all_actor_status() const if (boost::dynamic_pointer_cast(actor->waiting_synchro_) != nullptr) synchro_description = "I/O"; - XBT_INFO("Actor %ld (%s@%s): waiting for %s activity %#zx (%s) in state %s to finish", actor->get_pid(), + XBT_INFO("Actor %ld (%s@%s): waiting for %s activity %#zx (%s) in state %s to finish %s", actor->get_pid(), actor->get_cname(), actor->get_host()->get_cname(), synchro_description, (xbt_log_no_loc ? (size_t)0xDEADBEEF : (size_t)actor->waiting_synchro_.get()), - actor->waiting_synchro_->get_cname(), actor->waiting_synchro_->get_state_str()); + actor->waiting_synchro_->get_cname(), actor->waiting_synchro_->get_state_str(), + (actor->simcall_.observer_ != nullptr && not xbt_log_no_loc + ? actor->simcall_.observer_->to_string().c_str() + : "")); } else { XBT_INFO("Actor %ld (%s@%s) simcall %s", actor->get_pid(), actor->get_cname(), actor->get_host()->get_cname(), - actor->simcall_.get_cname()); - } - } -} - -void EngineImpl::presolve() const -{ - XBT_DEBUG("Consume all trace events occurring before the starting time."); - double next_event_date; - while ((next_event_date = profile::future_evt_set.next_date()) != -1.0) { - if (next_event_date > now_) - break; - - double value = -1.0; - resource::Resource* resource = nullptr; - while (auto* event = profile::future_evt_set.pop_leq(next_event_date, &value, &resource)) { - if (value >= 0) - resource->apply_event(event, value); + (actor->simcall_.observer_ != nullptr ? actor->simcall_.observer_->to_string().c_str() + : actor->simcall_.get_cname())); } } - - XBT_DEBUG("Set every models in the right state by updating them to 0."); - for (auto const& model : models_) - model->update_actions_state(now_, 0.0); } double EngineImpl::solve(double max_date) const @@ -537,10 +496,10 @@ double EngineImpl::solve(double max_date) const } XBT_DEBUG("Looking for next event in all models"); - for (auto model : models_) { - if (not model->next_occurring_event_is_idempotent()) { + for (auto* model : models_) { + if (not model->next_occurring_event_is_idempotent()) continue; - } + double next_event = model->next_occurring_event(now_); if ((time_delta < 0.0 || next_event < time_delta) && next_event >= 0.0) { time_delta = next_event; @@ -555,7 +514,7 @@ double EngineImpl::solve(double max_date) const double next_event_date = profile::future_evt_set.next_date(); XBT_DEBUG("Next TRACE event: %f", next_event_date); - for (auto model : models_) { + for (auto* model : models_) { /* Skip all idempotent models, they were already treated above * NS3 is the one to handled here */ if (model->next_occurring_event_is_idempotent()) @@ -587,13 +546,12 @@ double EngineImpl::solve(double max_date) const while (auto* event = profile::future_evt_set.pop_leq(next_event_date, &value, &resource)) { if(value<0) continue; - if (resource->is_used() || (watched_hosts().find(resource->get_cname()) != watched_hosts().end())) { + if (resource->is_used()) { time_delta = next_event_date - now_; XBT_DEBUG("This event invalidates the next_occurring_event() computation of models. Next event set to %f", time_delta); } - // FIXME: I'm too lame to update now_ live, so I change it and restore it so that the real update with surf_min - // will work + // FIXME: I'm too lame to update now_ live, so I change it and restore it so that the real update works double round_start = now_; now_ = next_event_date; /* update state of the corresponding resource to the new value. Does not touch lmm. @@ -632,6 +590,9 @@ void EngineImpl::run(double max_date) { seal_platform(); + XBT_DEBUG("Running the main loop until t=%.3f in mode %s", max_date, + to_c_str(simgrid::mc::get_model_checking_mode())); + if (MC_is_active()) { #if SIMGRID_HAVE_MC mc::AppSide::get()->main_loop(); diff --git a/src/kernel/EngineImpl.hpp b/src/kernel/EngineImpl.hpp index 6ea9106128..149c0c2a36 100644 --- a/src/kernel/EngineImpl.hpp +++ b/src/kernel/EngineImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -16,10 +16,10 @@ #include "src/kernel/activity/ExecImpl.hpp" #include "src/kernel/activity/IoImpl.hpp" #include "src/kernel/activity/MailboxImpl.hpp" +#include "src/kernel/activity/MessageQueueImpl.hpp" #include "src/kernel/activity/SleepImpl.hpp" #include "src/kernel/activity/Synchro.hpp" #include "src/kernel/actor/ActorImpl.hpp" -#include "src/kernel/resource/SplitDuplexLinkImpl.hpp" #include #include @@ -34,6 +34,7 @@ namespace simgrid::kernel { class EngineImpl { std::unordered_map netpoints_; std::unordered_map mailboxes_; + std::unordered_map mqueues_; std::unordered_map registered_functions; // Maps function names to actor code actor::ActorCodeFactory default_function; // Function to use as a fallback when the provided name matches nothing @@ -48,16 +49,6 @@ class EngineImpl { boost::intrusive::member_hook, &actor::ActorImpl::kernel_destroy_list_hook>> actors_to_destroy_; -#if SIMGRID_HAVE_MC - /* MCer cannot read members actor_list_ above in the remote process, so we copy the info it needs in a dynar. - * FIXME: This is supposed to be a temporary hack. - * A better solution would be to change the split between MCer and MCed, where the responsibility - * to compute the list of the enabled transitions goes to the MCed. - * That way, the MCer would not need to have the list of actors on its side. - * These info could be published by the MCed to the MCer in a way inspired of vd.so - */ - xbt_dynar_t actors_vector_ = xbt_dynar_new(sizeof(actor::ActorImpl*), nullptr); -#endif static double now_; static EngineImpl* instance_; @@ -67,6 +58,8 @@ class EngineImpl { std::unique_ptr> platf_handle_; //!< handle for platform library friend s4u::Engine; + std::vector cmdline_; // Copy of the argv we got (including argv[0]) + public: EngineImpl() = default; @@ -79,6 +72,10 @@ public: #endif void initialize(int* argc, char** argv); + const std::vector& get_cmdline() const + { + return cmdline_; + } void load_platform(const std::string& platf); void load_deployment(const std::string& file) const; void seal_platform() const; @@ -107,8 +104,14 @@ public: const std::vector& get_all_models() const { return models_; } static bool has_instance() { return s4u::Engine::has_instance(); } - static EngineImpl* get_instance() { return s4u::Engine::get_instance()->pimpl; } - static EngineImpl* get_instance(int* argc, char** argv) { return s4u::Engine::get_instance(argc, argv)->pimpl; } + static EngineImpl* get_instance() + { + return s4u::Engine::get_instance()->pimpl_; + } + static EngineImpl* get_instance(int* argc, char** argv) + { + return s4u::Engine::get_instance(argc, argv)->pimpl_; + } actor::ActorCodeFactory get_function(const std::string& name) { @@ -136,11 +139,6 @@ public: void add_actor(aid_t pid, actor::ActorImpl* actor) { actor_list_[pid] = actor; } void remove_actor(aid_t pid) { actor_list_.erase(pid); } -#if SIMGRID_HAVE_MC - void reset_actor_dynar() { xbt_dynar_reset(actors_vector_); } - void add_actor_to_dynar(actor::ActorImpl* actor) { xbt_dynar_push_as(actors_vector_, actor::ActorImpl*, actor); } -#endif - const std::map& get_actor_list() const { return actor_list_; } const std::vector& get_actors_to_run() const { return actors_to_run_; } const std::vector& get_actors_that_ran() const { return actors_that_ran_; } @@ -155,10 +153,6 @@ public: void display_all_actor_status() const; void run_all_actors(); - /* @brief Finish simulation initialization - * This function must be called before the first call to solve() - */ - void presolve() const; /** @brief Performs a part of the simulation * @param max_date Maximum date to update the simulation to, or -1 * @return the elapsed time, or -1.0 if no event could be executed diff --git a/src/kernel/activity/ActivityImpl.cpp b/src/kernel/activity/ActivityImpl.cpp index c75799ab3f..f1a9859319 100644 --- a/src/kernel/activity/ActivityImpl.cpp +++ b/src/kernel/activity/ActivityImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -44,15 +44,15 @@ void ActivityImpl::unregister_simcall(actor::Simcall* simcall) void ActivityImpl::clean_action() { - if (surf_action_) { - surf_action_->unref(); - surf_action_ = nullptr; + if (model_action_) { + model_action_->unref(); + model_action_ = nullptr; } } double ActivityImpl::get_remaining() const { - return surf_action_ ? surf_action_->get_remains() : 0; + return model_action_ ? model_action_->get_remains() : 0; } const char* ActivityImpl::get_state_str() const @@ -108,6 +108,10 @@ void ActivityImpl::wait_for(actor::ActorImpl* issuer, double timeout) if (state_ != State::WAITING && state_ != State::RUNNING) { finish(); } else { + /* As Messages in Message Queues are virtually instantaneous, we do not need a timeout */ + /* Or maybe we do, and will have to implement a specific way to handle them is need arises */ + if (dynamic_cast(this) != nullptr) + return; /* we need a sleep action (even when the timeout is infinite) to be notified of host failures */ /* Comms handle that a bit differently of the other activities */ if (auto* comm = dynamic_cast(this)) { @@ -115,9 +119,9 @@ void ActivityImpl::wait_for(actor::ActorImpl* issuer, double timeout) sleep_action->set_activity(comm); if (issuer == comm->src_actor_) - comm->src_timeout_ = sleep_action; + comm->src_timeout_.reset(sleep_action); else - comm->dst_timeout_ = sleep_action; + comm->dst_timeout_.reset(sleep_action); } else { SynchroImplPtr synchro(new SynchroImpl([this, issuer]() { this->unregister_simcall(&issuer->simcall_); @@ -140,12 +144,13 @@ void ActivityImpl::wait_any_for(actor::ActorImpl* issuer, const std::vector(issuer->simcall_.observer_); xbt_assert(observer != nullptr); xbt_assert(timeout <= 0.0, "Timeout not implemented for waitany in the model-checker"); - int idx = observer->get_value(); - auto* act = activities[idx]; - act->simcalls_.push_back(&issuer->simcall_); - observer->set_result(idx); - act->set_state(State::DONE); - act->finish(); + if (int idx = observer->get_value(); idx != -1) { + auto* act = activities.at(idx); + act->register_simcall(&issuer->simcall_); + observer->set_result(idx); + act->set_state(State::DONE); + act->finish(); + } return; } @@ -163,7 +168,7 @@ void ActivityImpl::wait_any_for(actor::ActorImpl* issuer, const std::vectorsimcalls_.push_back(&issuer->simcall_); + act->register_simcall(&issuer->simcall_); /* see if the synchro is already finished */ if (act->get_state() != State::WAITING && act->get_state() != State::RUNNING) { act->finish(); @@ -175,27 +180,27 @@ void ActivityImpl::wait_any_for(actor::ActorImpl* issuer, const std::vectorget_remains()); - surf_action_->suspend(); - s4u::Activity::on_suspended(*get_iface()); + XBT_VERB("This activity is suspended (remain: %f)", model_action_->get_remains()); + get_iface()->fire_on_suspend(); + get_iface()->fire_on_this_suspend(); + model_action_->suspend(); } void ActivityImpl::resume() { - if (surf_action_ == nullptr) + if (model_action_ == nullptr) return; - XBT_VERB("This activity is resumed (remain: %f)", surf_action_->get_remains()); - surf_action_->resume(); - s4u::Activity::on_resumed(*get_iface()); + XBT_VERB("This activity is resumed (remain: %f)", model_action_->get_remains()); + get_iface()->fire_on_resume(); + get_iface()->fire_on_this_resume(); + model_action_->resume(); } void ActivityImpl::cancel() { XBT_VERB("Activity %p is canceled", this); - if (surf_action_ != nullptr) - surf_action_->cancel(); + if (model_action_ != nullptr) + model_action_->cancel(); state_ = State::CANCELED; } @@ -235,4 +240,5 @@ void intrusive_ptr_release(ActivityImpl* activity) delete activity; } } + } // namespace simgrid::kernel::activity diff --git a/src/kernel/activity/ActivityImpl.hpp b/src/kernel/activity/ActivityImpl.hpp index f3dca0b2cc..cbabdcdc03 100644 --- a/src/kernel/activity/ActivityImpl.hpp +++ b/src/kernel/activity/ActivityImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,23 +6,23 @@ #ifndef SIMGRID_KERNEL_ACTIVITY_ACTIVITYIMPL_HPP #define SIMGRID_KERNEL_ACTIVITY_ACTIVITYIMPL_HPP -#include -#include -#include - #include "simgrid/forward.h" -#include +#include "simgrid/kernel/resource/Action.hpp" +#include "simgrid/simix.hpp" +#include "src/kernel/actor/Simcall.hpp" +#include "xbt/utility.hpp" #include -#include -#include +#include +#include +#include namespace simgrid::kernel::activity { XBT_DECLARE_ENUM_CLASS(State, WAITING, READY, RUNNING, DONE, CANCELED, FAILED, SRC_HOST_FAILURE, DST_HOST_FAILURE, TIMEOUT, SRC_TIMEOUT, DST_TIMEOUT, LINK_FAILURE); -class XBT_PUBLIC ActivityImpl { +class XBT_PUBLIC ActivityImpl : public kernel::actor::ObjectAccessSimcallItem { std::atomic_int_fast32_t refcount_{0}; std::string name_ = ""; actor::ActorImpl* actor_ = nullptr; @@ -35,8 +35,8 @@ public: virtual ~ActivityImpl(); ActivityImpl() = default; std::list simcalls_; /* List of simcalls waiting for this activity */ - s4u::Activity* piface_ = nullptr; - resource::Action* surf_action_ = nullptr; + s4u::Activity* piface_ = nullptr; + resource::Action* model_action_ = nullptr; /* The resource consumption in the used model */ protected: void inline set_name(std::string_view name) @@ -79,11 +79,8 @@ public: virtual void resume(); virtual void cancel(); - virtual void post() = 0; // Called by the main loop when the activity is marked as terminated or failed by its model. - // Setups the status, clean things up, and call finish() virtual void set_exception(actor::ActorImpl* issuer) = 0; // Raising exceptions and stuff - virtual void finish() = 0; // Unlock all simcalls blocked on that activity, either because it was marked as done by - // the model or because it terminated without waiting for the model + virtual void finish() = 0; // Setups the status, clean things up, unlock all simcalls blocked on that activity. s4u::Host* get_host() const { return hosts_.front(); } const std::vector& get_hosts() const { return hosts_; }; diff --git a/src/kernel/activity/BarrierImpl.cpp b/src/kernel/activity/BarrierImpl.cpp index b048eb8de6..7b6436e819 100644 --- a/src/kernel/activity/BarrierImpl.cpp +++ b/src/kernel/activity/BarrierImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -28,6 +28,7 @@ void BarrierAcquisitionImpl::wait_for(actor::ActorImpl* issuer, double timeout) // Already in the queue } } + void BarrierAcquisitionImpl::finish() { xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size()); diff --git a/src/kernel/activity/BarrierImpl.hpp b/src/kernel/activity/BarrierImpl.hpp index 7d72f6b6f7..c4dd9e03a6 100644 --- a/src/kernel/activity/BarrierImpl.hpp +++ b/src/kernel/activity/BarrierImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,6 +10,7 @@ #include "src/kernel/activity/ActivityImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SynchroObserver.hpp" +#include "xbt/string.hpp" namespace simgrid::kernel::activity { /** Barrier Acquisition: the act / process of acquiring the barrier. @@ -31,9 +32,6 @@ public: bool test(actor::ActorImpl* issuer = nullptr) override; void wait_for(actor::ActorImpl* issuer, double timeout) override; - void post() override - { /*no surf action*/ - } void finish() override; void set_exception(actor::ActorImpl* issuer) override { /* nothing to do */ diff --git a/src/kernel/activity/CommImpl.cpp b/src/kernel/activity/CommImpl.cpp index e0272554cc..f264993204 100644 --- a/src/kernel/activity/CommImpl.cpp +++ b/src/kernel/activity/CommImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,9 +8,6 @@ #include #include -#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v333) -#include - #include "src/kernel/EngineImpl.hpp" #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/activity/MailboxImpl.hpp" @@ -22,32 +19,17 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_network, kernel, "Kernel network-related synchronization"); -/******************************************************************************/ -/* SIMIX_comm_copy_data callbacks */ -/******************************************************************************/ -// XBT_ATTRIB_DEPRECATED_v333 -void SIMIX_comm_set_copy_data_callback(void (*callback)(simgrid::kernel::activity::CommImpl*, void*, size_t)) -{ - simgrid::kernel::activity::CommImpl::set_copy_data_callback(callback); -} - -// XBT_ATTRIB_DEPRECATED_v333 -void SIMIX_comm_copy_buffer_callback(simgrid::kernel::activity::CommImpl* comm, void* buff, size_t buff_size) -{ - simgrid::s4u::Comm::copy_buffer_callback(comm, buff, buff_size); -} - -// XBT_ATTRIB_DEPRECATED_v333 -void SIMIX_comm_copy_pointer_callback(simgrid::kernel::activity::CommImpl* comm, void* buff, size_t buff_size) -{ - simgrid::s4u::Comm::copy_pointer_callback(comm, buff, buff_size); -} - namespace simgrid::kernel::activity { -xbt::signal CommImpl::on_start; -xbt::signal CommImpl::on_completion; -std::function CommImpl::copy_data_callback_ = &s4u::Comm::copy_pointer_callback; +unsigned CommImpl::next_id_ = 0; + +std::function CommImpl::copy_data_callback_ = [](kernel::activity::CommImpl* comm, + void* buff, size_t buff_size) { + xbt_assert((buff_size == sizeof(void*)), "Cannot copy %zu bytes: must be sizeof(void*)", buff_size); + if (comm->dst_buff_ != nullptr) // get_async provided a buffer + *(void**)(comm->dst_buff_) = buff; + comm->payload_ = buff; // Setup what will be retrieved by s4u::Comm::get_payload() +}; void CommImpl::set_copy_data_callback(const std::function& callback) { @@ -112,7 +94,7 @@ CommImpl& CommImpl::set_dst_buff(unsigned char* buff, size_t* size) CommImpl& CommImpl::detach() { detached_ = true; - EngineImpl::get_instance()->get_maestro()->activities_.emplace_back(this); + EngineImpl::get_instance()->get_maestro()->activities_.insert(this); return *this; } @@ -120,7 +102,7 @@ CommImpl::~CommImpl() { XBT_DEBUG("Really free communication %p in state %s (detached = %d)", this, get_state_str(), detached_); - cleanup_surf(); + clean_action(); if (detached_ && get_state() != State::DONE) { /* the communication has failed and was detached: @@ -145,30 +127,29 @@ CommImpl* CommImpl::start() /* Getting the network_model from the origin host * Valid while we have a single network model, otherwise we would need to change this function to first get the - * routes and later create the respective surf actions */ + * routes and later create the respective model actions */ auto net_model = from_->get_netpoint()->get_englobing_zone()->get_network_model(); - surf_action_ = net_model->communicate(from_, to_, size_, rate_); - surf_action_->set_activity(this); - surf_action_->set_category(get_tracing_category()); - set_start_time(surf_action_->get_start_time()); + model_action_ = net_model->communicate(from_, to_, size_, rate_, false); + model_action_->set_activity(this); + model_action_->set_category(get_tracing_category()); + set_start_time(model_action_->get_start_time()); set_state(State::RUNNING); - on_start(*this); - XBT_DEBUG("Starting communication %p from '%s' to '%s' (surf_action: %p; state: %s)", this, from_->get_cname(), - to_->get_cname(), surf_action_, get_state_str()); + XBT_DEBUG("Starting communication %p from '%s' to '%s' (model action: %p; state: %s)", this, from_->get_cname(), + to_->get_cname(), model_action_, get_state_str()); /* If a link is failed, detect it immediately */ - if (surf_action_->get_state() == resource::Action::State::FAILED) { + if (model_action_->get_state() == resource::Action::State::FAILED) { XBT_DEBUG("Communication from '%s' to '%s' failed to start because of a link failure", from_->get_cname(), to_->get_cname()); set_state(State::LINK_FAILURE); - post(); + finish(); } else if ((src_actor_ != nullptr && src_actor_->is_suspended()) || (dst_actor_ != nullptr && dst_actor_->is_suspended())) { /* If any of the actor is suspended, create the synchro but stop its execution, - it will be restarted when the sender actor resume */ + it will be restarted when the sender actor resumes */ if (src_actor_->is_suspended()) XBT_DEBUG("The communication is suspended on startup because src (%s@%s) was suspended since it initiated the " "communication", @@ -178,7 +159,7 @@ CommImpl* CommImpl::start() "communication", dst_actor_->get_cname(), dst_actor_->get_host()->get_cname()); - surf_action_->suspend(); + model_action_->suspend(); } } @@ -187,7 +168,7 @@ CommImpl* CommImpl::start() std::vector CommImpl::get_traversed_links() const { - xbt_assert(get_state() != State::WAITING, "You cannot use %s() if your communication is not ready (%s)", __FUNCTION__, + xbt_assert(get_state() != State::WAITING, "You cannot use %s() if your communication is not ready (%s)", __func__, get_state_str()); std::vector vlinks; XBT_ATTRIB_UNUSED double res = 0; @@ -200,7 +181,7 @@ void CommImpl::copy_data() { size_t buff_size = src_buff_size_; /* If there is no data to copy then return */ - if (not src_buff_ || not dst_buff_ || copied_) + if (not src_buff_ || not dst_buff_size_ || copied_) return; XBT_DEBUG("Copying comm %p data from %s (%p) -> %s (%p) (%zu bytes)", this, @@ -269,7 +250,7 @@ ActivityImplPtr CommImpl::isend(actor::CommIsendSimcall* observer) other_comm->clean_fun = observer->get_clean_fun(); } else { other_comm->clean_fun = nullptr; - observer->get_issuer()->activities_.emplace_back(other_comm); + observer->get_issuer()->activities_.insert(other_comm); } /* Setup the communication synchro */ @@ -306,7 +287,7 @@ ActivityImplPtr CommImpl::irecv(actor::CommIrecvSimcall* observer) // find a match in the list of already received comms other_comm = mbox->find_matching_comm(CommImplType::SEND, observer->get_match_fun(), observer->get_payload(), this_synchro, /*done*/ true, /*remove_matching*/ true); - if (other_comm && other_comm->surf_action_ && other_comm->get_remaining() < 1e-12) { + if (other_comm && other_comm->model_action_ && other_comm->get_remaining() < 1e-12) { XBT_DEBUG("comm %p has been already sent, and is finished, destroy it", other_comm.get()); other_comm->set_state(State::DONE); other_comm->set_mailbox(nullptr); @@ -318,7 +299,7 @@ ActivityImplPtr CommImpl::irecv(actor::CommIrecvSimcall* observer) other_comm = std::move(this_synchro); mbox->push(other_comm); } - observer->get_issuer()->activities_.emplace_back(other_comm); + observer->get_issuer()->activities_.insert(other_comm); } } else { /* Prepare a comm describing us, so that it gets passed to the user-provided filter of other side */ @@ -339,7 +320,7 @@ ActivityImplPtr CommImpl::irecv(actor::CommIrecvSimcall* observer) other_comm->set_state(simgrid::kernel::activity::State::READY); } - observer->get_issuer()->activities_.emplace_back(other_comm); + observer->get_issuer()->activities_.insert(other_comm); } observer->set_comm(other_comm.get()); @@ -394,16 +375,16 @@ void CommImpl::wait_any_for(actor::ActorImpl* issuer, const std::vectorsuspend(); + if (model_action_) + model_action_->suspend(); /* if not created yet, the action will be suspended on creation, in CommImpl::start() */ } void CommImpl::resume() { /*FIXME: check what happen with the timeouts */ - if (surf_action_) - surf_action_->resume(); + if (model_action_) + model_action_->resume(); /* in the other case, the synchro were not really suspended yet, see CommImpl::suspend() and CommImpl::start() */ } @@ -415,58 +396,12 @@ void CommImpl::cancel() mbox_->remove(this); set_state(State::CANCELED); } - } else if (not MC_is_active() /* when running the MC there are no surf actions */ + } else if (not MC_is_active() /* when running the MC there are no model actions */ && not MC_record_replay_is_active() && (get_state() == State::READY || get_state() == State::RUNNING)) { - surf_action_->cancel(); - } -} - -/** @brief This is part of the cleanup process, probably an internal command */ -void CommImpl::cleanup_surf() -{ - clean_action(); - - if (src_timeout_) { - src_timeout_->unref(); - src_timeout_ = nullptr; - } - - if (dst_timeout_) { - dst_timeout_->unref(); - dst_timeout_ = nullptr; + model_action_->cancel(); } } -void CommImpl::post() -{ - on_completion(*this); - - /* Update synchro state */ - if (src_timeout_ && src_timeout_->get_state() == resource::Action::State::FINISHED) - set_state(State::SRC_TIMEOUT); - else if (dst_timeout_ && dst_timeout_->get_state() == resource::Action::State::FINISHED) - set_state(State::DST_TIMEOUT); - else if ((from_ && not from_->is_on()) || (src_timeout_ && src_timeout_->get_state() == resource::Action::State::FAILED)) - set_state(State::SRC_HOST_FAILURE); - else if ((to_ && not to_->is_on()) || (dst_timeout_ && dst_timeout_->get_state() == resource::Action::State::FAILED)) - set_state(State::DST_HOST_FAILURE); - else if (surf_action_ && surf_action_->get_state() == resource::Action::State::FAILED) { - set_state(State::LINK_FAILURE); - } else if (get_state() == State::RUNNING) { - xbt_assert(from_ && from_->is_on()); - xbt_assert(to_ && to_->is_on()); - set_state(State::DONE); - } - - XBT_DEBUG("CommImpl::post(): comm %p, state %s, src_proc %p, dst_proc %p, detached: %d", this, get_state_str(), - src_actor_.get(), dst_actor_.get(), detached_); - - /* destroy the surf actions associated with the Simix communication */ - cleanup_surf(); - - /* Answer all simcalls associated with the synchro */ - finish(); -} void CommImpl::set_exception(actor::ActorImpl* issuer) { switch (get_state()) { @@ -534,7 +469,39 @@ void CommImpl::set_exception(actor::ActorImpl* issuer) void CommImpl::finish() { - XBT_DEBUG("CommImpl::finish() in state %s", get_state_str()); + XBT_DEBUG("CommImpl::finish() comm %p, state %s, src_proc %p, dst_proc %p, detached: %d", this, get_state_str(), + src_actor_.get(), dst_actor_.get(), detached_); + + if (get_iface()) { + const auto& piface = static_cast(*get_iface()); + set_iface(nullptr); // reset iface to protect against multiple trigger of the on_completion signals + piface.fire_on_completion_for_real(); + piface.fire_on_this_completion_for_real(); + } + + /* Update synchro state */ + if (src_timeout_ && src_timeout_->get_state() == resource::Action::State::FINISHED) + set_state(State::SRC_TIMEOUT); + else if (dst_timeout_ && dst_timeout_->get_state() == resource::Action::State::FINISHED) + set_state(State::DST_TIMEOUT); + else if ((from_ && not from_->is_on()) || + (src_timeout_ && src_timeout_->get_state() == resource::Action::State::FAILED)) + set_state(State::SRC_HOST_FAILURE); + else if ((to_ && not to_->is_on()) || (dst_timeout_ && dst_timeout_->get_state() == resource::Action::State::FAILED)) + set_state(State::DST_HOST_FAILURE); + else if (model_action_ && model_action_->get_state() == resource::Action::State::FAILED) { + set_state(State::LINK_FAILURE); + } else if (get_state() == State::RUNNING) { + xbt_assert(from_ && from_->is_on()); + xbt_assert(to_ && to_->is_on()); + set_state(State::DONE); + } + src_timeout_ = nullptr; + dst_timeout_ = nullptr; + + /* destroy the model actions associated with the communication activity */ + clean_action(); + /* If the synchro is still in a rendez-vous point then remove from it */ if (mbox_) mbox_->remove(this); @@ -542,6 +509,9 @@ void CommImpl::finish() if (get_state() == State::DONE) copy_data(); + if (detached_) + EngineImpl::get_instance()->get_maestro()->activities_.erase(this); + while (not simcalls_.empty()) { actor::Simcall* simcall = simcalls_.front(); simcalls_.pop_front(); @@ -568,12 +538,12 @@ void CommImpl::finish() } simcall->issuer_->waiting_synchro_ = nullptr; - simcall->issuer_->activities_.remove(this); + simcall->issuer_->activities_.erase(this); if (detached_) { if (simcall->issuer_ != dst_actor_ && dst_actor_ != nullptr) - dst_actor_->activities_.remove(this); + dst_actor_->activities_.erase(this); if (simcall->issuer_ != src_actor_ && src_actor_ != nullptr) - src_actor_->activities_.remove(this); + src_actor_->activities_.erase(this); } } } diff --git a/src/kernel/activity/CommImpl.hpp b/src/kernel/activity/CommImpl.hpp index e9d2d7ca74..4f249a4bbf 100644 --- a/src/kernel/activity/CommImpl.hpp +++ b/src/kernel/activity/CommImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,9 +14,10 @@ namespace simgrid::kernel::activity { enum class CommImplType { SEND, RECEIVE }; +using timeout_action_type = std::unique_ptr>; + class XBT_PUBLIC CommImpl : public ActivityImpl_T { ~CommImpl() override; - void cleanup_surf(); static std::function copy_data_callback_; @@ -31,6 +32,9 @@ class XBT_PUBLIC CommImpl : public ActivityImpl_T { s4u::Host* to_ = nullptr; /* Otherwise, computed at start() time from the actors */ CommImplType type_ = CommImplType::SEND; /* Type of the communication (SEND or RECEIVE) */ + static unsigned next_id_; // Next ID to be given (for MC) + const unsigned id_ = ++next_id_; // ID of this comm (for MC) -- 0 as an ID denotes "invalid/unknown comm" + public: CommImpl() = default; @@ -51,7 +55,8 @@ public: double get_rate() const { return rate_; } MailboxImpl* get_mailbox() const { return mbox_; } - long get_mailbox_id() const { return mbox_id_; } + unsigned get_mailbox_id() const { return mbox_id_; } + unsigned get_id() const { return id_; } bool is_detached() const { return detached_; } bool is_assigned() const { return (to_ != nullptr && from_ != nullptr); } @@ -69,7 +74,6 @@ public: void suspend() override; void resume() override; void cancel() override; - void post() override; void set_exception(actor::ActorImpl* issuer) override; void finish() override; @@ -79,9 +83,10 @@ looking if a given communication matches my needs. For that, myself must match t expectations of the other side, too. See */ std::function copy_data_fun; - /* Surf action data */ - resource::Action* src_timeout_ = nullptr; /* Surf's actions to instrument the timeouts */ - resource::Action* dst_timeout_ = nullptr; /* Surf's actions to instrument the timeouts */ + /* Model actions */ + timeout_action_type src_timeout_{nullptr, [](resource::Action* a) { a->unref(); }}; /* timeout set by the sender */ + timeout_action_type dst_timeout_{nullptr, [](resource::Action* a) { a->unref(); }}; /* timeout set by the receiver */ + actor::ActorImplPtr src_actor_ = nullptr; actor::ActorImplPtr dst_actor_ = nullptr; @@ -90,11 +95,10 @@ expectations of the other side, too. See */ unsigned char* dst_buff_ = nullptr; size_t src_buff_size_ = 0; size_t* dst_buff_size_ = nullptr; + void* payload_ = nullptr; // If dst_buff_ is NULL, the default copy callback puts the data here void* src_data_ = nullptr; /* User data associated to the communication */ void* dst_data_ = nullptr; - static xbt::signal on_start; - static xbt::signal on_completion; }; } // namespace simgrid::kernel::activity diff --git a/src/kernel/activity/ConditionVariableImpl.cpp b/src/kernel/activity/ConditionVariableImpl.cpp index f059db3b4f..ec3fb6ae52 100644 --- a/src/kernel/activity/ConditionVariableImpl.cpp +++ b/src/kernel/activity/ConditionVariableImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,7 +6,7 @@ #include "src/kernel/activity/ConditionVariableImpl.hpp" #include "src/kernel/activity/MutexImpl.hpp" #include "src/kernel/activity/Synchro.hpp" -#include "src/kernel/actor/SimcallObserver.hpp" +#include "src/kernel/actor/SynchroObserver.hpp" #include // std::isfinite XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_condition, ker_synchro, "Condition variables kernel-space implementation"); @@ -35,7 +35,7 @@ void ConditionVariableImpl::signal() /* Now transform the cond wait simcall into a mutex lock one */ actor::Simcall* simcall = &proc.simcall_; - const auto* observer = dynamic_cast(simcall->observer_); + const auto* observer = dynamic_cast(simcall->observer_); xbt_assert(observer != nullptr); observer->get_mutex()->lock_async(simcall->issuer_)->wait_for(simcall->issuer_, -1); } @@ -62,18 +62,18 @@ void ConditionVariableImpl::wait(MutexImpl* mutex, double timeout, actor::ActorI XBT_DEBUG("Wait condition %p", this); xbt_assert(std::isfinite(timeout), "timeout is not finite!"); - /* If there is a mutex unlock it */ - if (mutex != nullptr) { - xbt_assert(mutex->get_owner() == issuer, - "Actor %s cannot wait on ConditionVariable %p since it does not own the provided mutex %p", - issuer->get_cname(), this, mutex); - mutex_ = mutex; - mutex->unlock(issuer); - } + /* Unlock the provided mutex (the simcall observer ensures that one is provided, no need to check) */ + auto* owner = mutex->get_owner(); + xbt_assert(owner == issuer, + "Actor %s cannot wait on ConditionVariable %p since it does not own the provided mutex %p (which is " + "owned by %s).", + issuer->get_cname(), this, mutex, (owner == nullptr ? "nobody" : owner->get_cname())); + mutex_ = mutex; + mutex->unlock(issuer); SynchroImplPtr synchro(new SynchroImpl([this, issuer]() { this->remove_sleeping_actor(*issuer); - auto* observer = dynamic_cast(issuer->simcall_.observer_); + auto* observer = dynamic_cast(issuer->simcall_.observer_); xbt_assert(observer != nullptr); observer->set_result(true); })); diff --git a/src/kernel/activity/ConditionVariableImpl.hpp b/src/kernel/activity/ConditionVariableImpl.hpp index 6dac7e0fd1..a142e90729 100644 --- a/src/kernel/activity/ConditionVariableImpl.hpp +++ b/src/kernel/activity/ConditionVariableImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,7 +7,9 @@ #define SIMGRID_KERNEL_ACTIVITY_CONDITIONVARIABLE_HPP #include "simgrid/s4u/ConditionVariable.hpp" +#include "src/kernel/activity/ActivityImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" + #include namespace simgrid::kernel::activity { diff --git a/src/kernel/activity/ExecImpl.cpp b/src/kernel/activity/ExecImpl.cpp index 32bbd8a1d3..a05e00c29c 100644 --- a/src/kernel/activity/ExecImpl.cpp +++ b/src/kernel/activity/ExecImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,8 +12,8 @@ #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" #include "src/kernel/resource/CpuImpl.hpp" +#include "src/kernel/resource/HostImpl.hpp" #include "src/mc/mc_replay.hpp" -#include "src/surf/HostImpl.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_cpu, kernel, "Kernel cpu-related synchronization"); @@ -25,7 +25,7 @@ ExecImpl::ExecImpl() actor::ActorImpl* self = actor::ActorImpl::self(); if (self) { set_actor(self); - self->activities_.emplace_back(this); + self->activities_.insert(this); } } @@ -41,15 +41,6 @@ ExecImpl& ExecImpl::set_hosts(const std::vector& hosts) return *this; } -ExecImpl& ExecImpl::set_timeout(double timeout) -{ - if (timeout >= 0 && not MC_is_active() && not MC_record_replay_is_active()) { - timeout_detector_.reset(get_host()->get_cpu()->sleep(timeout)); - timeout_detector_->set_activity(this); - } - return *this; -} - ExecImpl& ExecImpl::set_flops_amount(double flops_amount) { flops_amounts_.assign(1, flops_amount); @@ -80,21 +71,22 @@ ExecImpl* ExecImpl::start() set_state(State::RUNNING); if (not MC_is_active() && not MC_record_replay_is_active()) { if (get_hosts().size() == 1) { + xbt_assert(not flops_amounts_.empty(), "Cannot start Exec: no flops_amount defined."); if (thread_count_ == 1) { - surf_action_ = get_host()->get_cpu()->execution_start(flops_amounts_.front(), bound_); - surf_action_->set_sharing_penalty(sharing_penalty_); + model_action_ = get_host()->get_cpu()->execution_start(flops_amounts_.front(), bound_); + model_action_->set_sharing_penalty(sharing_penalty_); } else { auto host_model = get_host()->get_netpoint()->get_englobing_zone()->get_host_model(); - surf_action_ = host_model->execute_thread(get_host(), flops_amounts_.front(), thread_count_); + model_action_ = host_model->execute_thread(get_host(), flops_amounts_.front(), thread_count_); } - surf_action_->set_category(get_tracing_category()); + model_action_->set_category(get_tracing_category()); } else { // get the model from first host since we have only 1 by now auto host_model = get_host()->get_netpoint()->get_englobing_zone()->get_host_model(); - surf_action_ = host_model->execute_parallel(get_hosts(), flops_amounts_.data(), bytes_amounts_.data(), -1); + model_action_ = host_model->execute_parallel(get_hosts(), flops_amounts_.data(), bytes_amounts_.data(), -1); } - surf_action_->set_activity(this); - set_start_time(surf_action_->get_start_time()); + model_action_->set_activity(this); + set_start_time(model_action_->get_start_time()); } XBT_DEBUG("Create execute synchro %p: %s", this, get_cname()); @@ -112,7 +104,7 @@ double ExecImpl::get_seq_remaining_ratio() { if (get_state() == State::WAITING) return 1; - return (surf_action_ == nullptr) ? 0 : surf_action_->get_remains() / surf_action_->get_cost(); + return (model_action_ == nullptr) ? 0 : model_action_->get_remains() / model_action_->get_cost(); } double ExecImpl::get_par_remaining_ratio() @@ -120,7 +112,7 @@ double ExecImpl::get_par_remaining_ratio() // parallel task: their remain is already between 0 and 1 if (get_state() == State::WAITING) return 1; - return (surf_action_ == nullptr) ? 0 : surf_action_->get_remains(); + return (model_action_ == nullptr) ? 0 : model_action_->get_remains(); } ExecImpl& ExecImpl::set_bound(double bound) @@ -138,43 +130,10 @@ ExecImpl& ExecImpl::set_sharing_penalty(double sharing_penalty) ExecImpl& ExecImpl::update_sharing_penalty(double sharing_penalty) { sharing_penalty_ = sharing_penalty; - surf_action_->set_sharing_penalty(sharing_penalty); + model_action_->set_sharing_penalty(sharing_penalty); return *this; } -void ExecImpl::post() -{ - xbt_assert(surf_action_ != nullptr); - if (auto const& hosts = get_hosts(); - std::any_of(hosts.begin(), hosts.end(), [](const s4u::Host* host) { return not host->is_on(); })) { - /* If one of the hosts running the synchro failed, notice it. This way, the asking - * process can be killed if it runs on that host itself */ - set_state(State::FAILED); - } else if (surf_action_->get_state() == resource::Action::State::FAILED) { - /* If all the hosts are running the synchro didn't fail, then the synchro was canceled */ - set_state(State::CANCELED); - } else if (timeout_detector_ && timeout_detector_->get_state() == resource::Action::State::FINISHED) { - if (surf_action_->get_remains() > 0.0) { - surf_action_->set_state(resource::Action::State::FAILED); - set_state(State::TIMEOUT); - } else { - set_state(State::DONE); - } - } else { - set_state(State::DONE); - } - - clean_action(); - timeout_detector_.reset(); - if (get_actor() != nullptr) { - get_actor()->activities_.remove(this); - } - if (get_state() != State::FAILED && cb_id_ >= 0) - s4u::Host::on_state_change.disconnect(cb_id_); - /* Answer all simcalls associated with the synchro */ - finish(); -} - void ExecImpl::set_exception(actor::ActorImpl* issuer) { switch (get_state()) { @@ -202,6 +161,25 @@ void ExecImpl::set_exception(actor::ActorImpl* issuer) void ExecImpl::finish() { XBT_DEBUG("ExecImpl::finish() in state %s", get_state_str()); + if (model_action_ != nullptr) { + if (auto const& hosts = get_hosts(); + std::any_of(hosts.begin(), hosts.end(), [](const s4u::Host* host) { return not host->is_on(); })) { + /* If one of the hosts running the synchro failed, notice it. This way, the asking + * process can be killed if it runs on that host itself */ + set_state(State::FAILED); + } else if (model_action_->get_state() == resource::Action::State::FAILED) { + /* If all the hosts are running the synchro didn't fail, then the synchro was canceled */ + set_state(State::CANCELED); + } else { + set_state(State::DONE); + } + + clean_action(); + } + + if (get_actor() != nullptr) + get_actor()->activities_.erase(this); + while (not simcalls_.empty()) { actor::Simcall* simcall = simcalls_.front(); simcalls_.pop_front(); @@ -225,15 +203,13 @@ void ExecImpl::finish() void ExecImpl::reset() { clear_hosts(); - bytes_amounts_.clear(); - flops_amounts_.clear(); set_start_time(-1.0); } ActivityImpl* ExecImpl::migrate(s4u::Host* to) { if (not MC_is_active() && not MC_record_replay_is_active()) { - resource::Action* old_action = this->surf_action_; + resource::Action* old_action = this->model_action_; resource::Action* new_action = to->get_cpu()->execution_start(old_action->get_cost(), old_action->get_user_bound()); new_action->set_remains(old_action->get_remains()); new_action->set_activity(this); @@ -243,7 +219,7 @@ ActivityImpl* ExecImpl::migrate(s4u::Host* to) old_action->set_activity(nullptr); old_action->cancel(); old_action->unref(); - this->surf_action_ = new_action; + this->model_action_ = new_action; } on_migration(*this, to); diff --git a/src/kernel/activity/ExecImpl.hpp b/src/kernel/activity/ExecImpl.hpp index 22dfb5c00f..37c0f0d7c4 100644 --- a/src/kernel/activity/ExecImpl.hpp +++ b/src/kernel/activity/ExecImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,25 +14,19 @@ namespace simgrid::kernel::activity { class XBT_PUBLIC ExecImpl : public ActivityImpl_T { - std::unique_ptr> timeout_detector_{ - nullptr, [](resource::Action* a) { a->unref(); }}; double sharing_penalty_ = 1.0; double bound_ = 0.0; std::vector flops_amounts_; std::vector bytes_amounts_; int thread_count_ = 1; - int cb_id_ = -1; // callback id from Host::on_state_change.connect() public: ExecImpl(); - ExecImpl& set_timeout(double timeout) override; ExecImpl& set_bound(double bound); ExecImpl& set_sharing_penalty(double sharing_penalty); ExecImpl& update_sharing_penalty(double sharing_penalty); - void set_cb_id(unsigned int cb_id) { cb_id_ = cb_id; } - ExecImpl& set_flops_amount(double flop_amount); ExecImpl& set_host(s4u::Host* host); @@ -42,13 +36,13 @@ public: ExecImpl& set_hosts(const std::vector& hosts); unsigned int get_host_number() const { return static_cast(get_hosts().size()); } + int get_thread_count() const { return thread_count_; } double get_seq_remaining_ratio(); double get_par_remaining_ratio(); double get_remaining() const override; virtual ActivityImpl* migrate(s4u::Host* to); ExecImpl* start(); - void post() override; void set_exception(actor::ActorImpl* issuer) override; void finish() override; diff --git a/src/kernel/activity/IoImpl.cpp b/src/kernel/activity/IoImpl.cpp index c30b1a93aa..1a7e46fd9e 100644 --- a/src/kernel/activity/IoImpl.cpp +++ b/src/kernel/activity/IoImpl.cpp @@ -1,20 +1,15 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include #include -#include -#include -#include "mc/mc.h" #include "src/kernel/activity/IoImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" -#include "src/kernel/actor/SimcallObserver.hpp" -#include "src/kernel/resource/CpuImpl.hpp" #include "src/kernel/resource/DiskImpl.hpp" -#include "src/mc/mc_replay.hpp" +#include "src/kernel/resource/HostImpl.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_io, kernel, "Kernel io-related synchronization"); @@ -26,7 +21,7 @@ IoImpl::IoImpl() actor::ActorImpl* self = actor::ActorImpl::self(); if (self) { set_actor(self); - self->activities_.emplace_back(this); + self->activities_.insert(this); } } @@ -39,15 +34,7 @@ IoImpl& IoImpl::set_sharing_penalty(double sharing_penalty) IoImpl& IoImpl::update_sharing_penalty(double sharing_penalty) { sharing_penalty_ = sharing_penalty; - surf_action_->set_sharing_penalty(sharing_penalty); - return *this; -} - -IoImpl& IoImpl::set_timeout(double timeout) -{ - const s4u::Host* host = get_disk()->get_host(); - timeout_detector_ = host->get_cpu()->sleep(timeout); - timeout_detector_->set_activity(this); + model_action_->set_sharing_penalty(sharing_penalty); return *this; } @@ -69,48 +56,45 @@ IoImpl& IoImpl::set_disk(resource::DiskImpl* disk) return *this; } -IoImpl* IoImpl::start() +IoImpl& IoImpl::set_host(s4u::Host* host) { - set_state(State::RUNNING); - surf_action_ = - disk_->get_host()->get_netpoint()->get_englobing_zone()->get_disk_model()->io_start(disk_, size_, type_); - surf_action_->set_sharing_penalty(sharing_penalty_); - surf_action_->set_activity(this); - set_start_time(surf_action_->get_start_time()); + host_ = host; + return *this; +} - XBT_DEBUG("Create IO synchro %p %s", this, get_cname()); +IoImpl& IoImpl::set_dst_disk(resource::DiskImpl* disk) +{ + dst_disk_ = disk; + return *this; +} - return this; +IoImpl& IoImpl::set_dst_host(s4u::Host* host) +{ + dst_host_ = host; + return *this; } -void IoImpl::post() +IoImpl* IoImpl::start() { - performed_ioops_ = surf_action_->get_cost(); - if (surf_action_->get_state() == resource::Action::State::FAILED) { - if (disk_ && not disk_->is_on()) - set_state(State::FAILED); - else - set_state(State::CANCELED); - } else if (timeout_detector_ && timeout_detector_->get_state() == resource::Action::State::FINISHED) { - if (surf_action_->get_remains() > 0.0) { - surf_action_->set_state(resource::Action::State::FAILED); - set_state(State::TIMEOUT); - } else { - set_state(State::DONE); - } + set_state(State::RUNNING); + if (dst_host_ == nullptr) { + XBT_DEBUG("Starting regular I/O"); + model_action_ = disk_->io_start(size_, type_); + model_action_->set_sharing_penalty(sharing_penalty_); } else { - set_state(State::DONE); + XBT_DEBUG("Starting streaming I/O"); + auto host_model = dst_host_->get_netpoint()->get_englobing_zone()->get_host_model(); + model_action_ = host_model->io_stream(host_, disk_, dst_host_, dst_disk_, size_); } - clean_action(); - if (timeout_detector_) { - timeout_detector_->unref(); - timeout_detector_ = nullptr; - } + model_action_->set_activity(this); + set_start_time(model_action_->get_start_time()); + + XBT_DEBUG("Create IO synchro %p %s", this, get_cname()); - /* Answer all simcalls associated with the synchro */ - finish(); + return this; } + void IoImpl::set_exception(actor::ActorImpl* issuer) { switch (get_state()) { @@ -122,6 +106,12 @@ void IoImpl::set_exception(actor::ActorImpl* issuer) case State::CANCELED: issuer->exception_ = std::make_exception_ptr(CancelException(XBT_THROW_POINT, "I/O Canceled")); break; + case State::SRC_HOST_FAILURE: + case State::DST_HOST_FAILURE: + issuer->set_wannadie(); + static_cast(get_iface())->complete(s4u::Activity::State::FAILED); + issuer->exception_ = std::make_exception_ptr(StorageFailureException(XBT_THROW_POINT, "Host failed")); + break; case State::TIMEOUT: issuer->exception_ = std::make_exception_ptr(TimeoutException(XBT_THROW_POINT, "Timeouted")); break; @@ -134,6 +124,25 @@ void IoImpl::set_exception(actor::ActorImpl* issuer) void IoImpl::finish() { XBT_DEBUG("IoImpl::finish() in state %s", get_state_str()); + if (model_action_ != nullptr) { + performed_ioops_ = model_action_->get_cost(); + if (model_action_->get_state() == resource::Action::State::FAILED) { + if (host_ && dst_host_) { // this is an I/O stream + if (not host_->is_on()) + set_state(State::SRC_HOST_FAILURE); + else if (not dst_host_->is_on()) + set_state(State::DST_HOST_FAILURE); + } else if ((disk_ && not disk_->is_on()) || (dst_disk_ && not dst_disk_->is_on())) + set_state(State::FAILED); + else + set_state(State::CANCELED); + } else { + set_state(State::DONE); + } + + clean_action(); + } + while (not simcalls_.empty()) { actor::Simcall* simcall = simcalls_.front(); simcalls_.pop_front(); @@ -147,10 +156,16 @@ void IoImpl::finish() handle_activity_waitany(simcall); - set_exception(simcall->issuer_); - - simcall->issuer_->waiting_synchro_ = nullptr; - simcall->issuer_->simcall_answer(); + if (not simcall->issuer_->get_host()->is_on()) { + simcall->issuer_->set_wannadie(); + } else { + // Do not answer to dying actors + if (not simcall->issuer_->wannadie()) { + set_exception(simcall->issuer_); + simcall->issuer_->waiting_synchro_ = nullptr; + simcall->issuer_->simcall_answer(); + } + } } } diff --git a/src/kernel/activity/IoImpl.hpp b/src/kernel/activity/IoImpl.hpp index 399775bfca..6562f2e393 100644 --- a/src/kernel/activity/IoImpl.hpp +++ b/src/kernel/activity/IoImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,21 +12,27 @@ namespace simgrid::kernel::activity { class XBT_PUBLIC IoImpl : public ActivityImpl_T { + s4u::Host* host_ = nullptr; resource::DiskImpl* disk_ = nullptr; + s4u::Host* dst_host_ = nullptr; + resource::DiskImpl* dst_disk_ = nullptr; double sharing_penalty_ = 1.0; sg_size_t size_ = 0; s4u::Io::OpType type_ = s4u::Io::OpType::READ; sg_size_t performed_ioops_ = 0; - resource::Action* timeout_detector_ = nullptr; public: IoImpl(); IoImpl& set_sharing_penalty(double sharing_penalty); - IoImpl& set_timeout(double timeout) override; IoImpl& set_size(sg_size_t size); IoImpl& set_type(s4u::Io::OpType type); IoImpl& set_disk(resource::DiskImpl* disk); + IoImpl& set_host(s4u::Host* host); + s4u::Host* get_host() const { return host_; } + IoImpl& set_dst_disk(resource::DiskImpl* disk); + IoImpl& set_dst_host(s4u::Host* host); + s4u::Host* get_dst_host() const { return dst_host_; } IoImpl& update_sharing_penalty(double sharing_penalty); @@ -34,7 +40,6 @@ public: resource::DiskImpl* get_disk() const { return disk_; } IoImpl* start(); - void post() override; void set_exception(actor::ActorImpl* issuer) override; void finish() override; }; diff --git a/src/kernel/activity/MailboxImpl.cpp b/src/kernel/activity/MailboxImpl.cpp index 7ee160c332..aaeeb83dc4 100644 --- a/src/kernel/activity/MailboxImpl.cpp +++ b/src/kernel/activity/MailboxImpl.cpp @@ -1,10 +1,9 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/activity/MailboxImpl.hpp" -#include "simgrid/msg.h" #include "src/kernel/activity/CommImpl.hpp" #include @@ -21,7 +20,11 @@ unsigned MailboxImpl::next_id_ = 0; MailboxImpl::~MailboxImpl() { - clear(false); + try { + clear(false); + } catch (const std::bad_alloc& ba) { + XBT_ERROR("MailboxImpl::clear() failure: %s", ba.what()); + } set_receiver(nullptr); } @@ -43,7 +46,7 @@ void MailboxImpl::set_receiver(s4u::ActorPtr actor) /** @brief Pushes a communication activity into a mailbox * @param comm What to add */ -void MailboxImpl::push(CommImplPtr comm) +void MailboxImpl::push(const CommImplPtr& comm) { comm->set_mailbox(this); this->comm_queue_.push_back(std::move(comm)); @@ -58,24 +61,23 @@ void MailboxImpl::remove(const CommImplPtr& comm) (comm->get_mailbox() ? comm->get_mailbox()->get_cname() : "(null)"), this->get_cname()); comm->set_mailbox(nullptr); - for (auto it = this->comm_queue_.begin(); it != this->comm_queue_.end(); it++) - if (*it == comm) { - this->comm_queue_.erase(it); - return; - } - xbt_die("Comm %p not found in mailbox %s", comm.get(), this->get_cname()); + auto it = std::find(this->comm_queue_.begin(), this->comm_queue_.end(), comm); + if (it != this->comm_queue_.end()) + this->comm_queue_.erase(it); + else + xbt_die("Comm %p not found in mailbox %s", comm.get(), this->get_cname()); } /** @brief Removes all communication activities from a mailbox */ -void MailboxImpl::clear( bool do_post ) +void MailboxImpl::clear(bool do_finish) { // CommImpl::cancel() will remove the comm from the mailbox.. - for (auto comm : done_comm_queue_) { + for (const auto& comm : done_comm_queue_) { comm->cancel(); comm->set_state(State::FAILED); - if(do_post) - comm->post(); + if (do_finish) + comm->finish(); } done_comm_queue_.clear(); @@ -84,8 +86,8 @@ void MailboxImpl::clear( bool do_post ) if (comm->get_state() == State::WAITING && not comm->is_detached()) { comm->cancel(); comm->set_state(State::FAILED); - if(do_post) - comm->post(); + if (do_finish) + comm->finish(); } else comm_queue_.pop_back(); } diff --git a/src/kernel/activity/MailboxImpl.hpp b/src/kernel/activity/MailboxImpl.hpp index 353b963e73..172bda4cee 100644 --- a/src/kernel/activity/MailboxImpl.hpp +++ b/src/kernel/activity/MailboxImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,9 +6,7 @@ #ifndef SIMGRID_KERNEL_ACTIVITY_MAILBOX_HPP #define SIMGRID_KERNEL_ACTIVITY_MAILBOX_HPP -#include -#include - +#include "simgrid/config.h" /* FIXME: KILLME. This makes the ABI config-dependent, but mandatory for the hack below */ #include "simgrid/s4u/Engine.hpp" #include "simgrid/s4u/Mailbox.hpp" #include "src/kernel/activity/CommImpl.hpp" @@ -19,14 +17,13 @@ namespace simgrid::kernel::activity { /** @brief Implementation of the s4u::Mailbox */ class MailboxImpl { - static constexpr size_t MAX_MAILBOX_SIZE = 10000000; - s4u::Mailbox piface_; - xbt::string name_; + std::string name_; actor::ActorImplPtr permanent_receiver_; // actor to which the mailbox is attached - boost::circular_buffer_space_optimized comm_queue_{MAX_MAILBOX_SIZE}; + + std::deque comm_queue_; // messages already received in the permanent receive mode - boost::circular_buffer_space_optimized done_comm_queue_{MAX_MAILBOX_SIZE}; + std::deque done_comm_queue_; friend s4u::Engine; friend s4u::Mailbox; @@ -48,13 +45,13 @@ public: const s4u::Mailbox* get_iface() const { return &piface_; } s4u::Mailbox* get_iface() { return &piface_; } - const xbt::string& get_name() const { return name_; } + const std::string& get_name() const { return name_; } const char* get_cname() const { return name_.c_str(); } void set_receiver(s4u::ActorPtr actor); - void push(CommImplPtr comm); - void push_done(CommImplPtr done_comm) { done_comm_queue_.push_back(done_comm); } + void push(const CommImplPtr& comm); + void push_done(const CommImplPtr& done_comm) { done_comm_queue_.push_back(done_comm); } void remove(const CommImplPtr& comm); - void clear(bool do_post ); + void clear(bool do_finish); CommImplPtr iprobe(int type, const std::function& match_fun, void* data); CommImplPtr find_matching_comm(CommImplType type, const std::function& match_fun, void* this_user_data, const CommImplPtr& my_synchro, bool done, bool remove_matching); @@ -62,9 +59,9 @@ public: actor::ActorImplPtr get_permanent_receiver() const { return permanent_receiver_; } bool empty() const { return comm_queue_.empty(); } size_t size() const { return comm_queue_.size(); } - CommImplPtr front() const { return comm_queue_.front(); } + const CommImplPtr& front() const { return comm_queue_.front(); } bool has_some_done_comm() const { return not done_comm_queue_.empty(); } - CommImplPtr done_front() const { return done_comm_queue_.front(); } + const CommImplPtr& done_front() const { return done_comm_queue_.front(); } }; } // namespace simgrid::kernel::activity diff --git a/src/kernel/activity/MessImpl.cpp b/src/kernel/activity/MessImpl.cpp new file mode 100644 index 0000000000..3a3e307b77 --- /dev/null +++ b/src/kernel/activity/MessImpl.cpp @@ -0,0 +1,196 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include +#include + +#include "src/kernel/EngineImpl.hpp" +#include "src/kernel/activity/MessImpl.hpp" +#include "src/kernel/activity/MessageQueueImpl.hpp" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_mess, kernel, "Kernel message synchronization"); + +namespace simgrid::kernel::activity { + +MessImpl::~MessImpl() +{ + if (queue_) + queue_->remove(this); +} + +MessImpl& MessImpl::set_type(MessImplType type) +{ + type_ = type; + return *this; +} + +MessImpl& MessImpl::set_queue(MessageQueueImpl* queue) +{ + queue_ = queue; + return *this; +} + +MessImpl& MessImpl::set_payload(void* payload) +{ + payload_ = payload; + return *this; +} + +MessImpl& MessImpl::set_dst_buff(unsigned char* buff, size_t* size) +{ + dst_buff_ = buff; + dst_buff_size_ = size; + return *this; +} + +MessImpl* MessImpl::start() +{ + if (get_state() == State::READY) { + XBT_DEBUG("Starting message exchange %p from '%s' to '%s' (state: %s)", this, src_actor_->get_host()->get_cname(), + dst_actor_->get_host()->get_cname(), get_state_str()); + set_state(State::RUNNING); + finish(); + } + return this; +} + +ActivityImplPtr MessImpl::iput(actor::MessIputSimcall* observer) +{ + auto* queue = observer->get_queue(); + XBT_DEBUG("put from message queue %p", queue); + + /* Prepare a synchro describing us, so that it gets passed to the user-provided filter of other side */ + MessImplPtr this_mess(new MessImpl()); + this_mess->set_type(MessImplType::PUT); + + /* Look for message synchro matching our needs. + * + * If it is not found then push our communication into the rendez-vous point */ + MessImplPtr other_mess = queue->find_matching_message(MessImplType::GET); + + if (not other_mess) { + other_mess = std::move(this_mess); + queue->push(other_mess); + } else { + XBT_DEBUG("Get already pushed"); + other_mess->set_state(State::READY); + } + + observer->set_message(other_mess.get()); + observer->get_issuer()->activities_.insert(other_mess); + + /* Setup synchro */ + other_mess->src_actor_ = observer->get_issuer(); + other_mess->payload_ = observer->get_payload(); + other_mess->start(); + + return other_mess; +} + +ActivityImplPtr MessImpl::iget(actor::MessIgetSimcall* observer) +{ + MessImplPtr this_mess(new MessImpl()); + this_mess->set_type(MessImplType::GET); + + auto* queue = observer->get_queue(); + XBT_DEBUG("get from message queue %p. this_synchro=%p", queue, this_mess.get()); + + MessImplPtr other_mess = queue->find_matching_message(MessImplType::PUT); + + if (other_mess == nullptr) { + XBT_DEBUG("Get pushed first (%zu comm enqueued so far)", queue->size()); + other_mess = std::move(this_mess); + queue->push(other_mess); + } else { + XBT_DEBUG("Match my %p with the existing %p", this_mess.get(), other_mess.get()); + + other_mess->set_state(State::READY); + } + + observer->get_issuer()->activities_.insert(other_mess); + observer->set_message(other_mess.get()); + + /* Setup synchro */ + other_mess->set_dst_buff(observer->get_dst_buff(), observer->get_dst_buff_size()); + other_mess->dst_actor_ = observer->get_issuer(); + + other_mess->start(); + + return other_mess; +} + +void MessImpl::wait_for(actor::ActorImpl* issuer, double timeout) +{ + XBT_DEBUG("MessImpl::wait_for(%g), %p, state %s", timeout, this, get_state_str()); + + /* Associate this simcall to the wait synchro */ + register_simcall(&issuer->simcall_); + ActivityImpl::wait_for(issuer, timeout); +} + +void MessImpl::cancel() +{ + /* if the synchro is a waiting state means that it is still in a mbox so remove from it and delete it */ + if (get_state() == State::WAITING) { + queue_->remove(this); + set_state(State::CANCELED); + } +} + +void MessImpl::finish() +{ + XBT_DEBUG("MessImpl::finish() mess %p, state %s, src_proc %p, dst_proc %p", this, get_state_str(), + src_actor_.get(), dst_actor_.get()); + + if (get_iface()) { + const auto& piface = static_cast(*get_iface()); + set_iface(nullptr); // reset iface to protect against multiple trigger of the on_completion signals + piface.fire_on_completion_for_real(); + piface.fire_on_this_completion_for_real(); + } + + /* Update synchro state */ + if (get_state() == State::RUNNING) { + set_state(State::DONE); + } + + /* If the synchro is still in a rendez-vous point then remove from it */ + if (queue_) + queue_->remove(this); + + if (get_state() == State::DONE && payload_ != nullptr) + *(void**)(dst_buff_) = payload_; + + while (not simcalls_.empty()) { + actor::Simcall* simcall = simcalls_.front(); + simcalls_.pop_front(); + + /* If a waitany simcall is waiting for this synchro to finish, then remove it from the other synchros in the waitany + * list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the + * simcall */ + + if (simcall->call_ == actor::Simcall::Type::NONE) // FIXME: maybe a better way to handle this case + continue; // if actor handling comm is killed + + handle_activity_waitany(simcall); + + /* Check out for errors */ + + if (not simcall->issuer_->get_host()->is_on()) { + simcall->issuer_->set_wannadie(); + } else { + // Do not answer to dying actors + if (not simcall->issuer_->wannadie()) { + set_exception(simcall->issuer_); + simcall->issuer_->simcall_answer(); + } + } + + simcall->issuer_->waiting_synchro_ = nullptr; + simcall->issuer_->activities_.erase(this); + } +} + +} // namespace simgrid::kernel::activity diff --git a/src/kernel/activity/MessImpl.hpp b/src/kernel/activity/MessImpl.hpp new file mode 100644 index 0000000000..2b2932f311 --- /dev/null +++ b/src/kernel/activity/MessImpl.hpp @@ -0,0 +1,53 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_KERNEL_ACTIVITY_MESS_HPP +#define SIMGRID_KERNEL_ACTIVITY_MESS_HPP + +#include "src/kernel/activity/ActivityImpl.hpp" +#include "src/kernel/actor/ActorImpl.hpp" +#include "src/kernel/actor/CommObserver.hpp" + +namespace simgrid::kernel::activity { + +enum class MessImplType { PUT, GET }; + +class XBT_PUBLIC MessImpl : public ActivityImpl_T { + ~MessImpl() override; + + MessageQueueImpl* queue_ = nullptr; + void* payload_ = nullptr; + MessImplType type_ = MessImplType::PUT; + unsigned char* dst_buff_ = nullptr; + size_t* dst_buff_size_ = nullptr; + +public: + MessImpl& set_type(MessImplType type); + MessImplType get_type() const { return type_; } + MessImpl& set_payload(void* payload); + void* get_payload() { return payload_; } + + MessImpl& set_queue(MessageQueueImpl* queue); + MessageQueueImpl* get_queue() const { return queue_; } + MessImpl& set_dst_buff(unsigned char* buff, size_t* size); + + static ActivityImplPtr iput(actor::MessIputSimcall* observer); + static ActivityImplPtr iget(actor::MessIgetSimcall* observer); + + void wait_for(actor::ActorImpl* issuer, double timeout) override; + + MessImpl* start(); + void suspend() override { /* no action to suspend for Mess */ } + void resume() override { /* no action to resume for Mess */ } + void cancel() override; + void set_exception(actor::ActorImpl* issuer) override {}; + void finish() override; + + actor::ActorImplPtr src_actor_ = nullptr; + actor::ActorImplPtr dst_actor_ = nullptr; +}; +} // namespace simgrid::kernel::activity + +#endif diff --git a/src/kernel/activity/MessageQueueImpl.cpp b/src/kernel/activity/MessageQueueImpl.cpp new file mode 100644 index 0000000000..d649e6ee0b --- /dev/null +++ b/src/kernel/activity/MessageQueueImpl.cpp @@ -0,0 +1,77 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/kernel/activity/MessageQueueImpl.hpp" + +#include + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_mq, kernel, "Message queue implementation"); + +namespace simgrid::kernel::activity { + +unsigned MessageQueueImpl::next_id_ = 0; + +MessageQueueImpl::~MessageQueueImpl() +{ + try { + clear(); + } catch (const std::bad_alloc& ba) { + XBT_ERROR("MessageQueueImpl::clear() failure: %s", ba.what()); + } +} + +/** @brief Removes all message activities from a message queue */ +void MessageQueueImpl::clear() +{ + while (not queue_.empty()) { + auto mess = queue_.back(); + if (mess->get_state() == State::WAITING) { + mess->cancel(); + mess->set_state(State::FAILED); + } else + queue_.pop_back(); + } + xbt_assert(queue_.empty()); +} + +void MessageQueueImpl::push(const MessImplPtr& mess) +{ + mess->set_queue(this); + this->queue_.push_back(std::move(mess)); +} + +void MessageQueueImpl::remove(const MessImplPtr& mess) +{ + xbt_assert(mess->get_queue() == this, "Message %p is in queue %s, not queue %s", mess.get(), + (mess->get_queue() ? mess->get_queue()->get_cname() : "(null)"), get_cname()); + + mess->set_queue(nullptr); + auto it = std::find(queue_.begin(), queue_.end(), mess); + if (it != queue_.end()) + queue_.erase(it); + else + xbt_die("Message %p not found in queue %s", mess.get(), get_cname()); +} + +MessImplPtr MessageQueueImpl::find_matching_message(MessImplType type) +{ + auto iter = std::find_if(queue_.begin(), queue_.end(), [&type](const MessImplPtr& mess) + { + return (mess->get_type() == type); + }); + if (iter == queue_.end()) { + XBT_DEBUG("No matching message synchro found"); + return nullptr; + } + + const MessImplPtr& mess = *iter; + XBT_DEBUG("Found a matching message synchro %p", mess.get()); + mess->set_queue(nullptr); + MessImplPtr mess_cpy = mess; + queue_.erase(iter); + return mess_cpy; +} + +} // namespace simgrid::kernel::activity diff --git a/src/kernel/activity/MessageQueueImpl.hpp b/src/kernel/activity/MessageQueueImpl.hpp new file mode 100644 index 0000000000..3016e049d5 --- /dev/null +++ b/src/kernel/activity/MessageQueueImpl.hpp @@ -0,0 +1,55 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_KERNEL_ACTIVITY_MESSAGEQUEUE_HPP +#define SIMGRID_KERNEL_ACTIVITY_MESSAGEQUEUE_HPP + +#include "simgrid/s4u/Engine.hpp" +#include "simgrid/s4u/MessageQueue.hpp" +#include "src/kernel/activity/MessImpl.hpp" + +namespace simgrid::kernel::activity { + +/** @brief Implementation of the s4u::MessageQueue */ + +class MessageQueueImpl { + s4u::MessageQueue piface_; + std::string name_; + std::deque queue_; + + friend s4u::Engine; + friend s4u::MessageQueue; + friend s4u::MessageQueue* s4u::Engine::message_queue_by_name_or_create(const std::string& name) const; + friend s4u::MessageQueue* s4u::MessageQueue::by_name(const std::string& name); + + static unsigned next_id_; // Next ID to be given + const unsigned id_ = next_id_++; + explicit MessageQueueImpl(const std::string& name) : piface_(this), name_(name) {} + MessageQueueImpl(const MailboxImpl&) = delete; + MessageQueueImpl& operator=(const MailboxImpl&) = delete; + +public: + ~MessageQueueImpl(); + + /** @brief Public interface */ + unsigned get_id() const { return id_; } + + const s4u::MessageQueue* get_iface() const { return &piface_; } + s4u::MessageQueue* get_iface() { return &piface_; } + + const std::string& get_name() const { return name_; } + const char* get_cname() const { return name_.c_str(); } + void push(const MessImplPtr& mess); + void remove(const MessImplPtr& mess); + void clear(); + bool empty() const { return queue_.empty(); } + size_t size() const { return queue_.size(); } + const MessImplPtr& front() const { return queue_.front(); } + + MessImplPtr find_matching_message(MessImplType type); +}; +} // namespace simgrid::kernel::activity + +#endif diff --git a/src/kernel/activity/MutexImpl.cpp b/src/kernel/activity/MutexImpl.cpp index e6053e1610..cac3e9524d 100644 --- a/src/kernel/activity/MutexImpl.cpp +++ b/src/kernel/activity/MutexImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -30,6 +30,7 @@ void MutexAcquisitionImpl::wait_for(actor::ActorImpl* issuer, double timeout) // Already in the queue } } + void MutexAcquisitionImpl::finish() { xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size()); @@ -46,13 +47,41 @@ unsigned MutexImpl::next_id_ = 0; MutexAcquisitionImplPtr MutexImpl::lock_async(actor::ActorImpl* issuer) { - auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); - - if (owner_ != nullptr) { - /* Somebody is using the mutex; register the acquisition */ + /* If the mutex is recursive */ + if (is_recursive_) { + if (owner_ == issuer) { + recursive_depth++; + auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); + res->grant(); + return res; + } else if (owner_ == nullptr) { // Free + owner_ = issuer; + recursive_depth = 1; + auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); + res->grant(); + return res; + } + + for (auto acq : ongoing_acquisitions_) + if (acq->get_issuer() == issuer) { + acq->recursive_depth_++; + return acq; + } + + // Not yet in the ongoing acquisition list. Get in there + auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); ongoing_acquisitions_.push_back(res); - } else { + return res; + } + + // Non-recursive mutex + auto res = MutexAcquisitionImplPtr(new kernel::activity::MutexAcquisitionImpl(issuer, this), true); + if (owner_ == nullptr) { // Lock is free, take it owner_ = issuer; + recursive_depth = 1; + res->grant(); + } else { // Somebody is using the mutex; register the acquisition + ongoing_acquisitions_.push_back(res); } return res; } @@ -64,14 +93,14 @@ MutexAcquisitionImplPtr MutexImpl::lock_async(actor::ActorImpl* issuer) */ bool MutexImpl::try_lock(actor::ActorImpl* issuer) { - XBT_IN("(%p, %p)", this, issuer); - if (owner_ != nullptr) { - XBT_OUT(); - return false; + if (owner_ == issuer && is_recursive_) { + recursive_depth++; + return true; } + if (owner_ != nullptr) + return false; - owner_ = issuer; - XBT_OUT(); + owner_ = issuer; return true; } @@ -87,12 +116,20 @@ void MutexImpl::unlock(actor::ActorImpl* issuer) xbt_assert(issuer == owner_, "Cannot release that mutex: you're not the owner. %s is (pid:%ld).", owner_ != nullptr ? owner_->get_cname() : "(nobody)", owner_ != nullptr ? owner_->get_pid() : -1); + if (is_recursive_) { + recursive_depth--; + if (recursive_depth > 0) // Still owning the lock + return; + } + if (not ongoing_acquisitions_.empty()) { /* Give the ownership to the first waiting actor */ auto acq = ongoing_acquisitions_.front(); ongoing_acquisitions_.pop_front(); owner_ = acq->get_issuer(); + acq->grant(); + recursive_depth = acq->recursive_depth_; if (acq == owner_->waiting_synchro_) acq->finish(); // else, the issuer is not blocked on this acquisition so no need to release it diff --git a/src/kernel/activity/MutexImpl.hpp b/src/kernel/activity/MutexImpl.hpp index 3f80092cb8..8bf71be533 100644 --- a/src/kernel/activity/MutexImpl.hpp +++ b/src/kernel/activity/MutexImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,6 +9,7 @@ #include "simgrid/s4u/Mutex.hpp" #include "src/kernel/activity/ActivityImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" +#include "xbt/asserts.h" #include namespace simgrid::kernel::activity { @@ -42,17 +43,22 @@ namespace simgrid::kernel::activity { class XBT_PUBLIC MutexAcquisitionImpl : public ActivityImpl_T { actor::ActorImpl* issuer_ = nullptr; MutexImpl* mutex_ = nullptr; + int recursive_depth_ = 1; + // TODO: use granted_ this instead of owner_ == self to test(). + // This is mandatory to get double-lock on non-recursive locks to properly deadlock + bool granted_ = false; + + friend MutexImpl; public: MutexAcquisitionImpl(actor::ActorImpl* issuer, MutexImpl* mutex) : issuer_(issuer), mutex_(mutex) {} - MutexImplPtr get_mutex() { return mutex_; } - actor::ActorImpl* get_issuer() { return issuer_; } + MutexImplPtr get_mutex() const { return mutex_; } + actor::ActorImpl* get_issuer() const { return issuer_; } + void grant() { granted_ = true; } + bool is_granted() const { return granted_; } bool test(actor::ActorImpl* issuer = nullptr) override; void wait_for(actor::ActorImpl* issuer, double timeout) override; - void post() override - { /*no surf action*/ - } void finish() override; void set_exception(actor::ActorImpl* issuer) override { /* nothing to do */ @@ -66,11 +72,13 @@ class XBT_PUBLIC MutexImpl { std::deque ongoing_acquisitions_; static unsigned next_id_; unsigned id_ = next_id_++; + bool is_recursive_ = false; + int recursive_depth = 0; friend MutexAcquisitionImpl; public: - MutexImpl() : piface_(this) {} + explicit MutexImpl(bool recursive = false) : piface_(this), is_recursive_(recursive) {} MutexImpl(MutexImpl const&) = delete; MutexImpl& operator=(MutexImpl const&) = delete; @@ -90,11 +98,15 @@ public: friend void intrusive_ptr_release(MutexImpl* mutex) { - if (mutex->refcount_.fetch_sub(1) == 1) + if (mutex->refcount_.fetch_sub(1) == 1) { + xbt_assert(mutex->ongoing_acquisitions_.empty(), "The destroyed mutex still had ongoing acquisitions"); + xbt_assert(mutex->owner_ == nullptr, "The destroyed mutex is still owned by actor %s", + mutex->owner_->get_cname()); delete mutex; + } } - s4u::Mutex& mutex() { return piface_; } + s4u::Mutex& get_iface() { return piface_; } }; } // namespace simgrid::kernel::activity #endif diff --git a/src/kernel/activity/SemaphoreImpl.cpp b/src/kernel/activity/SemaphoreImpl.cpp index c53825f872..b53f45771b 100644 --- a/src/kernel/activity/SemaphoreImpl.cpp +++ b/src/kernel/activity/SemaphoreImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -29,27 +29,23 @@ void SemAcquisitionImpl::wait_for(actor::ActorImpl* issuer, double timeout) this->register_simcall(&issuer_->simcall_); // Block on that acquisition if (granted_) { - post(); + finish(); } else if (timeout > 0) { - surf_action_ = get_issuer()->get_host()->get_cpu()->sleep(timeout); - surf_action_->set_activity(this); + model_action_ = get_issuer()->get_host()->get_cpu()->sleep(timeout); + model_action_->set_activity(this); } else { // Already in the queue } } -void SemAcquisitionImpl::post() -{ - finish(); -} void SemAcquisitionImpl::finish() { xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size()); actor::Simcall* simcall = simcalls_.front(); simcalls_.pop_front(); - if (surf_action_ != nullptr) { // A timeout was declared - if (surf_action_->get_state() == resource::Action::State::FINISHED) { // The timeout elapsed + if (model_action_ != nullptr) { // A timeout was declared + if (model_action_->get_state() == resource::Action::State::FINISHED) { // The timeout elapsed if (granted_) { // but we got the semaphore, just in time! set_state(State::DONE); @@ -62,8 +58,8 @@ void SemAcquisitionImpl::finish() observer->set_result(true); } } - surf_action_->unref(); - surf_action_ = nullptr; + model_action_->unref(); + model_action_ = nullptr; } simcall->issuer_->waiting_synchro_ = nullptr; @@ -72,7 +68,7 @@ void SemAcquisitionImpl::finish() void SemAcquisitionImpl::cancel() { /* Remove myself from the list of interested parties */ - auto issuer = get_issuer(); + const auto* issuer = get_issuer(); auto it = std::find_if(semaphore_->ongoing_acquisitions_.begin(), semaphore_->ongoing_acquisitions_.end(), [issuer](SemAcquisitionImplPtr acqui) { return acqui->get_issuer() == issuer; }); xbt_assert(it != semaphore_->ongoing_acquisitions_.end(), @@ -87,12 +83,12 @@ SemAcquisitionImplPtr SemaphoreImpl::acquire_async(actor::ActorImpl* issuer) { auto res = SemAcquisitionImplPtr(new kernel::activity::SemAcquisitionImpl(issuer, this), true); - if (value_ <= 0) { - /* No free token in the semaphore; register the acquisition */ - ongoing_acquisitions_.push_back(res); - } else { + if (value_ > 0) { value_--; res->granted_ = true; + } else { + /* No free token in the semaphore; register the acquisition */ + ongoing_acquisitions_.push_back(res); } return res; } @@ -108,7 +104,7 @@ void SemaphoreImpl::release() acqui->granted_ = true; if (acqui == acqui->get_issuer()->waiting_synchro_) - acqui->post(); + acqui->finish(); // else, the issuer is not blocked on this acquisition so no need to release it } else { diff --git a/src/kernel/activity/SemaphoreImpl.hpp b/src/kernel/activity/SemaphoreImpl.hpp index d715a650a5..e7b21d2b0c 100644 --- a/src/kernel/activity/SemaphoreImpl.hpp +++ b/src/kernel/activity/SemaphoreImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,13 +6,13 @@ #ifndef SIMGRID_KERNEL_ACTIVITY_SEMAPHOREIMPL_HPP #define SIMGRID_KERNEL_ACTIVITY_SEMAPHOREIMPL_HPP -#include -#include - #include "simgrid/s4u/Semaphore.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SynchroObserver.hpp" +#include +#include + namespace simgrid::kernel::activity { /** Semaphore Acquisition: the act / process of acquiring the semaphore. @@ -35,7 +35,6 @@ public: bool test(actor::ActorImpl* issuer = nullptr) override { return granted_; } void wait_for(actor::ActorImpl* issuer, double timeout) override; - void post() override; void finish() override; void cancel() override; void set_exception(actor::ActorImpl* issuer) override @@ -50,7 +49,7 @@ class XBT_PUBLIC SemaphoreImpl { std::deque ongoing_acquisitions_; static unsigned next_id_; - unsigned id_ = next_id_++; + const unsigned id_ = next_id_++; friend SemAcquisitionImpl; friend actor::SemaphoreObserver; diff --git a/src/kernel/activity/SleepImpl.cpp b/src/kernel/activity/SleepImpl.cpp index 0288909a25..6a529e8cd6 100644 --- a/src/kernel/activity/SleepImpl.cpp +++ b/src/kernel/activity/SleepImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -27,33 +27,28 @@ SleepImpl& SleepImpl::set_duration(double duration) SleepImpl* SleepImpl::start() { - surf_action_ = host_->get_cpu()->sleep(duration_); - surf_action_->set_activity(this); + model_action_ = host_->get_cpu()->sleep(duration_); + model_action_->set_activity(this); XBT_DEBUG("Create sleep synchronization %p", this); return this; } -void SleepImpl::post() +void SleepImpl::set_exception(actor::ActorImpl* issuer) +{ + /* FIXME: Really, nothing bad can happen while we sleep? */ +} +void SleepImpl::finish() { - if (surf_action_->get_state() == resource::Action::State::FAILED) { + if (model_action_->get_state() == resource::Action::State::FAILED) { if (host_ && not host_->is_on()) set_state(State::SRC_HOST_FAILURE); else set_state(State::CANCELED); - } else if (surf_action_->get_state() == resource::Action::State::FINISHED) { + } else if (model_action_->get_state() == resource::Action::State::FINISHED) { set_state(State::DONE); } clean_action(); - /* Answer all simcalls associated with the synchro */ - finish(); -} -void SleepImpl::set_exception(actor::ActorImpl* issuer) -{ - /* FIXME: Really, nothing bad can happen while we sleep? */ -} -void SleepImpl::finish() -{ XBT_DEBUG("SleepImpl::finish() in state %s", get_state_str()); while (not simcalls_.empty()) { const actor::Simcall* simcall = simcalls_.front(); diff --git a/src/kernel/activity/SleepImpl.hpp b/src/kernel/activity/SleepImpl.hpp index 5e22c49644..42aed855ad 100644 --- a/src/kernel/activity/SleepImpl.hpp +++ b/src/kernel/activity/SleepImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -17,7 +17,6 @@ class XBT_PUBLIC SleepImpl : public ActivityImpl_T { public: SleepImpl& set_host(s4u::Host* host); SleepImpl& set_duration(double duration); - void post() override; void set_exception(actor::ActorImpl* issuer) override; void finish() override; SleepImpl* start(); diff --git a/src/kernel/activity/Synchro.cpp b/src/kernel/activity/Synchro.cpp index 438a8f4b30..aa57662850 100644 --- a/src/kernel/activity/Synchro.cpp +++ b/src/kernel/activity/Synchro.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -28,8 +28,8 @@ SynchroImpl& SynchroImpl::set_timeout(double timeout) SynchroImpl* SynchroImpl::start() { - surf_action_ = host_->get_cpu()->sleep(timeout_); - surf_action_->set_activity(this); + model_action_ = host_->get_cpu()->sleep(timeout_); + model_action_->set_activity(this); return this; } @@ -49,17 +49,6 @@ void SynchroImpl::cancel() /* I cannot cancel raw synchros directly. */ } -void SynchroImpl::post() -{ - if (surf_action_->get_state() == resource::Action::State::FAILED) - set_state(State::FAILED); - else if (surf_action_->get_state() == resource::Action::State::FINISHED) - set_state(State::SRC_TIMEOUT); - - clean_action(); - /* Answer all simcalls associated with the synchro */ - finish(); -} void SynchroImpl::set_exception(actor::ActorImpl* issuer) { if (get_state() == State::FAILED) { @@ -74,6 +63,13 @@ void SynchroImpl::set_exception(actor::ActorImpl* issuer) void SynchroImpl::finish() { XBT_DEBUG("SynchroImpl::finish() in state %s", get_state_str()); + if (model_action_->get_state() == resource::Action::State::FAILED) + set_state(State::FAILED); + else if (model_action_->get_state() == resource::Action::State::FINISHED) + set_state(State::SRC_TIMEOUT); + + clean_action(); + xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size()); actor::Simcall* simcall = simcalls_.front(); simcalls_.pop_front(); diff --git a/src/kernel/activity/Synchro.hpp b/src/kernel/activity/Synchro.hpp index fe73b3b3e3..a2f8daa57a 100644 --- a/src/kernel/activity/Synchro.hpp +++ b/src/kernel/activity/Synchro.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -27,7 +27,6 @@ public: void suspend() override; void resume() override; void cancel() override; - void post() override; void set_exception(actor::ActorImpl* issuer) override; void finish() override; }; diff --git a/src/kernel/actor/ActorImpl.cpp b/src/kernel/actor/ActorImpl.cpp index bb40b4d284..61e0479325 100644 --- a/src/kernel/actor/ActorImpl.cpp +++ b/src/kernel/actor/ActorImpl.cpp @@ -1,20 +1,19 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "src/mc/mc_replay.hpp" #include #include #include -#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v333) -#include - +#include "src/internal_config.h" #include "src/kernel/EngineImpl.hpp" #if HAVE_SMPI #include "src/smpi/include/private.hpp" #endif -#include "src/surf/HostImpl.hpp" +#include "src/kernel/resource/HostImpl.hpp" #include #include @@ -22,18 +21,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_actor, kernel, "Logging specific to Actor's kernel side"); -/** - * @brief Returns the current agent. - * - * This functions returns the currently running SIMIX process. - * - * @return The SIMIX process - */ -simgrid::kernel::actor::ActorImpl* SIMIX_process_self() // XBT_ATTRIB_DEPRECATED_v333 -{ - return simgrid::kernel::actor::ActorImpl::self(); -} - namespace simgrid::kernel::actor { /*------------------------- [ ActorIDTrait ] -------------------------*/ @@ -48,17 +35,19 @@ ActorImpl* ActorImpl::self() return (self_context != nullptr) ? self_context->get_actor() : nullptr; } -ActorImpl::ActorImpl(xbt::string name, s4u::Host* host, aid_t ppid) - : ActorIDTrait(std::move(name), ppid), host_(host), piface_(this) +ActorImpl::ActorImpl(const std::string& name, s4u::Host* host, aid_t ppid) + : ActorIDTrait(name, ppid), host_(host), piface_(this) { simcall_.issuer_ = this; - stacksize_ = context::stack_size; + stacksize_ = context::Context::stack_size; } ActorImpl::~ActorImpl() { - if (EngineImpl::has_instance() && not EngineImpl::get_instance()->is_maestro(this)) + if (EngineImpl::has_instance() && not EngineImpl::get_instance()->is_maestro(this)) { s4u::Actor::on_destruction(*get_ciface()); + get_ciface()->on_this_destruction(*get_ciface()); + } } /* Become an actor in the simulation @@ -80,7 +69,7 @@ ActorImplPtr ActorImpl::attach(const std::string& name, void* data, s4u::Host* h throw HostFailureException(XBT_THROW_POINT, "Cannot attach actor on failed host."); } - auto* actor = new ActorImpl(xbt::string(name), host, /*ppid*/ -1); + auto* actor = new ActorImpl(name, host, /*ppid*/ -1); /* Actor data */ actor->piface_.set_data(data); actor->code_ = nullptr; @@ -140,14 +129,9 @@ void ActorImpl::cleanup_from_kernel() if (not kernel_destroy_list_hook.is_linked()) engine->add_actor_to_destroy_list(*this); - if (has_to_auto_restart() && not get_host()->is_on()) { - XBT_DEBUG("Insert host %s to watched_hosts because it's off and %s needs to restart", get_host()->get_cname(), - get_cname()); - watched_hosts().insert(get_host()->get_name()); - } - undaemonize(); s4u::Actor::on_termination(*get_ciface()); + get_ciface()->on_this_termination(*get_ciface()); while (not mailboxes_.empty()) mailboxes_.back()->set_receiver(nullptr); @@ -202,9 +186,9 @@ void ActorImpl::exit() activity::ActivityImplPtr activity = waiting_synchro_; activity->cancel(); activity->set_state(activity::State::FAILED); - activity->post(); + activity->finish(); - activities_.remove(waiting_synchro_); + activities_.erase(waiting_synchro_); waiting_synchro_ = nullptr; } for (auto const& activity : activities_) @@ -294,6 +278,8 @@ void ActorImpl::yield() if (not wannadie()) smpi_switch_data_segment(get_iface()); #endif + if (simgrid_mc_replay_show_backtraces) + xbt_backtrace_display_current(); } /** This actor will be terminated automatically when the last non-daemon actor finishes */ @@ -369,12 +355,12 @@ activity::ActivityImplPtr ActorImpl::join(const ActorImpl* actor, double timeout { activity::ActivityImplPtr sleep_activity = this->sleep(timeout); if (actor->wannadie() || actor->to_be_freed()) { - if (sleep_activity->surf_action_) - sleep_activity->surf_action_->finish(resource::Action::State::FINISHED); + if (sleep_activity->model_action_) + sleep_activity->model_action_->finish(resource::Action::State::FINISHED); } else { actor->on_exit->emplace_back([sleep_activity](bool) { - if (sleep_activity->surf_action_) - sleep_activity->surf_action_->finish(resource::Action::State::FINISHED); + if (sleep_activity->model_action_) + sleep_activity->model_action_->finish(resource::Action::State::FINISHED); }); } return sleep_activity; @@ -383,10 +369,10 @@ activity::ActivityImplPtr ActorImpl::join(const ActorImpl* actor, double timeout activity::ActivityImplPtr ActorImpl::sleep(double duration) { if (not host_->is_on()) - throw_exception(std::make_exception_ptr(HostFailureException( - XBT_THROW_POINT, std::string("Host ") + host_->get_cname() + " failed, you cannot sleep there."))); + throw_exception(std::make_exception_ptr( + HostFailureException(XBT_THROW_POINT, "Host " + host_->get_name() + " failed, you cannot sleep there."))); - auto sleep_activity = new activity::SleepImpl(); + auto* sleep_activity = new activity::SleepImpl(); sleep_activity->set_name("sleep").set_host(host_).set_duration(duration).start(); return activity::SleepImplPtr(sleep_activity); } @@ -401,7 +387,7 @@ void ActorImpl::throw_exception(std::exception_ptr e) /* cancel the blocking synchro if any */ if (waiting_synchro_) { waiting_synchro_->cancel(); - activities_.remove(waiting_synchro_); + activities_.erase(waiting_synchro_); waiting_synchro_ = nullptr; } } @@ -430,7 +416,7 @@ void ActorImpl::set_host(s4u::Host* dest) ActorImplPtr ActorImpl::init(const std::string& name, s4u::Host* host) const { - auto* actor = new ActorImpl(xbt::string(name), host, get_pid()); + auto* actor = new ActorImpl(name, host, get_pid()); intrusive_ptr_add_ref(actor); /* The on_creation() signal must be delayed until there, where the pid and everything is set */ @@ -473,9 +459,9 @@ ActorImplPtr ActorImpl::create(const std::string& name, const ActorCode& code, v ActorImplPtr actor; if (parent_actor != nullptr) - actor = parent_actor->init(xbt::string(name), host); + actor = parent_actor->init(name, host); else - actor = self()->init(xbt::string(name), host); + actor = self()->init(name, host); actor->piface_.set_data(data); /* actor data */ @@ -508,7 +494,7 @@ void create_maestro(const std::function& code) { auto* engine = EngineImpl::get_instance(); /* Create maestro actor and initialize it */ - auto* maestro = new ActorImpl(xbt::string(""), /*host*/ nullptr, /*ppid*/ -1); + auto* maestro = new ActorImpl(/*name*/ "", /*host*/ nullptr, /*ppid*/ -1); if (not code) { maestro->context_.reset(engine->get_context_factory()->create_context(ActorCode(), maestro)); @@ -520,16 +506,24 @@ void create_maestro(const std::function& code) engine->set_maestro(maestro); } -} // namespace simgrid::kernel::actor - -/* needs to be public and without simcall because it is called by exceptions and logging events */ -const char* SIMIX_process_self_get_name() // XBT_ATTRIB_DEPRECATED_v333 +/** (in kernel mode) unpack the simcall and activate the handler */ +void ActorImpl::simcall_handle(int times_considered) { - return simgrid::s4u::Actor::is_maestro() ? "maestro" : simgrid::kernel::actor::ActorImpl::self()->get_cname(); -} + XBT_DEBUG("Handling simcall %p: %s(%ld) %s (times_considered:%d)", &simcall_, simcall_.issuer_->get_cname(), + simcall_.issuer_->get_pid(), + (simcall_.observer_ != nullptr ? simcall_.observer_->to_string().c_str() : simcall_.get_cname()), + times_considered); + if (simcall_.observer_ != nullptr) + simcall_.observer_->prepare(times_considered); + if (wannadie()) + return; -int SIMIX_is_maestro() // XBT_ATTRIB_DEPRECATED_v333 -{ - const auto* self = simgrid::kernel::actor::ActorImpl::self(); - return self != nullptr && self->is_maestro(); + xbt_assert(simcall_.call_ != Simcall::Type::NONE, "Asked to do the noop syscall on %s@%s", get_cname(), + get_host()->get_cname()); + + (*simcall_.code_)(); + if (simcall_.call_ == Simcall::Type::RUN_ANSWERED) + simcall_answer(); } + +} // namespace simgrid::kernel::actor diff --git a/src/kernel/actor/ActorImpl.hpp b/src/kernel/actor/ActorImpl.hpp index 8f6f640aee..69741aceee 100644 --- a/src/kernel/actor/ActorImpl.hpp +++ b/src/kernel/actor/ActorImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,11 +9,16 @@ #include "Simcall.hpp" #include "simgrid/kernel/Timer.hpp" #include "simgrid/s4u/Actor.hpp" +#include "src/kernel/actor/Simcall.hpp" #include "xbt/PropertyHolder.hpp" + +#include #include #include #include #include +#include +#include #include namespace simgrid::kernel::actor { @@ -21,22 +26,20 @@ class ProcessArg; /*------------------------- [ ActorIDTrait ] -------------------------*/ class XBT_PUBLIC ActorIDTrait { - xbt::string name_; - aid_t pid_ = 0; - aid_t ppid_ = -1; + std::string name_; + aid_t pid_ = 0; + aid_t ppid_ = -1; static unsigned long maxpid_; public: explicit ActorIDTrait(const std::string& name, aid_t ppid); - const xbt::string& get_name() const { return name_; } + const std::string& get_name() const { return name_; } const char* get_cname() const { return name_.c_str(); } aid_t get_pid() const { return pid_; } aid_t get_ppid() const { return ppid_; } static unsigned long get_maxpid() { return maxpid_; } - // In MC mode, the application sends this pointer to the MC - static unsigned long* get_maxpid_addr() { return &maxpid_; } }; /*------------------------- [ ActorRestartingTrait ] -------------------------*/ @@ -64,7 +67,7 @@ class XBT_PUBLIC ActorImpl : public xbt::PropertyHolder, public ActorIDTrait, pu friend activity::MailboxImpl; public: - ActorImpl(xbt::string name, s4u::Host* host, aid_t ppid); + ActorImpl(const std::string& name, s4u::Host* host, aid_t ppid); ActorImpl(const ActorImpl&) = delete; ActorImpl& operator=(const ActorImpl&) = delete; ~ActorImpl(); @@ -102,7 +105,7 @@ public: bool suspended_ = false; activity::ActivityImplPtr waiting_synchro_ = nullptr; /* the current blocking synchro if any */ - std::list activities_; /* the current non-blocking synchros */ + std::set activities_; /* the current non-blocking synchros */ Simcall simcall_; /* list of functions executed when the actor dies */ std::shared_ptr>> on_exit = diff --git a/src/kernel/actor/CommObserver.cpp b/src/kernel/actor/CommObserver.cpp index f44571e5bc..a7257d780d 100644 --- a/src/kernel/actor/CommObserver.cpp +++ b/src/kernel/actor/CommObserver.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,6 +6,7 @@ #include "simgrid/s4u/Host.hpp" #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/activity/MailboxImpl.hpp" +#include "src/kernel/activity/MessageQueueImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" #include "src/mc/mc_config.hpp" @@ -16,18 +17,19 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(obs_comm, mc_observer, "Logging specific to the namespace simgrid::kernel::actor { -ActivityTestanySimcall::ActivityTestanySimcall(ActorImpl* actor, const std::vector& activities) - : ResultingSimcall(actor, -1), activities_(activities) -{ -} - -int ActivityTestanySimcall::get_max_consider() +ActivityTestanySimcall::ActivityTestanySimcall(ActorImpl* actor, const std::vector& activities, + std::string_view fun_call) + : ResultingSimcall(actor, -1), activities_(activities), fun_call_(fun_call) { indexes_.clear(); // list all the activities that are ready for (unsigned i = 0; i < activities_.size(); i++) if (activities_[i]->test(get_issuer())) indexes_.push_back(i); +} + +int ActivityTestanySimcall::get_max_consider() const +{ return indexes_.size() + 1; } @@ -38,62 +40,136 @@ void ActivityTestanySimcall::prepare(int times_considered) else next_value_ = -1; } -static void serialize_activity_test(const activity::ActivityImpl* act, std::stringstream& stream) +static void serialize_activity_test(const activity::ActivityImpl* act, std::string const& call_location, + std::stringstream& stream) { - if (auto* comm = dynamic_cast(act)) { + if (const auto* comm = dynamic_cast(act)) { stream << " " << (short)mc::Transition::Type::COMM_TEST; - stream << ' ' << (uintptr_t)comm; + stream << ' ' << comm->get_id(); stream << ' ' << (comm->src_actor_ != nullptr ? comm->src_actor_->get_pid() : -1); stream << ' ' << (comm->dst_actor_ != nullptr ? comm->dst_actor_->get_pid() : -1); stream << ' ' << comm->get_mailbox_id(); - stream << ' ' << (uintptr_t)comm->src_buff_ << ' ' << (uintptr_t)comm->dst_buff_ << ' ' << comm->src_buff_size_; + stream << ' ' << call_location; } else { stream << (short)mc::Transition::Type::UNKNOWN; + XBT_CRITICAL("Unknown transition in a test any. Bad things may happen"); + } +} +static std::string to_string_activity_test(const activity::ActivityImpl* act) +{ + if (const auto* comm = dynamic_cast(act)) { + return "CommTest(comm_id:" + std::to_string(comm->get_id()) + + " src:" + std::to_string(comm->src_actor_ != nullptr ? comm->src_actor_->get_pid() : -1) + + " dst:" + std::to_string(comm->dst_actor_ != nullptr ? comm->dst_actor_->get_pid() : -1) + + " mbox:" + std::to_string(comm->get_mailbox_id()) + ")"; + } else { + return "TestUnknownType()"; } } void ActivityTestanySimcall::serialize(std::stringstream& stream) const { + XBT_DEBUG("Serialize %s", to_string().c_str()); stream << (short)mc::Transition::Type::TESTANY << ' ' << activities_.size() << ' '; - for (auto const& act : activities_) { - serialize_activity_test(act, stream); + for (auto const* act : activities_) { + // fun_call of each activity embedded in the TestAny is not known, so let's use the location of the TestAny itself + serialize_activity_test(act, fun_call_, stream); stream << ' '; } + stream << fun_call_; } +std::string ActivityTestanySimcall::to_string() const +{ + std::stringstream buffer("TestAny("); + bool first = true; + for (auto const* act : activities_) { + if (first) + first = false; + else + buffer << " | "; + buffer << to_string_activity_test(act); + } + buffer << ")"; + return buffer.str(); +} + void ActivityTestSimcall::serialize(std::stringstream& stream) const { - serialize_activity_test(activity_, stream); + serialize_activity_test(activity_, fun_call_, stream); } -static void serialize_activity_wait(const activity::ActivityImpl* act, bool timeout, std::stringstream& stream) +std::string ActivityTestSimcall::to_string() const { - if (auto* comm = dynamic_cast(act)) { + return to_string_activity_test(activity_); +} +static void serialize_activity_wait(const activity::ActivityImpl* act, bool timeout, std::string const& call_location, + std::stringstream& stream) +{ + if (const auto* comm = dynamic_cast(act)) { stream << (short)mc::Transition::Type::COMM_WAIT << ' '; - stream << timeout << ' ' << (uintptr_t)comm; + stream << timeout << ' ' << comm->get_id(); stream << ' ' << (comm->src_actor_ != nullptr ? comm->src_actor_->get_pid() : -1); stream << ' ' << (comm->dst_actor_ != nullptr ? comm->dst_actor_->get_pid() : -1); stream << ' ' << comm->get_mailbox_id(); - stream << ' ' << (uintptr_t)comm->src_buff_ << ' ' << (uintptr_t)comm->dst_buff_ << ' ' << comm->src_buff_size_; + stream << ' ' << call_location; } else { stream << (short)mc::Transition::Type::UNKNOWN; } } +static std::string to_string_activity_wait(const activity::ActivityImpl* act) +{ + if (const auto* comm = dynamic_cast(act)) { + return "CommWait(comm_id:" + std::to_string(comm->get_id()) + + " src:" + std::to_string(comm->src_actor_ != nullptr ? comm->src_actor_->get_pid() : -1) + + " dst:" + std::to_string(comm->dst_actor_ != nullptr ? comm->dst_actor_->get_pid() : -1) + + " mbox:" + (comm->get_mailbox() == nullptr ? "-" : comm->get_mailbox()->get_name()) + + "(id:" + std::to_string(comm->get_mailbox_id()) + "))"; + } else { + return "WaitUnknownType()"; + } +} void ActivityWaitSimcall::serialize(std::stringstream& stream) const { - serialize_activity_wait(activity_, timeout_ > 0, stream); + serialize_activity_wait(activity_, timeout_ > 0, fun_call_, stream); } void ActivityWaitanySimcall::serialize(std::stringstream& stream) const { + XBT_DEBUG("Serialize %s", to_string().c_str()); stream << (short)mc::Transition::Type::WAITANY << ' ' << activities_.size() << ' '; - for (auto const& act : activities_) { - serialize_activity_wait(act, timeout_ > 0, stream); + for (auto const* act : activities_) { + // fun_call of each activity embedded in the WaitAny is not known, so let's use the location of the WaitAny itself + serialize_activity_wait(act, timeout_ > 0, fun_call_, stream); stream << ' '; } + stream << fun_call_; +} +std::string ActivityWaitSimcall::to_string() const +{ + return to_string_activity_wait(activity_); +} +std::string ActivityWaitanySimcall::to_string() const +{ + std::stringstream buffer("WaitAny("); + bool first = true; + for (auto const* act : activities_) { + if (first) + first = false; + else + buffer << " | "; + buffer << to_string_activity_test(act); + } + buffer << ")"; + return buffer.str(); } ActivityWaitanySimcall::ActivityWaitanySimcall(ActorImpl* actor, const std::vector& activities, - double timeout) - : ResultingSimcall(actor, -1), activities_(activities), timeout_(timeout) + double timeout, std::string_view fun_call) + : ResultingSimcall(actor, -1), activities_(activities), timeout_(timeout), fun_call_(fun_call) { + // list all the activities that are ready + indexes_.clear(); + for (unsigned i = 0; i < activities_.size(); i++) + if (activities_[i]->test(get_issuer())) + indexes_.push_back(i); } bool ActivityWaitSimcall::is_enabled() @@ -119,14 +195,8 @@ bool ActivityWaitanySimcall::is_enabled() return not indexes_.empty(); } -int ActivityWaitanySimcall::get_max_consider() +int ActivityWaitanySimcall::get_max_consider() const { - // list all the activities that are ready - indexes_.clear(); - for (unsigned i = 0; i < activities_.size(); i++) - if (activities_[i]->test(get_issuer())) - indexes_.push_back(i); - int res = indexes_.size(); // if (_sg_mc_timeout && timeout_) // res++; @@ -144,18 +214,55 @@ void ActivityWaitanySimcall::prepare(int times_considered) void CommIsendSimcall::serialize(std::stringstream& stream) const { - stream << (short)mc::Transition::Type::COMM_SEND << ' '; - stream << (uintptr_t)comm_ << ' ' << mbox_->get_id() << ' ' << (uintptr_t)src_buff_ << ' ' << src_buff_size_ << ' ' - << tag_; - XBT_DEBUG("SendObserver comm:%p mbox:%u buff:%p size:%zu tag:%d", comm_, mbox_->get_id(), src_buff_, src_buff_size_, - tag_); + /* Note that the comm_ is 0 until after the execution of the simcall */ + stream << (short)mc::Transition::Type::COMM_ASYNC_SEND << ' '; + stream << (comm_ ? comm_->get_id() : 0) << ' ' << mbox_->get_id() << ' ' << tag_; + XBT_DEBUG("SendObserver comm:%p mbox:%u tag:%d", comm_, mbox_->get_id(), tag_); + stream << ' ' << fun_call_; +} +std::string CommIsendSimcall::to_string() const +{ + return "CommAsyncSend(comm_id: " + std::to_string(comm_ ? comm_->get_id() : 0) + + " mbox:" + std::to_string(mbox_->get_id()) + " tag: " + std::to_string(tag_) + ")"; } void CommIrecvSimcall::serialize(std::stringstream& stream) const { - stream << (short)mc::Transition::Type::COMM_RECV << ' '; - stream << (uintptr_t)comm_ << ' ' << mbox_->get_id() << ' ' << (uintptr_t)dst_buff_ << ' ' << tag_; - XBT_DEBUG("RecvObserver comm:%p mbox:%u buff:%p tag:%d", comm_, mbox_->get_id(), dst_buff_, tag_); + /* Note that the comm_ is 0 until after the execution of the simcall */ + stream << (short)mc::Transition::Type::COMM_ASYNC_RECV << ' '; + stream << (comm_ ? comm_->get_id() : 0) << ' ' << mbox_->get_id() << ' ' << tag_; + XBT_DEBUG("RecvObserver comm:%p mbox:%u tag:%d", comm_, mbox_->get_id(), tag_); + stream << ' ' << fun_call_; } +std::string CommIrecvSimcall::to_string() const +{ + return "CommAsyncRecv(comm_id: " + std::to_string(comm_ ? comm_->get_id() : 0) + + " mbox:" + std::to_string(mbox_->get_id()) + " tag: " + std::to_string(tag_) + ")"; +} + +void MessIputSimcall::serialize(std::stringstream& stream) const +{ + stream << mess_ << ' ' << queue_; + XBT_DEBUG("PutObserver mess:%p queue:%p", mess_, queue_); +} + +std::string MessIputSimcall::to_string() const +{ + return "MessAsyncPut(queue:" + queue_->get_name() + ")"; +} + +void MessIgetSimcall::serialize(std::stringstream& stream) const +{ + stream << mess_ << ' ' << queue_; + XBT_DEBUG("GettObserver mess:%p queue:%p", mess_, queue_); +} + +std::string MessIgetSimcall::to_string() const +{ + return "MessAsyncGet(queue:" + queue_->get_name() + ")"; +} + + + } // namespace simgrid::kernel::actor diff --git a/src/kernel/actor/CommObserver.hpp b/src/kernel/actor/CommObserver.hpp index 9cba17d454..161e095e05 100644 --- a/src/kernel/actor/CommObserver.hpp +++ b/src/kernel/actor/CommObserver.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,33 +12,37 @@ #include "xbt/asserts.h" #include +#include namespace simgrid::kernel::actor { class ActivityTestSimcall final : public ResultingSimcall { activity::ActivityImpl* const activity_; + std::string fun_call_; public: - ActivityTestSimcall(ActorImpl* actor, activity::ActivityImpl* activity) - : ResultingSimcall(actor, true), activity_(activity) + ActivityTestSimcall(ActorImpl* actor, activity::ActivityImpl* activity, std::string_view fun_call) + : ResultingSimcall(actor, true), activity_(activity), fun_call_(fun_call) { } - bool is_visible() const override { return true; } activity::ActivityImpl* get_activity() const { return activity_; } void serialize(std::stringstream& stream) const override; + std::string to_string() const override; }; class ActivityTestanySimcall final : public ResultingSimcall { const std::vector& activities_; std::vector indexes_; // indexes in activities_ pointing to ready activities (=whose test() is positive) int next_value_ = 0; + std::string fun_call_; public: - ActivityTestanySimcall(ActorImpl* actor, const std::vector& activities); - bool is_visible() const override { return true; } + ActivityTestanySimcall(ActorImpl* actor, const std::vector& activities, + std::string_view fun_call); bool is_enabled() override { return true; /* can return -1 if no activity is ready */ } void serialize(std::stringstream& stream) const override; - int get_max_consider() override; + std::string to_string() const override; + int get_max_consider() const override; void prepare(int times_considered) override; const std::vector& get_activities() const { return activities_; } int get_value() const { return next_value_; } @@ -47,14 +51,15 @@ public: class ActivityWaitSimcall final : public ResultingSimcall { activity::ActivityImpl* activity_; const double timeout_; + std::string fun_call_; public: - ActivityWaitSimcall(ActorImpl* actor, activity::ActivityImpl* activity, double timeout) - : ResultingSimcall(actor, false), activity_(activity), timeout_(timeout) + ActivityWaitSimcall(ActorImpl* actor, activity::ActivityImpl* activity, double timeout, std::string_view fun_call) + : ResultingSimcall(actor, false), activity_(activity), timeout_(timeout), fun_call_(fun_call) { } void serialize(std::stringstream& stream) const override; - bool is_visible() const override { return true; } + std::string to_string() const override; bool is_enabled() override; activity::ActivityImpl* get_activity() const { return activity_; } void set_activity(activity::ActivityImpl* activity) { activity_ = activity; } @@ -66,14 +71,16 @@ class ActivityWaitanySimcall final : public ResultingSimcall { std::vector indexes_; // indexes in activities_ pointing to ready activities (=whose test() is positive) const double timeout_; int next_value_ = 0; + std::string fun_call_; public: - ActivityWaitanySimcall(ActorImpl* actor, const std::vector& activities, double timeout); + ActivityWaitanySimcall(ActorImpl* actor, const std::vector& activities, double timeout, + std::string_view fun_call); bool is_enabled() override; void serialize(std::stringstream& stream) const override; - bool is_visible() const override { return true; } + std::string to_string() const override; void prepare(int times_considered) override; - int get_max_consider() override; + int get_max_consider() const override; const std::vector& get_activities() const { return activities_; } double get_timeout() const { return timeout_; } int get_value() const { return next_value_; } @@ -94,6 +101,8 @@ class CommIsendSimcall final : public SimcallObserver { std::function clean_fun_; // used to free the synchro in case of problem after a detached send std::function copy_data_fun_; // used to copy data if not default one + std::string fun_call_; + public: CommIsendSimcall( ActorImpl* actor, activity::MailboxImpl* mbox, double payload_size, double rate, unsigned char* src_buff, @@ -101,7 +110,7 @@ public: const std::function& clean_fun, // used to free the synchro in case of problem after a detached send const std::function& copy_data_fun, // used to copy data if not default one - void* payload, bool detached) + void* payload, bool detached, std::string_view fun_call) : SimcallObserver(actor) , mbox_(mbox) , payload_size_(payload_size) @@ -113,10 +122,11 @@ public: , match_fun_(match_fun) , clean_fun_(clean_fun) , copy_data_fun_(copy_data_fun) + , fun_call_(fun_call) { } void serialize(std::stringstream& stream) const override; - bool is_visible() const override { return true; } + std::string to_string() const override; activity::MailboxImpl* get_mailbox() const { return mbox_; } double get_payload_size() const { return payload_size_; } double get_rate() const { return rate_; } @@ -144,11 +154,13 @@ class CommIrecvSimcall final : public SimcallObserver { std::function match_fun_; std::function copy_data_fun_; // used to copy data if not default one + std::string fun_call_; + public: CommIrecvSimcall(ActorImpl* actor, activity::MailboxImpl* mbox, unsigned char* dst_buff, size_t* dst_buff_size, const std::function& match_fun, const std::function& copy_data_fun, void* payload, - double rate) + double rate, std::string_view fun_call) : SimcallObserver(actor) , mbox_(mbox) , dst_buff_(dst_buff) @@ -157,10 +169,11 @@ public: , rate_(rate) , match_fun_(match_fun) , copy_data_fun_(copy_data_fun) + , fun_call_(fun_call) { } void serialize(std::stringstream& stream) const override; - bool is_visible() const override { return true; } + std::string to_string() const override; activity::MailboxImpl* get_mailbox() const { return mbox_; } double get_rate() const { return rate_; } unsigned char* get_dst_buff() const { return dst_buff_; } @@ -173,6 +186,52 @@ public: auto const& get_copy_data_fun() const { return copy_data_fun_; } }; +class MessIputSimcall final : public SimcallObserver { + activity::MessageQueueImpl* queue_; + void* payload_; + activity::MessImpl* mess_ = {}; + +public: + MessIputSimcall( + ActorImpl* actor, activity::MessageQueueImpl* queue, void* payload) + : SimcallObserver(actor) + , queue_(queue) + , payload_(payload) + { + } + void serialize(std::stringstream& stream) const override; + std::string to_string() const override; + activity::MessageQueueImpl* get_queue() const { return queue_; } + void* get_payload() const { return payload_; } + void set_message(activity::MessImpl* mess) { mess_ = mess; } +}; + +class MessIgetSimcall final : public SimcallObserver { + activity::MessageQueueImpl* queue_; + unsigned char* dst_buff_; + size_t* dst_buff_size_; + void* payload_; + activity::MessImpl* mess_ = {}; + +public: + MessIgetSimcall(ActorImpl* actor, activity::MessageQueueImpl* queue, unsigned char* dst_buff, size_t* dst_buff_size, + void* payload) + : SimcallObserver(actor) + , queue_(queue) + , dst_buff_(dst_buff) + , dst_buff_size_(dst_buff_size) + , payload_(payload) + { + } + void serialize(std::stringstream& stream) const override; + std::string to_string() const override; + activity::MessageQueueImpl* get_queue() const { return queue_; } + unsigned char* get_dst_buff() const { return dst_buff_; } + size_t* get_dst_buff_size() const { return dst_buff_size_; } + void* get_payload() const { return payload_; } + void set_message(activity::MessImpl* mess) { mess_ = mess; } +}; + } // namespace simgrid::kernel::actor #endif diff --git a/src/kernel/actor/Simcall.cpp b/src/kernel/actor/Simcall.cpp index 156636dbc6..05f232f19d 100644 --- a/src/kernel/actor/Simcall.cpp +++ b/src/kernel/actor/Simcall.cpp @@ -1,39 +1,22 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "Simcall.hpp" +#include "src/kernel/actor/Simcall.hpp" +#include "simgrid/modelchecker.h" #include "simgrid/s4u/Host.hpp" +#include "src/kernel/EngineImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" #include "src/kernel/context/Context.hpp" +#include "src/mc/mc_replay.hpp" #include "xbt/log.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_simcall, kernel, "transmuting from user request into kernel handlers"); namespace simgrid::kernel::actor { -/** @private - * @brief (in kernel mode) unpack the simcall and activate the handler - * - */ -void ActorImpl::simcall_handle(int times_considered) -{ - XBT_DEBUG("Handling simcall %p: %s", &simcall_, simcall_.get_cname()); - if (simcall_.observer_ != nullptr) - simcall_.observer_->prepare(times_considered); - if (wannadie()) - return; - - xbt_assert(simcall_.call_ != Simcall::Type::NONE, "Asked to do the noop syscall on %s@%s", get_cname(), - get_host()->get_cname()); - - (*simcall_.code_)(); - if (simcall_.call_ == Simcall::Type::RUN_ANSWERED) - simcall_answer(); -} - /** @brief returns a printable string representing a simcall */ const char* Simcall::get_cname() const { @@ -48,5 +31,63 @@ const char* Simcall::get_cname() const return to_c_str(call_); } } +ObjectAccessSimcallItem::ObjectAccessSimcallItem() +{ + take_ownership(); +} +void ObjectAccessSimcallItem::take_ownership() +{ + simcall_owner_ = ActorImpl::self(); +} } // namespace simgrid::kernel::actor + +static void simcall(simgrid::kernel::actor::Simcall::Type call, std::function const& code, + simgrid::kernel::actor::SimcallObserver* observer) +{ + auto* self = simgrid::kernel::actor::ActorImpl::self(); + self->simcall_.call_ = call; + self->simcall_.code_ = &code; + self->simcall_.observer_ = observer; + if (simgrid::kernel::EngineImpl::get_instance()->is_maestro(self)) { + self->simcall_handle(0); + } else { + XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), self->simcall_.get_cname()); + self->yield(); + } + self->simcall_.observer_ = nullptr; +} + +void simcall_run_answered(std::function const& code, simgrid::kernel::actor::SimcallObserver* observer) +{ + // The function `code` is called in kernel mode (either because we are already in maestor or after a context switch) + // and simcall_answer() is called + simcall(simgrid::kernel::actor::Simcall::Type::RUN_ANSWERED, code, observer); +} + +void simcall_run_blocking(std::function const& code, simgrid::kernel::actor::SimcallObserver* observer) +{ + // The function `code` is called in kernel mode (either because we are already in maestor or after a context switch) + // BUT simcall_answer IS NOT CALLED + simcall(simgrid::kernel::actor::Simcall::Type::RUN_BLOCKING, code, observer); +} + +void simcall_run_object_access(std::function const& code, simgrid::kernel::actor::ObjectAccessSimcallItem* item) +{ + auto* self = simgrid::kernel::actor::ActorImpl::self(); + + // We only need a simcall if the order of the setters is important (parallel run or MC execution). + // Otherwise, just call the function with no simcall + + if (simgrid::kernel::context::Context::is_parallel() || MC_is_active() || MC_record_replay_is_active()) { + simgrid::kernel::actor::ObjectAccessSimcallObserver observer{self, item}; + simcall(simgrid::kernel::actor::Simcall::Type::RUN_ANSWERED, code, &observer); + item->take_ownership(); + } else { + // don't return from the context-switch we don't do + self->simcall_.call_ = simgrid::kernel::actor::Simcall::Type::RUN_BLOCKING; + self->simcall_.code_ = &code; + self->simcall_.observer_ = nullptr; + self->simcall_handle(0); + } +} diff --git a/src/kernel/actor/Simcall.hpp b/src/kernel/actor/Simcall.hpp index b98ee1e4fb..0138878bd9 100644 --- a/src/kernel/actor/Simcall.hpp +++ b/src/kernel/actor/Simcall.hpp @@ -1,21 +1,17 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SIMCALL_HPP -#define SIMCALL_HPP +#ifndef SIMGRID_SIMCALL_HPP +#define SIMGRID_SIMCALL_HPP #include "simgrid/forward.h" -#include "src/kernel/activity/ActivityImpl.hpp" #include "xbt/utility.hpp" -/********************************* Simcalls *********************************/ namespace simgrid::kernel::actor { -/** - * @brief Represents a simcall to the kernel. - */ +/** Contains what's needed to run some code in kernel mode on behalf of an actor */ class Simcall { public: /** All possible simcalls. */ @@ -25,13 +21,19 @@ public: simgrid::kernel::actor::ActorImpl* issuer_ = nullptr; simgrid::kernel::timer::Timer* timeout_cb_ = nullptr; // Callback to timeouts simgrid::kernel::actor::SimcallObserver* observer_ = nullptr; // makes that simcall observable by the MC - unsigned int mc_max_consider_ = - 0; // How many times this simcall should be used. If >1, this will be a fork in the state space. std::function const* code_ = nullptr; const char* get_cname() const; }; +/** A thing that can be used for an ObjectAccess simcall (getter or setter). */ +class ObjectAccessSimcallItem { +public: + ObjectAccessSimcallItem(); + void take_ownership(); + ActorImpl* simcall_owner_; +}; + } // namespace simgrid::kernel::actor #endif diff --git a/src/kernel/actor/SimcallObserver.cpp b/src/kernel/actor/SimcallObserver.cpp index e4ffca22ff..d7657a4bcd 100644 --- a/src/kernel/actor/SimcallObserver.cpp +++ b/src/kernel/actor/SimcallObserver.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,6 +7,7 @@ #include "simgrid/s4u/Host.hpp" #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/activity/MailboxImpl.hpp" +#include "src/kernel/activity/MutexImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/mc/mc_config.hpp" @@ -16,15 +17,15 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_observer, mc, "Logging specific to MC simcall namespace simgrid::kernel::actor { -void SimcallObserver::serialize(std::stringstream& stream) const -{ - stream << (short)mc::Transition::Type::UNKNOWN; -} void RandomSimcall::serialize(std::stringstream& stream) const { stream << (short)mc::Transition::Type::RANDOM << ' '; stream << min_ << ' ' << max_; } +std::string RandomSimcall::to_string() const +{ + return "Random(min:" + std::to_string(min_) + " max:" + std::to_string(max_) + ")"; +} void RandomSimcall::prepare(int times_considered) { @@ -32,17 +33,55 @@ void RandomSimcall::prepare(int times_considered) XBT_DEBUG("MC_RANDOM(%d, %d) will return %d after %d times", min_, max_, next_value_, times_considered); } -int RandomSimcall::get_max_consider() +int RandomSimcall::get_max_consider() const { return max_ - min_ + 1; } -bool ConditionWaitSimcall::is_enabled() +ActorJoinSimcall::ActorJoinSimcall(ActorImpl* actor, ActorImpl* other, double timeout) + : SimcallObserver(actor), other_(s4u::ActorPtr(other->get_iface())), timeout_(timeout) { - if (static bool warned = false; not warned) { - XBT_INFO("Using condition variables in model-checked code is still experimental. Use at your own risk"); - warned = true; - } - return true; } +bool ActorJoinSimcall::is_enabled() +{ + return other_->get_impl()->wannadie(); +} +void ActorJoinSimcall::serialize(std::stringstream& stream) const +{ + stream << (short)mc::Transition::Type::ACTOR_JOIN << ' '; + stream << other_->get_pid() << ' ' << (timeout_ > 0); +} +std::string ActorJoinSimcall::to_string() const +{ + return "ActorJoin(pid:" + std::to_string(other_->get_pid()) + ")"; +} +void ActorSleepSimcall::serialize(std::stringstream& stream) const +{ + stream << (short)mc::Transition::Type::ACTOR_SLEEP; +} + +std::string ActorSleepSimcall::to_string() const +{ + return "ActorSleep()"; +} + +void ObjectAccessSimcallObserver::serialize(std::stringstream& stream) const +{ + stream << (short)mc::Transition::Type::OBJECT_ACCESS << ' '; + stream << object_ << ' ' << get_owner()->get_pid(); +} +std::string ObjectAccessSimcallObserver::to_string() const +{ + return "ObjectAccess(obj:" + ptr_to_id(object_) + + " owner:" + std::to_string(get_owner()->get_pid()) + ")"; +} +bool ObjectAccessSimcallObserver::is_visible() const +{ + return get_owner() != get_issuer(); +} +ActorImpl* ObjectAccessSimcallObserver::get_owner() const +{ + return object_->simcall_owner_; +} + } // namespace simgrid::kernel::actor diff --git a/src/kernel/actor/SimcallObserver.hpp b/src/kernel/actor/SimcallObserver.hpp index 6eabf88b57..de3f4fc27c 100644 --- a/src/kernel/actor/SimcallObserver.hpp +++ b/src/kernel/actor/SimcallObserver.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,6 +11,7 @@ #include "xbt/asserts.h" #include +#include namespace simgrid::kernel::actor { @@ -37,7 +38,7 @@ public: * If it's more than one (as with mc_random or waitany), we need to consider this transition several times to start * differing branches */ - virtual int get_max_consider() { return 1; } + virtual int get_max_consider() const { return 1; } /** Prepares the simcall to be used. * @@ -52,11 +53,15 @@ public: { /* Nothing to do by default */ } - /** Serialize to the given string buffer */ - virtual void serialize(std::stringstream& stream) const; + /** Serialize to the given string buffer, to send over the network */ + virtual void serialize(std::stringstream& stream) const = 0; - /** Some simcalls may only be observable under some conditions. - * Most simcalls are not visible from the MC because they don't have an observer at all. */ + /** Used to debug (to display the simcall on which each actor is blocked when displaying it */ + virtual std::string to_string() const = 0; + + /** Whether the MC should see this simcall. + * Simcall that don't have an observer (ie, most of them) are not visible from the MC, but if there is an observer, + * they are observable by default. */ virtual bool is_visible() const { return true; } }; @@ -80,32 +85,63 @@ class RandomSimcall final : public SimcallObserver { public: RandomSimcall(ActorImpl* actor, int min, int max) : SimcallObserver(actor), min_(min), max_(max) { - xbt_assert(min < max); + xbt_assert(min <= max); } void serialize(std::stringstream& stream) const override; - int get_max_consider() override; + std::string to_string() const override; + int get_max_consider() const override; void prepare(int times_considered) override; int get_value() const { return next_value_; } }; -class ConditionWaitSimcall final : public ResultingSimcall { - activity::ConditionVariableImpl* const cond_; - activity::MutexImpl* const mutex_; +class ActorJoinSimcall final : public SimcallObserver { + s4u::ActorPtr const other_; // We need a Ptr to ensure access to the actor after its end, but Ptr requires s4u const double timeout_; public: - ConditionWaitSimcall(ActorImpl* actor, activity::ConditionVariableImpl* cond, activity::MutexImpl* mutex, - double timeout = -1.0) - : ResultingSimcall(actor, false), cond_(cond), mutex_(mutex), timeout_(timeout) - { - } + ActorJoinSimcall(ActorImpl* actor, ActorImpl* other, double timeout = -1.0); + void serialize(std::stringstream& stream) const override; + std::string to_string() const override; bool is_enabled() override; - bool is_visible() const override { return false; } - activity::ConditionVariableImpl* get_cond() const { return cond_; } - activity::MutexImpl* get_mutex() const { return mutex_; } + + s4u::ActorPtr get_other_actor() const { return other_; } double get_timeout() const { return timeout_; } }; +class ActorSleepSimcall final : public SimcallObserver { + +public: + explicit ActorSleepSimcall(ActorImpl* actor) : SimcallObserver(actor) {} + void serialize(std::stringstream& stream) const override; + std::string to_string() const override; +}; + +class ObjectAccessSimcallObserver final : public SimcallObserver { + ObjectAccessSimcallItem* const object_; + +public: + ObjectAccessSimcallObserver(ActorImpl* actor, ObjectAccessSimcallItem* object) + : SimcallObserver(actor), object_(object) + { + } + void serialize(std::stringstream& stream) const override; + std::string to_string() const override; + bool is_visible() const override; + bool is_enabled() override { return true; } + + ActorImpl* get_owner() const; +}; + +/* Semi private template used by the to_string methods of various observer classes */ +template static std::string ptr_to_id(A* ptr) +{ + static std::unordered_map map({{nullptr, "-"}}); + auto [elm, inserted] = map.try_emplace(ptr); + if (inserted) + elm->second = std::to_string(map.size() - 1); + return elm->second; +} + } // namespace simgrid::kernel::actor #endif diff --git a/src/kernel/actor/SynchroObserver.cpp b/src/kernel/actor/SynchroObserver.cpp index 5e5ca9d6b6..50a4ce39eb 100644 --- a/src/kernel/actor/SynchroObserver.cpp +++ b/src/kernel/actor/SynchroObserver.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -28,6 +28,12 @@ void MutexObserver::serialize(std::stringstream& stream) const const auto* owner = get_mutex()->get_owner(); stream << (short)type_ << ' ' << get_mutex()->get_id() << ' ' << (owner != nullptr ? owner->get_pid() : -1); } +std::string MutexObserver::to_string() const +{ + return std::string(mc::Transition::to_c_str(type_)) + "(mutex_id:" + std::to_string(get_mutex()->get_id()) + + " owner:" + + (get_mutex()->get_owner() == nullptr ? "none" : std::to_string(get_mutex()->get_owner()->get_pid())) + ")"; +} bool MutexObserver::is_enabled() { @@ -43,7 +49,12 @@ SemaphoreObserver::SemaphoreObserver(ActorImpl* actor, mc::Transition::Type type void SemaphoreObserver::serialize(std::stringstream& stream) const { - stream << (short)type_ << ' ' << get_sem()->get_id() << ' ' << false /* Granted is ignored for LOCK/UNLOCK */; + stream << (short)type_ << ' ' << get_sem()->get_id() << ' ' << false /* Granted is ignored for LOCK/UNLOCK */ << ' ' + << get_sem()->get_capacity(); +} +std::string SemaphoreObserver::to_string() const +{ + return std::string(mc::Transition::to_c_str(type_)) + "(sem_id:" + std::to_string(get_sem()->get_id()) + ")"; } SemaphoreAcquisitionObserver::SemaphoreAcquisitionObserver(ActorImpl* actor, mc::Transition::Type type, @@ -57,13 +68,20 @@ bool SemaphoreAcquisitionObserver::is_enabled() } void SemaphoreAcquisitionObserver::serialize(std::stringstream& stream) const { - stream << (short)type_ << ' ' << acquisition_->semaphore_->get_id() << ' ' << acquisition_->granted_; + stream << (short)type_ << ' ' << acquisition_->semaphore_->get_id() << ' ' << acquisition_->granted_ << ' ' + << acquisition_->semaphore_->get_capacity(); +} +std::string SemaphoreAcquisitionObserver::to_string() const +{ + return std::string(mc::Transition::to_c_str(type_)) + + "(sem_id:" + std::to_string(acquisition_->semaphore_->get_id()) + ' ' + + (acquisition_->granted_ ? "granted)" : "not granted)"); } BarrierObserver::BarrierObserver(ActorImpl* actor, mc::Transition::Type type, activity::BarrierImpl* bar) : ResultingSimcall(actor, false), type_(type), barrier_(bar), timeout_(-1) { - xbt_assert(type_ == mc::Transition::Type::BARRIER_LOCK); + xbt_assert(type_ == mc::Transition::Type::BARRIER_ASYNC_LOCK); } BarrierObserver::BarrierObserver(ActorImpl* actor, mc::Transition::Type type, activity::BarrierAcquisitionImpl* acqui, double timeout) @@ -76,10 +94,34 @@ void BarrierObserver::serialize(std::stringstream& stream) const xbt_assert(barrier_ != nullptr || (acquisition_ != nullptr && acquisition_->barrier_ != nullptr)); stream << (short)type_ << ' ' << (barrier_ != nullptr ? barrier_->get_id() : acquisition_->barrier_->get_id()); } +std::string BarrierObserver::to_string() const +{ + return std::string(mc::Transition::to_c_str(type_)) + + "(barrier_id:" + std::to_string(barrier_ != nullptr ? barrier_->get_id() : acquisition_->barrier_->get_id()) + + ")"; +} bool BarrierObserver::is_enabled() { - return type_ == mc::Transition::Type::BARRIER_LOCK || + return type_ == mc::Transition::Type::BARRIER_ASYNC_LOCK || (type_ == mc::Transition::Type::BARRIER_WAIT && acquisition_ != nullptr && acquisition_->granted_); } +bool ConditionVariableObserver::is_enabled() +{ + if (static bool warned = false; not warned) { + XBT_INFO("Using condition variables in model-checked code is still experimental. Use at your own risk"); + warned = true; + } + return true; +} +void ConditionVariableObserver::serialize(std::stringstream& stream) const +{ + THROW_UNIMPLEMENTED; +} +std::string ConditionVariableObserver::to_string() const +{ + return "ConditionWait(cond_id:" + ptr_to_id(get_cond()) + + " mutex_id:" + std::to_string(get_mutex()->get_id()) + ")"; +} + } // namespace simgrid::kernel::actor diff --git a/src/kernel/actor/SynchroObserver.hpp b/src/kernel/actor/SynchroObserver.hpp index c953c5d20d..ffcfcabcf0 100644 --- a/src/kernel/actor/SynchroObserver.hpp +++ b/src/kernel/actor/SynchroObserver.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,6 +7,7 @@ #define SIMGRID_MC_MUTEX_OBSERVER_HPP #include "simgrid/forward.h" +#include "src/kernel/activity/ConditionVariableImpl.hpp" #include "src/kernel/activity/MutexImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" @@ -24,6 +25,7 @@ public: MutexObserver(ActorImpl* actor, mc::Transition::Type type, activity::MutexImpl* mutex); void serialize(std::stringstream& stream) const override; + std::string to_string() const override; bool is_enabled() override; activity::MutexImpl* get_mutex() const { return mutex_; } @@ -38,6 +40,7 @@ public: SemaphoreObserver(ActorImpl* actor, mc::Transition::Type type, activity::SemaphoreImpl* sem); void serialize(std::stringstream& stream) const override; + std::string to_string() const override; activity::SemaphoreImpl* get_sem() const { return sem_; } }; @@ -53,12 +56,13 @@ public: double timeout = -1.0); void serialize(std::stringstream& stream) const override; + std::string to_string() const override; bool is_enabled() override; double get_timeout() const { return timeout_; } }; -/* This observer is ued for BARRIER_LOCK and BARRIER_WAIT. WAIT is returning and needs the acquisition */ +/* This observer is used for BARRIER_LOCK and BARRIER_WAIT. WAIT is returning and needs the acquisition */ class BarrierObserver final : public ResultingSimcall { mc::Transition::Type type_; activity::BarrierImpl* const barrier_ = nullptr; @@ -71,11 +75,33 @@ public: double timeout = -1.0); void serialize(std::stringstream& stream) const override; + std::string to_string() const override; bool is_enabled() override; double get_timeout() const { return timeout_; } }; +class ConditionVariableObserver final : public ResultingSimcall { + //mc::Transition::Type type_; Will be used when we implement CV on the MC side + activity::ConditionVariableImpl* const cond_; + activity::MutexImpl* const mutex_; + const double timeout_; + +public: + ConditionVariableObserver(ActorImpl* actor, activity::ConditionVariableImpl* cond, activity::MutexImpl* mutex, + double timeout = -1.0) + : ResultingSimcall(actor, false), cond_(cond), mutex_(mutex), timeout_(timeout) + { + xbt_assert(mutex != nullptr, "Cannot wait on a condition variable without a valid mutex"); + } + void serialize(std::stringstream& stream) const override; + std::string to_string() const override; + bool is_enabled() override; + activity::ConditionVariableImpl* get_cond() const { return cond_; } + activity::MutexImpl* get_mutex() const { return mutex_; } + double get_timeout() const { return timeout_; } +}; + } // namespace simgrid::kernel::actor #endif diff --git a/src/kernel/context/Context.cpp b/src/kernel/context/Context.cpp index 6827ff96c4..5736b265cd 100644 --- a/src/kernel/context/Context.cpp +++ b/src/kernel/context/Context.cpp @@ -1,16 +1,15 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "mc/mc.h" +#include "src/mc/mc.h" #include "simgrid/Exception.hpp" #include "simgrid/s4u/Host.hpp" #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/context/Context.hpp" #include "src/sthread/sthread.h" -#include "src/surf/surf_interface.hpp" #include @@ -18,80 +17,33 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_context, kernel, "Context switching mechanis namespace simgrid::kernel::context { -std::function ContextFactory::initializer; - -static e_xbt_parmap_mode_t parallel_synchronization_mode = XBT_PARMAP_DEFAULT; -static int parallel_contexts = 1; -unsigned stack_size; -unsigned guard_size; - -/** @brief Returns whether some parallel threads are used for the user contexts. */ -bool is_parallel() -{ - return parallel_contexts > 1; -} - -/** - * @brief Returns the number of parallel threads used for the user contexts. - * @return the number of threads (1 means no parallelism) - */ -int get_nthreads() -{ - return parallel_contexts; -} - -/** - * @brief Sets the number of parallel threads to use for the user contexts. - * - * This function should be called before initializing SIMIX. - * A value of 1 means no parallelism (1 thread only). - * If the value is greater than 1, the thread support must be enabled. - * - * @param nb_threads the number of threads to use - */ -void set_nthreads(int nb_threads) +void Context::set_nthreads(int nb_threads) { if (nb_threads <= 0) { nb_threads = std::thread::hardware_concurrency(); XBT_INFO("Auto-setting contexts/nthreads to %d", nb_threads); } - parallel_contexts = nb_threads; -} - -/** - * @brief Sets the synchronization mode to use when actors are run in parallel. - * @param mode how to synchronize threads if actors are run in parallel - */ -void set_parallel_mode(e_xbt_parmap_mode_t mode) -{ - parallel_synchronization_mode = mode; -} - -/** - * @brief Returns the synchronization mode used when actors are run in parallel. - * @return how threads are synchronized if actors are run in parallel - */ -e_xbt_parmap_mode_t get_parallel_mode() -{ - return parallel_synchronization_mode; + Context::parallel_contexts = nb_threads; } ContextFactory::~ContextFactory() = default; +e_xbt_parmap_mode_t Context::parallel_mode = XBT_PARMAP_DEFAULT; +int Context::parallel_contexts = 1; +unsigned Context::stack_size; +unsigned Context::guard_size; thread_local Context* Context::current_context_ = nullptr; -#ifndef WIN32 /* Install or disable alternate signal stack, for SIGSEGV handler. */ -int Context::install_sigsegv_stack(stack_t* old_stack, bool enable) +int Context::install_sigsegv_stack(bool enable) { static std::vector sigsegv_stack(SIGSTKSZ); stack_t stack; stack.ss_sp = sigsegv_stack.data(); stack.ss_size = sigsegv_stack.size(); stack.ss_flags = enable ? 0 : SS_DISABLE; - return sigaltstack(&stack, old_stack); + return sigaltstack(&stack, nullptr); } -#endif Context* Context::self() { @@ -102,15 +54,6 @@ void Context::set_current(Context* self) current_context_ = self; } -void Context::declare_context(std::size_t size) -{ -#if SIMGRID_HAVE_MC - /* Store the address of the stack in heap to compare it apart of heap comparison */ - if(MC_is_active()) - MC_ignore_heap(this, size); -#endif -} - Context* ContextFactory::attach(actor::ActorImpl*) { xbt_die("Cannot attach with this ContextFactory.\n" diff --git a/src/kernel/context/Context.hpp b/src/kernel/context/Context.hpp index c8aba566f3..16c5e82274 100644 --- a/src/kernel/context/Context.hpp +++ b/src/kernel/context/Context.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,8 +15,6 @@ #include namespace simgrid::kernel::context { -extern unsigned stack_size; -extern unsigned guard_size; class XBT_PUBLIC ContextFactory { public: @@ -33,14 +31,10 @@ public: virtual void run_all(std::vector const& actors_list) = 0; - /* This allows Java to hijack the context factory (Java induces factories of factory :) */ - static std::function initializer; - protected: template T* new_context(Args&&... args) { auto* context = new T(std::forward(args)...); - context->declare_context(sizeof(T)); return context; } }; @@ -48,17 +42,19 @@ protected: class XBT_PUBLIC Context { friend ContextFactory; + static int parallel_contexts; static thread_local Context* current_context_; std::function code_; actor::ActorImpl* actor_ = nullptr; bool is_maestro_; - void declare_context(std::size_t size); public: -#ifndef WIN32 - static int install_sigsegv_stack(stack_t* old_stack, bool enable); -#endif + static e_xbt_parmap_mode_t parallel_mode; + static unsigned stack_size; + static unsigned guard_size; + + static int install_sigsegv_stack(bool enable); Context(std::function&& code, actor::ActorImpl* actor, bool maestro); Context(const Context&) = delete; @@ -70,6 +66,22 @@ public: bool has_code() const { return static_cast(code_); } actor::ActorImpl* get_actor() const { return this->actor_; } + /** @brief Returns whether some parallel threads are used for the user contexts. */ + static bool is_parallel() { return parallel_contexts > 1; } + /** @brief Returns the number of parallel threads used for the user contexts (1 means no parallelism). */ + static int get_nthreads() { return parallel_contexts; } + /** + * @brief Sets the number of parallel threads to use for the user contexts. + * + * This function should be called before initializing SIMIX. + * A value of 1 means no parallelism (1 thread only). + * If the value is greater than 1, the thread support must be enabled. + * If the value is less than 1, the optimal number of threads is chosen automatically. + * + * @param nb_threads the number of threads to use + */ + static void set_nthreads(int nb_threads); + // Scheduling methods virtual void stop(); virtual void suspend() = 0; @@ -103,11 +115,6 @@ XBT_PRIVATE ContextFactory* sysv_factory(); XBT_PRIVATE ContextFactory* raw_factory(); XBT_PRIVATE ContextFactory* boost_factory(); -XBT_PUBLIC bool is_parallel(); -XBT_PUBLIC int get_nthreads(); -XBT_PUBLIC void set_nthreads(int nb_threads); -XBT_PUBLIC void set_parallel_mode(e_xbt_parmap_mode_t mode); -XBT_PUBLIC e_xbt_parmap_mode_t get_parallel_mode(); } // namespace simgrid::kernel::context #endif diff --git a/src/kernel/context/ContextBoost.cpp b/src/kernel/context/ContextBoost.cpp index 0041debea6..8f3a9e4b34 100644 --- a/src/kernel/context/ContextBoost.cpp +++ b/src/kernel/context/ContextBoost.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/kernel/context/ContextBoost.hpp b/src/kernel/context/ContextBoost.hpp index 94682e2352..22295c55a1 100644 --- a/src/kernel/context/ContextBoost.hpp +++ b/src/kernel/context/ContextBoost.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -18,11 +18,8 @@ #include #include -#include -#include - -#include "src/internal_config.h" #include "src/kernel/context/ContextSwapped.hpp" +#include "src/xbt/parmap.hpp" namespace simgrid::kernel::context { diff --git a/src/kernel/context/ContextRaw.cpp b/src/kernel/context/ContextRaw.cpp index 85e81698f7..de72fce947 100644 --- a/src/kernel/context/ContextRaw.cpp +++ b/src/kernel/context/ContextRaw.cpp @@ -1,11 +1,11 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "ContextRaw.hpp" -#include "mc/mc.h" #include "simgrid/Exception.hpp" +#include "src/mc/mc.h" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ker_context); @@ -23,144 +23,132 @@ extern "C" void raw_swapcontext(raw_stack_t* old, raw_stack_t new_context); #if HAVE_RAW_CONTEXTS #if SIMGRID_PROCESSOR_x86_64 -__asm__ ( +__asm__( #if defined(__APPLE__) - ".text\n" - ".globl _raw_makecontext\n" - "_raw_makecontext:\n" -#elif defined(_WIN32) - ".text\n" - ".globl raw_makecontext\n" - "raw_makecontext:\n" + ".text\n" + ".globl _raw_makecontext\n" + "_raw_makecontext:\n" #else - ".text\n" - ".globl raw_makecontext\n" - ".type raw_makecontext,@function\n" - "raw_makecontext:\n"/* Calling convention sets the arguments in rdi, rsi, rdx and rcx, respectively */ + ".text\n" + ".globl raw_makecontext\n" + ".type raw_makecontext,@function\n" + "raw_makecontext:\n" /* Calling convention sets the arguments in rdi, rsi, rdx and rcx, respectively */ #endif - " mov %rdi,%rax\n" /* stack */ - " add %rsi,%rax\n" /* size */ - " andq $-16, %rax\n" /* align stack */ - " movq $0, -8(%rax)\n" /* @return for func */ - " mov %rdx,-16(%rax)\n" /* func */ - " mov %rcx,-24(%rax)\n" /* arg/rdi */ - " movq $0, -32(%rax)\n" /* rsi */ - " movq $0, -40(%rax)\n" /* rdx */ - " movq $0, -48(%rax)\n" /* rcx */ - " movq $0, -56(%rax)\n" /* r8 */ - " movq $0, -64(%rax)\n" /* r9 */ - " movq $0, -72(%rax)\n" /* rbp */ - " movq $0, -80(%rax)\n" /* rbx */ - " movq $0, -88(%rax)\n" /* r12 */ - " movq $0, -96(%rax)\n" /* r13 */ - " movq $0, -104(%rax)\n" /* r14 */ - " movq $0, -112(%rax)\n" /* r15 */ - " sub $112,%rax\n" - " ret\n" -); - -__asm__ ( + " mov %rdi,%rax\n" /* stack */ + " add %rsi,%rax\n" /* size */ + " andq $-16, %rax\n" /* align stack */ + " movq $0, -8(%rax)\n" /* @return for func */ + " mov %rdx,-16(%rax)\n" /* func */ + " mov %rcx,-24(%rax)\n" /* arg/rdi */ + " movq $0, -32(%rax)\n" /* rsi */ + " movq $0, -40(%rax)\n" /* rdx */ + " movq $0, -48(%rax)\n" /* rcx */ + " movq $0, -56(%rax)\n" /* r8 */ + " movq $0, -64(%rax)\n" /* r9 */ + " movq $0, -72(%rax)\n" /* rbp */ + " movq $0, -80(%rax)\n" /* rbx */ + " movq $0, -88(%rax)\n" /* r12 */ + " movq $0, -96(%rax)\n" /* r13 */ + " movq $0, -104(%rax)\n" /* r14 */ + " movq $0, -112(%rax)\n" /* r15 */ + " sub $112,%rax\n" + " ret\n"); + +__asm__( #if defined(__APPLE__) - ".text\n" - ".globl _raw_swapcontext\n" - "_raw_swapcontext:\n" -#elif defined(_WIN32) - ".text\n" - ".globl raw_swapcontext\n" - "raw_swapcontext:\n" + ".text\n" + ".globl _raw_swapcontext\n" + "_raw_swapcontext:\n" #else - ".text\n" - ".globl raw_swapcontext\n" - ".type raw_swapcontext,@function\n" - "raw_swapcontext:\n" /* Calling convention sets the arguments in rdi and rsi, respectively */ + ".text\n" + ".globl raw_swapcontext\n" + ".type raw_swapcontext,@function\n" + "raw_swapcontext:\n" /* Calling convention sets the arguments in rdi and rsi, respectively */ #endif - " push %rdi\n" - " push %rsi\n" - " push %rdx\n" - " push %rcx\n" - " push %r8\n" - " push %r9\n" - " push %rbp\n" - " push %rbx\n" - " push %r12\n" - " push %r13\n" - " push %r14\n" - " push %r15\n" - " mov %rsp,(%rdi)\n" /* old */ - " mov %rsi,%rsp\n" /* new */ - " pop %r15\n" - " pop %r14\n" - " pop %r13\n" - " pop %r12\n" - " pop %rbx\n" - " pop %rbp\n" - " pop %r9\n" - " pop %r8\n" - " pop %rcx\n" - " pop %rdx\n" - " pop %rsi\n" - " pop %rdi\n" - " ret\n" -); + " push %rdi\n" + " push %rsi\n" + " push %rdx\n" + " push %rcx\n" + " push %r8\n" + " push %r9\n" + " push %rbp\n" + " push %rbx\n" + " push %r12\n" + " push %r13\n" + " push %r14\n" + " push %r15\n" + " mov %rsp,(%rdi)\n" /* old */ + " mov %rsi,%rsp\n" /* new */ + " pop %r15\n" + " pop %r14\n" + " pop %r13\n" + " pop %r12\n" + " pop %rbx\n" + " pop %rbp\n" + " pop %r9\n" + " pop %r8\n" + " pop %rcx\n" + " pop %rdx\n" + " pop %rsi\n" + " pop %rdi\n" + " ret\n"); #elif SIMGRID_PROCESSOR_i686 -__asm__ ( -#if defined(__APPLE__) || defined(_WIN32) - ".text\n" - ".globl _raw_makecontext\n" - "_raw_makecontext:\n" +__asm__( +#if defined(__APPLE__) + ".text\n" + ".globl _raw_makecontext\n" + "_raw_makecontext:\n" #else - ".text\n" - ".globl raw_makecontext\n" - ".type raw_makecontext,@function\n" - "raw_makecontext:\n" + ".text\n" + ".globl raw_makecontext\n" + ".type raw_makecontext,@function\n" + "raw_makecontext:\n" #endif - " movl 4(%esp),%eax\n" /* stack */ - " addl 8(%esp),%eax\n" /* size */ - " andl $-16, %eax\n" /* align stack */ - " movl 12(%esp),%ecx\n" /* func */ - " movl 16(%esp),%edx\n" /* arg */ - " movl %edx, -4(%eax)\n" - " movl $0, -8(%eax)\n" /* @return for func */ - " movl %ecx,-12(%eax)\n" - " movl $0, -16(%eax)\n" /* ebp */ - " movl $0, -20(%eax)\n" /* ebx */ - " movl $0, -24(%eax)\n" /* esi */ - " movl $0, -28(%eax)\n" /* edi */ - " subl $28,%eax\n" - " retl\n" -); - -__asm__ ( -#if defined(__APPLE__) || defined(_WIN32) - ".text\n" - ".globl _raw_swapcontext\n" - "_raw_swapcontext:\n" + " movl 4(%esp),%eax\n" /* stack */ + " addl 8(%esp),%eax\n" /* size */ + " andl $-16, %eax\n" /* align stack */ + " movl 12(%esp),%ecx\n" /* func */ + " movl 16(%esp),%edx\n" /* arg */ + " movl %edx, -4(%eax)\n" + " movl $0, -8(%eax)\n" /* @return for func */ + " movl %ecx,-12(%eax)\n" + " movl $0, -16(%eax)\n" /* ebp */ + " movl $0, -20(%eax)\n" /* ebx */ + " movl $0, -24(%eax)\n" /* esi */ + " movl $0, -28(%eax)\n" /* edi */ + " subl $28,%eax\n" + " retl\n"); + +__asm__( +#if defined(__APPLE__) + ".text\n" + ".globl _raw_swapcontext\n" + "_raw_swapcontext:\n" #else - ".text\n" - ".globl raw_swapcontext\n" - ".type raw_swapcontext,@function\n" - "raw_swapcontext:\n" + ".text\n" + ".globl raw_swapcontext\n" + ".type raw_swapcontext,@function\n" + "raw_swapcontext:\n" #endif - // Fetch the parameters: - " movl 4(%esp),%eax\n" /* old (raw_stack_t*) */ - " movl 8(%esp),%edx\n" /* new (raw_stack_t) */ - // Save registers of the current context on the stack: - " pushl %ebp\n" - " pushl %ebx\n" - " pushl %esi\n" - " pushl %edi\n" - // Save the current context (stack pointer) in *old: - " movl %esp,(%eax)\n" - // Switch to the stack of the new context: - " movl %edx,%esp\n" - // Pop the values of the new context: - " popl %edi\n" - " popl %esi\n" - " popl %ebx\n" - " popl %ebp\n" - // Return using the return address of the new context: - " retl\n" -); + // Fetch the parameters: + " movl 4(%esp),%eax\n" /* old (raw_stack_t*) */ + " movl 8(%esp),%edx\n" /* new (raw_stack_t) */ + // Save registers of the current context on the stack: + " pushl %ebp\n" + " pushl %ebx\n" + " pushl %esi\n" + " pushl %edi\n" + // Save the current context (stack pointer) in *old: + " movl %esp,(%eax)\n" + // Switch to the stack of the new context: + " movl %edx,%esp\n" + // Pop the values of the new context: + " popl %edi\n" + " popl %esi\n" + " popl %ebx\n" + " popl %ebp\n" + // Return using the return address of the new context: + " retl\n"); #else #error HAVE_RAW_CONTEXTS defined, but neither SIMGRID_PROCESSOR_x86_64 nor SIMGRID_PROCESSOR_i686. Please update the code. #endif @@ -202,9 +190,6 @@ RawContext::RawContext(std::function&& code, actor::ActorImpl* actor, Sw XBT_VERB("Creating a context of stack %uMb", actor->get_stacksize() / 1024 / 1024); if (has_code()) { this->stack_top_ = raw_makecontext(get_stack(), actor->get_stacksize(), smx_ctx_wrapper, this); - } else { - if (MC_is_active()) - MC_ignore_heap(&stack_top_, sizeof stack_top_); } } diff --git a/src/kernel/context/ContextRaw.hpp b/src/kernel/context/ContextRaw.hpp index 8362aeafbf..dfa2c03281 100644 --- a/src/kernel/context/ContextRaw.hpp +++ b/src/kernel/context/ContextRaw.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,7 +11,7 @@ #include #include -#include +#include "src/xbt/parmap.hpp" #include "src/kernel/context/ContextSwapped.hpp" diff --git a/src/kernel/context/ContextSwapped.cpp b/src/kernel/context/ContextSwapped.cpp index 599d52a6b3..aff10af720 100644 --- a/src/kernel/context/ContextSwapped.cpp +++ b/src/kernel/context/ContextSwapped.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,25 +9,14 @@ #include "src/kernel/EngineImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/sthread/sthread.h" -#include "xbt/parmap.hpp" +#include "src/xbt/parmap.hpp" #include "src/kernel/context/ContextSwapped.hpp" #include #include -#include - -#ifdef _WIN32 -#include -#include -#else #include -#endif - -#ifdef __MINGW32__ -#define _aligned_malloc __mingw_aligned_malloc -#define _aligned_free __mingw_aligned_free -#endif /*MINGW*/ +#include #if HAVE_VALGRIND_H #include @@ -93,21 +82,10 @@ SwappedContext::SwappedContext(std::function&& code, actor::ActorImpl* a #endif size_t size = actor->get_stacksize() + guard_size; -#if SIMGRID_HAVE_MC - /* Cannot use posix_memalign when SIMGRID_HAVE_MC. Align stack by hand, and save the - * pointer returned by xbt_malloc0. */ - auto* alloc = static_cast(xbt_malloc0(size + xbt_pagesize)); - stack_ = alloc - (reinterpret_cast(alloc) & (xbt_pagesize - 1)) + xbt_pagesize; - reinterpret_cast(stack_)[-1] = alloc; -#elif !defined(_WIN32) void* alloc; xbt_assert(posix_memalign(&alloc, xbt_pagesize, size) == 0, "Failed to allocate stack."); this->stack_ = static_cast(alloc); -#else - this->stack_ = static_cast(_aligned_malloc(size, xbt_pagesize)); -#endif -#ifndef _WIN32 /* This is fatal. We are going to fail at some point when we try reusing this. */ xbt_assert( mprotect(this->stack_, guard_size, PROT_NONE) != -1, @@ -117,7 +95,7 @@ SwappedContext::SwappedContext(std::function&& code, actor::ActorImpl* a "Please see https://simgrid.org/doc/latest/Configuring_SimGrid.html#configuring-the-user-code-virtualization " "for more information.", strerror(errno)); -#endif + this->stack_ = this->stack_ + guard_size; } else { this->stack_ = static_cast(xbt_malloc0(actor->get_stacksize())); @@ -154,19 +132,13 @@ SwappedContext::~SwappedContext() VALGRIND_STACK_DEREGISTER(valgrind_stack_id_); #endif -#ifndef _WIN32 if (guard_size > 0 && not MC_is_active()) { stack_ = stack_ - guard_size; if (mprotect(stack_, guard_size, PROT_READ | PROT_WRITE) == -1) { XBT_WARN("Failed to remove page protection: %s", strerror(errno)); /* try to pursue anyway */ } -#if SIMGRID_HAVE_MC - /* Retrieve the saved pointer. See the initialization above. */ - stack_ = reinterpret_cast(stack_)[-1]; -#endif } -#endif /* not windows */ xbt_free(stack_); } @@ -207,10 +179,11 @@ void SwappedContextFactory::run_all(std::vector const& actors * stuff It is much easier to understand what happens if you see the working threads as bodies that swap their soul * for the ones of the simulated processes that must run. */ - if (is_parallel()) { + if (Context::is_parallel()) { // We lazily create the parmap so that all options are actually processed when doing so. if (parmap_ == nullptr) - parmap_ = std::make_unique>(get_nthreads(), get_parallel_mode()); + parmap_ = + std::make_unique>(Context::get_nthreads(), Context::parallel_mode); // Usually, Parmap::apply() executes the provided function on all elements of the array. // Here, the executed function does not return the control to the parmap before all the array is processed: diff --git a/src/kernel/context/ContextSwapped.hpp b/src/kernel/context/ContextSwapped.hpp index d687827cf7..ed98656216 100644 --- a/src/kernel/context/ContextSwapped.hpp +++ b/src/kernel/context/ContextSwapped.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,6 +8,7 @@ #include "src/internal_config.h" // HAVE_SANITIZER_* #include "src/kernel/context/Context.hpp" +#include "src/xbt/parmap.hpp" #include diff --git a/src/kernel/context/ContextThread.cpp b/src/kernel/context/ContextThread.cpp index 54319b2bb5..40efb6b4c1 100644 --- a/src/kernel/context/ContextThread.cpp +++ b/src/kernel/context/ContextThread.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,7 +9,6 @@ #include "src/internal_config.h" /* loads context system definitions */ #include "src/kernel/EngineImpl.hpp" #include "xbt/function_types.h" -#include "xbt/xbt_modinter.h" /* prototype of os thread module's init/exit in XBT */ #include #include @@ -24,21 +23,21 @@ namespace simgrid::kernel::context { ThreadContextFactory::ThreadContextFactory() : ContextFactory() { - if (stack_size != 8 * 1024 * 1024) + if (Context::stack_size != 8 * 1024 * 1024) XBT_INFO("Stack size modifications are ignored by thread factory."); - if (is_parallel()) + if (Context::is_parallel()) ParallelThreadContext::initialize(); } ThreadContextFactory::~ThreadContextFactory() { - if (is_parallel()) + if (Context::is_parallel()) ParallelThreadContext::finalize(); } ThreadContext* ThreadContextFactory::create_context(std::function&& code, actor::ActorImpl* actor, bool maestro) { - if (is_parallel()) + if (Context::is_parallel()) return this->new_context(std::move(code), actor, maestro); else return this->new_context(std::move(code), actor, maestro); @@ -46,7 +45,7 @@ ThreadContext* ThreadContextFactory::create_context(std::function&& code void ThreadContextFactory::run_all(std::vector const& actors_list) { - if (is_parallel()) + if (Context::is_parallel()) ParallelThreadContext::run_all(actors_list); else @@ -84,9 +83,7 @@ void ThreadContext::wrapper(ThreadContext* context) { Context::set_current(context); -#ifndef WIN32 - install_sigsegv_stack(nullptr, true); -#endif + install_sigsegv_stack(true); // Tell the caller (normally the maestro) we are starting, and wait for its green light context->end_.release(); context->start(); @@ -105,9 +102,7 @@ void ThreadContext::wrapper(ThreadContext* context) // Signal to the caller (normally the maestro) that we have finished: context->yield(); -#ifndef WIN32 - install_sigsegv_stack(nullptr, false); -#endif + install_sigsegv_stack(false); XBT_DEBUG("Terminating"); Context::set_current(nullptr); } diff --git a/src/kernel/context/ContextThread.hpp b/src/kernel/context/ContextThread.hpp index 5980d3ae56..cb578d7e63 100644 --- a/src/kernel/context/ContextThread.hpp +++ b/src/kernel/context/ContextThread.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -39,7 +39,7 @@ private: void start(); // match a call to release() void yield(); // match a call to yield() - virtual void start_hook() { /* empty placeholder, called after start(). Used in parallel mode and Java */} + virtual void start_hook() { /* empty placeholder, called after start(). Used in parallel mode */} virtual void yield_hook() { /* empty placeholder, called before yield(). Used in parallel mode */} static void wrapper(ThreadContext* context); diff --git a/src/kernel/context/ContextUnix.cpp b/src/kernel/context/ContextUnix.cpp index 24b2b1f34d..2061a2535e 100644 --- a/src/kernel/context/ContextUnix.cpp +++ b/src/kernel/context/ContextUnix.cpp @@ -1,14 +1,14 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ /* \file UContext.cpp Context switching with ucontexts from System V */ -#include "mc/mc.h" #include "simgrid/Exception.hpp" #include "src/kernel/actor/ActorImpl.hpp" -#include "src/mc/mc_ignore.hpp" +#include "src/mc/mc.h" +#include "src/mc/remote/AppSide.hpp" #include "ContextUnix.hpp" @@ -60,12 +60,6 @@ UContext::UContext(std::function&& code, actor::ActorImpl* actor, Swappe UContext* arg = this; memcpy(ctx_addr, &arg, sizeof arg); makecontext(&this->uc_, (void (*)())sysv_ctx_wrapper, 2, ctx_addr[0], ctx_addr[1]); - -#if SIMGRID_HAVE_MC - if (MC_is_active()) { - MC_register_stack_area(get_stack(), &(this->uc_), stack_size); - } -#endif } } diff --git a/src/kernel/context/ContextUnix.hpp b/src/kernel/context/ContextUnix.hpp index 69d6a5ca3f..15b1b8722a 100644 --- a/src/kernel/context/ContextUnix.hpp +++ b/src/kernel/context/ContextUnix.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,8 +13,8 @@ #include #include +#include "src/xbt/parmap.hpp" #include -#include #include "src/internal_config.h" #include "src/kernel/context/ContextSwapped.hpp" diff --git a/src/kernel/lmm/System.cpp b/src/kernel/lmm/System.cpp index 326b404928..cebcb9632d 100644 --- a/src/kernel/lmm/System.cpp +++ b/src/kernel/lmm/System.cpp @@ -1,20 +1,23 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "src/internal_config.h" #include "src/kernel/lmm/fair_bottleneck.hpp" #include "src/kernel/lmm/maxmin.hpp" +#include "src/simgrid/math_utils.h" #if SIMGRID_HAVE_EIGEN3 #include "src/kernel/lmm/bmf.hpp" #endif + #include #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_lmm, kernel, "Kernel Linear Max-Min solver"); -double sg_maxmin_precision = 1E-5; /* Change this with --cfg=maxmin/precision:VALUE */ -double sg_surf_precision = 1E-9; /* Change this with --cfg=surf/precision:VALUE */ +double sg_precision_workamount = 1E-5; /* Change this with --cfg=precision/work-amount:VALUE */ +double sg_precision_timing = 1E-9; /* Change this with --cfg=precision/timing:VALUE */ int sg_concurrency_limit = -1; /* Change this with --cfg=maxmin/concurrency-limit:VALUE */ namespace simgrid::kernel::lmm { @@ -29,6 +32,11 @@ Element::Element(Constraint* constraint, Variable* variable, double cweight) int Element::get_concurrency() const { + // just to try having the computation of the concurrency + if (constraint->get_sharing_policy() == Constraint::SharingPolicy::WIFI) { + return 1; + } + // Ignore element with weight less than one (e.g. cross-traffic) return (consumption_weight >= 1) ? 1 : 0; // There are other alternatives, but they will change the behavior of the model.. @@ -57,7 +65,7 @@ void Element::increase_concurrency(bool check_limit) "Concurrency limit overflow!"); } -System* System::build(const std::string& solver_name, bool selective_update) +System* System::build(std::string_view solver_name, bool selective_update) { System* system = nullptr; if (solver_name == "bmf") { @@ -87,7 +95,7 @@ void System::validate_solver(const std::string& solver_name) void System::check_concurrency() const { - // These checks are very expensive, so do them only if we want to debug SURF LMM + // These checks are very expensive, so do them only if we want to debug the LMM if (not XBT_LOG_ISENABLED(ker_lmm, xbt_log_priority_debug)) return; @@ -270,18 +278,20 @@ Element& System::expand_add_to_elem(Element& elem, const Constraint* cnst, doubl return elem; } -void System::expand(Constraint* cnst, Variable* var, double consumption_weight) +void System::expand(Constraint* cnst, Variable* var, double consumption_weight, bool force_creation) { modified_ = true; auto elem_it = std::find_if(begin(var->cnsts_), end(var->cnsts_), [&cnst](Element const& x) { return x.constraint == cnst; }); - if (elem_it != end(var->cnsts_) && var->sharing_penalty_ != 0.0) { + + bool reuse_elem = elem_it != end(var->cnsts_) && not force_creation; + if (reuse_elem && var->sharing_penalty_ != 0.0) { /* before changing it, decreases concurrency on constraint, it'll be added back later */ elem_it->decrease_concurrency(); } - Element& elem = elem_it != end(var->cnsts_) ? expand_add_to_elem(*elem_it, cnst, consumption_weight) - : expand_create_elem(cnst, var, consumption_weight); + Element& elem = reuse_elem ? expand_add_to_elem(*elem_it, cnst, consumption_weight) + : expand_create_elem(cnst, var, consumption_weight); // Check if we need to disable the variable if (var->sharing_penalty_ != 0) { @@ -419,7 +429,7 @@ void System::print() const } XBT_DEBUG("%s", buf.c_str()); buf.clear(); - xbt_assert(not double_positive(sum - cnst.bound_, cnst.bound_ * sg_maxmin_precision), + xbt_assert(not double_positive(sum - cnst.bound_, cnst.bound_ * sg_precision_workamount), "Incorrect value (%f is not smaller than %f): %g", sum, cnst.bound_, sum - cnst.bound_); } @@ -428,7 +438,7 @@ void System::print() const for (Variable const& var : variable_set) { if (var.bound_ > 0) { XBT_DEBUG("'%d'(%f) : %f (<=%f)", var.rank_, var.sharing_penalty_, var.value_, var.bound_); - xbt_assert(not double_positive(var.value_ - var.bound_, var.bound_ * sg_maxmin_precision), + xbt_assert(not double_positive(var.value_ - var.bound_, var.bound_ * sg_precision_workamount), "Incorrect value (%f is not smaller than %f", var.value_, var.bound_); } else { XBT_DEBUG("'%d'(%f) : %f", var.rank_, var.sharing_penalty_, var.value_); @@ -737,7 +747,7 @@ void System::remove_all_modified_cnst_set() * If the resource is not shared (ie in FATPIPE mode), then the load is the max (not the sum) * of all resource usages located on this resource. */ -double Constraint::get_usage() const +double Constraint::get_load() const { double result = 0.0; if (sharing_policy_ != SharingPolicy::FATPIPE) { @@ -754,7 +764,7 @@ double Constraint::get_usage() const void Constraint::set_sharing_policy(SharingPolicy policy, const s4u::NonLinearResourceCb& cb) { - xbt_assert(policy == SharingPolicy::NONLINEAR || not cb, + xbt_assert(policy == SharingPolicy::NONLINEAR || policy == SharingPolicy::WIFI || not cb, "Invalid sharing policy for constraint. Callback should be used with NONLINEAR sharing policy"); sharing_policy_ = policy; dyn_constraint_cb_ = cb; diff --git a/src/kernel/lmm/System.hpp b/src/kernel/lmm/System.hpp index 173d0444be..25fa550730 100644 --- a/src/kernel/lmm/System.hpp +++ b/src/kernel/lmm/System.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,21 +8,24 @@ #include "simgrid/kernel/resource/Action.hpp" #include "simgrid/kernel/resource/Model.hpp" -#include "simgrid/s4u/Link.hpp" -#include "src/surf/surf_interface.hpp" #include "xbt/asserts.h" -#include "xbt/ex.h" #include "xbt/mallocator.h" #include #include #include #include +#include #include +/* user-visible parameters */ +XBT_PUBLIC_DATA double sg_precision_workamount; +XBT_PUBLIC_DATA double sg_precision_timing; +XBT_PUBLIC_DATA int sg_concurrency_limit; + namespace simgrid::kernel::lmm { -/** @addtogroup SURF_lmm +/** @addtogroup Model_lmm * @details * A linear maxmin solver to resolve inequations systems. * @@ -132,7 +135,7 @@ namespace simgrid::kernel::lmm { * At the current state, each variable counts as 1 if its consumption weight is greater than 1. */ -/** @{ @ingroup SURF_lmm */ +/** @{ @ingroup Model_lmm */ /** * @brief LMM element @@ -205,7 +208,7 @@ public: */ class XBT_PUBLIC Constraint { public: - enum class SharingPolicy { NONLINEAR = 2, SHARED = 1, FATPIPE = 0 }; + enum class SharingPolicy { WIFI = 3, NONLINEAR = 2, SHARED = 1, FATPIPE = 0 }; Constraint(resource::Resource* id_value, double bound_value); @@ -217,8 +220,8 @@ public: /** @brief Check how a constraint is shared */ SharingPolicy get_sharing_policy() const { return sharing_policy_; } - /** @brief Get the usage of the constraint after the last lmm solve */ - double get_usage() const; + /** @brief Get the load of the constraint after the last lmm solve */ + double get_load() const; /** @brief Sets the concurrency limit for this constraint */ void set_concurrency_limit(int limit) @@ -242,7 +245,7 @@ public: int get_concurrency_maximum() const { xbt_assert(concurrency_limit_ < 0 || concurrency_maximum_ <= concurrency_limit_, - "Very bad: maximum observed concurrency is higher than limit. This is a bug of SURF, please report it."); + "Very bad: maximum observed concurrency is higher than limit. This is a bug, please report it."); return concurrency_maximum_; } @@ -418,7 +421,7 @@ public: * @param selective_update Enables lazy updates * @return pointer to System instance */ - static System* build(const std::string& solver_name, bool selective_update); + static System* build(std::string_view solver_name, bool selective_update); /** @brief Validates solver configuration */ static void validate_solver(const std::string& solver_name); @@ -464,8 +467,11 @@ public: * @param cnst A constraint * @param var A variable * @param value The coefficient associated to the variable in the constraint + * @param force_creation Force the creation of new element linking the variable to the constraint. Should be used only + * by the model ptask_L07 to cope with ptasks composed of flows running on the same resource (see + * https://framagit.org/simgrid/simgrid/-/issues/111) */ - void expand(Constraint * cnst, Variable * var, double value); + void expand(Constraint* cnst, Variable* var, double value, bool force_creation = false); /** @brief Update the bound of a variable */ void update_variable_bound(Variable * var, double bound); diff --git a/src/kernel/lmm/bmf.cpp b/src/kernel/lmm/bmf.cpp index b6647a6453..d6950bf3b8 100644 --- a/src/kernel/lmm/bmf.cpp +++ b/src/kernel/lmm/bmf.cpp @@ -1,10 +1,10 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/lmm/bmf.hpp" -#include "xbt/config.hpp" +#include "src/simgrid/math_utils.h" #include #include @@ -13,13 +13,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_bmf, kernel, "Kernel BMF solver"); -simgrid::config::Flag - cfg_bmf_max_iteration("bmf/max-iterations", - "Maximum number of steps to be performed while searching for a BMF allocation", 1000); - -simgrid::config::Flag cfg_bmf_precision{"bmf/precision", - "Numerical precision used when computing resource sharing", 1E-12}; - namespace simgrid::kernel::lmm { AllocationGenerator::AllocationGenerator(Eigen::MatrixXd A) : A_(std::move(A)), alloc_(A_.cols(), 0) @@ -71,7 +64,6 @@ BmfSolver::BmfSolver(Eigen::MatrixXd A, Eigen::MatrixXd maxA, Eigen::VectorXd C, , C_shared_(std::move(shared)) , phi_(std::move(phi)) , gen_(A_) - , max_iteration_(cfg_bmf_max_iteration) { xbt_assert(max_iteration_ > 0, @@ -93,7 +85,7 @@ template std::string BmfSolver::debug_vector(const C& container) co { std::stringstream debug; std::copy(container.begin(), container.end(), - std::ostream_iterator::type::value_type>(debug, " ")); + std::ostream_iterator::value_type>(debug, " ")); return debug.str(); } @@ -318,7 +310,7 @@ bool BmfSolver::is_bmf(const Eigen::VectorXd& rho) const Eigen::VectorXd remaining = (A_ * rho) - C_; remaining = remaining.array() * shared.array(); // ignore non shared resources bmf = bmf && (not std::any_of(remaining.data(), remaining.data() + remaining.size(), - [](double v) { return double_positive(v, sg_maxmin_precision); })); + [](double v) { return double_positive(v, sg_precision_workamount); })); // 3) every player receives maximum share in at least 1 saturated resource // due to subflows, compare with the maximum consumption and not the A matrix @@ -330,15 +322,15 @@ bool BmfSolver::is_bmf(const Eigen::VectorXd& rho) const // matrix_ji: boolean indicating player p has the maximum share at resource j Eigen::MatrixXi player_max_share = - ((usage.array().colwise() - max_share.array()).abs() <= sg_maxmin_precision).cast(); + ((usage.array().colwise() - max_share.array()).abs() <= sg_precision_workamount).cast(); // but only saturated resources must be considered - Eigen::VectorXi saturated = (remaining.array().abs() <= sg_maxmin_precision).cast(); + Eigen::VectorXi saturated = (remaining.array().abs() <= sg_precision_workamount).cast(); XBT_DEBUG("Saturated_j resources:\n%s", debug_eigen(saturated).c_str()); player_max_share.array().colwise() *= saturated.array(); // just check if it has received at least it's bound for (int p = 0; p < rho.size(); p++) { - if (double_equals(rho[p], phi_[p], sg_maxmin_precision)) { + if (double_equals(rho[p], phi_[p], sg_precision_workamount)) { player_max_share(0, p) = 1; // it doesn't really matter, just to say that it's a bmf saturated[0] = 1; } diff --git a/src/kernel/lmm/bmf.hpp b/src/kernel/lmm/bmf.hpp index dfc7ff98e2..3bebff17d9 100644 --- a/src/kernel/lmm/bmf.hpp +++ b/src/kernel/lmm/bmf.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,6 +7,9 @@ #define SIMGRID_KERNEL_LMM_BMF_HPP #include "src/kernel/lmm/System.hpp" +#include "xbt/config.hpp" + +#include #ifdef __clang__ // Ignore deprecation warnings with Eigen < 4.0 (see https://gitlab.com/libeigen/eigen/-/issues/1850) @@ -73,6 +76,12 @@ private: * @endrst */ class XBT_PUBLIC BmfSolver { + inline static simgrid::config::Flag cfg_bmf_max_iteration{ + "bmf/max-iterations", "Maximum number of steps to be performed while searching for a BMF allocation", 1000}; + + inline static simgrid::config::Flag cfg_bmf_precision{ + "bmf/precision", {"precision/bmf"}, "Numerical precision used when computing resource sharing", 1E-12}; + public: /** * @brief Instantiate the BMF solver @@ -195,7 +204,7 @@ private: std::set> allocations_; //!< set of already tested allocations, since last identified loop AllocationGenerator gen_; static constexpr int NO_RESOURCE = -1; //!< flag to indicate player has selected no resource - int max_iteration_; //!< number maximum of iterations of BMF algorithm + int max_iteration_ = cfg_bmf_max_iteration; //!< number maximum of iterations of BMF algorithm }; /** diff --git a/src/kernel/lmm/bmf_test.cpp b/src/kernel/lmm/bmf_test.cpp index dee0b14007..12af94ff88 100644 --- a/src/kernel/lmm/bmf_test.cpp +++ b/src/kernel/lmm/bmf_test.cpp @@ -1,11 +1,11 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "src/include/catch.hpp" +#include "src/3rd-party/catch.hpp" #include "src/kernel/lmm/bmf.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/math_utils.h" #include "xbt/log.h" namespace lmm = simgrid::kernel::lmm; @@ -34,7 +34,7 @@ TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]") Sys.expand(sys_cnst, rho_1, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 3, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 3, sg_precision_workamount)); } SECTION("Two flows") @@ -60,8 +60,8 @@ TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]") Sys.expand(sys_cnst, rho_2, 10); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 3.0 / 2.0, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), (3.0 / 2.0) / 10.0, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 3.0 / 2.0, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), (3.0 / 2.0) / 10.0, sg_precision_workamount)); } SECTION("Variable penalty/priority") @@ -87,8 +87,8 @@ TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]") Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 2.0 / 3.0, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 1.0 / 3.0, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 2.0 / 3.0, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 1.0 / 3.0, sg_precision_workamount)); } SECTION("Disable variable doesn't count") @@ -113,8 +113,8 @@ TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]") Sys.expand(sys_cnst, rho_2, 10); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 1.0, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 0.0, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 1.0, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 0.0, sg_precision_workamount)); } SECTION("No consumption variable") @@ -138,7 +138,7 @@ TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]") Sys.expand(sys_cnst, rho_2, 10); Sys.solve(); - REQUIRE(double_positive(rho_1->get_value(), sg_maxmin_precision)); + REQUIRE(double_positive(rho_1->get_value(), sg_precision_workamount)); } SECTION("Bounded variable") @@ -163,8 +163,8 @@ TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]") Sys.expand(sys_cnst, rho_1, 2); Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), .1, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), .8, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), .1, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), .8, sg_precision_workamount)); } SECTION("Fatpipe") @@ -191,8 +191,8 @@ TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]") Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 3.0, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 3.0, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 3.0, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 3.0, sg_precision_workamount)); } SECTION("(un)Bounded variable") @@ -217,8 +217,8 @@ TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]") Sys.expand(sys_cnst, rho_1, 1); Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), .5, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), .5, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), .5, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), .5, sg_precision_workamount)); } SECTION("Dynamic bounds") @@ -242,15 +242,15 @@ TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]") lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1); Sys.expand(sys_cnst, rho_1, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 1, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 1, sg_precision_workamount)); // add another variable, half initial capacity lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1); Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), .25, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), .25, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), .25, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), .25, sg_precision_workamount)); } Sys.variable_free_all(); @@ -291,8 +291,8 @@ TEST_CASE("kernel::bmf Advanced tests", "[kernel-bmf-advanced]") Sys.expand(sys_cnst2, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 1.0 / 11.0, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 1.0 / 11.0, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 1.0 / 11.0, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 1.0 / 11.0, sg_precision_workamount)); } SECTION("BMF paper example") @@ -327,9 +327,9 @@ TEST_CASE("kernel::bmf Advanced tests", "[kernel-bmf-advanced]") Sys.expand(sys_cnst3, rho_3, 3.0 / 4.0); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 1.0 / 3.0, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 4.0 / 9.0, sg_maxmin_precision)); - REQUIRE(double_equals(rho_3->get_value(), 4.0 / 9.0, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 1.0 / 3.0, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 4.0 / 9.0, sg_precision_workamount)); + REQUIRE(double_equals(rho_3->get_value(), 4.0 / 9.0, sg_precision_workamount)); } SECTION("IO - example") @@ -368,8 +368,8 @@ TEST_CASE("kernel::bmf Advanced tests", "[kernel-bmf-advanced]") Sys.expand(sys_cnst3, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 1e6 / 2.0, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 1e6 / 2.0, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 1e6 / 2.0, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 1e6 / 2.0, sg_precision_workamount)); } SECTION("Proportional fairness") @@ -398,9 +398,9 @@ TEST_CASE("kernel::bmf Advanced tests", "[kernel-bmf-advanced]") Sys.expand(sys_cnst, rho_3, epsilon); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 1.0 / (2.0 + 2 * epsilon), sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 1.0 / (2.0 + 2 * epsilon), sg_maxmin_precision)); - REQUIRE(double_equals(rho_3->get_value(), 1.0 / (1.0 + epsilon), sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 1.0 / (2.0 + 2 * epsilon), sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 1.0 / (2.0 + 2 * epsilon), sg_precision_workamount)); + REQUIRE(double_equals(rho_3->get_value(), 1.0 / (1.0 + epsilon), sg_precision_workamount)); } Sys.variable_free_all(); @@ -440,8 +440,8 @@ TEST_CASE("kernel::bmf Subflows", "[kernel-bmf-subflow]") Sys.expand(sys_cnst, rho_2, 5); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 5.0 / 24.0, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 5.0 / 24.0, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 5.0 / 24.0, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 5.0 / 24.0, sg_precision_workamount)); } SECTION("1 subflows, 1 flow and 1 resource") @@ -475,9 +475,9 @@ TEST_CASE("kernel::bmf Subflows", "[kernel-bmf-subflow]") Sys.expand(sys_cnst, rho_2, 10); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), (5.0 / 25.0), sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), (5.0 / 25.0), sg_maxmin_precision)); - REQUIRE(double_equals(15 * rho_1->get_value(), 10 * rho_2->get_value() * 3 / 2, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), (5.0 / 25.0), sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), (5.0 / 25.0), sg_precision_workamount)); + REQUIRE(double_equals(15 * rho_1->get_value(), 10 * rho_2->get_value() * 3 / 2, sg_precision_workamount)); } SECTION("1 subflows using 2 resources: different max for each resource") @@ -513,8 +513,8 @@ TEST_CASE("kernel::bmf Subflows", "[kernel-bmf-subflow]") Sys.expand(sys_cnst2, rho_2, 3.0 / 2.0); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), (1.0 / 3.0), sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), (1.0 / 3.0), sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), (1.0 / 3.0), sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), (1.0 / 3.0), sg_precision_workamount)); } Sys.variable_free_all(); @@ -556,7 +556,7 @@ TEST_CASE("kernel::bmf Loop", "[kernel-bmf-loop]") Sys.solve(); for (const auto* rho : vars) { - REQUIRE(double_positive(rho->get_value(), sg_maxmin_precision)); + REQUIRE(double_positive(rho->get_value(), sg_precision_workamount)); } } @@ -655,8 +655,8 @@ TEST_CASE("kernel::bmf Bugs", "[kernel-bmf-bug]") Sys.expand(sys_cnst, rho_2, 1.0); Sys.expand(sys_cnst2, rho_2, 1.0); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 1.4, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 3, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 1.4, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 3, sg_precision_workamount)); } SECTION("s4u-cloud-capping bug: all limited by bound extra case") @@ -675,8 +675,8 @@ TEST_CASE("kernel::bmf Bugs", "[kernel-bmf-bug]") Sys.expand(sys_cnst, rho_1, 1); Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 7.6296e+06, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 3.8148e+07, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 7.6296e+06, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 3.8148e+07, sg_precision_workamount)); } SECTION("Variable penalty with bounds: thread bug") @@ -694,8 +694,8 @@ TEST_CASE("kernel::bmf Bugs", "[kernel-bmf-bug]") Sys.expand(sys_cnst, rho_1, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 8e7, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 3.2e8, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 8e7, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 3.2e8, sg_precision_workamount)); } SECTION("Variable penalty with bounds greater than C") @@ -709,7 +709,7 @@ TEST_CASE("kernel::bmf Bugs", "[kernel-bmf-bug]") Sys.expand(sys_cnst, rho_1, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 4e8, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 4e8, sg_precision_workamount)); } Sys.variable_free_all(); diff --git a/src/kernel/lmm/fair_bottleneck.cpp b/src/kernel/lmm/fair_bottleneck.cpp index 5f89cbbe0b..3349fc5867 100644 --- a/src/kernel/lmm/fair_bottleneck.cpp +++ b/src/kernel/lmm/fair_bottleneck.cpp @@ -1,10 +1,10 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/lmm/fair_bottleneck.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/math_utils.h" #include "xbt/sysdep.h" #include @@ -103,7 +103,7 @@ void simgrid::kernel::lmm::FairBottleneck::do_solve() xbt_assert(elem.variable->sharing_penalty_ > 0); XBT_DEBUG("\tUpdate constraint %p (%g) with variable %p by %g", &cnst, cnst.remaining_, elem.variable, elem.variable->mu_); - double_update(&cnst.remaining_, elem.consumption_weight * elem.variable->mu_, sg_maxmin_precision); + double_update(&cnst.remaining_, elem.consumption_weight * elem.variable->mu_, sg_precision_workamount); } } else { for (const Element& elem : cnst.enabled_element_set_) { @@ -113,7 +113,7 @@ void simgrid::kernel::lmm::FairBottleneck::do_solve() cnst.usage_ = std::min(cnst.usage_, elem.consumption_weight * elem.variable->mu_); } XBT_DEBUG("\tUpdate constraint %p (%g) by %g", &cnst, cnst.remaining_, cnst.usage_); - double_update(&cnst.remaining_, cnst.usage_, sg_maxmin_precision); + double_update(&cnst.remaining_, cnst.usage_, sg_precision_workamount); } XBT_DEBUG("\tRemaining for %p : %g", &cnst, cnst.remaining_); diff --git a/src/kernel/lmm/fair_bottleneck.hpp b/src/kernel/lmm/fair_bottleneck.hpp index eaa22deee0..228eeea625 100644 --- a/src/kernel/lmm/fair_bottleneck.hpp +++ b/src/kernel/lmm/fair_bottleneck.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/kernel/lmm/maxmin.cpp b/src/kernel/lmm/maxmin.cpp index d12f588225..4a94887b09 100644 --- a/src/kernel/lmm/maxmin.cpp +++ b/src/kernel/lmm/maxmin.cpp @@ -1,9 +1,11 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/lmm/maxmin.hpp" +#include "src/simgrid/math_utils.h" +#include "xbt/ex.h" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ker_lmm); @@ -67,11 +69,11 @@ template void MaxMin::maxmin_solve(CnstList& cnst_list) /* INIT: Collect constraints that actually need to be saturated (i.e remaining and usage are strictly positive) * into cnst_light_tab. */ cnst.dynamic_bound_ = cnst.bound_; - if (cnst.get_sharing_policy() == Constraint::SharingPolicy::NONLINEAR && cnst.dyn_constraint_cb_) { + if ((cnst.get_sharing_policy() == Constraint::SharingPolicy::NONLINEAR || cnst.get_sharing_policy() == Constraint::SharingPolicy::WIFI) && cnst.dyn_constraint_cb_) { cnst.dynamic_bound_ = cnst.dyn_constraint_cb_(cnst.bound_, cnst.concurrency_current_); } cnst.remaining_ = cnst.dynamic_bound_; - if (not double_positive(cnst.remaining_, cnst.dynamic_bound_ * sg_maxmin_precision)) + if (not double_positive(cnst.remaining_, cnst.dynamic_bound_ * sg_precision_workamount)) continue; cnst.usage_ = 0; for (Element& elem : cnst.enabled_element_set_) { @@ -132,7 +134,7 @@ template void MaxMin::maxmin_solve(CnstList& cnst_list) XBT_DEBUG("Setting var (%d) value to %f\n", var.rank_, var.value_); } else { // If there exist a variable that can reach its bound, only update it (and other with the same bound) for now. - if (double_equals(min_bound, var.bound_ * var.sharing_penalty_, sg_maxmin_precision)) { + if (double_equals(min_bound, var.bound_ * var.sharing_penalty_, sg_precision_workamount)) { var.value_ = var.bound_; XBT_DEBUG("Setting %p (%d) value to %f\n", &var, var.rank_, var.value_); } else { @@ -151,11 +153,11 @@ template void MaxMin::maxmin_solve(CnstList& cnst_list) if (cnst->sharing_policy_ != Constraint::SharingPolicy::FATPIPE) { // Remember: shared constraints require that sum(elem.value * var.value) < cnst->bound double_update(&(cnst->remaining_), elem.consumption_weight * var.value_, - cnst->dynamic_bound_ * sg_maxmin_precision); - double_update(&(cnst->usage_), elem.consumption_weight / var.sharing_penalty_, sg_maxmin_precision); + cnst->dynamic_bound_ * sg_precision_workamount); + double_update(&(cnst->usage_), elem.consumption_weight / var.sharing_penalty_, sg_precision_workamount); // If the constraint is saturated, remove it from the set of active constraints (light_tab) - if (not double_positive(cnst->usage_, sg_maxmin_precision) || - not double_positive(cnst->remaining_, cnst->dynamic_bound_ * sg_maxmin_precision)) { + if (not double_positive(cnst->usage_, sg_precision_workamount) || + not double_positive(cnst->remaining_, cnst->dynamic_bound_ * sg_precision_workamount)) { if (cnst->cnst_light_) { size_t index = (cnst->cnst_light_ - cnst_light_tab); XBT_DEBUG("index: %zu \t cnst_light_num: %d \t || usage: %f remaining: %f bound: %f", index, @@ -183,8 +185,8 @@ template void MaxMin::maxmin_solve(CnstList& cnst_list) cnst->usage_ = std::max(cnst->usage_, elem2.consumption_weight / elem2.variable->sharing_penalty_); } // If the constraint is saturated, remove it from the set of active constraints (light_tab) - if (not double_positive(cnst->usage_, sg_maxmin_precision) || - not double_positive(cnst->remaining_, cnst->dynamic_bound_ * sg_maxmin_precision)) { + if (not double_positive(cnst->usage_, sg_precision_workamount) || + not double_positive(cnst->remaining_, cnst->dynamic_bound_ * sg_precision_workamount)) { if (cnst->cnst_light_) { size_t index = (cnst->cnst_light_ - cnst_light_tab); XBT_DEBUG("index: %zu \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p " @@ -214,12 +216,15 @@ template void MaxMin::maxmin_solve(CnstList& cnst_list) min_bound = -1; saturated_constraints.clear(); for (int pos = 0; pos < cnst_light_num; pos++) { - xbt_assert(not cnst_light_tab[pos].cnst->active_element_set_.empty(), - "Cannot saturate more a constraint that has" - " no active element! You may want to change the maxmin precision (--cfg=maxmin/precision:)" - " because of possible rounding effects.\n\tFor the record, the usage of this constraint is %g while " - "the maxmin precision to which it is compared is %g.\n\tThe usage of the previous constraint is %g.", - cnst_light_tab[pos].cnst->usage_, sg_maxmin_precision, cnst_light_tab[pos - 1].cnst->usage_); + xbt_assert( + not cnst_light_tab[pos].cnst->active_element_set_.empty(), + "Cannot saturate more a constraint that has" + " no active element! You may want to change the work amount precision (--cfg=precision/work-amount:)" + " because of possible rounding effects.\n\tFor the record, the usage of this constraint is %g while " + "the maxmin precision to which it is compared is %g.\n\t%s%g.", + cnst_light_tab[pos].cnst->usage_, sg_precision_workamount, + (pos > 0 ? "The usage of the previous constraint is " : "There is no previous constraint. "), + (pos > 0 ? cnst_light_tab[pos - 1].cnst->usage_ : -1)); saturated_constraints_update(cnst_light_tab[pos].remaining_over_usage, pos, saturated_constraints, &min_usage); } diff --git a/src/kernel/lmm/maxmin.hpp b/src/kernel/lmm/maxmin.hpp index f5bd0ce2e0..5d0619ee79 100644 --- a/src/kernel/lmm/maxmin.hpp +++ b/src/kernel/lmm/maxmin.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/kernel/lmm/maxmin_test.cpp b/src/kernel/lmm/maxmin_test.cpp index 07232d3c06..a7d16dc91b 100644 --- a/src/kernel/lmm/maxmin_test.cpp +++ b/src/kernel/lmm/maxmin_test.cpp @@ -1,11 +1,11 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "src/include/catch.hpp" +#include "src/3rd-party/catch.hpp" #include "src/kernel/lmm/maxmin.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/math_utils.h" #include "xbt/log.h" namespace lmm = simgrid::kernel::lmm; @@ -37,8 +37,8 @@ TEST_CASE("kernel::lmm Single constraint shared systems", "[kernel-lmm-shared-si Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 2, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 1, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 2, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 1, sg_precision_workamount)); } SECTION("Consumption weight") @@ -65,8 +65,8 @@ TEST_CASE("kernel::lmm Single constraint shared systems", "[kernel-lmm-shared-si Sys.expand(sys_cnst, rho_2, 2); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 1, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 1, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 1, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 1, sg_precision_workamount)); } SECTION("Consumption weight + variable penalty") @@ -94,8 +94,8 @@ TEST_CASE("kernel::lmm Single constraint shared systems", "[kernel-lmm-shared-si Sys.solve(); double rho_1_share = 10; - REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), rho_1_share / 2, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), rho_1_share / 2, sg_precision_workamount)); } SECTION("Multiple constraints systems") @@ -134,9 +134,9 @@ TEST_CASE("kernel::lmm Single constraint shared systems", "[kernel-lmm-shared-si Sys.solve(); double rho_1_share = 10; // Start by solving the first constraint (results is the same as previous tests) - REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), rho_1_share / 2, sg_maxmin_precision)); - REQUIRE(double_equals(rho_3->get_value(), 60 - 2 * rho_1_share, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), rho_1_share / 2, sg_precision_workamount)); + REQUIRE(double_equals(rho_3->get_value(), 60 - 2 * rho_1_share, sg_precision_workamount)); } Sys.variable_free_all(); @@ -171,8 +171,8 @@ TEST_CASE("kernel::lmm Single constraint unshared systems", "[kernel-lmm-unshare Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 10, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 10 / 2, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 10, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 10 / 2, sg_precision_workamount)); } SECTION("Consumption weight") @@ -201,8 +201,8 @@ TEST_CASE("kernel::lmm Single constraint unshared systems", "[kernel-lmm-unshare Sys.expand(sys_cnst, rho_2, 2); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 5, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 5, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 5, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 5, sg_precision_workamount)); } SECTION("Consumption weight + variable penalty") @@ -231,8 +231,8 @@ TEST_CASE("kernel::lmm Single constraint unshared systems", "[kernel-lmm-unshare Sys.expand(sys_cnst, sys_var_2, 2); Sys.solve(); - REQUIRE(double_equals(sys_var_1->get_value(), 10, sg_maxmin_precision)); - REQUIRE(double_equals(sys_var_2->get_value(), 5, sg_maxmin_precision)); + REQUIRE(double_equals(sys_var_1->get_value(), 10, sg_precision_workamount)); + REQUIRE(double_equals(sys_var_2->get_value(), 5, sg_precision_workamount)); } SECTION("Multiple constraints systems") @@ -273,9 +273,9 @@ TEST_CASE("kernel::lmm Single constraint unshared systems", "[kernel-lmm-unshare Sys.solve(); double rho_1_share = 10; // Start by solving the first constraint (results is the same as previous tests) - REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), rho_1_share / 2, sg_maxmin_precision)); - REQUIRE(double_equals(rho_3->get_value(), 60, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), rho_1_share / 2, sg_precision_workamount)); + REQUIRE(double_equals(rho_3->get_value(), 60, sg_precision_workamount)); } Sys.variable_free_all(); @@ -310,7 +310,7 @@ TEST_CASE("kernel::lmm dynamic constraint shared systems", "[kernel-lmm-shared-s Sys.expand(sys_cnst, rho_1, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 10, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 10, sg_precision_workamount)); } SECTION("2 activities, but ignore crosstraffic 100% C") @@ -336,8 +336,8 @@ TEST_CASE("kernel::lmm dynamic constraint shared systems", "[kernel-lmm-shared-s Sys.expand(sys_cnst, rho_2, 0.05); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 10 / 1.05, sg_maxmin_precision)); - REQUIRE(double_equals(rho_1->get_value(), rho_2->get_value(), sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 10 / 1.05, sg_precision_workamount)); + REQUIRE(double_equals(rho_1->get_value(), rho_2->get_value(), sg_precision_workamount)); } SECTION("2 activities, 1 inactive 100% C") @@ -362,8 +362,8 @@ TEST_CASE("kernel::lmm dynamic constraint shared systems", "[kernel-lmm-shared-s Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 10, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 0, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 10, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 0, sg_precision_workamount)); } SECTION("2 activity, 90% C") @@ -388,8 +388,8 @@ TEST_CASE("kernel::lmm dynamic constraint shared systems", "[kernel-lmm-shared-s Sys.expand(sys_cnst, rho_2, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 4.5, sg_maxmin_precision)); - REQUIRE(double_equals(rho_1->get_value(), 4.5, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 4.5, sg_precision_workamount)); + REQUIRE(double_equals(rho_1->get_value(), 4.5, sg_precision_workamount)); } SECTION("3 activity, 80% C") @@ -417,9 +417,9 @@ TEST_CASE("kernel::lmm dynamic constraint shared systems", "[kernel-lmm-shared-s Sys.expand(sys_cnst, rho_3, 1); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 4, sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 2, sg_maxmin_precision)); - REQUIRE(double_equals(rho_3->get_value(), 2, sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 4, sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 2, sg_precision_workamount)); + REQUIRE(double_equals(rho_3->get_value(), 2, sg_precision_workamount)); } Sys.variable_free_all(); @@ -458,9 +458,9 @@ TEST_CASE("kernel::lmm shared systems with crosstraffic", "[kernel-lmm-shared-cr Sys.expand(sys_cnst, rho_3, epsilon); Sys.solve(); - REQUIRE(double_equals(rho_1->get_value(), 1.0 / (2.0 + epsilon), sg_maxmin_precision)); - REQUIRE(double_equals(rho_2->get_value(), 1.0 / (2.0 + epsilon), sg_maxmin_precision)); - REQUIRE(double_equals(rho_3->get_value(), 1.0 / (2.0 + epsilon), sg_maxmin_precision)); + REQUIRE(double_equals(rho_1->get_value(), 1.0 / (2.0 + epsilon), sg_precision_workamount)); + REQUIRE(double_equals(rho_2->get_value(), 1.0 / (2.0 + epsilon), sg_precision_workamount)); + REQUIRE(double_equals(rho_3->get_value(), 1.0 / (2.0 + epsilon), sg_precision_workamount)); } Sys.variable_free_all(); diff --git a/src/kernel/resource/Action.cpp b/src/kernel/resource/Action.cpp index 6920fd7d86..9651cde842 100644 --- a/src/kernel/resource/Action.cpp +++ b/src/kernel/resource/Action.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,7 +7,7 @@ #include "simgrid/kernel/resource/Model.hpp" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/lmm/maxmin.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/math_utils.h" XBT_LOG_NEW_CATEGORY(kernel, "SimGrid internals"); XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_resource, kernel, "Resources, modeling the platform performance"); @@ -194,12 +194,12 @@ double Action::get_remains() void Action::update_max_duration(double delta) { if (max_duration_ != NO_MAX_DURATION) - double_update(&max_duration_, delta, sg_surf_precision); + double_update(&max_duration_, delta, sg_precision_timing); } void Action::update_remains(double delta) { - double_update(&remains_, delta, sg_maxmin_precision * sg_surf_precision); + double_update(&remains_, delta, sg_precision_workamount * sg_precision_timing); } void Action::set_last_update() diff --git a/src/kernel/resource/CpuImpl.cpp b/src/kernel/resource/CpuImpl.cpp index 6a6deb4b42..acd7aa4a89 100644 --- a/src/kernel/resource/CpuImpl.cpp +++ b/src/kernel/resource/CpuImpl.cpp @@ -1,12 +1,12 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/resource/CpuImpl.hpp" +#include "src/kernel/resource/models/cpu_ti.hpp" #include "src/kernel/resource/profile/Profile.hpp" -#include "src/surf/cpu_ti.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/math_utils.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_cpu, ker_resource, "CPU resource, fueling execution activites"); @@ -18,7 +18,7 @@ namespace simgrid::kernel::resource { void CpuModel::update_actions_state_lazy(double now, double /*delta*/) { - while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_surf_precision)) { + while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_precision_timing)) { auto* action = static_cast(get_action_heap().pop()); XBT_DEBUG("Something happened to action %p", action); @@ -66,9 +66,9 @@ CpuImpl* CpuImpl::set_pstate(unsigned long pstate_index) { xbt_assert( pstate_index < speed_per_pstate_.size(), - "Invalid parameters for CPU %s (pstate %lu >= length of pstates %d). Please fix your platform file, or your " + "Invalid parameters for CPU %s (pstate %lu >= length of pstates %zu). Please fix your platform file, or your " "call to change the pstate.", - get_cname(), pstate_index, static_cast(speed_per_pstate_.size())); + get_cname(), pstate_index, speed_per_pstate_.size()); double new_peak_speed = speed_per_pstate_[pstate_index]; pstate_ = pstate_index; @@ -89,14 +89,15 @@ CpuImpl* CpuImpl::set_pstate_speed(const std::vector& speed_per_state) double CpuImpl::get_pstate_peak_speed(unsigned long pstate_index) const { - xbt_assert((pstate_index <= speed_per_pstate_.size()), "Invalid parameters (pstate index out of bounds)"); - + xbt_assert(pstate_index < speed_per_pstate_.size(), "Invalid parameters (pstate index %lu out of bounds %zu)", + pstate_index, speed_per_pstate_.size()); return speed_per_pstate_[pstate_index]; } void CpuImpl::on_speed_change() { s4u::Host::on_speed_change(*piface_); + piface_->on_this_speed_change(*piface_); } CpuImpl* CpuImpl::set_core_count(int core_count) @@ -112,7 +113,7 @@ CpuImpl* CpuImpl::set_core_count(int core_count) void CpuImpl::apply_sharing_policy_cfg() const { - if (!get_constraint()) + if (not get_constraint()) return; kernel::lmm::Constraint::SharingPolicy lmm_policy = kernel::lmm::Constraint::SharingPolicy::SHARED; @@ -151,6 +152,14 @@ void CpuImpl::seal() Resource::seal(); } +void CpuImpl::turn_off() +{ + if (is_on()) { + Resource::turn_off(); + cancel_actions(); + } +} + /********** * Action * **********/ @@ -175,27 +184,11 @@ void CpuAction::update_remains_lazy(double now) set_last_value(get_rate()); } -xbt::signal CpuAction::on_state_change; - -void CpuAction::suspend() -{ - Action::State previous = get_state(); - on_state_change(*this, previous); - Action::suspend(); -} - -void CpuAction::resume() -{ - Action::State previous = get_state(); - on_state_change(*this, previous); - Action::resume(); -} - void CpuAction::set_state(Action::State state) { Action::State previous = get_state(); Action::set_state(state); - on_state_change(*this, previous); + s4u::Host::on_exec_state_change(*this, previous); } /** @brief returns a list of all CPUs that this action is using */ diff --git a/src/kernel/resource/CpuImpl.hpp b/src/kernel/resource/CpuImpl.hpp index aff4172d8a..ae35bd5ba9 100644 --- a/src/kernel/resource/CpuImpl.hpp +++ b/src/kernel/resource/CpuImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,6 +10,7 @@ #include "simgrid/s4u/Host.hpp" #include "src/kernel/lmm/maxmin.hpp" #include "src/kernel/resource/Resource.hpp" +#include "xbt/ex.h" #include @@ -77,6 +78,8 @@ public: CpuImpl* set_core_count(int core_count); virtual int get_core_count() const { return core_count_; } + void turn_off() override; + bool is_used() const override { return true; } void seal() override; @@ -170,25 +173,17 @@ protected: * Action * **********/ -/** @ingroup SURF_cpu_interface +/** @ingroup Model_cpu_interface * @brief A CpuAction represents the execution of code on one or several Cpus */ class XBT_PUBLIC CpuAction : public Action { public: using Action::Action; - /** @brief Signal emitted when the action state changes (ready/running/done, etc) - * Signature: `void(CpuAction const& action, simgrid::kernel::resource::Action::State previous)` - */ - static xbt::signal on_state_change; - void set_state(Action::State state) override; void update_remains_lazy(double now) override; std::list cpus() const; - - void suspend() override; - void resume() override; }; } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/DiskImpl.cpp b/src/kernel/resource/DiskImpl.cpp index 29198e10a3..20c23ac077 100644 --- a/src/kernel/resource/DiskImpl.cpp +++ b/src/kernel/resource/DiskImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,32 +6,15 @@ #include "DiskImpl.hpp" #include "simgrid/s4u/Engine.hpp" -#include "simgrid/sg_config.hpp" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/lmm/maxmin.hpp" #include "src/kernel/resource/profile/Profile.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_disk, ker_resource, "Disk resources, that fuel I/O activities"); -/*********** - * Options * - ***********/ -static simgrid::config::Flag cfg_disk_solver("disk/solver", - "Set linear equations solver used by disk model", "maxmin", - &simgrid::kernel::lmm::System::validate_solver); - namespace simgrid::kernel::resource { xbt::signal DiskAction::on_state_change; -/********* - * Model * - *********/ - -DiskModel::DiskModel(const std::string& name) : Model(name) -{ - set_maxmin_system(lmm::System::build(cfg_disk_solver, true /* selective update */)); -} - /************ * Resource * ************/ @@ -70,6 +53,7 @@ DiskImpl* DiskImpl::set_write_constraint(lmm::Constraint* constraint_write) void DiskImpl::destroy() { s4u::Disk::on_destruction(piface_); + piface_.on_this_destruction(piface_); delete this; } @@ -77,14 +61,17 @@ void DiskImpl::turn_on() { if (not is_on()) { Resource::turn_on(); - s4u::Disk::on_state_change(piface_); + s4u::Disk::on_onoff(piface_); + piface_.on_this_onoff(piface_); } } void DiskImpl::turn_off() { if (is_on()) { Resource::turn_off(); - s4u::Disk::on_state_change(piface_); + s4u::Disk::on_onoff(piface_); + piface_.on_this_onoff(piface_); + cancel_actions(); } } @@ -134,6 +121,29 @@ constexpr kernel::lmm::Constraint::SharingPolicy to_maxmin_policy(s4u::Disk::Sha return lmm_policy; } +void DiskImpl::set_read_bandwidth(double value) +{ + read_bw_.peak = value; + if (constraint_read_) + get_model()->get_maxmin_system()->update_constraint_bound(constraint_read_, read_bw_.peak * read_bw_.scale); +} + +void DiskImpl::set_write_bandwidth(double value) +{ + write_bw_.peak = value; + if (constraint_write_) { + get_model()->get_maxmin_system()->update_constraint_bound(constraint_write_, write_bw_.peak* write_bw_.scale); + } +} + +void DiskImpl::set_readwrite_bandwidth(double value) +{ + readwrite_bw_ = value; + if (get_constraint()) { + get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(), readwrite_bw_); + } +} + void DiskImpl::set_sharing_policy(s4u::Disk::Operation op, s4u::Disk::SharingPolicy policy, const s4u::NonLinearResourceCb& cb) { @@ -177,4 +187,9 @@ void DiskAction::set_state(Action::State new_state) on_state_change(*this, previous_state, new_state); } } + +void DiskAction::update_remains_lazy(double /*now*/) +{ + THROW_IMPOSSIBLE; +} } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/DiskImpl.hpp b/src/kernel/resource/DiskImpl.hpp index 611234d1ae..a1bdb8ae50 100644 --- a/src/kernel/resource/DiskImpl.hpp +++ b/src/kernel/resource/DiskImpl.hpp @@ -1,25 +1,20 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#ifndef DISK_IMPL_HPP_ +#define DISK_IMPL_HPP_ + #include "simgrid/kernel/resource/Action.hpp" #include "simgrid/kernel/resource/Model.hpp" #include "simgrid/s4u/Disk.hpp" #include "simgrid/s4u/Io.hpp" #include "src/kernel/resource/Resource.hpp" -#include "src/surf/surf_interface.hpp" #include "xbt/PropertyHolder.hpp" #include -#ifndef DISK_IMPL_HPP_ -#define DISK_IMPL_HPP_ - -/********* - * Model * - *********/ - namespace simgrid::kernel::resource { /*********** * Classes * @@ -32,13 +27,9 @@ class DiskAction; *********/ class DiskModel : public Model { public: - explicit DiskModel(const std::string& name); - DiskModel(const DiskModel&) = delete; - DiskModel& operator=(const DiskModel&) = delete; + using Model::Model; virtual DiskImpl* create_disk(const std::string& name, double read_bandwidth, double write_bandwidth) = 0; - - virtual DiskAction* io_start(const DiskImpl* disk, sg_size_t size, s4u::Io::OpType type) = 0; }; /************ @@ -59,6 +50,7 @@ class DiskImpl : public Resource_T, public xbt::PropertyHolder { Metric read_bw_ = {0.0, 0, nullptr}; Metric write_bw_ = {0.0, 0, nullptr}; double readwrite_bw_ = -1; /* readwrite constraint bound, usually max(read, write) */ + std::atomic_int_fast32_t refcount_{0}; void apply_sharing_policy_cfg(); @@ -69,6 +61,17 @@ public: explicit DiskImpl(const std::string& name, double read_bandwidth, double write_bandwidth); DiskImpl(const DiskImpl&) = delete; DiskImpl& operator=(const DiskImpl&) = delete; + friend void intrusive_ptr_add_ref(DiskImpl* disk) + { + disk->refcount_.fetch_add(1, std::memory_order_acq_rel); + } + friend void intrusive_ptr_release(DiskImpl* disk) + { + if (disk->refcount_.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + delete disk; + } + } /** @brief Public interface */ const s4u::Disk* get_iface() const { return &piface_; } @@ -76,13 +79,13 @@ public: DiskImpl* set_host(s4u::Host* host); s4u::Host* get_host() const { return host_; } - virtual void set_read_bandwidth(double value) { read_bw_.peak = value; } + void set_read_bandwidth(double value); double get_read_bandwidth() const { return read_bw_.peak * read_bw_.scale; } - virtual void set_write_bandwidth(double value) { write_bw_.peak = value; } + void set_write_bandwidth(double value); double get_write_bandwidth() const { return write_bw_.peak * write_bw_.scale; } - virtual void set_readwrite_bandwidth(double value) { readwrite_bw_ = value; } + void set_readwrite_bandwidth(double value); double get_readwrite_bandwidth() const { return readwrite_bw_; } DiskImpl* set_read_constraint(lmm::Constraint* constraint_read); @@ -111,6 +114,8 @@ public: void seal() override; void destroy(); // Must be called instead of the destructor + + virtual DiskAction* io_start(sg_size_t size, s4u::Io::OpType type) = 0; }; /********** @@ -123,6 +128,7 @@ public: using Action::Action; void set_state(simgrid::kernel::resource::Action::State state) override; + void update_remains_lazy(double now) override; }; } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/FactorSet.cpp b/src/kernel/resource/FactorSet.cpp new file mode 100644 index 0000000000..8e42bb90c5 --- /dev/null +++ b/src/kernel/resource/FactorSet.cpp @@ -0,0 +1,118 @@ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/kernel/resource/FactorSet.hpp" +#include "xbt/ex.h" +#include "xbt/file.hpp" +#include "xbt/log.h" +#include "xbt/parse_units.hpp" +#include "xbt/str.h" +#include "xbt/sysdep.h" + +#include +#include + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ker_resource); + +extern std::string simgrid_parsed_filename; +extern int simgrid_parse_lineno; + +namespace simgrid::kernel::resource { + +void FactorSet::parse(const std::string& values) +{ + initialized_ = true; + + if (values.find_first_of(":;") == std::string::npos) { // Single value + default_value_ = xbt_str_parse_double(values.c_str(), name_.c_str()); + return; + } + + /** Setup the tokenizer that parses the string **/ + using Tokenizer = boost::tokenizer>; + boost::char_separator sep(";"); + boost::char_separator factor_separator(":"); + Tokenizer tokens(values, sep); + + /** + * Iterate over patterns like A:B:C:D;E:F;G:H + * These will be broken down into: + * A --> B, C, D + * E --> F + * G --> H + */ + for (auto token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) { + XBT_DEBUG("token: %s", token_iter->c_str()); + Tokenizer factor_values(*token_iter, factor_separator); + s_smpi_factor_t fact; + xbt_assert(factor_values.begin() != factor_values.end(), "Malformed radical for %s: '%s'", name_.c_str(), + values.c_str()); + unsigned int iteration = 0; + for (auto factor_iter = factor_values.begin(); factor_iter != factor_values.end(); ++factor_iter) { + iteration++; + + if (factor_iter == factor_values.begin()) { /* first element */ + try { + fact.factor = std::stoi(*factor_iter); + } catch (const std::invalid_argument&) { + throw std::invalid_argument("Invalid factor in chunk " + std::to_string(factors_.size() + 1) + ": " + + *factor_iter + " for " + name_); + } + } else { + try { + fact.values.push_back(xbt_parse_get_time(simgrid_parsed_filename, simgrid_parse_lineno, *factor_iter, "")); + } catch (const std::invalid_argument&) { + throw std::invalid_argument("Invalid factor value " + std::to_string(iteration) + " in chunk " + + std::to_string(factors_.size() + 1) + ": " + *factor_iter + " for " + name_); + } + } + } + + factors_.push_back(fact); + XBT_DEBUG("smpi_factor:\t%zu: %zu values, first: %f", fact.factor, factors_.size(), fact.values[0]); + } + std::sort(factors_.begin(), factors_.end(), + [](const s_smpi_factor_t& pa, const s_smpi_factor_t& pb) { return (pa.factor < pb.factor); }); + for (auto const& fact : factors_) { + XBT_DEBUG("smpi_factor:\t%zu: %zu values, first: %f", fact.factor, factors_.size(), fact.values[0]); + } + factors_.shrink_to_fit(); +} + +FactorSet::FactorSet(const std::string& name, double default_value, + std::function const&, double)> const& lambda) + : name_(name), default_value_(default_value), lambda_(lambda) +{ +} + +double FactorSet::operator()() const +{ + return default_value_; +} + +double FactorSet::operator()(double size) const +{ + if (factors_.empty()) + return default_value_; + + for (long unsigned i = 0; i < factors_.size(); i++) { + auto const& fact = factors_[i]; + + if (size <= fact.factor) { // Too large already, use the previous value + if (i == 0) { // Before the first boundary: use the default value + XBT_DEBUG("%s: %f <= %zu return default %f", name_.c_str(), size, fact.factor, default_value_); + return default_value_; + } + double val = lambda_(factors_[i - 1].values, size); + XBT_DEBUG("%s: %f <= %zu return %f", name_.c_str(), size, fact.factor, val); + return val; + } + } + double val = lambda_(factors_.back().values, size); + + XBT_DEBUG("%s: %f > %zu return %f", name_.c_str(), size, factors_.back().factor, val); + return val; +} +} // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/FactorSet.hpp b/src/kernel/resource/FactorSet.hpp new file mode 100644 index 0000000000..9fe3453456 --- /dev/null +++ b/src/kernel/resource/FactorSet.hpp @@ -0,0 +1,46 @@ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef RESOURCE_FACTORSET_HPP +#define RESOURCE_FACTORSET_HPP +#include + +#include +#include +#include +#include +#include + +// Methods used to parse and store the values for timing injections in smpi +struct s_smpi_factor_t { + size_t factor = 0; + std::vector values; +}; + +namespace simgrid::kernel::resource { + +class FactorSet { + const std::string name_; + std::vector factors_; + double default_value_; + const std::function const&, double)> lambda_; + bool initialized_ = false; + +public: + // Parse the factor from a string + FactorSet( + const std::string& name, double default_value = 1, + std::function const&, double)> const& lambda = [](std::vector const& values, + double) { return values.front(); }); + void parse(const std::string& string_values); + bool is_initialized() const { return initialized_; } + // Get the default value + double operator()() const; + // Get the factor to use for the provided size + double operator()(double size) const; +}; + +} // namespace simgrid::kernel::resource +#endif diff --git a/src/surf/HostImpl.cpp b/src/kernel/resource/HostImpl.cpp similarity index 79% rename from src/surf/HostImpl.cpp rename to src/kernel/resource/HostImpl.cpp index 82b2f92995..da11f9aa1e 100644 --- a/src/surf/HostImpl.cpp +++ b/src/kernel/resource/HostImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,16 +7,17 @@ #include #include -#include "xbt/asserts.hpp" #include "src/kernel/EngineImpl.hpp" +#include "src/kernel/resource/NetworkModel.hpp" #include "src/kernel/resource/VirtualMachineImpl.hpp" +#include "xbt/asserts.hpp" #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_host, ker_resource, "Host resources agregate CPU, networking and I/O features"); /************* - * Callbacks *t + * Callbacks * *************/ namespace simgrid::kernel::resource { @@ -24,12 +25,35 @@ namespace simgrid::kernel::resource { /********* * Model * *********/ +Action* HostModel::io_stream(s4u::Host* src_host, DiskImpl* src_disk, s4u::Host* dst_host, DiskImpl* dst_disk, + double size) +{ + auto* net_model = src_host->get_englobing_zone()->get_network_model(); + auto* system = net_model->get_maxmin_system(); + auto* action = net_model->communicate(src_host, dst_host, size, -1, true); + + // We don't want to apply the network model bandwidth factor to the I/O constraints + double bw_factor = net_model->get_bandwidth_factor(); + if (src_disk != nullptr) { + // FIXME: if the stream starts from a disk, we might not want to pay the network latency + system->expand(src_disk->get_constraint(), action->get_variable(), bw_factor); + system->expand(src_disk->get_read_constraint(), action->get_variable(), bw_factor); + } + if (dst_disk != nullptr) { + system->expand(dst_disk->get_constraint(), action->get_variable(), bw_factor); + system->expand(dst_disk->get_write_constraint(), action->get_variable(), bw_factor); + } + + return action; +} + /************ * Resource * ************/ HostImpl::HostImpl(const std::string& name) : piface_(this), name_(name) { - xbt_enforce(s4u::Host::by_name_or_null(name_) == nullptr, "Refusing to create a second host named '%s'.", get_cname()); + xbt_enforce(s4u::Host::by_name_or_null(name_) == nullptr, "Refusing to create a second host named '%s'.", + get_cname()); } HostImpl::~HostImpl() @@ -40,7 +64,7 @@ HostImpl::~HostImpl() try { std::string actors; for (auto const& actor : actor_list_) - actors += "\n\t" + std::string(actor.get_name()); + actors += "\n\t" + actor.get_name(); EngineImpl::get_instance()->display_all_actor_status(); xbt_die("%s:%s", msg, actors.c_str()); @@ -52,9 +76,6 @@ HostImpl::~HostImpl() delete arg; actors_at_boot_.clear(); - for (auto const& [_, d] : disks_) - d->destroy(); - for (auto const& [_, vm] : vms_) vm->vm_destroy(); } @@ -66,6 +87,7 @@ HostImpl::~HostImpl() void HostImpl::destroy() { s4u::Host::on_destruction(*this->get_iface()); + this->get_iface()->on_this_destruction(*this->get_iface()); delete this; } @@ -126,6 +148,7 @@ std::vector HostImpl::get_all_actors() res.emplace_back(actor.get_ciface()); return res; } + size_t HostImpl::get_actor_count() const { return actor_list_.size(); @@ -159,11 +182,12 @@ s4u::VirtualMachine* HostImpl::create_vm(const std::string& name, s4u::VirtualMa auto* cpu = englobing_zone_->get_cpu_vm_model()->create_cpu(vm, speeds)->set_core_count(vm->get_vm_impl()->get_core_amount()); - if (get_iface()->get_pstate() != 0) - cpu->set_pstate(get_iface()->get_pstate()); - cpu->seal(); + if (get_iface()->get_pstate() != 0) { + cpu->set_pstate(get_iface()->get_pstate()); + } + /* Currently, a VM uses the network resource of its physical host */ vm->set_netpoint(get_iface()->get_netpoint()); @@ -204,14 +228,16 @@ std::vector HostImpl::get_vms() const s4u::Disk* HostImpl::create_disk(const std::string& name, double read_bandwidth, double write_bandwidth) { - auto disk = piface_.get_netpoint()->get_englobing_zone()->get_disk_model()->create_disk(name, read_bandwidth, - write_bandwidth); + auto* disk = piface_.get_netpoint()->get_englobing_zone()->get_disk_model()->create_disk(name, read_bandwidth, + write_bandwidth); + if (sealed_) + disk->seal(); return disk->set_host(&piface_)->get_iface(); } void HostImpl::add_disk(const s4u::Disk* disk) { - disks_[disk->get_name()] = disk->get_impl(); + disks_.insert({disk->get_name(), kernel::resource::DiskImplPtr(disk->get_impl())}); } void HostImpl::remove_disk(const std::string& name) diff --git a/src/surf/HostImpl.hpp b/src/kernel/resource/HostImpl.hpp similarity index 83% rename from src/surf/HostImpl.hpp rename to src/kernel/resource/HostImpl.hpp index 610068b153..506a3d6b5a 100644 --- a/src/surf/HostImpl.hpp +++ b/src/kernel/resource/HostImpl.hpp @@ -1,10 +1,10 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_HOST_INTERFACE_HPP -#define SURF_HOST_INTERFACE_HPP +#ifndef SIMGRID_KERNEL_HOST_INTERFACE_HPP +#define SIMGRID_KERNEL_HOST_INTERFACE_HPP #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/resource/CpuImpl.hpp" @@ -18,8 +18,8 @@ namespace simgrid::kernel::resource { * Model * *********/ -/** @ingroup SURF_host_interface - * @brief SURF Host model interface class +/** @ingroup Model_host_interface + * @brief Host model interface class * @details A model is an object which handle the interactions between its Resources and its Actions */ class XBT_PRIVATE HostModel : public Model { @@ -29,16 +29,18 @@ public: virtual Action* execute_parallel(const std::vector& host_list, const double* flops_amount, const double* bytes_amount, double rate) = 0; + Action* io_stream(s4u::Host* src_host, DiskImpl* src_disk, s4u::Host* dst_host, DiskImpl* dst_disk, + double size); }; /************ * Resource * ************/ -/** @ingroup SURF_host_interface - * @brief SURF Host interface class +/** @ingroup Model_host_interface + * @brief Host interface class * @details A host represents a machine with an aggregation of a Cpu, a RoutingEdge and Disk(s) */ -class XBT_PRIVATE HostImpl : public xbt::PropertyHolder { +class XBT_PRIVATE HostImpl : public xbt::PropertyHolder, public actor::ObjectAccessSimcallItem { using ActorList = boost::intrusive::list, @@ -47,11 +49,11 @@ class XBT_PRIVATE HostImpl : public xbt::PropertyHolder { ActorList actor_list_; std::vector actors_at_boot_; s4u::Host piface_; - std::map> disks_; + std::map> disks_; std::map> vms_; - xbt::string name_{"noname"}; + std::string name_{"noname"}; routing::NetZoneImpl* englobing_zone_ = nullptr; - bool sealed_ = false; + bool sealed_ = false; protected: virtual ~HostImpl(); // Use destroy() instead of this destructor. @@ -78,7 +80,7 @@ public: virtual s4u::Host* get_iface() { return &piface_; } /** Retrieves the name of that host as a C++ string */ - xbt::string const& get_name() const { return name_; } + std::string const& get_name() const { return name_; } /** Retrieves the name of that host as a C string */ const char* get_cname() const { return name_.c_str(); } diff --git a/src/kernel/resource/LinkImpl.hpp b/src/kernel/resource/LinkImpl.hpp index 5575fcae5e..8b6ac8af4e 100644 --- a/src/kernel/resource/LinkImpl.hpp +++ b/src/kernel/resource/LinkImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -38,8 +38,6 @@ public: /* setup the profile file with latency events (peak latency changes due to external load). * Profile must contain absolute values */ virtual void set_latency_profile(kernel::profile::Profile* profile) = 0; - /** @brief Set the concurrency limit for this link */ - virtual void set_concurrency_limit(int limit) const = 0; }; } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/Model.cpp b/src/kernel/resource/Model.cpp index 89cac54e7c..6006754e4d 100644 --- a/src/kernel/resource/Model.cpp +++ b/src/kernel/resource/Model.cpp @@ -1,10 +1,11 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "simgrid/kernel/resource/Model.hpp" #include "src/kernel/lmm/maxmin.hpp" +#include "xbt/ex.h" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ker_resource); diff --git a/src/kernel/resource/NetworkModel.cpp b/src/kernel/resource/NetworkModel.cpp index 01ded589b2..0d34f48797 100644 --- a/src/kernel/resource/NetworkModel.cpp +++ b/src/kernel/resource/NetworkModel.cpp @@ -1,20 +1,17 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include -#include "simgrid/sg_config.hpp" +#include "src/kernel/resource/FactorSet.hpp" #include "src/kernel/resource/NetworkModel.hpp" #include "src/kernel/resource/profile/Profile.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/sg_config.hpp" #include -#ifndef NETWORK_INTERFACE_CPP_ -#define NETWORK_INTERFACE_CPP_ - XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_network, ker_resource, "Network resources, that fuel communications"); /********* @@ -35,6 +32,10 @@ config::Flag NetworkModel::cfg_crosstraffic( "network/crosstraffic", "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)", "yes"); +config::Flag NetworkModel::cfg_weight_S_parameter( + "network/weight-S", + "Correction factor to apply to the weight of competing streams (default value set by network model)", 0.0); + NetworkModel::~NetworkModel() = default; double NetworkModel::next_occurring_event_full(double now) @@ -109,5 +110,3 @@ void insert_link_latency(std::vector& result, const std::vect } } // namespace simgrid::kernel::resource - -#endif /* NETWORK_INTERFACE_CPP_ */ diff --git a/src/kernel/resource/NetworkModel.hpp b/src/kernel/resource/NetworkModel.hpp index 833cc1e8ec..350877794c 100644 --- a/src/kernel/resource/NetworkModel.hpp +++ b/src/kernel/resource/NetworkModel.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,7 +7,7 @@ #define SIMGRID_KERNEL_RESOURCE_NETWORKMODEL_HPP #include "simgrid/kernel/resource/Model.hpp" -#include "simgrid/kernel/resource/NetworkModelIntf.hpp" +#include "src/kernel/resource/NetworkModelFactors.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" #include @@ -18,14 +18,15 @@ namespace simgrid::kernel::resource { * Model * *********/ -/** @ingroup SURF_network_interface - * @brief SURF network model interface class +/** @ingroup Model_network_interface + * @brief Network model interface class * @details A model is an object which handles the interactions between its Resources and its Actions */ -class NetworkModel : public Model, public NetworkModelIntf { +class NetworkModel : public Model, public NetworkModelFactors { public: static config::Flag cfg_tcp_gamma; static config::Flag cfg_crosstraffic; + static config::Flag cfg_weight_S_parameter; using Model::Model; NetworkModel(const NetworkModel&) = delete; @@ -52,43 +53,18 @@ public: * @param rate Allows to limit the transfer rate. Negative value means unlimited. * @return The action representing the communication */ - virtual Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) = 0; - - /** - * @brief Get the right multiplicative factor for the latency. - * @details Depending on the model, the effective latency when sending a message might be different from the - * theoretical latency of the link, in function of the message size. In order to account for this, this function gets - * this factor. - * - * @param size The size of the message. - * @return The latency factor. - */ - virtual double get_latency_factor(double /* size */) { return sg_latency_factor; } - - /** - * @brief Get the right multiplicative factor for the bandwidth. - * @details Depending on the model, the effective bandwidth when sending a message might be different from the - * theoretical bandwidth of the link, in function of the message size. In order to account for this, this function - * gets this factor. - * - * @param size The size of the message. - * @return The bandwidth factor. - */ - virtual double get_bandwidth_factor(double /* size*/) { return sg_bandwidth_factor; } + virtual Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool streamed) = 0; double next_occurring_event_full(double now) override; - void set_lat_factor_cb(const std::function& cb) override { THROW_UNIMPLEMENTED; } - void set_bw_factor_cb(const std::function& cb) override { THROW_UNIMPLEMENTED; } - std::unique_ptr loopback_; }; /********** * Action * **********/ -/** @ingroup SURF_network_interface - * @brief SURF network action interface class +/** @ingroup Model_network_interface + * @brief Network action interface class * @details A NetworkAction represents a communication between two [hosts](@ref HostImpl) */ class NetworkAction : public Action { @@ -99,8 +75,8 @@ public: /** @brief Constructor * * @param model The NetworkModel associated to this NetworkAction - * @param cost The cost of this NetworkAction in [TODO] - * @param failed [description] + * @param cost The cost of this NetworkAction in bytes + * @param failed Actions can be created in a failed state */ NetworkAction(Model* model, s4u::Host& src, s4u::Host& dst, double cost, bool failed) : Action(model, cost, failed), src_(src), dst_(dst) diff --git a/src/kernel/resource/NetworkModelFactors.cpp b/src/kernel/resource/NetworkModelFactors.cpp new file mode 100644 index 0000000000..3e9f8cf278 --- /dev/null +++ b/src/kernel/resource/NetworkModelFactors.cpp @@ -0,0 +1,94 @@ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/kernel/resource/NetworkModelFactors.hpp" +#include "src/simgrid/sg_config.hpp" + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_network); + +/********* + * Model * + *********/ + +namespace simgrid::kernel::resource { +config::Flag cfg_latency_factor_str( + "network/latency-factor", std::initializer_list{"smpi/lat-factor"}, + "Correction factor to apply to the provided latency (default value overridden by network model)", "1.0"); +static config::Flag cfg_bandwidth_factor_str( + "network/bandwidth-factor", std::initializer_list{"smpi/bw-factor"}, + "Correction factor to apply to the provided bandwidth (default value overridden by network model)", "1.0"); + +FactorSet NetworkModelFactors::cfg_latency_factor("network/latency-factor"); +FactorSet NetworkModelFactors::cfg_bandwidth_factor("network/bandwidth-factor"); + +double NetworkModelFactors::get_bandwidth_factor() const +{ + xbt_assert(not bw_factor_cb_, + "Cannot access the global bandwidth factor since a callback is used. Please go for the advanced API."); + + if (not cfg_bandwidth_factor.is_initialized()) + cfg_bandwidth_factor.parse(cfg_bandwidth_factor_str.get()); + + return cfg_bandwidth_factor(0); +} + +double NetworkModelFactors::get_latency_factor() const +{ + xbt_assert(not lat_factor_cb_, + "Cannot access the global latency factor since a callback is used. Please go for the advanced API."); + + if (not cfg_latency_factor.is_initialized()) // lazy initiaization to avoid initialization fiasco + cfg_latency_factor.parse(cfg_latency_factor_str.get()); + + return cfg_latency_factor(0); +} + +double NetworkModelFactors::get_latency_factor(double size, const s4u::Host* src, const s4u::Host* dst, + const std::vector& links, + const std::unordered_set& netzones) const +{ + if (lat_factor_cb_) + return lat_factor_cb_(size, src, dst, links, netzones); + + if (not cfg_latency_factor.is_initialized()) // lazy initiaization to avoid initialization fiasco + cfg_latency_factor.parse(cfg_latency_factor_str.get()); + + return cfg_latency_factor(size); +} + +double NetworkModelFactors::get_bandwidth_factor(double size, const s4u::Host* src, const s4u::Host* dst, + const std::vector& links, + const std::unordered_set& netzones) const +{ + if (bw_factor_cb_) + return bw_factor_cb_(size, src, dst, links, netzones); + + if (not cfg_bandwidth_factor.is_initialized()) + cfg_bandwidth_factor.parse(cfg_bandwidth_factor_str.get()); + + return cfg_bandwidth_factor(size); +} + +void NetworkModelFactors::set_lat_factor_cb(const std::function& cb) +{ + if (not cb) + throw std::invalid_argument("NetworkModelFactors: Invalid callback"); + if (not simgrid::config::is_default("network/latency-factor")) + throw std::invalid_argument("You must choose between network/latency-factor and callback configuration."); + + lat_factor_cb_ = cb; +} + +void NetworkModelFactors::set_bw_factor_cb(const std::function& cb) +{ + if (not cb) + throw std::invalid_argument("NetworkModelFactors: Invalid callback"); + if (not simgrid::config::is_default("network/bandwidth-factor")) + throw std::invalid_argument("You must choose between network/bandwidth-factor and callback configuration."); + + bw_factor_cb_ = cb; +} + +} // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/NetworkModelFactors.hpp b/src/kernel/resource/NetworkModelFactors.hpp new file mode 100644 index 0000000000..b01ae2894d --- /dev/null +++ b/src/kernel/resource/NetworkModelFactors.hpp @@ -0,0 +1,86 @@ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_KERNEL_RESOURCE_NETWORKMODELFACTORS_HPP +#define SIMGRID_KERNEL_RESOURCE_NETWORKMODELFACTORS_HPP + +#include "src/kernel/resource/FactorSet.hpp" +#include "src/simgrid/sg_config.hpp" +#include "xbt/asserts.h" +#include + +#include +#include + +namespace simgrid::kernel::resource { + +/** This Trait of NetworkModel is in charge of handling the network factors (bw and lat) */ + +class XBT_PUBLIC NetworkModelFactors { + static FactorSet cfg_latency_factor; + static FactorSet cfg_bandwidth_factor; + + using NetworkFactorCb = double(double size, const s4u::Host* src, const s4u::Host* dst, + const std::vector& links, + const std::unordered_set& netzones); + + std::function lat_factor_cb_; + std::function bw_factor_cb_; + +public: + /** + * @brief Get the right multiplicative factor for the latency. + * @details Depending on the model, the effective latency when sending a message might be different from the + * theoretical latency of the link, in function of the message size. In order to account for this, this function gets + * this factor. + */ + double get_latency_factor(double size, const s4u::Host* src, const s4u::Host* dst, + const std::vector& links, + const std::unordered_set& netzones) const; + + /** Get the right multiplicative factor for the bandwidth (only if no callback was defined) */ + double get_latency_factor() const; + + /** + * @brief Get the right multiplicative factor for the bandwidth. + * + * @details Depending on the model, the effective bandwidth when sending a message might be different from the + * theoretical bandwidth of the link, in function of the message size. In order to account for this, this function + * gets this factor. + */ + double get_bandwidth_factor(double size, const s4u::Host* src, const s4u::Host* dst, + const std::vector& links, + const std::unordered_set& netzones) const; + + /** Get the right multiplicative factor for the bandwidth (only if no callback was defined) */ + double get_bandwidth_factor() const; + + /** + * @brief Callback to set the bandwidth and latency factors used in a communication + * + * This callback offers more flexibility when setting the network factors. + * It is an alternative to SimGrid's configs, such as network/latency-factors + * and network/bandwidth-factors. + * + * @param size Communication size in bytes + * @param src Source host + * @param dst Destination host + * @param links Vectors with the links used in this comm + * @param netzones Set with NetZones involved in the comm + * @return Multiply factor + */ + /** @brief Configure the latency factor callback */ + void set_lat_factor_cb(const std::function& cb); + + /** @brief Configure the bandwidth factor callback */ + void set_bw_factor_cb(const std::function& cb); + + /** Returns whether a callback was set for latency-factor OR bandwidth-factor */ + bool has_network_factor_cb() const { return lat_factor_cb_ || bw_factor_cb_; } +}; + +} // namespace simgrid::kernel::resource + +#endif /* SIMGRID_KERNEL_RESOURCE_NETWORKMODELFACTORS_HPP */ diff --git a/src/kernel/resource/NetworkModelFactors_test.cpp b/src/kernel/resource/NetworkModelFactors_test.cpp new file mode 100644 index 0000000000..0d5064ba44 --- /dev/null +++ b/src/kernel/resource/NetworkModelFactors_test.cpp @@ -0,0 +1,67 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" + +#include "simgrid/s4u/Engine.hpp" +#include "src/internal_config.h" // HAVE_SMPI +#include "src/kernel/resource/NetworkModelFactors.hpp" +#include "src/simgrid/sg_config.hpp" + +static double factor_cb(double, const simgrid::s4u::Host*, const simgrid::s4u::Host*, + const std::vector&, const std::unordered_set&) +{ + return 1.0; +} + +TEST_CASE("kernel::resource::NetworkModelFactors: Factors invalid callbacks: exception", "") +{ + std::vector models{"LV08", "CM02"}; +#if HAVE_SMPI + models.emplace_back("SMPI"); + models.emplace_back("IB"); +#endif + + for (const auto& model : models) { + _sg_cfg_init_status = 0; /* HACK: clear config global to be able to do set_config in UTs */ + simgrid::s4u::Engine e("test"); + simgrid::s4u::Engine::set_config("network/model:" + model); + simgrid::s4u::create_full_zone("root"); + + SECTION("Model: " + model) + { + const auto* zone = e.get_netzone_root(); + REQUIRE_THROWS_AS(zone->set_latency_factor_cb({}), std::invalid_argument); + REQUIRE_THROWS_AS(zone->set_latency_factor_cb(nullptr), std::invalid_argument); + REQUIRE_THROWS_AS(zone->set_bandwidth_factor_cb({}), std::invalid_argument); + REQUIRE_THROWS_AS(zone->set_bandwidth_factor_cb(nullptr), std::invalid_argument); + } + } +} + +TEST_CASE("kernel::resource::NetworkModelFactors: Invalid network/latency-factor and network/bandwidth-factor", "") +{ + std::vector models{"LV08", "CM02"}; +#if HAVE_SMPI + models.emplace_back("SMPI"); + models.emplace_back("IB"); +#endif + + for (const auto& model : models) { + _sg_cfg_init_status = 0; /* HACK: clear config global to be able to do set_config in UTs */ + simgrid::s4u::Engine e("test"); + simgrid::s4u::Engine::set_config("network/model:" + model); + simgrid::s4u::Engine::set_config("network/latency-factor:10"); + simgrid::s4u::Engine::set_config("network/bandwidth-factor:0.3"); + simgrid::s4u::create_full_zone("root"); + + SECTION("Model: " + model) + { + const auto* zone = e.get_netzone_root(); + REQUIRE_THROWS_AS(zone->set_latency_factor_cb(factor_cb), std::invalid_argument); + REQUIRE_THROWS_AS(zone->set_bandwidth_factor_cb(factor_cb), std::invalid_argument); + } + } +} diff --git a/src/kernel/resource/NetworkModelIntf_test.cpp b/src/kernel/resource/NetworkModelIntf_test.cpp deleted file mode 100644 index 5af8c05036..0000000000 --- a/src/kernel/resource/NetworkModelIntf_test.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "catch.hpp" - -#include "simgrid/kernel/resource/NetworkModelIntf.hpp" -#include "simgrid/s4u/Engine.hpp" -#include "simgrid/sg_config.hpp" -#include "src/internal_config.h" // HAVE_SMPI - -static double factor_cb(double, const simgrid::s4u::Host*, const simgrid::s4u::Host*, - const std::vector&, const std::unordered_set&) -{ - return 1.0; -} - -TEST_CASE("kernel::resource::NetworkModelIntf: Factors invalid callbacks: exception", "") -{ - std::vector models{"LV08", "CM02"}; -#if HAVE_SMPI - models.emplace_back("SMPI"); - models.emplace_back("IB"); -#endif - - for (const auto& model : models) { - _sg_cfg_init_status = 0; /* HACK: clear config global to be able to do set_config in UTs */ - simgrid::s4u::Engine e("test"); - simgrid::s4u::Engine::set_config("network/model:" + model); - simgrid::s4u::create_full_zone("root"); - - SECTION("Model: " + model) - { - simgrid::kernel::resource::NetworkModelIntf* m = e.get_netzone_root()->get_network_model(); - REQUIRE_THROWS_AS(m->set_lat_factor_cb({}), std::invalid_argument); - REQUIRE_THROWS_AS(m->set_lat_factor_cb(nullptr), std::invalid_argument); - REQUIRE_THROWS_AS(m->set_bw_factor_cb({}), std::invalid_argument); - REQUIRE_THROWS_AS(m->set_bw_factor_cb(nullptr), std::invalid_argument); - } - } -} - -TEST_CASE("kernel::resource::NetworkModelIntf: Invalid network/latency-factor and network/bandwidth-factor", "") -{ - for (const auto& model : std::vector{"LV08", "CM02"}) { - _sg_cfg_init_status = 0; /* HACK: clear config global to be able to do set_config in UTs */ - simgrid::s4u::Engine e("test"); - simgrid::s4u::Engine::set_config("network/model:" + model); - simgrid::s4u::Engine::set_config("network/latency-factor:10"); - simgrid::s4u::Engine::set_config("network/bandwidth-factor:0.3"); - simgrid::s4u::create_full_zone("root"); - - SECTION("Model: " + model) - { - simgrid::kernel::resource::NetworkModelIntf* m = e.get_netzone_root()->get_network_model(); - REQUIRE_THROWS_AS(m->set_lat_factor_cb(factor_cb), std::invalid_argument); - REQUIRE_THROWS_AS(m->set_bw_factor_cb(factor_cb), std::invalid_argument); - } - } -} - -#if HAVE_SMPI -TEST_CASE("kernel::resource::NetworkModelIntf: Invalid smpi/lat-factor and smpi/bw-factor", "") -{ - for (const auto& model : std::vector{"SMPI", "IB"}) { - _sg_cfg_init_status = 0; /* HACK: clear config global to be able to do set_config in UTs */ - simgrid::s4u::Engine e("test"); - simgrid::s4u::Engine::set_config("network/model:" + model); - simgrid::s4u::Engine::set_config( - "smpi/lat-factor:65472:0.940694;15424:0.697866;9376:0.58729;5776:1.08739;3484:0.77493"); - simgrid::s4u::Engine::set_config("smpi/bw-factor:65472:11.6436;15424:3.48845"); - simgrid::s4u::create_full_zone("root"); - - SECTION("Model: " + model) - { - simgrid::kernel::resource::NetworkModelIntf* m = e.get_netzone_root()->get_network_model(); - REQUIRE_THROWS_AS(m->set_lat_factor_cb(factor_cb), std::invalid_argument); - REQUIRE_THROWS_AS(m->set_bw_factor_cb(factor_cb), std::invalid_argument); - } - } -} -#endif diff --git a/src/kernel/resource/Resource.hpp b/src/kernel/resource/Resource.hpp index ea32b925e2..1ed1e3541c 100644 --- a/src/kernel/resource/Resource.hpp +++ b/src/kernel/resource/Resource.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,6 +7,8 @@ #define SIMGRID_KERNEL_RESOURCE_RESOURCE_HPP #include "simgrid/forward.h" +#include "src/kernel/EngineImpl.hpp" +#include "src/kernel/actor/Simcall.hpp" #include "src/kernel/lmm/maxmin.hpp" // Constraint #include "src/kernel/resource/profile/Event.hpp" #include "src/kernel/resource/profile/FutureEvtSet.hpp" @@ -19,11 +21,11 @@ namespace simgrid::kernel::resource { -/** @ingroup SURF_interface - * @brief SURF resource interface class +/** @ingroup Model_interface + * @brief Resource interface class * @details This is the ancestor class of every resources in SimGrid, such as links, CPU or disk */ -class XBT_PUBLIC Resource { +class XBT_PUBLIC Resource : public actor::ObjectAccessSimcallItem { std::string name_ = "unnamed"; bool is_on_ = true; bool sealed_ = false; @@ -71,6 +73,21 @@ template class Resource_T : public Resource { Model* model_ = nullptr; lmm::Constraint* constraint_ = nullptr; +protected: + void cancel_actions() + { + const kernel::lmm::Element* elem = nullptr; + double now = EngineImpl::get_clock(); + while (const auto* var = get_constraint()->get_variable(&elem)) { + Action* action = var->get_id(); + if (action->get_state() == Action::State::INITED || action->get_state() == Action::State::STARTED || + action->get_state() == Action::State::IGNORED) { + action->set_finish_time(now); + action->set_state(Action::State::FAILED); + } + } + } + public: using Resource::Resource; /** @brief setup the profile file with states events (ON or OFF). The profile must contain boolean values. */ @@ -100,10 +117,21 @@ public: lmm::Constraint* get_constraint() const { return constraint_; } + /** @brief Set the concurrency limit for this resource */ + virtual void set_concurrency_limit(int limit) const + { + if (limit != -1) + get_constraint()->reset_concurrency_maximum(); + get_constraint()->set_concurrency_limit(limit); + } + + /** @brief Get the concurrency limit of this resource */ + virtual int get_concurrency_limit() const { return get_constraint()->get_concurrency_limit(); } + /** @brief returns the current load due to activities (in flops per second, byte per second or similar) * * The load due to external usages modeled by profile files is ignored.*/ - virtual double get_load() const { return constraint_->get_usage(); } + virtual double get_load() const { return constraint_->get_load(); } bool is_used() const override { return model_->get_maxmin_system()->constraint_used(constraint_); } }; diff --git a/src/kernel/resource/SplitDuplexLinkImpl.cpp b/src/kernel/resource/SplitDuplexLinkImpl.cpp index cd4ec9fe97..d5b08c9a06 100644 --- a/src/kernel/resource/SplitDuplexLinkImpl.cpp +++ b/src/kernel/resource/SplitDuplexLinkImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -85,6 +85,11 @@ void SplitDuplexLinkImpl::set_latency_profile(profile::Profile* profile) link_down_->set_latency_profile(profile); } +int SplitDuplexLinkImpl::get_concurrency_limit() const +{ + return link_up_->get_concurrency_limit(); +} + void SplitDuplexLinkImpl::set_concurrency_limit(int limit) const { link_up_->set_concurrency_limit(limit); diff --git a/src/kernel/resource/SplitDuplexLinkImpl.hpp b/src/kernel/resource/SplitDuplexLinkImpl.hpp index f1bdbe9dc3..dc574f7645 100644 --- a/src/kernel/resource/SplitDuplexLinkImpl.hpp +++ b/src/kernel/resource/SplitDuplexLinkImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,8 +14,8 @@ namespace simgrid::kernel::resource { /************ * Resource * ************/ -/** @ingroup SURF_network_interface - * @brief SURF network link interface class +/** @ingroup Model_network_interface + * @brief Network link interface class * @details A Link represents the link between two [hosts](@ref HostImpl) */ class SplitDuplexLinkImpl : public LinkImpl { @@ -66,6 +66,7 @@ public: * Profile must contain absolute values */ void set_latency_profile(kernel::profile::Profile* profile) override; void set_concurrency_limit(int limit) const override; + int get_concurrency_limit() const override; }; } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/SplitDuplexLinkImpl_test.cpp b/src/kernel/resource/SplitDuplexLinkImpl_test.cpp index 5e7bb76303..3e3797d131 100644 --- a/src/kernel/resource/SplitDuplexLinkImpl_test.cpp +++ b/src/kernel/resource/SplitDuplexLinkImpl_test.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch.hpp" +#include "src/3rd-party/catch.hpp" #include #include diff --git a/src/kernel/resource/StandardLinkImpl.cpp b/src/kernel/resource/StandardLinkImpl.cpp index 6648c23d45..9df40d0924 100644 --- a/src/kernel/resource/StandardLinkImpl.cpp +++ b/src/kernel/resource/StandardLinkImpl.cpp @@ -1,11 +1,10 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include -#include "src/kernel/EngineImpl.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" #include @@ -37,12 +36,15 @@ void StandardLinkImpl::Deleter::operator()(resource::StandardLinkImpl* link) con void StandardLinkImpl::destroy() { s4u::Link::on_destruction(piface_); + piface_.on_this_destruction(piface_); delete this; } constexpr kernel::lmm::Constraint::SharingPolicy to_maxmin_policy(s4u::Link::SharingPolicy policy) { switch (policy) { + case s4u::Link::SharingPolicy::WIFI: + return kernel::lmm::Constraint::SharingPolicy::WIFI; case s4u::Link::SharingPolicy::NONLINEAR: return kernel::lmm::Constraint::SharingPolicy::NONLINEAR; case s4u::Link::SharingPolicy::FATPIPE: @@ -60,11 +62,11 @@ void StandardLinkImpl::set_sharing_policy(s4u::Link::SharingPolicy policy, const void StandardLinkImpl::latency_check(double latency) const { - static double last_warned_latency = sg_surf_precision; + static double last_warned_latency = sg_precision_timing; if (latency != 0.0 && latency < last_warned_latency) { - XBT_WARN("Latency for link %s is smaller than surf/precision (%g < %g)." - " For more accuracy, consider setting \"--cfg=surf/precision:%g\".", - get_cname(), latency, sg_surf_precision, latency); + XBT_WARN("Latency for link %s is smaller than precision/timing (%g < %g)." + " For more accuracy, consider setting \"--cfg=precision/timing:%g\".", + get_cname(), latency, sg_precision_timing, latency); last_warned_latency = latency; } } @@ -79,7 +81,8 @@ void StandardLinkImpl::turn_on() { if (not is_on()) { Resource::turn_on(); - s4u::Link::on_state_change(piface_); + s4u::Link::on_onoff(piface_); + piface_.on_this_onoff(piface_); } } @@ -87,17 +90,9 @@ void StandardLinkImpl::turn_off() { if (is_on()) { Resource::turn_off(); - s4u::Link::on_state_change(piface_); - - const kernel::lmm::Element* elem = nullptr; - double now = EngineImpl::get_clock(); - while (const auto* var = get_constraint()->get_variable(&elem)) { - Action* action = var->get_id(); - if (action->get_state() == Action::State::INITED || action->get_state() == Action::State::STARTED) { - action->set_finish_time(now); - action->set_state(Action::State::FAILED); - } - } + s4u::Link::on_onoff(piface_); + piface_.on_this_onoff(piface_); + cancel_actions(); } } @@ -113,6 +108,7 @@ void StandardLinkImpl::seal() void StandardLinkImpl::on_bandwidth_change() const { s4u::Link::on_bandwidth_change(piface_); + piface_.on_this_bandwidth_change(piface_); } void StandardLinkImpl::set_bandwidth_profile(profile::Profile* profile) @@ -131,12 +127,4 @@ void StandardLinkImpl::set_latency_profile(profile::Profile* profile) } } -void StandardLinkImpl::set_concurrency_limit(int limit) const -{ - if (limit != -1) { - get_constraint()->reset_concurrency_maximum(); - } - get_constraint()->set_concurrency_limit(limit); -} - } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/StandardLinkImpl.hpp b/src/kernel/resource/StandardLinkImpl.hpp index d79e687526..d573fe127f 100644 --- a/src/kernel/resource/StandardLinkImpl.hpp +++ b/src/kernel/resource/StandardLinkImpl.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -70,8 +70,6 @@ public: /* setup the profile file with latency events (peak latency changes due to external load). * Profile must contain absolute values */ void set_latency_profile(kernel::profile::Profile* profile) override; - - void set_concurrency_limit(int limit) const override; }; } // namespace simgrid::kernel::resource diff --git a/src/kernel/resource/VirtualMachineImpl.cpp b/src/kernel/resource/VirtualMachineImpl.cpp index 854aafcbf7..e8d813ffd8 100644 --- a/src/kernel/resource/VirtualMachineImpl.cpp +++ b/src/kernel/resource/VirtualMachineImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,19 +8,21 @@ #include #include -#include "simgrid/sg_config.hpp" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/activity/ExecImpl.hpp" #include "src/kernel/resource/VirtualMachineImpl.hpp" -#include "src/surf/cpu_cas01.hpp" -#include "src/surf/cpu_ti.hpp" +#include "src/kernel/resource/models/cpu_cas01.hpp" +#include "src/kernel/resource/models/cpu_ti.hpp" +#include "src/simgrid/module.hpp" +#include "src/simgrid/sg_config.hpp" #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_vm, ker_resource, "Virtual Machines, containing actors and mobile across hosts"); -void surf_vm_model_init_HL13(simgrid::kernel::resource::CpuModel* cpu_pm_model) +void simgrid_vm_model_init_HL13() { + auto* cpu_pm_model = simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->get_cpu_pm_model().get(); auto vm_model = std::make_shared("VM_HL13"); auto* engine = simgrid::kernel::EngineImpl::get_instance(); @@ -53,15 +55,15 @@ std::deque VirtualMachineImpl::allVms_; */ const double virt_overhead = 1; // 0.95 -static void host_state_change(s4u::Host const& host) +static void host_onoff(s4u::Host const& host) { if (not host.is_on()) { // just turned off. std::vector trash; /* Find all VMs living on that host */ - for (s4u::VirtualMachine* const& vm : VirtualMachineImpl::allVms_) + for (auto* vm : VirtualMachineImpl::allVms_) if (vm->get_pm() == &host) trash.push_back(vm); - for (s4u::VirtualMachine* vm : trash) + for (auto* vm : trash) vm->shutdown(); } } @@ -71,29 +73,28 @@ static void add_active_exec(s4u::Exec const& task) const s4u::VirtualMachine* vm = dynamic_cast(task.get_host()); if (vm != nullptr) { VirtualMachineImpl* vm_impl = vm->get_vm_impl(); - vm_impl->add_active_exec(); + for (int i = 1; i <= task.get_thread_count(); i++) + vm_impl->add_active_exec(); vm_impl->update_action_weight(); } } -static void remove_active_exec(s4u::Activity const& task) +static void remove_active_exec(s4u::Exec const& exec) { - const auto* exec = dynamic_cast(&task); - if (exec == nullptr) - return; - if (not exec->is_assigned()) + if (not exec.is_assigned()) return; - const s4u::VirtualMachine* vm = dynamic_cast(exec->get_host()); + const s4u::VirtualMachine* vm = dynamic_cast(exec.get_host()); if (vm != nullptr) { VirtualMachineImpl* vm_impl = vm->get_vm_impl(); - vm_impl->remove_active_exec(); + for (int i = 1; i <= exec.get_thread_count(); i++) + vm_impl->remove_active_exec(); vm_impl->update_action_weight(); } } static s4u::VirtualMachine* get_vm_from_activity(s4u::Activity const& act) { - auto* exec = dynamic_cast(act.get_impl()); + const auto* exec = dynamic_cast(act.get_impl()); return exec != nullptr ? dynamic_cast(exec->get_host()) : nullptr; } @@ -119,11 +120,11 @@ static void remove_active_activity(s4u::Activity const& act) VMModel::VMModel(const std::string& name) : HostModel(name) { - s4u::Host::on_state_change_cb(host_state_change); + s4u::Host::on_onoff_cb(host_onoff); s4u::Exec::on_start_cb(add_active_exec); - s4u::Activity::on_completion_cb(remove_active_exec); - s4u::Activity::on_resumed_cb(add_active_activity); - s4u::Activity::on_suspended_cb(remove_active_activity); + s4u::Exec::on_completion_cb(remove_active_exec); + s4u::Exec::on_resume_cb(add_active_activity); + s4u::Exec::on_suspend_cb(remove_active_activity); } double VMModel::next_occurring_event(double now) @@ -153,7 +154,7 @@ double VMModel::next_occurring_event(double now) **/ /* iterate for all virtual machines */ - for (s4u::VirtualMachine* const& ws_vm : VirtualMachineImpl::allVms_) { + for (auto const* ws_vm : VirtualMachineImpl::allVms_) { if (ws_vm->get_state() == s4u::VirtualMachine::State::SUSPENDED) // Ignore suspended VMs continue; @@ -172,7 +173,7 @@ double VMModel::next_occurring_event(double now) Action* VMModel::execute_thread(const s4u::Host* host, double flops_amount, int thread_count) { - auto cpu = host->get_cpu(); + auto* cpu = host->get_cpu(); return cpu->execution_start(thread_count * flops_amount, thread_count, -1); } @@ -235,6 +236,7 @@ void VirtualMachineImpl::vm_destroy() void VirtualMachineImpl::start() { s4u::VirtualMachine::on_start(*get_iface()); + get_iface()->on_this_start(*get_iface()); s4u::VmHostExt::ensureVmExtInstalled(); if (physical_host_->extension() == nullptr) @@ -245,7 +247,7 @@ void VirtualMachineImpl::start() not physical_host_->extension()->overcommit) { /* Need to verify that we don't overcommit */ /* Retrieve the memory occupied by the VMs on that host. Yep, we have to traverse all VMs of all hosts for that */ size_t total_ramsize_of_vms = 0; - for (auto* const& ws_vm : allVms_) + for (auto const* ws_vm : allVms_) if (physical_host_ == ws_vm->get_pm()) total_ramsize_of_vms += ws_vm->get_ramsize(); @@ -260,11 +262,13 @@ void VirtualMachineImpl::start() vm_state_ = s4u::VirtualMachine::State::RUNNING; s4u::VirtualMachine::on_started(*get_iface()); + get_iface()->on_this_started(*get_iface()); } void VirtualMachineImpl::suspend(const actor::ActorImpl* issuer) { s4u::VirtualMachine::on_suspend(*get_iface()); + get_iface()->on_this_suspend(*get_iface()); if (vm_state_ != s4u::VirtualMachine::State::RUNNING) throw VmFailureException(XBT_THROW_POINT, @@ -304,6 +308,7 @@ void VirtualMachineImpl::resume() vm_state_ = s4u::VirtualMachine::State::RUNNING; s4u::VirtualMachine::on_resume(*get_iface()); + get_iface()->on_this_resume(*get_iface()); } /** @brief Power off a VM. @@ -330,7 +335,7 @@ void VirtualMachineImpl::shutdown(actor::ActorImpl* issuer) set_state(s4u::VirtualMachine::State::DESTROYED); s4u::VirtualMachine::on_shutdown(*get_iface()); - /* FIXME: we may have to do something at the surf layer, e.g., vcpu action */ + get_iface()->on_this_shutdown(*get_iface()); } /** @brief Change the physical host on which the given VM is running @@ -399,12 +404,14 @@ void VirtualMachineImpl::start_migration() { is_migrating_ = true; s4u::VirtualMachine::on_migration_start(*get_iface()); + get_iface()->on_this_migration_start(*get_iface()); } void VirtualMachineImpl::end_migration() { is_migrating_ = false; s4u::VirtualMachine::on_migration_end(*get_iface()); + get_iface()->on_this_migration_end(*get_iface()); } void VirtualMachineImpl::seal() diff --git a/src/kernel/resource/VirtualMachineImpl.hpp b/src/kernel/resource/VirtualMachineImpl.hpp index 81cd3d6942..781a33be18 100644 --- a/src/kernel/resource/VirtualMachineImpl.hpp +++ b/src/kernel/resource/VirtualMachineImpl.hpp @@ -1,11 +1,11 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include -#include "src/surf/HostImpl.hpp" +#include "src/kernel/resource/HostImpl.hpp" #ifndef VM_INTERFACE_HPP_ #define VM_INTERFACE_HPP_ @@ -83,8 +83,8 @@ private: /********* * Model * *********/ -/** @ingroup SURF_vm_interface - * @brief SURF VM model interface class +/** @ingroup Model_vm_interface + * @brief VM model interface class * @details A model is an object which handle the interactions between its Resources and its Actions */ class XBT_PRIVATE VMModel : public HostModel { diff --git a/src/kernel/resource/WifiLinkImpl.cpp b/src/kernel/resource/WifiLinkImpl.cpp index 556a7ff7a9..a40a12a6e6 100644 --- a/src/kernel/resource/WifiLinkImpl.cpp +++ b/src/kernel/resource/WifiLinkImpl.cpp @@ -1,12 +1,13 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include #include +#include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/resource/WifiLinkImpl.hpp" -#include "src/surf/surf_interface.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_network); @@ -15,6 +16,21 @@ namespace simgrid::kernel::resource { /************ * Resource * ************/ +static void update_bw_comm_start(const s4u::Comm& comm) +{ + const auto* pimpl = static_cast(comm.get_impl()); + + auto const* actionWifi = dynamic_cast(pimpl->model_action_); + if (actionWifi == nullptr) + return; + + if (auto* link_src = actionWifi->get_src_link()) { + link_src->inc_active_flux(); + } + if (auto* link_dst = actionWifi->get_dst_link()) { + link_dst->inc_active_flux(); + } +} WifiLinkImpl::WifiLinkImpl(const std::string& name, const std::vector& bandwidths, lmm::System* system) : StandardLinkImpl(name) @@ -22,14 +38,13 @@ WifiLinkImpl::WifiLinkImpl(const std::string& name, const std::vector& b this->set_constraint(system->constraint_new(this, 1)); for (auto bandwidth : bandwidths) bandwidths_.push_back({bandwidth, 1.0, nullptr}); + s4u::Comm::on_start_cb(&update_bw_comm_start); + s4u::Link::on_communication_state_change_cb(&update_bw_comm_end); } void WifiLinkImpl::set_host_rate(const s4u::Host* host, int rate_level) { host_rates_[host->get_name()] = rate_level; - - // Each time we add a host, we refresh the decay model - refresh_decay_bandwidths(); } double WifiLinkImpl::get_host_rate(const s4u::Host* host) const @@ -47,7 +62,7 @@ double WifiLinkImpl::get_host_rate(const s4u::Host* host) const "Link '%s' only has %zu wifi rate levels, so the provided level %d is invalid for host '%s'.", this->get_cname(), bandwidths_.size(), rate_id, host->get_cname()); - Metric rate = use_decay_model_ ? decay_bandwidths_[rate_id] : bandwidths_[rate_id]; + Metric rate = bandwidths_[rate_id]; return rate.peak * rate.scale; } @@ -61,31 +76,69 @@ size_t WifiLinkImpl::get_host_count() const return host_rates_.size(); } -void WifiLinkImpl::refresh_decay_bandwidths() +double WifiLinkImpl::wifi_link_dynamic_sharing(const WifiLinkImpl& link, double /*capacity*/, int /*n*/) +{ + double ratio = link.get_max_ratio(); + XBT_DEBUG("New ratio value concurrency %d: %lf of link capacity on link %s", link.nb_active_flux_, ratio, link.get_name().c_str()); + return ratio; +} + +void WifiLinkImpl::inc_active_flux() +{ + xbt_assert(nb_active_flux_ >= 0, "Negative nb_active_flux should not exist"); + nb_active_flux_++; +} + +void WifiLinkImpl::dec_active_flux() { - // Compute number of STAtion on the Access Point - const auto nSTA_minus_1 = static_cast(get_host_count() - 1); - - std::vector new_bandwidths; - for (auto const& bandwidth : bandwidths_) { - // Instantiate decay model relatively to the actual bandwidth - double max_bw = bandwidth.peak; - double min_bw = bandwidth.peak - (wifi_max_rate_ - wifi_min_rate_); - double model_rate = bandwidth.peak - (wifi_max_rate_ - model_rate_); - - double N0 = max_bw - min_bw; - double lambda = (-log(model_rate - min_bw) + log(N0)) / model_n_; - // Since decay model start at 0 we should use (nSTA-1) - double new_peak = N0 * exp(-lambda * nSTA_minus_1) + min_bw; - new_bandwidths.push_back({new_peak, 1.0, nullptr}); + xbt_assert(nb_active_flux_ > 0, "Negative nb_active_flux should not exist"); + nb_active_flux_--; +} + +void WifiLinkImpl::update_bw_comm_end(const simgrid::kernel::resource::NetworkAction& action, + simgrid::kernel::resource::Action::State /*state*/) +{ + if (action.get_state() != kernel::resource::Action::State::FINISHED) + return; + + auto const* actionWifi = dynamic_cast(&action); + if (actionWifi == nullptr) + return; + + if (auto* link_src = actionWifi->get_src_link()) { + link_src->dec_active_flux(); + } + if (auto* link_dst = actionWifi->get_dst_link()) { + link_dst->dec_active_flux(); } - decay_bandwidths_ = new_bandwidths; } -bool WifiLinkImpl::toggle_decay_model() +double WifiLinkImpl::get_max_ratio() const { - use_decay_model_ = not use_decay_model_; - return use_decay_model_; + double new_peak; + if (nb_active_flux_ > conc_lim_) { + new_peak = (nb_active_flux_-conc_lim_) * co_acc_ + x0_; + XBT_DEBUG("Wi-Fi link peak=(%d-%d)*%lf+%lf=%lf", nb_active_flux_, conc_lim_, co_acc_, x0_, new_peak); + } else { + new_peak = x0_; + XBT_DEBUG("Wi-Fi link peak=%lf", x0_); + } + // should be the new maximum bandwidth ratio (comparison between max throughput without concurrency and with it) + double propCap = new_peak / x0_; + + return propCap; +} + +bool WifiLinkImpl::toggle_callback() +{ + if (not use_callback_) { + XBT_DEBUG("Activate throughput reduction mechanism"); + use_callback_ = true; + this->set_sharing_policy( + simgrid::s4u::Link::SharingPolicy::WIFI, + std::bind(&wifi_link_dynamic_sharing, std::cref(*this), std::placeholders::_1, std::placeholders::_2)); + } + return use_callback_; } void WifiLinkImpl::set_latency(double value) diff --git a/src/kernel/resource/WifiLinkImpl.hpp b/src/kernel/resource/WifiLinkImpl.hpp index ea1e30a8bd..969eeeb260 100644 --- a/src/kernel/resource/WifiLinkImpl.hpp +++ b/src/kernel/resource/WifiLinkImpl.hpp @@ -1,15 +1,13 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_NETWORK_WIFI_HPP_ -#define SURF_NETWORK_WIFI_HPP_ +#ifndef SIMGRID_KERNEL_NETWORK_WIFI_HPP_ +#define SIMGRID_KERNEL_NETWORK_WIFI_HPP_ -#include - -#include "src/surf/network_cm02.hpp" -#include "xbt/string.hpp" +#include "src/kernel/resource/models/network_cm02.hpp" +#include "xbt/ex.h" /*********** * Classes * @@ -21,22 +19,25 @@ class XBT_PRIVATE WifiLinkAction; class WifiLinkImpl : public StandardLinkImpl { /** @brief Hold every rates association between host and links (host name, rates id) */ - std::map host_rates_; + std::map> host_rates_; /** @brief A link can have several bandwidths attached to it (mostly use by wifi model) */ std::vector bandwidths_; - /** @brief Should we use the decay model ? */ - bool use_decay_model_ = false; - /** @brief Wifi maximal bit rate according to the ns-3 802.11n standard */ - const double wifi_max_rate_ = 54 * 1e6 / 8; - /** @brief minimum bit rate observed with ns3 during our calibration experiments */ - const double wifi_min_rate_ = 41.70837 * 1e6 / 8; - /** @brief Amount of stations used in the reference point to rescale SimGrid predictions to fit ns-3 ones */ - const int model_n_ = 5; - /** @brief Bit rate observed on ns3 at the reference point used for rescaling */ - const double model_rate_ = 42.61438 * 1e6 / 8; - /** @brief The bandwidth to use for each SNR level, corrected with the decay rescale mechanism */ + bool use_callback_ = false; + /* + * Values used for the throughput degradation: + * ratio = x0_ + co_acc_ * nb_active_flux_ / x0_ + **/ + /** @brief base maximum throughput to compare to when computing the ratio */ + const double x0_ = 5678270; + /** @brief linear regression factor */ + const double co_acc_ = -5424; + /** @brief minimum number of concurrent flows before using the linear regression */ + const int conc_lim_ = 20; + /** @brief current concurrency on the link */ + int nb_active_flux_ = 0; + std::vector decay_bandwidths_; public: @@ -50,8 +51,13 @@ public: void apply_event(kernel::profile::Event*, double) override { THROW_UNIMPLEMENTED; } void set_bandwidth(double) override { THROW_UNIMPLEMENTED; } void set_latency(double) override; - void refresh_decay_bandwidths(); - bool toggle_decay_model(); + bool toggle_callback(); + + static void update_bw_comm_end(const NetworkAction& action, Action::State state); + void inc_active_flux(); + void dec_active_flux(); + static double wifi_link_dynamic_sharing(const WifiLinkImpl& link, double capacity, int n); + double get_max_ratio() const; size_t get_host_count() const; }; diff --git a/src/surf/cpu_cas01.cpp b/src/kernel/resource/models/cpu_cas01.cpp similarity index 88% rename from src/surf/cpu_cas01.cpp rename to src/kernel/resource/models/cpu_cas01.cpp index 8112b6a885..35af6fa8f1 100644 --- a/src/surf/cpu_cas01.cpp +++ b/src/kernel/resource/models/cpu_cas01.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,12 +6,12 @@ #include #include -#include "simgrid/sg_config.hpp" #include "src/kernel/EngineImpl.hpp" +#include "src/kernel/resource/models/cpu_cas01.hpp" +#include "src/kernel/resource/models/cpu_ti.hpp" #include "src/kernel/resource/profile/Event.hpp" -#include "src/surf/cpu_cas01.hpp" -#include "src/surf/cpu_ti.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/module.hpp" +#include "src/simgrid/sg_config.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(cpu_cas, res_cpu, "CPU resource, CAS01 model (used by default)"); @@ -40,8 +40,7 @@ static simgrid::config::Flag cfg_cpu_solver("cpu/solver", "Set line /********* * Model * *********/ -void surf_cpu_model_init_Cas01() -{ +SIMGRID_REGISTER_CPU_MODEL(Cas01, "Simplistic CPU model (time=size/speed)", []() { if (cpu_optim_opt == "TI") { simgrid::kernel::resource::CpuTiModel::create_pm_models(); return; @@ -51,7 +50,7 @@ void surf_cpu_model_init_Cas01() auto* engine = simgrid::kernel::EngineImpl::get_instance(); engine->add_model(cpu_model_pm); engine->get_netzone_root()->set_cpu_pm_model(cpu_model_pm); -} +}); namespace simgrid::kernel::resource { @@ -68,7 +67,7 @@ CpuCas01Model::CpuCas01Model(const std::string& name) : CpuModel(name) select = true; } - set_maxmin_system(lmm::System::build(cfg_cpu_solver, select)); + set_maxmin_system(lmm::System::build(cfg_cpu_solver.get(), select)); } CpuImpl* CpuCas01Model::create_cpu(s4u::Host* host, const std::vector& speed_per_pstate) @@ -114,20 +113,8 @@ void CpuCas01::apply_event(profile::Event* event, double value) get_iface()->turn_on(); } } else { - const lmm::Element* elem = nullptr; - double date = EngineImpl::get_clock(); - get_iface()->turn_off(); - - while (const auto* var = get_constraint()->get_variable(&elem)) { - Action* action = var->get_id(); - - if (action->get_state() == Action::State::INITED || action->get_state() == Action::State::STARTED || - action->get_state() == Action::State::IGNORED) { - action->set_finish_time(date); - action->set_state(Action::State::FAILED); - } - } + cancel_actions(); } unref_state_event(); @@ -160,7 +147,7 @@ CpuAction* CpuCas01::execution_start(double size, int requested_cores, double us CpuAction* CpuCas01::sleep(double duration) { if (duration > 0) - duration = std::max(duration, sg_surf_precision); + duration = std::max(duration, sg_precision_timing); XBT_IN("(%s, %g)", get_cname(), duration); auto* action = new CpuCas01Action(get_model(), 1.0, not is_on(), speed_.scale * speed_.peak, get_constraint(), 1); diff --git a/src/surf/cpu_cas01.hpp b/src/kernel/resource/models/cpu_cas01.hpp similarity index 84% rename from src/surf/cpu_cas01.hpp rename to src/kernel/resource/models/cpu_cas01.hpp index 94ab188b81..b1cc67b084 100644 --- a/src/surf/cpu_cas01.hpp +++ b/src/kernel/resource/models/cpu_cas01.hpp @@ -1,13 +1,12 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SIMGRID_SURF_CPUCAS01_HPP -#define SIMGRID_SURF_CPUCAS01_HPP +#ifndef SIMGRID_MODEL_CPU_CAS01_HPP +#define SIMGRID_MODEL_CPU_CAS01_HPP #include "src/kernel/resource/CpuImpl.hpp" -#include "xbt/base.h" namespace simgrid::kernel::resource { @@ -26,7 +25,7 @@ class XBT_PRIVATE CpuCas01Action; class CpuCas01Model : public CpuModel { public: explicit CpuCas01Model(const std::string& name); - CpuCas01Model(const CpuCas01Model&) = delete; + CpuCas01Model(const CpuCas01Model&) = delete; CpuCas01Model& operator=(const CpuCas01Model&) = delete; CpuImpl* create_cpu(s4u::Host* host, const std::vector& speed_per_pstate) override; @@ -41,7 +40,7 @@ class CpuCas01 : public CpuImpl { public: using CpuImpl::CpuImpl; - CpuCas01(const CpuCas01&) = delete; + CpuCas01(const CpuCas01&) = delete; CpuCas01& operator=(const CpuCas01&) = delete; void apply_event(profile::Event* event, double value) override; CpuAction* execution_start(double size, double user_bound) override; @@ -61,7 +60,7 @@ class CpuCas01Action : public CpuAction { public: CpuCas01Action(Model* model, double cost, bool failed, double speed, lmm::Constraint* constraint, int requested_core); - CpuCas01Action(const CpuCas01Action&) = delete; + CpuCas01Action(const CpuCas01Action&) = delete; CpuCas01Action& operator=(const CpuCas01Action&) = delete; int requested_core() const { return requested_core_; } }; diff --git a/src/surf/cpu_ti.cpp b/src/kernel/resource/models/cpu_ti.cpp similarity index 93% rename from src/surf/cpu_ti.cpp rename to src/kernel/resource/models/cpu_ti.cpp index 6f1121be7f..6b522bb296 100644 --- a/src/surf/cpu_ti.cpp +++ b/src/kernel/resource/models/cpu_ti.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,11 +6,11 @@ #include "cpu_ti.hpp" #include "simgrid/kernel/routing/NetZoneImpl.hpp" #include "simgrid/s4u/Engine.hpp" -#include "xbt/asserts.h" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/resource/profile/Event.hpp" #include "src/kernel/resource/profile/Profile.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/math_utils.h" +#include "xbt/asserts.h" #include #include @@ -27,15 +27,15 @@ namespace simgrid::kernel::resource { CpuTiProfile::CpuTiProfile(const profile::Profile* profile) { - double integral = 0; - double time = 0; - double prev_value = 1; - const std::vector& events=profile->get_event_list(); + double integral = 0; + double time = 0; + double prev_value = 1; + const std::vector& events = profile->get_event_list(); xbt_assert(not events.empty()); unsigned long nb_points = events.size() + 1; time_points_.reserve(nb_points); integral_.reserve(nb_points); - for (auto const& val : events) { + for (auto const& val : events) { time += val.date_; integral += val.date_ * prev_value; time_points_.push_back(time); @@ -43,11 +43,11 @@ CpuTiProfile::CpuTiProfile(const profile::Profile* profile) prev_value = val.value_; } - double delay=profile->get_repeat_delay()+ events.at(0).date_; + double delay = profile->get_repeat_delay() + events.at(0).date_; - xbt_assert( events.back().value_==prev_value,"Profiles need to end as they start"); + xbt_assert(events.back().value_ == prev_value, "Profiles need to end as they start"); time += delay; - integral += delay*prev_value; + integral += delay * prev_value; time_points_.push_back(time); integral_.push_back(integral); @@ -56,7 +56,7 @@ CpuTiProfile::CpuTiProfile(const profile::Profile* profile) /** * @brief Integrate trace * - * Wrapper around surf_cpu_integrate_trace_simple() to get + * Wrapper around profile_->integrate_simple() to get * the cyclic effect. * * @param a Begin of interval @@ -120,7 +120,7 @@ double CpuTiProfile::integrate_simple_point(double a) const XBT_DEBUG("a %f ind %ld integral %f ind + 1 %f ind %f time +1 %f time %f", a, ind, integral, integral_[ind + 1], integral_[ind], time_points_[ind + 1], time_points_[ind]); - double_update(&a_aux, time_points_[ind], sg_maxmin_precision * sg_surf_precision); + double_update(&a_aux, time_points_[ind], sg_precision_workamount * sg_precision_timing); if (a_aux > 0) integral += ((integral_[ind + 1] - integral_[ind]) / (time_points_[ind + 1] - time_points_[ind])) * (a - time_points_[ind]); @@ -311,7 +311,7 @@ double CpuTiModel::next_occurring_event(double now) void CpuTiModel::update_actions_state(double now, double /*delta*/) { - while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_surf_precision)) { + while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_precision_timing)) { auto* action = static_cast(get_action_heap().pop()); XBT_DEBUG("Action %p: finish", action); action->finish(Action::State::FINISHED); @@ -337,6 +337,16 @@ CpuTi::~CpuTi() delete speed_integrated_trace_; } +void CpuTi::turn_off() +{ + /* Skip CpuImpl::turn_off() that marks the actions as failing, as it seems to be done otherwise in CPU TI. + * So, just avoid the segfault for now. + * + * TODO: a proper solution would be to understand and adapt the way actions are marked FAILED in here, + * and adapt it to align with the other resources. */ + Resource::turn_off(); +} + CpuImpl* CpuTi::set_speed_profile(kernel::profile::Profile* profile) { delete speed_integrated_trace_; @@ -377,13 +387,13 @@ void CpuTi::apply_event(kernel::profile::Event* event, double value) } } else { get_iface()->turn_off(); - double date = EngineImpl::get_clock(); /* put all action running on cpu to failed */ + double now = EngineImpl::get_clock(); for (CpuTiAction& action : action_set_) { if (action.get_state() == Action::State::INITED || action.get_state() == Action::State::STARTED || action.get_state() == Action::State::IGNORED) { - action.set_finish_time(date); + action.set_finish_time(now); action.set_state(Action::State::FAILED); get_model()->get_action_heap().remove(&action); } @@ -520,7 +530,7 @@ CpuAction* CpuTi::execution_start(double size, double user_bound) CpuAction* CpuTi::sleep(double duration) { if (duration > 0) - duration = std::max(duration, sg_surf_precision); + duration = std::max(duration, sg_precision_timing); XBT_IN("(%s,%g)", get_cname(), duration); auto* action = new CpuTiAction(this, 1.0); diff --git a/src/surf/cpu_ti.hpp b/src/kernel/resource/models/cpu_ti.hpp similarity index 87% rename from src/surf/cpu_ti.hpp rename to src/kernel/resource/models/cpu_ti.hpp index c1c72bb82d..9def4f1f0e 100644 --- a/src/surf/cpu_ti.hpp +++ b/src/kernel/resource/models/cpu_ti.hpp @@ -1,13 +1,15 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_MODEL_CPUTI_HPP_ -#define SURF_MODEL_CPUTI_HPP_ +#ifndef SIMGRID_MODEL_CPUTI_HPP_ +#define SIMGRID_MODEL_CPUTI_HPP_ #include "src/kernel/resource/CpuImpl.hpp" #include "src/kernel/resource/profile/Profile.hpp" +#include "xbt/ex.h" + #include #include @@ -44,7 +46,7 @@ class CpuTiTmgr { FIXED, /*< Trace fixed, no availability file */ DYNAMIC /*< Dynamic, have an availability file */ }; - Type type_ = Type::FIXED; + Type type_ = Type::FIXED; double value_ = 0.0; /*< Percentage of cpu speed available. Value fixed between 0 and 1 */ /* Dynamic */ @@ -57,7 +59,7 @@ class CpuTiTmgr { public: explicit CpuTiTmgr(double value) : value_(value){}; CpuTiTmgr(profile::Profile* speed_profile, double value); - CpuTiTmgr(const CpuTiTmgr&) = delete; + CpuTiTmgr(const CpuTiTmgr&) = delete; CpuTiTmgr& operator=(const CpuTiTmgr&) = delete; double integrate(double a, double b) const; @@ -71,9 +73,10 @@ public: class XBT_PRIVATE CpuTiAction : public CpuAction { friend class CpuTi; + public: CpuTiAction(CpuTi* cpu, double cost); - CpuTiAction(const CpuTiAction&) = delete; + CpuTiAction(const CpuTiAction&) = delete; CpuTiAction& operator=(const CpuTiAction&) = delete; ~CpuTiAction() override; @@ -84,7 +87,7 @@ public: void set_sharing_penalty(double sharing_penalty) override; double get_remains() override; - CpuTi *cpu_; + CpuTi* cpu_; boost::intrusive::list_member_hook<> action_ti_hook; }; @@ -104,6 +107,7 @@ public: ~CpuTi() override; CpuImpl* set_speed_profile(profile::Profile* profile) override; + void turn_off() override; void apply_event(profile::Event* event, double value) override; void update_actions_finish_time(double now); @@ -123,8 +127,8 @@ public: CpuTiTmgr* speed_integrated_trace_ = nullptr; /*< Structure with data needed to integrate trace file */ ActionTiList action_set_; /*< set with all actions running on cpu */ - double sum_priority_ = 0; /*< the sum of actions' priority that are running on cpu */ - double last_update_ = 0; /*< last update of actions' remaining amount done */ + double sum_priority_ = 0; /*< the sum of actions' priority that are running on cpu */ + double last_update_ = 0; /*< last update of actions' remaining amount done */ boost::intrusive::list_member_hook<> cpu_ti_hook; }; @@ -141,7 +145,7 @@ public: static void create_pm_models(); // Make CPU PM model using CpuModel::CpuModel; - CpuTiModel(const CpuTiModel&) = delete; + CpuTiModel(const CpuTiModel&) = delete; CpuTiModel& operator=(const CpuTiModel&) = delete; CpuImpl* create_cpu(s4u::Host* host, const std::vector& speed_per_pstate) override; double next_occurring_event(double now) override; @@ -152,4 +156,4 @@ public: } // namespace simgrid::kernel::resource -#endif /* SURF_MODEL_CPUTI_HPP_ */ +#endif /* SIMGRID_MODEL_CPUTI_HPP_ */ diff --git a/src/surf/disk_s19.cpp b/src/kernel/resource/models/disk_s19.cpp similarity index 66% rename from src/surf/disk_s19.cpp rename to src/kernel/resource/models/disk_s19.cpp index a6f894faa7..5d11e78028 100644 --- a/src/surf/disk_s19.cpp +++ b/src/kernel/resource/models/disk_s19.cpp @@ -1,8 +1,9 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "src/simgrid/sg_config.hpp" #include #include #include @@ -10,24 +11,38 @@ #include "src/kernel/EngineImpl.hpp" #include "src/kernel/lmm/maxmin.hpp" +#include "src/kernel/resource/models/disk_s19.hpp" #include "src/kernel/resource/profile/Event.hpp" -#include "src/surf/disk_s19.hpp" +#include "src/simgrid/module.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_disk); +/*********** + * Options * + ***********/ +static simgrid::config::Flag cfg_disk_solver("disk/solver", + "Set linear equations solver used by disk model", "maxmin", + &simgrid::kernel::lmm::System::validate_solver); /********* * Model * *********/ -void surf_disk_model_init_default() -{ +SIMGRID_REGISTER_DISK_MODEL(S19, "Simplistic disk model.", []() { auto disk_model = std::make_shared("Disk"); auto* engine = simgrid::kernel::EngineImpl::get_instance(); engine->add_model(disk_model); engine->get_netzone_root()->set_disk_model(disk_model); -} +}); namespace simgrid::kernel::resource { +/********* + * Model * + *********/ + +DiskS19Model::DiskS19Model(const std::string& name) : DiskModel(name) +{ + set_maxmin_system(lmm::System::build(cfg_disk_solver.get(), true /* selective update */)); +} DiskImpl* DiskS19Model::create_disk(const std::string& name, double read_bandwidth, double write_bandwidth) { @@ -49,52 +64,9 @@ void DiskS19Model::update_actions_state(double /*now*/, double delta) } } -DiskAction* DiskS19Model::io_start(const DiskImpl* disk, sg_size_t size, s4u::Io::OpType type) -{ - auto* action = new DiskS19Action(this, static_cast(size), not disk->is_on()); - get_maxmin_system()->expand(disk->get_constraint(), action->get_variable(), 1.0); - switch (type) { - case s4u::Io::OpType::READ: - get_maxmin_system()->expand(disk->get_read_constraint(), action->get_variable(), 1.0); - break; - case s4u::Io::OpType::WRITE: - get_maxmin_system()->expand(disk->get_write_constraint(), action->get_variable(), 1.0); - break; - default: - THROW_UNIMPLEMENTED; - } - if (const auto& factor_cb = disk->get_factor_cb()) { // handling disk variability - action->set_rate_factor(factor_cb(size, type)); - } - return action; -} - /************ * Resource * ************/ -void DiskS19::set_read_bandwidth(double value) -{ - DiskImpl::set_read_bandwidth(value); - if (get_read_constraint()) { - get_model()->get_maxmin_system()->update_constraint_bound(get_read_constraint(), get_read_bandwidth()); - } -} - -void DiskS19::set_write_bandwidth(double value) -{ - DiskImpl::set_write_bandwidth(value); - if (get_write_constraint()) { - get_model()->get_maxmin_system()->update_constraint_bound(get_write_constraint(), get_write_bandwidth()); - } -} - -void DiskS19::set_readwrite_bandwidth(double value) -{ - DiskImpl::set_readwrite_bandwidth(value); - if (get_constraint()) { - get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(), get_readwrite_bandwidth()); - } -} void DiskS19::apply_event(kernel::profile::Event* triggered, double value) { @@ -128,8 +100,24 @@ DiskS19Action::DiskS19Action(Model* model, double cost, bool failed) { } -void DiskS19Action::update_remains_lazy(double /*now*/) +DiskAction* DiskS19::io_start(sg_size_t size, s4u::Io::OpType type) { - THROW_IMPOSSIBLE; + auto* action = new DiskS19Action(get_model(), static_cast(size), not is_on()); + get_model()->get_maxmin_system()->expand(get_constraint(), action->get_variable(), 1.0); + switch (type) { + case s4u::Io::OpType::READ: + get_model()->get_maxmin_system()->expand(get_read_constraint(), action->get_variable(), 1.0); + break; + case s4u::Io::OpType::WRITE: + get_model()->get_maxmin_system()->expand(get_write_constraint(), action->get_variable(), 1.0); + break; + default: + THROW_UNIMPLEMENTED; + } + if (const auto& factor_cb = get_factor_cb()) { // handling disk variability + action->set_rate_factor(factor_cb(size, type)); + } + return action; } + } // namespace simgrid::kernel::resource diff --git a/src/surf/disk_s19.hpp b/src/kernel/resource/models/disk_s19.hpp similarity index 74% rename from src/surf/disk_s19.hpp rename to src/kernel/resource/models/disk_s19.hpp index a6413ddb6c..8da736c81c 100644 --- a/src/surf/disk_s19.hpp +++ b/src/kernel/resource/models/disk_s19.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -26,11 +26,11 @@ class XBT_PRIVATE DiskS19Action; class DiskS19Model : public DiskModel { public: - using DiskModel::DiskModel; + explicit DiskS19Model(const std::string& name); + DiskS19Model(const DiskS19Model&) = delete; + DiskS19Model& operator=(const DiskS19Model&) = delete; DiskImpl* create_disk(const std::string& name, double read_bandwidth, double write_bandwidth) override; - DiskAction* io_start(const DiskImpl* disk, sg_size_t size, s4u::Io::OpType type) override; - void update_actions_state(double now, double delta) override; }; @@ -41,10 +41,8 @@ public: class DiskS19 : public DiskImpl { public: using DiskImpl::DiskImpl; - void set_read_bandwidth(double value) override; - void set_write_bandwidth(double value) override; - void set_readwrite_bandwidth(double value) override; void apply_event(kernel::profile::Event* triggered, double value) override; + DiskAction* io_start(sg_size_t size, s4u::Io::OpType type) override; }; /********** @@ -54,7 +52,6 @@ public: class DiskS19Action : public DiskAction { public: DiskS19Action(Model* model, double cost, bool failed); - void update_remains_lazy(double now) override; }; } // namespace simgrid::kernel::resource diff --git a/src/surf/host_clm03.cpp b/src/kernel/resource/models/host_clm03.cpp similarity index 76% rename from src/surf/host_clm03.cpp rename to src/kernel/resource/models/host_clm03.cpp index 0005ed40b6..5050b1fd2e 100644 --- a/src/surf/host_clm03.cpp +++ b/src/kernel/resource/models/host_clm03.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,31 +7,26 @@ #include #include -#include "simgrid/sg_config.hpp" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/resource/NetworkModel.hpp" -#include "src/surf/host_clm03.hpp" +#include "src/kernel/resource/models/host_clm03.hpp" +#include "src/simgrid/module.hpp" +#include "src/simgrid/sg_config.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_host); -void surf_host_model_init_current_default() -{ - simgrid::config::set_default("network/crosstraffic", true); - auto host_model = std::make_shared("Host_CLM03"); - auto* engine = simgrid::kernel::EngineImpl::get_instance(); - engine->add_model(host_model); - engine->get_netzone_root()->set_host_model(host_model); - surf_cpu_model_init_Cas01(); - surf_network_model_init_LegrandVelho(); -} +SIMGRID_REGISTER_HOST_MODEL( + default, "Default host model. Currently, CPU:Cas01, network:LV08 (with cross traffic enabled), and disk:S19", []() { + simgrid::config::set_default("network/crosstraffic", true); + auto host_model = std::make_shared("Host_CLM03"); + auto* engine = simgrid::kernel::EngineImpl::get_instance(); + engine->add_model(host_model); + engine->get_netzone_root()->set_host_model(host_model); -void surf_host_model_init_compound() -{ - auto host_model = std::make_shared("Host_CLM03"); - auto* engine = simgrid::kernel::EngineImpl::get_instance(); - engine->add_model(host_model); - engine->get_netzone_root()->set_host_model(host_model); -} + simgrid_cpu_models().init_from_flag_value(); + simgrid_disk_models().init_from_flag_value(); + simgrid_network_models().init_from_flag_value(); + }); namespace simgrid::kernel::resource { @@ -63,7 +58,7 @@ Action* HostCLM03Model::execute_parallel(const std::vector& host_lis if ((host_list.size() == 1) && (has_cost(bytes_amount, 0) <= 0) && (has_cost(flops_amount, 0) > 0)) { action = host_list[0]->get_cpu()->execution_start(flops_amount[0], rate); } else if ((host_list.size() == 1) && (has_cost(flops_amount, 0) <= 0)) { - action = net_model->communicate(host_list[0], host_list[0], bytes_amount[0], rate); + action = net_model->communicate(host_list[0], host_list[0], bytes_amount[0], rate, false); } else if ((host_list.size() == 2) && (has_cost(flops_amount, 0) <= 0) && (has_cost(flops_amount, 1) <= 0)) { int nb = 0; double value = 0.0; @@ -75,7 +70,7 @@ Action* HostCLM03Model::execute_parallel(const std::vector& host_lis } } if (nb == 1) { - action = net_model->communicate(host_list[0], host_list[1], value, rate); + action = net_model->communicate(host_list[0], host_list[1], value, rate, false); } else if (nb == 0) { xbt_die("Cannot have a communication with no flop to exchange in this model. You should consider using the " "ptask model"); @@ -95,7 +90,7 @@ Action* HostCLM03Model::execute_parallel(const std::vector& host_lis Action* HostCLM03Model::execute_thread(const s4u::Host* host, double flops_amount, int thread_count) { - auto cpu = host->get_cpu(); + auto* cpu = host->get_cpu(); /* Create a single action whose cost is thread_count * flops_amount and that requests thread_count cores. */ return cpu->execution_start(thread_count * flops_amount, thread_count, -1); } diff --git a/src/surf/host_clm03.hpp b/src/kernel/resource/models/host_clm03.hpp similarity index 88% rename from src/surf/host_clm03.hpp rename to src/kernel/resource/models/host_clm03.hpp index e972cb7af3..cc5fc9f8ab 100644 --- a/src/surf/host_clm03.hpp +++ b/src/kernel/resource/models/host_clm03.hpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "src/surf/HostImpl.hpp" +#include "src/kernel/resource/HostImpl.hpp" #ifndef HOST_CLM03_HPP_ #define HOST_CLM03_HPP_ diff --git a/src/surf/network_cm02.cpp b/src/kernel/resource/models/network_cm02.cpp similarity index 74% rename from src/surf/network_cm02.cpp rename to src/kernel/resource/models/network_cm02.cpp index c7f15ec492..1a3f926feb 100644 --- a/src/surf/network_cm02.cpp +++ b/src/kernel/resource/models/network_cm02.cpp @@ -1,18 +1,19 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "src/surf/network_cm02.hpp" +#include "src/kernel/resource/models/network_cm02.hpp" #include "simgrid/kernel/routing/NetZoneImpl.hpp" #include "simgrid/s4u/Engine.hpp" #include "simgrid/s4u/Host.hpp" -#include "simgrid/sg_config.hpp" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" #include "src/kernel/resource/WifiLinkImpl.hpp" #include "src/kernel/resource/profile/Event.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/math_utils.h" +#include "src/simgrid/module.hpp" +#include "src/simgrid/sg_config.hpp" #include #include @@ -26,13 +27,9 @@ static simgrid::config::Flag cfg_network_solver("network/solver", "Set linear equations solver used by network model", "maxmin", &simgrid::kernel::lmm::System::validate_solver); -double sg_latency_factor = 1.0; /* default value; can be set by model or from command line */ -double sg_bandwidth_factor = 1.0; /* default value; can be set by model or from command line */ -double sg_weight_S_parameter = 0.0; /* default value; can be set by model or from command line */ - -/************************************************************************/ -/* New model based on optimizations discussed during Pedro Velho's thesis*/ -/************************************************************************/ +/******************************************************************************/ +/* Network model based on optimizations discussed during Pedro Velho's thesis */ +/******************************************************************************/ /* @techreport{VELHO:2011:HAL-00646896:1, */ /* url = {http://hal.inria.fr/hal-00646896/en/}, */ /* title = {{Flow-level network models: have we reached the limits?}}, */ @@ -44,21 +41,24 @@ double sg_weight_S_parameter = 0.0; /* default value; can be set by model or fro /* month = Nov, */ /* pdf = {http://hal.inria.fr/hal-00646896/PDF/rr-validity.pdf}, */ /* } */ -void surf_network_model_init_LegrandVelho() -{ - auto net_model = std::make_shared("Network_LegrandVelho"); - auto* engine = simgrid::kernel::EngineImpl::get_instance(); - engine->add_model(net_model); - engine->get_netzone_root()->set_network_model(net_model); - - simgrid::config::set_default("network/latency-factor", 13.01); - simgrid::config::set_default("network/bandwidth-factor", 0.97); - simgrid::config::set_default("network/weight-S", 20537); -} - -/***************************************************************************/ -/* The nice TCP sharing model designed by Loris Marchal and Henri Casanova */ -/***************************************************************************/ +SIMGRID_REGISTER_NETWORK_MODEL( + LV08, + "Realistic network analytic model (slow-start modeled by multiplying latency by 13.01, bandwidth by .97; " + "bottleneck sharing uses a payload of S=20537 for evaluating RTT). ", + []() { + auto net_model = std::make_shared("Network_LegrandVelho"); + auto* engine = simgrid::kernel::EngineImpl::get_instance(); + engine->add_model(net_model); + engine->get_netzone_root()->set_network_model(net_model); + + simgrid::config::set_default("network/latency-factor", "13.01"); + simgrid::config::set_default("network/bandwidth-factor", "0.97"); + simgrid::config::set_default("network/weight-S", 20537); + }); + +/****************************************************************************/ +/* The older TCP sharing model designed by Loris Marchal and Henri Casanova */ +/****************************************************************************/ /* @TechReport{ rr-lip2002-40, */ /* author = {Henri Casanova and Loris Marchal}, */ /* institution = {LIP}, */ @@ -67,33 +67,78 @@ void surf_network_model_init_LegrandVelho() /* month = {oct}, */ /* year = {2002} */ /* } */ -void surf_network_model_init_CM02() -{ - simgrid::config::set_default("network/latency-factor", 1.0); - simgrid::config::set_default("network/bandwidth-factor", 1.0); - simgrid::config::set_default("network/weight-S", 0.0); - - auto net_model = std::make_shared("Network_CM02"); - auto* engine = simgrid::kernel::EngineImpl::get_instance(); - engine->add_model(net_model); - engine->get_netzone_root()->set_network_model(net_model); -} +SIMGRID_REGISTER_NETWORK_MODEL( + CM02, + "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of " + "small messages are thus poorly modeled).", + []() { + simgrid::config::set_default("network/latency-factor", "1.0"); + simgrid::config::set_default("network/bandwidth-factor", "1.0"); + simgrid::config::set_default("network/weight-S", 0.0); + + auto net_model = std::make_shared("Network_CM02"); + auto* engine = simgrid::kernel::EngineImpl::get_instance(); + engine->add_model(net_model); + engine->get_netzone_root()->set_network_model(net_model); + }); + +/********************************************************************/ +/* Model based on LV08 and experimental results of MPI ping-pongs */ +/********************************************************************/ +/* @Inproceedings{smpi_ipdps, */ +/* author={Pierre-Nicolas Clauss and Mark Stillwell and Stéphane Genaud and Frédéric Suter and Henri Casanova and + * Martin Quinson}, */ +/* title={Single Node On-Line Simulation of {MPI} Applications with SMPI}, */ +/* booktitle={25th IEEE International Parallel and Distributed Processing Symposium (IPDPS'11)}, */ +/* address={Anchorage (Alaska) USA}, */ +/* month=may, */ +/* year={2011} */ +/* } */ +SIMGRID_REGISTER_NETWORK_MODEL( + SMPI, + "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with " + "correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)", + []() { + auto net_model = std::make_shared("Network_SMPI"); + auto* engine = simgrid::kernel::EngineImpl::get_instance(); + engine->add_model(net_model); + engine->get_netzone_root()->set_network_model(net_model); + + simgrid::config::set_default("network/weight-S", 8775); + simgrid::config::set_default("network/bandwidth-factor", + "65472:0.940694;15424:0.697866;9376:0.58729;5776:1.08739;3484:0.77493;" + "1426:0.608902;732:0.341987;257:0.338112;0:0.812084"); + simgrid::config::set_default("network/latency-factor", + "65472:11.6436;15424:3.48845;9376:2.59299;5776:2.18796;3484:1.88101;" + "1426:1.61075;732:1.9503;257:1.95341;0:2.01467"); + }); namespace simgrid::kernel::resource { +static simgrid::config::Flag + network_optim_opt("network/optim", "Optimization algorithm to use for network resources. ", "Lazy", + + std::map>({ + {"Lazy", "Lazy action management (partial invalidation in lmm + heap in action remaining)."}, + {"Full", "Full update of remaining and variables. Slow but may be useful when debugging."}, + }), + + [](std::string const&) { + xbt_assert(_sg_cfg_init_status < 2, + "Cannot change the optimization algorithm after the initialization"); + }); NetworkCm02Model::NetworkCm02Model(const std::string& name) : NetworkModel(name) { - std::string optim = config::get_value("network/optim"); - bool select = config::get_value("network/maxmin-selective-update"); + bool select = config::get_value("network/maxmin-selective-update"); - if (optim == "Lazy") { + if (network_optim_opt == "Lazy") { set_update_algorithm(Model::UpdateAlgo::LAZY); xbt_assert(select || config::is_default("network/maxmin-selective-update"), "You cannot disable network selective update when using the lazy update mechanism"); select = true; } - set_maxmin_system(lmm::System::build(cfg_network_solver, select)); + set_maxmin_system(lmm::System::build(cfg_network_solver.get(), select)); loopback_.reset(create_link("__loopback__", {config::get_value("network/loopback-bw")})); loopback_->set_sharing_policy(s4u::Link::SharingPolicy::FATPIPE, {}); @@ -101,58 +146,24 @@ NetworkCm02Model::NetworkCm02Model(const std::string& name) : NetworkModel(name) loopback_->get_iface()->seal(); } -void NetworkCm02Model::check_lat_factor_cb() -{ - if (not simgrid::config::is_default("network/latency-factor")) { - throw std::invalid_argument( - "NetworkModelIntf: Cannot mix network/latency-factor and callback configuration. Choose only one of them."); - } -} - -void NetworkCm02Model::check_bw_factor_cb() -{ - if (not simgrid::config::is_default("network/bandwidth-factor")) { - throw std::invalid_argument( - "NetworkModelIntf: Cannot mix network/bandwidth-factor and callback configuration. Choose only one of them."); - } -} - -void NetworkCm02Model::set_lat_factor_cb(const std::function& cb) -{ - if (not cb) - throw std::invalid_argument("NetworkModelIntf: Invalid callback"); - check_lat_factor_cb(); - - lat_factor_cb_ = cb; -} - -void NetworkCm02Model::set_bw_factor_cb(const std::function& cb) -{ - if (not cb) - throw std::invalid_argument("NetworkModelIntf: Invalid callback"); - check_bw_factor_cb(); - - bw_factor_cb_ = cb; -} - StandardLinkImpl* NetworkCm02Model::create_link(const std::string& name, const std::vector& bandwidths) { xbt_assert(bandwidths.size() == 1, "Non-WIFI links must use only 1 bandwidth."); - auto link = new NetworkCm02Link(name, bandwidths[0], get_maxmin_system()); + auto* link = new NetworkCm02Link(name, bandwidths[0], get_maxmin_system()); link->set_model(this); return link; } StandardLinkImpl* NetworkCm02Model::create_wifi_link(const std::string& name, const std::vector& bandwidths) { - auto link = new WifiLinkImpl(name, bandwidths, get_maxmin_system()); + auto* link = new WifiLinkImpl(name, bandwidths, get_maxmin_system()); link->set_model(this); return link; } void NetworkCm02Model::update_actions_state_lazy(double now, double /*delta*/) { - while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_surf_precision)) { + while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_precision_timing)) { auto* action = static_cast(get_action_heap().pop()); XBT_DEBUG("Something happened to action %p", action); @@ -182,7 +193,7 @@ void NetworkCm02Model::update_actions_state_full(double /*now*/, double delta) XBT_DEBUG("Something happened to action %p", &action); if (action.latency_ > 0) { if (action.latency_ > delta) { - double_update(&action.latency_, delta, sg_surf_precision); + double_update(&action.latency_, delta, sg_precision_timing); } else { action.latency_ = 0.0; } @@ -225,19 +236,21 @@ void NetworkCm02Model::comm_action_expand_constraints(const s4u::Host* src, cons /* WI-FI links needs special treatment, do it here */ if (src_wifi_link != nullptr) { - /* In case of 0Mbps data rate, don't consider it in the LMM */ if (src_wifi_link->get_host_rate(src) > 0) get_maxmin_system()->expand(src_wifi_link->get_constraint(), action->get_variable(), 1.0 / src_wifi_link->get_host_rate(src)); - else + else { get_maxmin_system()->update_variable_penalty(action->get_variable(), 0); + } } + if (dst_wifi_link != nullptr) { if (dst_wifi_link->get_host_rate(dst) > 0) get_maxmin_system()->expand(dst_wifi_link->get_constraint(), action->get_variable(), 1.0 / dst_wifi_link->get_host_rate(dst)); - else + else { get_maxmin_system()->update_variable_penalty(action->get_variable(), 0); + } } for (auto const* link : route) { @@ -336,24 +349,20 @@ bool NetworkCm02Model::comm_get_route_info(const s4u::Host* src, const s4u::Host void NetworkCm02Model::comm_action_set_bounds(const s4u::Host* src, const s4u::Host* dst, double size, NetworkCm02Action* action, const std::vector& route, const std::unordered_set& netzones, - double rate) + double rate) const { std::vector s4u_route; std::unordered_set s4u_netzones; /* transform data to user structures if necessary */ - if (lat_factor_cb_ || bw_factor_cb_) { + if (has_network_factor_cb()) { std::for_each(route.begin(), route.end(), [&s4u_route](StandardLinkImpl* l) { s4u_route.push_back(l->get_iface()); }); std::for_each(netzones.begin(), netzones.end(), [&s4u_netzones](kernel::routing::NetZoneImpl* n) { s4u_netzones.insert(n->get_iface()); }); } - double bw_factor; - if (bw_factor_cb_) { - bw_factor = bw_factor_cb_(size, src, dst, s4u_route, s4u_netzones); - } else { - bw_factor = get_bandwidth_factor(size); - } + + double bw_factor = get_bandwidth_factor(size, src, dst, s4u_route, s4u_netzones); xbt_assert(bw_factor != 0, "Invalid param for comm %s -> %s. Bandwidth factor cannot be 0", src->get_cname(), dst->get_cname()); action->set_rate_factor(bw_factor); @@ -377,18 +386,20 @@ void NetworkCm02Model::comm_action_set_bounds(const s4u::Host* src, const s4u::H action->set_user_bound(bandwidth_bound); action->lat_current_ = action->latency_; - if (lat_factor_cb_) { - action->latency_ *= lat_factor_cb_(size, src, dst, s4u_route, s4u_netzones); - } else { - action->latency_ *= get_latency_factor(size); - } + action->latency_ *= get_latency_factor(size, src, dst, s4u_route, s4u_netzones); } void NetworkCm02Model::comm_action_set_variable(NetworkCm02Action* action, const std::vector& route, - const std::vector& back_route) + const std::vector& back_route, bool streamed) { size_t constraints_per_variable = route.size(); constraints_per_variable += back_route.size(); + if (streamed) { + // setting the number of variable for a communication action involved in a I/O streaming operation + // requires to reserve some extra space for the constraints related to the source disk (global and read + // bandwidth) and destination disk (global and write bandwidth). We thus add 4 constraints. + constraints_per_variable += 4; + } if (action->latency_ > 0) { action->set_variable(get_maxmin_system()->variable_new(action, 0.0, -1.0, constraints_per_variable)); @@ -407,16 +418,17 @@ void NetworkCm02Model::comm_action_set_variable(NetworkCm02Action* action, const /* after setting the variable, update the bounds depending on user configuration */ if (action->get_user_bound() < 0) { get_maxmin_system()->update_variable_bound( - action->get_variable(), (action->lat_current_ > 0) ? cfg_tcp_gamma / (2.0 * action->lat_current_) : -1.0); + action->get_variable(), + (action->lat_current_ > 0 && cfg_tcp_gamma > 0) ? cfg_tcp_gamma / (2.0 * action->lat_current_) : -1.0); } else { get_maxmin_system()->update_variable_bound( - action->get_variable(), (action->lat_current_ > 0) + action->get_variable(), (action->lat_current_ > 0 && cfg_tcp_gamma > 0) ? std::min(action->get_user_bound(), cfg_tcp_gamma / (2.0 * action->lat_current_)) : action->get_user_bound()); } } -Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) +Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool streamed) { double latency = 0.0; std::vector back_route; @@ -431,10 +443,10 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz action->sharing_penalty_ = latency; action->latency_ = latency; - if (sg_weight_S_parameter > 0) { + if (cfg_weight_S_parameter > 0) { action->sharing_penalty_ = std::accumulate(route.begin(), route.end(), action->sharing_penalty_, - [](double total, StandardLinkImpl* const& link) { - return total + sg_weight_S_parameter / link->get_bandwidth(); + [](double total, StandardLinkImpl const* link) { + return total + cfg_weight_S_parameter / link->get_bandwidth(); }); } @@ -442,7 +454,7 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz comm_action_set_bounds(src, dst, size, action, route, netzones, rate); /* creating the maxmin variable associated to this action */ - comm_action_set_variable(action, route, back_route); + comm_action_set_variable(action, route, back_route, streamed); /* expand maxmin system to consider this communication in bw constraint for each link in route and back_route */ comm_action_expand_constraints(src, dst, action, route, back_route); @@ -496,9 +508,9 @@ void NetworkCm02Link::set_bandwidth(double value) StandardLinkImpl::on_bandwidth_change(); - if (sg_weight_S_parameter > 0) { - double delta = sg_weight_S_parameter / (bandwidth_.peak * bandwidth_.scale) - - sg_weight_S_parameter / (old_peak * bandwidth_.scale); + if (NetworkModel::cfg_weight_S_parameter > 0) { + double delta = NetworkModel::cfg_weight_S_parameter / (bandwidth_.peak * bandwidth_.scale) - + NetworkModel::cfg_weight_S_parameter / (old_peak * bandwidth_.scale); const kernel::lmm::Element* elem = nullptr; const kernel::lmm::Element* nextelem = nullptr; @@ -528,20 +540,21 @@ void NetworkCm02Link::set_latency(double value) auto* action = static_cast(var->get_id()); action->lat_current_ += delta; action->sharing_penalty_ += delta; - if (action->get_user_bound() < 0) + if (action->get_user_bound() < 0 && NetworkModel::cfg_tcp_gamma > 0) get_model()->get_maxmin_system()->update_variable_bound(action->get_variable(), NetworkModel::cfg_tcp_gamma / (2.0 * action->lat_current_)); - else { + else if (NetworkModel::cfg_tcp_gamma > 0) { get_model()->get_maxmin_system()->update_variable_bound( action->get_variable(), std::min(action->get_user_bound(), NetworkModel::cfg_tcp_gamma / (2.0 * action->lat_current_))); - - if (action->get_user_bound() < NetworkModel::cfg_tcp_gamma / (2.0 * action->lat_current_)) { - XBT_DEBUG("Flow is limited BYBANDWIDTH"); - } else { - XBT_DEBUG("Flow is limited BYLATENCY, latency of flow is %f", action->lat_current_); - } } + if (NetworkModel::cfg_tcp_gamma == 0 || + action->get_user_bound() < NetworkModel::cfg_tcp_gamma / (2.0 * action->lat_current_)) { + XBT_DEBUG("Flow is limited BYBANDWIDTH"); + } else { + XBT_DEBUG("Flow is limited BYLATENCY, latency of flow is %f", action->lat_current_); + } + if (not action->is_suspended()) get_model()->get_maxmin_system()->update_variable_penalty(action->get_variable(), action->sharing_penalty_); } diff --git a/src/surf/network_cm02.hpp b/src/kernel/resource/models/network_cm02.hpp similarity index 81% rename from src/surf/network_cm02.hpp rename to src/kernel/resource/models/network_cm02.hpp index 2fb8af7c30..2b8ed4d186 100644 --- a/src/surf/network_cm02.hpp +++ b/src/kernel/resource/models/network_cm02.hpp @@ -1,17 +1,14 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_NETWORK_CM02_HPP_ -#define SURF_NETWORK_CM02_HPP_ - -#include +#ifndef SIMGRID_MODEL_NETWORK_CM02_HPP_ +#define SIMGRID_MODEL_NETWORK_CM02_HPP_ #include "src/kernel/resource/NetworkModel.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" -#include "xbt/graph.h" -#include "xbt/string.hpp" +#include "xbt/base.h" /*********** * Classes * @@ -42,10 +39,10 @@ class NetworkCm02Model : public NetworkModel { /** @brief Set communication bounds for latency and bandwidth */ void comm_action_set_bounds(const s4u::Host* src, const s4u::Host* dst, double size, NetworkCm02Action* action, const std::vector& route, - const std::unordered_set& netzones, double rate); + const std::unordered_set& netzones, double rate) const; /** @brief Create maxmin variable in communication action */ void comm_action_set_variable(NetworkCm02Action* action, const std::vector& route, - const std::vector& back_route); + const std::vector& back_route, bool streamed); public: explicit NetworkCm02Model(const std::string& name); @@ -53,17 +50,7 @@ public: StandardLinkImpl* create_wifi_link(const std::string& name, const std::vector& bandwidths) override; void update_actions_state_lazy(double now, double delta) override; void update_actions_state_full(double now, double delta) override; - Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) override; - void set_lat_factor_cb(const std::function& cb) override; - void set_bw_factor_cb(const std::function& cb) override; - -protected: - virtual void check_lat_factor_cb(); - virtual void check_bw_factor_cb(); - -private: - std::function lat_factor_cb_; - std::function bw_factor_cb_; + Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool streamed) override; }; /************ @@ -82,11 +69,11 @@ public: * Action * **********/ class NetworkCm02Action : public NetworkAction { - friend Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate); + friend Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool streamed); public: using NetworkAction::NetworkAction; void update_remains_lazy(double now) override; }; } // namespace simgrid::kernel::resource -#endif /* SURF_NETWORK_CM02_HPP_ */ +#endif /* SIMGRID_MODEL_NETWORK_CM02_HPP_ */ diff --git a/src/surf/network_constant.cpp b/src/kernel/resource/models/network_constant.cpp similarity index 69% rename from src/surf/network_constant.cpp rename to src/kernel/resource/models/network_constant.cpp index c81187484b..c55982ecdb 100644 --- a/src/surf/network_constant.cpp +++ b/src/kernel/resource/models/network_constant.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,21 +7,26 @@ #include #include "src/kernel/EngineImpl.hpp" -#include "src/surf/network_constant.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/kernel/resource/models/network_constant.hpp" +#include "src/simgrid/math_utils.h" +#include "src/simgrid/module.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_network); /********* * Model * *********/ -void surf_network_model_init_Constant() -{ - auto net_model = std::make_shared("Network_Constant"); - auto* engine = simgrid::kernel::EngineImpl::get_instance(); - engine->add_model(net_model); - engine->get_netzone_root()->set_network_model(net_model); -} +SIMGRID_REGISTER_NETWORK_MODEL( + Constant, + "Simplistic network model where all communication take a constant time (one second). This model " + "provides the lowest realism, but is (marginally) faster. It is mostly useful when studying theoretical " + "distributed algorithms where the network is usually abstracted away.", + []() { + auto net_model = std::make_shared("Network_Constant"); + auto* engine = simgrid::kernel::EngineImpl::get_instance(); + engine->add_model(net_model); + engine->get_netzone_root()->set_network_model(net_model); + }); namespace simgrid::kernel::resource { @@ -56,12 +61,12 @@ void NetworkConstantModel::update_actions_state(double /*now*/, double delta) ++it; // increment iterator here since the following calls to action.finish() may invalidate it if (action.latency_ > 0) { if (action.latency_ > delta) { - double_update(&action.latency_, delta, sg_surf_precision); + double_update(&action.latency_, delta, sg_precision_timing); } else { action.latency_ = 0.0; } } - action.update_remains(action.get_cost() * delta / sg_latency_factor); + action.update_remains(action.get_cost() * delta / get_latency_factor()); action.update_max_duration(delta); if ((action.get_remains_no_update() <= 0) || @@ -71,7 +76,8 @@ void NetworkConstantModel::update_actions_state(double /*now*/, double delta) } } -Action* NetworkConstantModel::communicate(s4u::Host* src, s4u::Host* dst, double size, double /*rate*/) +Action* NetworkConstantModel::communicate(s4u::Host* src, s4u::Host* dst, double size, double /*rate*/, + bool /*streamed*/) { return (new NetworkConstantAction(this, *src, *dst, size)); } @@ -82,7 +88,7 @@ Action* NetworkConstantModel::communicate(s4u::Host* src, s4u::Host* dst, double NetworkConstantAction::NetworkConstantAction(NetworkConstantModel* model_, s4u::Host& src, s4u::Host& dst, double size) : NetworkAction(model_, src, dst, size, false) { - latency_ = sg_latency_factor; + latency_ = model_->get_latency_factor(); if (latency_ <= 0.0) set_state(Action::State::FINISHED); } diff --git a/src/surf/network_constant.hpp b/src/kernel/resource/models/network_constant.hpp similarity index 85% rename from src/surf/network_constant.hpp rename to src/kernel/resource/models/network_constant.hpp index 229043ac12..ec9f384398 100644 --- a/src/surf/network_constant.hpp +++ b/src/kernel/resource/models/network_constant.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,7 +13,7 @@ namespace simgrid::kernel::resource { class NetworkConstantModel : public NetworkModel { public: using NetworkModel::NetworkModel; - Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) override; + Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool streamed) override; double next_occurring_event(double now) override; void update_actions_state(double now, double delta) override; @@ -24,7 +24,7 @@ public: class NetworkConstantAction final : public NetworkAction { public: NetworkConstantAction(NetworkConstantModel* model_, s4u::Host& src, s4u::Host& dst, double size); - void update_remains_lazy(double now) override; + XBT_ATTRIB_NORETURN void update_remains_lazy(double now) override; }; } // namespace simgrid::kernel::resource diff --git a/src/surf/network_ib.cpp b/src/kernel/resource/models/network_ib.cpp similarity index 80% rename from src/surf/network_ib.cpp rename to src/kernel/resource/models/network_ib.cpp index 0592a7d13a..df4abf17f1 100644 --- a/src/surf/network_ib.cpp +++ b/src/kernel/resource/models/network_ib.cpp @@ -1,28 +1,26 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include -#include "simgrid/sg_config.hpp" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/activity/CommImpl.hpp" -#include "src/surf/HostImpl.hpp" -#include "src/surf/network_ib.hpp" +#include "src/kernel/resource/HostImpl.hpp" +#include "src/kernel/resource/models/network_ib.hpp" +#include "src/simgrid/math_utils.h" +#include "src/simgrid/module.hpp" +#include "src/simgrid/sg_config.hpp" #include #include XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_network); -/********* - * Model * - *********/ - -/************************************************************************/ -/* New model based on MPI contention model for Infiniband platforms */ -/************************************************************************/ +/****************************************************************/ +/* Model based on MPI contention model for Infiniband platforms */ +/****************************************************************/ /* @Inproceedings{mescal_vienne_phd, */ /* author={Jérôme Vienne}, */ /* title={prédiction de performances d’applications de calcul haute performance sur réseau Infiniband}, */ @@ -30,20 +28,23 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_network); /* month=june, */ /* year={2010} */ /* } */ -void surf_network_model_init_IB() -{ - using simgrid::kernel::resource::NetworkIBModel; - - auto net_model = std::make_shared("Network_IB"); - auto* engine = simgrid::kernel::EngineImpl::get_instance(); - engine->add_model(net_model); - engine->get_netzone_root()->set_network_model(net_model); - - simgrid::s4u::Link::on_communication_state_change_cb(NetworkIBModel::IB_action_state_changed_callback); - simgrid::kernel::activity::CommImpl::on_start.connect(NetworkIBModel::IB_comm_start_callback); - simgrid::s4u::Host::on_creation_cb(NetworkIBModel::IB_create_host_callback); - simgrid::config::set_default("network/weight-S", 8775); -} +SIMGRID_REGISTER_NETWORK_MODEL( + IB, + "Realistic network model specifically tailored for HPC settings, with Infiniband contention model as described in " + "http://mescal.imag.fr/membres/jean-marc.vincent/index.html/PhD/Vienne.pdf", + []() { + using simgrid::kernel::resource::NetworkIBModel; + + auto net_model = std::make_shared("Network_IB"); + auto* engine = simgrid::kernel::EngineImpl::get_instance(); + engine->add_model(net_model); + engine->get_netzone_root()->set_network_model(net_model); + + simgrid::s4u::Link::on_communication_state_change_cb(NetworkIBModel::IB_action_state_changed_callback); + simgrid::s4u::Comm::on_start_cb(NetworkIBModel::IB_comm_start_callback); + simgrid::s4u::Host::on_creation_cb(NetworkIBModel::IB_create_host_callback); + simgrid::config::set_default("network/weight-S", 8775); + }); namespace simgrid::kernel::resource { @@ -63,22 +64,22 @@ void NetworkIBModel::IB_action_state_changed_callback(NetworkAction& action, Act auto [src, dst] = ibModel->active_comms[&action]; XBT_DEBUG("IB callback - action %p finished", &action); - ibModel->update_IB_factors(&action, src, dst, 1); + ibModel->update_IB_factors(&action, src, dst, true); ibModel->active_comms.erase(&action); } -void NetworkIBModel::IB_comm_start_callback(const activity::CommImpl& comm) +void NetworkIBModel::IB_comm_start_callback(const s4u::Comm& comm) { - auto* action = static_cast(comm.surf_action_); + auto* action = static_cast(static_cast(comm.get_impl())->model_action_); auto* ibModel = static_cast(action->get_model()); auto* act_src = &ibModel->active_nodes.at(action->get_src().get_name()); auto* act_dst = &ibModel->active_nodes.at(action->get_dst().get_name()); ibModel->active_comms[action] = std::make_pair(act_src, act_dst); - ibModel->update_IB_factors(action, act_src, act_dst, 0); + ibModel->update_IB_factors(action, act_src, act_dst, false); } -NetworkIBModel::NetworkIBModel(const std::string& name) : NetworkSmpiModel(name) +NetworkIBModel::NetworkIBModel(const std::string& name) : NetworkCm02Model(name) { std::string IB_factors_string = config::get_value("smpi/IB-penalty-factors"); std::vector radical_elements; @@ -140,7 +141,7 @@ void NetworkIBModel::compute_IB_factors(IBNode* root) const double penalized_bw = num_comm_out ? comm->init_rate / penalty : comm->init_rate; - if (not double_equals(penalized_bw, rate_before_update, sg_surf_precision)) { + if (not double_equals(penalized_bw, rate_before_update, sg_precision_timing)) { XBT_DEBUG("%d->%d action %p penalty updated : bw now %f, before %f , initial rate %f", root->id_, comm->destination->id_, comm->action, penalized_bw, comm->action->get_bound(), comm->init_rate); get_maxmin_system()->update_variable_bound(comm->action->get_variable(), penalized_bw); @@ -169,7 +170,7 @@ void NetworkIBModel::update_IB_factors_rec(IBNode* root, std::vector& upda } } -void NetworkIBModel::update_IB_factors(NetworkAction* action, IBNode* from, IBNode* to, int remove) const +void NetworkIBModel::update_IB_factors(NetworkAction* action, IBNode* from, IBNode* to, bool remove) const { if (from == to) // disregard local comms (should use loopback) return; diff --git a/src/surf/network_ib.hpp b/src/kernel/resource/models/network_ib.hpp similarity index 76% rename from src/surf/network_ib.hpp rename to src/kernel/resource/models/network_ib.hpp index 69b52fc48f..1400d8317b 100644 --- a/src/surf/network_ib.hpp +++ b/src/kernel/resource/models/network_ib.hpp @@ -1,14 +1,12 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#ifndef SURF_NETWORK_IB_HPP_ -#define SURF_NETWORK_IB_HPP_ +#ifndef SIMGRID_MODEL_NETWORK_IB_HPP_ +#define SIMGRID_MODEL_NETWORK_IB_HPP_ -#include "src/surf/network_smpi.hpp" -#include "xbt/base.h" +#include "src/kernel/resource/models/network_cm02.hpp" #include #include @@ -35,7 +33,7 @@ public: explicit IBNode(int id) : id_(id){}; }; -class XBT_PRIVATE NetworkIBModel : public NetworkSmpiModel { +class XBT_PRIVATE NetworkIBModel : public NetworkCm02Model { std::unordered_map active_nodes; std::unordered_map> active_comms; @@ -47,13 +45,13 @@ class XBT_PRIVATE NetworkIBModel : public NetworkSmpiModel { public: explicit NetworkIBModel(const std::string& name); - NetworkIBModel(const NetworkIBModel&) = delete; + NetworkIBModel(const NetworkIBModel&) = delete; NetworkIBModel& operator=(const NetworkIBModel&) = delete; - void update_IB_factors(NetworkAction* action, IBNode* from, IBNode* to, int remove) const; + void update_IB_factors(NetworkAction* action, IBNode* from, IBNode* to, bool remove) const; static void IB_create_host_callback(s4u::Host const& host); static void IB_action_state_changed_callback(NetworkAction& action, Action::State /*previous*/); - static void IB_comm_start_callback(const activity::CommImpl& comm); + static void IB_comm_start_callback(const s4u::Comm& comm); }; } // namespace simgrid::kernel::resource #endif diff --git a/src/surf/network_ns3.cpp b/src/kernel/resource/models/network_ns3.cpp similarity index 78% rename from src/surf/network_ns3.cpp rename to src/kernel/resource/models/network_ns3.cpp index 222766f624..3d4c0650ff 100644 --- a/src/surf/network_ns3.cpp +++ b/src/kernel/resource/models/network_ns3.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,6 +9,8 @@ #include #include +#include "src/simgrid/math_utils.h" +#include "src/simgrid/module.hpp" #include "xbt/config.hpp" #include "xbt/str.h" #include "xbt/string.hpp" @@ -25,11 +27,11 @@ #include #include -#include "ns3/mobility-module.h" -#include "ns3/wifi-module.h" +#include +#include #include "network_ns3.hpp" -#include "ns3/ns3_simulator.hpp" +#include "src/kernel/resource/models/ns3/ns3_simulator.hpp" #include "simgrid/kernel/routing/NetPoint.hpp" #include "simgrid/kernel/routing/NetZoneImpl.hpp" @@ -37,10 +39,9 @@ #include "simgrid/plugins/energy.h" #include "simgrid/s4u/Engine.hpp" #include "simgrid/s4u/NetZone.hpp" -#include "src/instr/instr_private.hpp" // TRACE_is_enabled(). FIXME: remove by subscribing tracing to the surf signals +#include "src/instr/instr_private.hpp" // TRACE_is_enabled(). FIXME: remove by subscribing tracing to the signals #include "src/kernel/EngineImpl.hpp" -#include "src/surf/surf_interface.hpp" -#include "src/surf/xml/platf_private.hpp" // ClusterCreationArgs +#include "src/kernel/xml/platf_private.hpp" // ClusterCreationArgs XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_ns3, res_network, "Network model based on ns-3"); @@ -49,9 +50,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_ns3, res_network, "Network model based on ns *****************/ extern std::map> flow_from_sock; -extern std::map> sink_from_sock; - -static ns3::InternetStackHelper stack; static int number_of_links = 1; static int number_of_networks = 1; @@ -67,6 +65,7 @@ static std::string transformIpv4Address(ns3::Ipv4Address from) NetPointNs3::NetPointNs3() { + static ns3::InternetStackHelper stack; stack.Install(ns3_node_); } @@ -102,7 +101,7 @@ static void zoneCreation_cb(simgrid::s4u::NetZone const& zone) wifi.SetStandard(ns3::WIFI_STANDARD_80211n_5GHZ); #else wifi.SetStandard(ns3::WIFI_STANDARD_80211n); - wifiPhy.Set ("ChannelSettings", ns3::StringValue ("{0, 0, BAND_5GHZ, 0}")); + wifiPhy.Set("ChannelSettings", ns3::StringValue("{0, 0, BAND_5GHZ, 0}")); #endif std::string ssid = wifizone->get_name(); @@ -120,8 +119,14 @@ static void zoneCreation_cb(simgrid::s4u::NetZone const& zone) wifiPhy.Set("Antennas", ns3::UintegerValue(nss_value)); wifiPhy.Set("MaxSupportedTxSpatialStreams", ns3::UintegerValue(nss_value)); wifiPhy.Set("MaxSupportedRxSpatialStreams", ns3::UintegerValue(nss_value)); -#if NS3_MINOR_VERSION > 33 +#if NS3_MINOR_VERSION < 33 + // This fails with "The channel width does not uniquely identify an operating channel" on v3.34, + // so we specified the ChannelWidth of wifiPhy to 40, above, when creating wifiPhy with v3.34 and higher + ns3::Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", ns3::UintegerValue(40)); +#elif NS3_MINOR_VERSION < 36 wifiPhy.Set("ChannelWidth", ns3::UintegerValue(40)); +#else + wifiPhy.Set("ChannelSettings", ns3::StringValue("{0, 40, BAND_UNSPECIFIED, 0}")); #endif wifiMac.SetType("ns3::ApWifiMac", "Ssid", ns3::SsidValue(ssid)); @@ -142,9 +147,9 @@ static void zoneCreation_cb(simgrid::s4u::NetZone const& zone) NetPointNs3* station_netpoint_ns3 = nullptr; ns3::Ptr station_ns3_node = nullptr; double distance; - double angle = 0; + double angle = 0; auto nb_stations = static_cast(wifizone->get_all_hosts().size() - 1); - double step = 2 * M_PI / nb_stations; + double step = 2 * M_PI / nb_stations; for (const auto* station_host : wifizone->get_all_hosts()) { station_netpoint_ns3 = station_host->get_netpoint()->extension(); if (station_netpoint_ns3 == access_point_netpoint_ns3) @@ -167,12 +172,6 @@ static void zoneCreation_cb(simgrid::s4u::NetZone const& zone) ns3::Simulator::Schedule(ns3::Seconds(start_time_value), &resumeWifiDevice, device); } -#if NS3_MINOR_VERSION < 33 - // This fails with "The channel width does not uniquely identify an operating channel" on v3.34, - // so we specified the ChannelWidth of wifiPhy to 40, above, when creating wifiPhy with v3.34 and higher - ns3::Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", ns3::UintegerValue(40)); -#endif - mobility.SetPositionAllocator(positionAllocS); mobility.Install(nodes); ns3::Ipv4AddressHelper address; @@ -262,16 +261,13 @@ static void routeCreation_cb(bool symmetrical, const simgrid::kernel::routing::N XBT_DEBUG("\tLink (%s) bw:%fbps lat:%fs", link->get_cname(), link->get_bandwidth(), link->get_latency()); ns3_add_direct_route(src, dst, link->get_bandwidth(), link->get_latency(), link->get_sharing_policy()); - } else { - static bool warned_about_long_routes = false; - - if (not warned_about_long_routes) - XBT_WARN("Ignoring a route between %s and %s of length %zu: Only routes of length 1 are considered with ns-3.\n" - "WARNING: You can ignore this warning if your hosts can still communicate when only considering routes " - "of length 1.\n" - "WARNING: Remove long routes to avoid this harmless message; subsequent long routes will be silently " - "ignored.", - src->get_cname(), dst->get_cname(), link_list.size()); + } else if (static bool warned_about_long_routes = false; not warned_about_long_routes) { + XBT_WARN("Ignoring a route between %s and %s of length %zu: Only routes of length 1 are considered with ns-3.\n" + "WARNING: You can ignore this warning if your hosts can still communicate when only considering routes " + "of length 1.\n" + "WARNING: Remove long routes to avoid this harmless message; subsequent long routes will be silently " + "ignored.", + src->get_cname(), dst->get_cname(), link_list.size()); warned_about_long_routes = true; } } @@ -279,16 +275,21 @@ static void routeCreation_cb(bool symmetrical, const simgrid::kernel::routing::N /********* * Model * *********/ -void surf_network_model_init_NS3() +// We can't use SIMGRID_REGISTER_NETWORK_MODEL here because ns-3 has a dash in its name +static void XBT_ATTRIB_CONSTRUCTOR(800) simgrid_ns3_network_model_register() { - auto net_model = std::make_shared("NS3 network model"); - auto* engine = simgrid::kernel::EngineImpl::get_instance(); - engine->add_model(net_model); - engine->get_netzone_root()->set_network_model(net_model); + simgrid_network_models().add( + "ns-3", "Network pseudo-model using the real ns-3 simulator instead of an analytic model", []() { + auto net_model = std::make_shared("NS3 network model"); + auto* engine = simgrid::kernel::EngineImpl::get_instance(); + engine->add_model(net_model); + engine->get_netzone_root()->set_network_model(net_model); + }); } -static simgrid::config::Flag - ns3_tcp_model("ns3/TcpModel", "The ns-3 tcp model can be: NewReno or Reno or Tahoe", "default"); +static simgrid::config::Flag ns3_network_model_name("ns3/NetworkModel", {"ns3/TcpModel"}, + "The ns-3 tcp model can be: NewReno or Cubic", + "default", [](const std::string&) {}); static simgrid::config::Flag ns3_seed( "ns3/seed", "The random seed provided to ns-3. Either 'time' to seed with time(), blank to not set (default), or a number.", "", @@ -316,20 +317,34 @@ NetworkNS3Model::NetworkNS3Model(const std::string& name) : NetworkModel(name) "LinkEnergy plugin and ns-3 network models are not compatible. Are you looking for Ecofen, maybe?"); NetPointNs3::EXTENSION_ID = routing::NetPoint::extension_create(); + auto const& NetworkProtocol = ns3_network_model_name.get(); + + if (NetworkProtocol == "UDP") { + /*UdpClient=0 +UdpEchoClientApplication=0 +UdpEchoServerApplication=0 +UdpL4Protocol=0 +UdpServer=0 +UdpSocket=0 +UdpSocketImpl=0 +UdpTraceClient=0*/ + LogComponentEnable("UdpSocket", ns3::LOG_LEVEL_DEBUG); + LogComponentEnable("UdpL4Protocol", ns3::LOG_LEVEL_DEBUG); + } else { + ns3::Config::SetDefault("ns3::TcpSocket::SegmentSize", ns3::UintegerValue(1000)); + ns3::Config::SetDefault("ns3::TcpSocket::DelAckCount", ns3::UintegerValue(1)); + ns3::Config::SetDefault("ns3::TcpSocketBase::Timestamp", ns3::BooleanValue(false)); + } - ns3::Config::SetDefault("ns3::TcpSocket::SegmentSize", ns3::UintegerValue(1000)); - ns3::Config::SetDefault("ns3::TcpSocket::DelAckCount", ns3::UintegerValue(1)); - ns3::Config::SetDefault("ns3::TcpSocketBase::Timestamp", ns3::BooleanValue(false)); - - if (auto const& TcpProtocol = ns3_tcp_model.get(); TcpProtocol == "default") { - /* nothing to do */ + if (NetworkProtocol == "NewReno" || NetworkProtocol == "Cubic") { + XBT_INFO("Switching Tcp protocol to '%s'", NetworkProtocol.c_str()); + ns3::Config::SetDefault("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::Tcp" + NetworkProtocol)); - } else if (TcpProtocol == "Reno" || TcpProtocol == "NewReno" || TcpProtocol == "Tahoe") { - XBT_INFO("Switching Tcp protocol to '%s'", TcpProtocol.c_str()); - ns3::Config::SetDefault("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::Tcp" + TcpProtocol)); + } else if (NetworkProtocol == "UDP") { + XBT_INFO("Switching network protocol to UDP."); - } else { - xbt_die("The ns3/TcpModel must be: NewReno or Reno or Tahoe"); + } else if (NetworkProtocol != "default") { + xbt_die("The ns3/NetworkModel must be: NewReno, Cubic or UDP but it's '%s'", NetworkProtocol.c_str()); } routing::NetPoint::on_creation.connect([](routing::NetPoint& pt) { @@ -339,7 +354,6 @@ NetworkNS3Model::NetworkNS3Model(const std::string& name) : NetworkModel(name) s4u::Engine::on_platform_created_cb([]() { /* Create the ns3 topology based on routing strategy */ - ns3::GlobalRouteManager::DeleteGlobalRoutes(); // just in case this callback is called twice ns3::GlobalRouteManager::BuildGlobalRoutingDatabase(); ns3::GlobalRouteManager::InitializeRoutes(); }); @@ -368,7 +382,7 @@ StandardLinkImpl* NetworkNS3Model::create_wifi_link(const std::string& name, con return link; } -Action* NetworkNS3Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) +Action* NetworkNS3Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool /*streamed*/) { xbt_assert(rate == -1, "Communication over ns-3 links cannot specify a specific rate. Please use -1 as a value instead of %f.", @@ -376,6 +390,31 @@ Action* NetworkNS3Model::communicate(s4u::Host* src, s4u::Host* dst, double size return new NetworkNS3Action(this, size, src, dst); } +#if SIMGRID_HAVE_NS3_GetNextEventTime +/* If patched, ns3 is idempotent and nice to use */ +bool NetworkNS3Model::next_occurring_event_is_idempotent() +{ + return true; +} + +double NetworkNS3Model::next_occurring_event(double sg_time) +{ + if (get_started_action_set()->empty()) { + return -1.0; + } + + double ns3_time = ns3::Simulator::GetNextEventTime().GetSeconds(); + XBT_DEBUG("NS3 tells that the next occuring event is at %f (it's %f in SimGrid), so NS3 returns a delta of %f.", + ns3_time, sg_time, ns3_time - sg_time); + return ns3_time - sg_time; +} +#else +/* NS3 is only idempotent with the appropriate patch */ +bool NetworkNS3Model::next_occurring_event_is_idempotent() +{ + return false; +} + double NetworkNS3Model::next_occurring_event(double now) { double time_to_next_flow_completion = 0.0; @@ -395,21 +434,35 @@ double NetworkNS3Model::next_occurring_event(double now) // NS-3 stops as soon as a flow ends, // but it does not process the other flows that may finish at the same (simulated) time. // If another flow ends at the same time, time_to_next_flow_completion = 0 - if (double_equals(time_to_next_flow_completion, 0, sg_surf_precision)) + if (double_equals(time_to_next_flow_completion, 0, sg_precision_timing)) time_to_next_flow_completion = 0.0; - XBT_DEBUG("min : %f", now); - XBT_DEBUG("ns3 time : %f", ns3::Simulator::Now().GetSeconds()); - XBT_DEBUG("surf time : %f", EngineImpl::get_clock()); + XBT_DEBUG("min : %f", now); + XBT_DEBUG("ns-3 time : %f", ns3::Simulator::Now().GetSeconds()); + XBT_DEBUG("simgrid time: %f", EngineImpl::get_clock()); XBT_DEBUG("Next completion %f :", time_to_next_flow_completion); return time_to_next_flow_completion; } +#endif void NetworkNS3Model::update_actions_state(double now, double delta) { static std::vector socket_to_destroy; +#if SIMGRID_HAVE_NS3_GetNextEventTime + /* If the ns-3 model is idempotent, it won't get updated in next_occurring_event() */ + + if (delta >= 0) { + XBT_DEBUG("DO START simulator delta: %f (current simgrid time: %f; current ns3 time: %f)", delta, + simgrid::kernel::EngineImpl::get_clock(), ns3::Simulator::Now().GetSeconds()); + ns3_simulator(delta); + } else { + XBT_DEBUG("don't start simulator delta: %f (current simgrid time: %f; current ns3 time: %f)", delta, + simgrid::kernel::EngineImpl::get_clock(), ns3::Simulator::Now().GetSeconds()); + } +#endif + for (const auto& [ns3_socket, sgFlow] : flow_from_sock) { NetworkNS3Action* action = sgFlow->action_; XBT_DEBUG("Processing flow %p (socket %s, action %p)", sgFlow, ns3_socket.c_str(), action); @@ -426,7 +479,7 @@ void NetworkNS3Model::update_actions_state(double now, double delta) std::vector route; action->get_src().route_to(&action->get_dst(), route, nullptr); - for (auto const& link : route) + for (auto const* link : route) instr::resource_set_utilization("LINK", "bandwidth_used", link->get_cname(), action->get_category(), data_delta_sent / delta, now - delta, delta); @@ -454,7 +507,6 @@ void NetworkNS3Model::update_actions_state(double now, double delta) } delete flow; flow_from_sock.erase(ns3_socket); - sink_from_sock.erase(ns3_socket); } } @@ -505,7 +557,7 @@ NetworkNS3Action::NetworkNS3Action(Model* model, double totalBytes, s4u::Host* s if (src == dst) { if (static bool warned = false; not warned) { XBT_WARN("Sending from a host %s to itself is not supported by ns-3. Every such communication finishes " - "immediately upon startup.", + "immediately upon startup in the SimGrid+ns-3 system.", src->get_cname()); warned = true; } @@ -515,7 +567,7 @@ NetworkNS3Action::NetworkNS3Action(Model* model, double totalBytes, s4u::Host* s // If there is no other started actions, we need to move NS-3 forward to be sync with SimGrid if (model->get_started_action_set()->size() == 1) { - while (double_positive(EngineImpl::get_clock() - ns3::Simulator::Now().GetSeconds(), sg_surf_precision)) { + while (double_positive(EngineImpl::get_clock() - ns3::Simulator::Now().GetSeconds(), sg_precision_timing)) { XBT_DEBUG("Synchronizing NS-3 (time %f) with SimGrid (time %f)", ns3::Simulator::Now().GetSeconds(), EngineImpl::get_clock()); ns3_simulator(EngineImpl::get_clock() - ns3::Simulator::Now().GetSeconds()); @@ -532,17 +584,18 @@ NetworkNS3Action::NetworkNS3Action(Model* model, double totalBytes, s4u::Host* s dst->get_netpoint()->get_cname()); ns3::PacketSinkHelper sink("ns3::TcpSocketFactory", ns3::InetSocketAddress(ns3::Ipv4Address::GetAny(), port_number)); - ns3::ApplicationContainer apps = sink.Install(dst_node); + sink.Install(dst_node); ns3::Ptr sock = ns3::Socket::CreateSocket(src_node, ns3::TcpSocketFactory::GetTypeId()); - XBT_DEBUG("Create socket %s for a flow of %.0f Bytes from %s to %s with Interface %s", - transform_socket_ptr(sock).c_str(), totalBytes, src->get_cname(), dst->get_cname(), addr.c_str()); + auto sock_addr = transform_socket_ptr(sock); + XBT_DEBUG("Create socket %s for a flow of %.0f Bytes from %s to %s with Interface %s", sock_addr.c_str(), totalBytes, + src->get_cname(), dst->get_cname(), addr.c_str()); - flow_from_sock.try_emplace(transform_socket_ptr(sock), new SgFlow(static_cast(totalBytes), this)); - sink_from_sock.try_emplace(transform_socket_ptr(sock), apps); + flow_from_sock.try_emplace(sock_addr, new SgFlow(static_cast(totalBytes), this)); sock->Bind(ns3::InetSocketAddress(port_number)); + ns3::Simulator::ScheduleNow(&start_flow, sock, addr.c_str(), port_number); port_number = 1 + (port_number % UINT16_MAX); @@ -573,22 +626,27 @@ void NetworkNS3Action::update_remains_lazy(double /*now*/) ns3::Ptr get_ns3node_from_sghost(const simgrid::s4u::Host* host) { - xbt_assert(host->get_netpoint()->extension() != nullptr, "Please only use this function on ns-3 nodes"); - return host->get_netpoint()->extension()->ns3_node_; + auto* netext = host->get_netpoint()->extension(); + xbt_assert(netext != nullptr, "Please only use this function on ns-3 nodes"); + return netext->ns3_node_; } } // namespace simgrid -void ns3_simulator(double maxSeconds) +void ns3_simulator(double maxSeconds) // maxSecond is a delay, not an absolute time { ns3::EventId id; - if (maxSeconds > 0.0) // If there is a maximum amount of time to run + if (maxSeconds >= 0.0) // If there is a maximum amount of time to run id = ns3::Simulator::Schedule(ns3::Seconds(maxSeconds), &ns3::Simulator::Stop); - XBT_DEBUG("Start simulator for at most %fs (current time: %f)", maxSeconds, simgrid::kernel::EngineImpl::get_clock()); + XBT_DEBUG("Start simulator for at most %fs (current simgrid time: %f; current ns3 time: %f)", maxSeconds, + simgrid::kernel::EngineImpl::get_clock(), ns3::Simulator::Now().GetSeconds()); +#if SIMGRID_HAVE_NS3_GetNextEventTime + xbt_assert(maxSeconds >= 0.0); +#endif ns3::Simulator::Run(); - XBT_DEBUG("Simulator stopped at %fs", ns3::Simulator::Now().GetSeconds()); + XBT_DEBUG("ns3 simulator stopped at %fs", ns3::Simulator::Now().GetSeconds()); - if (maxSeconds > 0.0) + if (maxSeconds >= 0.0) id.Cancel(); } diff --git a/src/surf/network_ns3.hpp b/src/kernel/resource/models/network_ns3.hpp similarity index 90% rename from src/surf/network_ns3.hpp rename to src/kernel/resource/models/network_ns3.hpp index a0328a27f4..f68c1f5999 100644 --- a/src/surf/network_ns3.hpp +++ b/src/kernel/resource/models/network_ns3.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,11 +7,12 @@ #define NETWORK_NS3_HPP_ #include "xbt/base.h" +#include "xbt/ex.h" #include "src/kernel/resource/NetworkModel.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" -namespace simgrid ::kernel::resource { +namespace simgrid::kernel::resource { class NetworkNS3Model : public NetworkModel { public: @@ -19,9 +20,9 @@ public: ~NetworkNS3Model() override; StandardLinkImpl* create_link(const std::string& name, const std::vector& bandwidth) override; StandardLinkImpl* create_wifi_link(const std::string& name, const std::vector& bandwidth) override; - Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) override; + Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool streamed) override; double next_occurring_event(double now) override; - bool next_occurring_event_is_idempotent() override { return false; } + bool next_occurring_event_is_idempotent() override; void update_actions_state(double now, double delta) override; }; diff --git a/src/surf/ns3/ns3_simulator.cpp b/src/kernel/resource/models/ns3/ns3_simulator.cpp similarity index 77% rename from src/surf/ns3/ns3_simulator.cpp rename to src/kernel/resource/models/ns3/ns3_simulator.cpp index db27ef5b6a..bbc62068f4 100644 --- a/src/surf/ns3/ns3_simulator.cpp +++ b/src/kernel/resource/models/ns3/ns3_simulator.cpp @@ -1,46 +1,35 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "src/surf/ns3/ns3_simulator.hpp" +#include "src/kernel/resource/models/ns3/ns3_simulator.hpp" + #include "xbt/log.h" #include "xbt/sysdep.h" -#include -#include #include -#include #include +#include #include +#include +#include #include -std::map> flow_from_sock; // ns3::sock -> SgFlow -std::map> sink_from_sock; // ns3::sock -> ns3::PacketSink +std::map> flow_from_sock; // ns3::sock -> SgFlow static void receive_callback(ns3::Ptr socket); static void datasent_cb(ns3::Ptr socket, uint32_t dataSent); XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_ns3); -SgFlow::SgFlow(uint32_t totalBytes, simgrid::kernel::resource::NetworkNS3Action* action) - : total_bytes_(totalBytes), remaining_(totalBytes), action_(action) -{ -} - static SgFlow* getFlowFromSocket(ns3::Ptr socket) { auto it = flow_from_sock.find(transform_socket_ptr(socket)); return (it == flow_from_sock.end()) ? nullptr : it->second; } -static ns3::ApplicationContainer* getSinkFromSocket(ns3::Ptr socket) -{ - auto it = sink_from_sock.find(transform_socket_ptr(socket)); - return (it == sink_from_sock.end()) ? nullptr : &(it->second); -} - static void receive_callback(ns3::Ptr socket) { SgFlow* flow = getFlowFromSocket(socket); @@ -57,7 +46,6 @@ static void receive_callback(ns3::Ptr socket) static void send_cb(ns3::Ptr sock, uint32_t /*txSpace*/) { SgFlow* flow = getFlowFromSocket(sock); - const ns3::ApplicationContainer* sink = getSinkFromSocket(sock); XBT_DEBUG("Asked to write on F[%p, total: %u, remain: %u]", flow, flow->total_bytes_, flow->remaining_); if (flow->remaining_ == 0) // all data was already buffered (and socket was already closed) @@ -83,16 +71,8 @@ static void send_cb(ns3::Ptr sock, uint32_t /*txSpace*/) flow->remaining_); } - if (flow->buffered_bytes_ >= flow->total_bytes_){ - XBT_DEBUG("Closing Sockets of flow %p", flow); - // Closing the sockets of the receiving application - ns3::Ptr app = ns3::DynamicCast(sink->Get(0)); - ns3::Ptr listening_sock = app->GetListeningSocket(); - listening_sock->Close(); - listening_sock->SetRecvCallback(ns3::MakeNullCallback>()); - for(ns3::Ptr accepted_sock : app->GetAcceptedSockets()) - accepted_sock->Close(); - // Closing the socket of the sender + if (flow->buffered_bytes_ >= flow->total_bytes_) { + XBT_DEBUG("Closing sender's socket of flow %p", flow); sock->Close(); } } @@ -140,10 +120,11 @@ XBT_ATTRIB_NORETURN static void failedConnect_callback(ns3::Ptr soc void start_flow(ns3::Ptr sock, const char* to, uint16_t port_number) { SgFlow* flow = getFlowFromSocket(sock); - ns3::InetSocketAddress serverAddr(to, port_number); + ns3::InetSocketAddress serverAddr(to, port_number); sock->Connect(serverAddr); - // tell the tcp implementation to call send_cb again + + // tell the network implementation to call send_cb again // if we blocked and new tx buffer space becomes available sock->SetSendCallback(MakeCallback(&send_cb)); // Notice when we actually sent some data (mostly for the TRACING module) diff --git a/src/surf/ns3/ns3_simulator.hpp b/src/kernel/resource/models/ns3/ns3_simulator.hpp similarity index 80% rename from src/surf/ns3/ns3_simulator.hpp rename to src/kernel/resource/models/ns3/ns3_simulator.hpp index f4cd203afa..d7e35a43a7 100644 --- a/src/surf/ns3/ns3_simulator.hpp +++ b/src/kernel/resource/models/ns3/ns3_simulator.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,11 +7,12 @@ #define NS3_SIMULATOR_HPP #include "simgrid/s4u/Host.hpp" -#include "src/surf/network_ns3.hpp" +#include "src/kernel/resource/models/network_ns3.hpp" -#include "ns3/wifi-module.h" #include #include +#include +#include #include @@ -31,7 +32,10 @@ XBT_PRIVATE void ns3_add_direct_route(const simgrid::kernel::routing::NetPoint* class XBT_PRIVATE SgFlow { public: - SgFlow(uint32_t total_bytes, simgrid::kernel::resource::NetworkNS3Action* action); + SgFlow(uint32_t totalBytes, simgrid::kernel::resource::NetworkNS3Action* action) + : total_bytes_(totalBytes), remaining_(totalBytes), action_(action) + { + } // private: std::uint32_t buffered_bytes_ = 0; diff --git a/src/surf/ptask_L07.cpp b/src/kernel/resource/models/ptask_L07.cpp similarity index 87% rename from src/surf/ptask_L07.cpp rename to src/kernel/resource/models/ptask_L07.cpp index 209639d8d1..13f4986b7d 100644 --- a/src/surf/ptask_L07.cpp +++ b/src/kernel/resource/models/ptask_L07.cpp @@ -1,19 +1,22 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include #include +#include #include #include "simgrid/config.h" #include "src/kernel/EngineImpl.hpp" +#include "src/simgrid/math_utils.h" +#include "src/simgrid/module.hpp" #if SIMGRID_HAVE_EIGEN3 #include "src/kernel/lmm/bmf.hpp" #endif +#include "src/kernel/resource/models/ptask_L07.hpp" #include "src/kernel/resource/profile/Event.hpp" -#include "src/surf/ptask_L07.hpp" #include @@ -31,17 +34,20 @@ static simgrid::config::Flag cfg_ptask_solver("host/solver", /**************************************/ /*** Resource Creation & Destruction **/ /**************************************/ -void surf_host_model_init_ptask_L07() -{ - XBT_CINFO(xbt_cfg, "Switching to the L07 model to handle parallel tasks."); - xbt_assert(cfg_ptask_solver != "maxmin", "Invalid configuration. Cannot use maxmin solver with parallel tasks."); - - auto* system = simgrid::kernel::lmm::System::build(cfg_ptask_solver, true /* selective update */); - auto host_model = std::make_shared("Host_Ptask", system); - auto* engine = simgrid::kernel::EngineImpl::get_instance(); - engine->add_model(host_model); - engine->get_netzone_root()->set_host_model(host_model); -} +SIMGRID_REGISTER_HOST_MODEL( + ptask_L07, "Host model somehow similar to Cas01+CM02+S19 but allowing parallel tasks", []() { + XBT_CINFO(xbt_cfg, "Switching to the L07 model to handle parallel tasks."); + xbt_assert(cfg_ptask_solver != "maxmin", "Invalid configuration. Cannot use maxmin solver with parallel tasks."); + + xbt_assert(simgrid::config::is_default("network/model") && simgrid::config::is_default("cpu/model"), + "Changing the network or CPU model is not allowed when using the ptasks host model."); + + auto* system = simgrid::kernel::lmm::System::build(cfg_ptask_solver.get(), true /* selective update */); + auto host_model = std::make_shared("Host_Ptask", system); + auto* engine = simgrid::kernel::EngineImpl::get_instance(); + engine->add_model(host_model); + engine->get_netzone_root()->set_host_model(host_model); + }); namespace simgrid::kernel::resource { @@ -50,13 +56,15 @@ HostL07Model::HostL07Model(const std::string& name, lmm::System* sys) : HostMode set_maxmin_system(sys); auto net_model = std::make_shared("Network_Ptask", this, sys); - auto engine = EngineImpl::get_instance(); + auto* engine = EngineImpl::get_instance(); engine->add_model(net_model); engine->get_netzone_root()->set_network_model(net_model); auto cpu_model = std::make_shared("Cpu_Ptask", this, sys); engine->add_model(cpu_model); engine->get_netzone_root()->set_cpu_pm_model(cpu_model); + + simgrid_disk_models().by_name("S19").init(); } CpuL07Model::CpuL07Model(const std::string& name, HostL07Model* hmodel, lmm::System* sys) @@ -107,7 +115,7 @@ void HostL07Model::update_actions_state(double /*now*/, double delta) ++it; // increment iterator here since the following calls to action.finish() may invalidate it if (action.get_latency() > 0) { if (action.get_latency() > delta) { - action.update_latency(delta, sg_surf_precision); + action.update_latency(delta, sg_precision_timing); } else { action.set_latency(0.0); } @@ -136,8 +144,8 @@ void HostL07Model::update_actions_state(double /*now*/, double delta) } /* Need to check that none of the model has failed */ - int i = 0; - const lmm::Constraint* cnst = action.get_variable()->get_constraint(i); + int i = 0; + const lmm::Constraint* cnst = action.get_variable()->get_constraint(i); while (cnst != nullptr) { i++; if (not cnst->get_id()->is_on()) { @@ -186,7 +194,7 @@ L07Action::L07Action(Model* model, const std::vector& host_list, con host_list_[k / host_nb]->route_to(host_list_[k % host_nb], route, &lat); latency = std::max(latency, lat); - for (auto const& link : route) + for (auto const* link : route) affected_links.insert(link->get_cname()); } @@ -196,7 +204,8 @@ L07Action::L07Action(Model* model, const std::vector& host_list, con XBT_DEBUG("Creating a parallel task (%p) with %zu hosts and %zu unique links.", this, host_nb, link_nb); latency_ = latency; - set_variable(model->get_maxmin_system()->variable_new(this, 1.0, (rate > 0 ? rate : -1.0), host_nb + link_nb)); + // Allocate more space for constraints (+4) in case users want to mix ptasks and io streams + set_variable(model->get_maxmin_system()->variable_new(this, 1.0, (rate > 0 ? rate : -1.0), host_nb + link_nb + 4)); if (latency_ > 0) model->get_maxmin_system()->update_variable_penalty(get_variable(), 0.0); @@ -205,7 +214,7 @@ L07Action::L07Action(Model* model, const std::vector& host_list, con * communication either */ for (size_t i = 0; i < host_nb; i++) { model->get_maxmin_system()->expand(host_list[i]->get_cpu()->get_constraint(), get_variable(), - (flops_amount == nullptr ? 0.0 : flops_amount[i])); + (flops_amount == nullptr ? 0.0 : flops_amount[i]), true); } if (bytes_amount != nullptr) { @@ -215,7 +224,7 @@ L07Action::L07Action(Model* model, const std::vector& host_list, con std::vector route; host_list_[k / host_nb]->route_to(host_list_[k % host_nb], route, nullptr); - for (auto const& link : route) + for (auto const* link : route) model->get_maxmin_system()->expand(link->get_constraint(), this->get_variable(), bytes_amount[k]); } } @@ -228,7 +237,7 @@ L07Action::L07Action(Model* model, const std::vector& host_list, con update_bound(); } -Action* NetworkL07Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) +Action* NetworkL07Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool /* streamed */) { std::vector host_list = {src, dst}; const auto* flops_amount = new double[2](); @@ -249,7 +258,7 @@ CpuImpl* CpuL07Model::create_cpu(s4u::Host* host, const std::vector& spe StandardLinkImpl* NetworkL07Model::create_link(const std::string& name, const std::vector& bandwidths) { xbt_assert(bandwidths.size() == 1, "Non WIFI link must have only 1 bandwidth."); - auto link = new LinkL07(name, bandwidths[0], get_maxmin_system()); + auto* link = new LinkL07(name, bandwidths[0], get_maxmin_system()); link->set_model(this); return link; } @@ -292,7 +301,8 @@ void CpuL07::on_speed_change() { const lmm::Element* elem = nullptr; - get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(), get_core_count() * speed_.peak * speed_.scale); + get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(), + get_core_count() * speed_.peak * speed_.scale); while (const auto* var = get_constraint()->get_variable(&elem)) { const auto* action = static_cast(var->get_id()); diff --git a/src/surf/ptask_L07.hpp b/src/kernel/resource/models/ptask_L07.hpp similarity index 91% rename from src/surf/ptask_L07.hpp rename to src/kernel/resource/models/ptask_L07.hpp index 68fc050684..0683aff609 100644 --- a/src/surf/ptask_L07.hpp +++ b/src/kernel/resource/models/ptask_L07.hpp @@ -1,17 +1,18 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#ifndef HOST_L07_HPP_ +#define HOST_L07_HPP_ + +#include "src/kernel/resource/HostImpl.hpp" #include "src/kernel/resource/NetworkModel.hpp" -#include "src/surf/HostImpl.hpp" +#include "src/simgrid/math_utils.h" #include #include #include -#ifndef HOST_L07_HPP_ -#define HOST_L07_HPP_ - namespace simgrid::kernel::resource { /*********** @@ -33,7 +34,7 @@ class XBT_PRIVATE L07Action; class HostL07Model : public HostModel { public: HostL07Model(const std::string& name, lmm::System* sys); - HostL07Model(const HostL07Model&) = delete; + HostL07Model(const HostL07Model&) = delete; HostL07Model& operator=(const HostL07Model&) = delete; double next_occurring_event(double now) override; @@ -46,7 +47,7 @@ public: class CpuL07Model : public CpuModel { public: CpuL07Model(const std::string& name, HostL07Model* hmodel, lmm::System* sys); - CpuL07Model(const CpuL07Model&) = delete; + CpuL07Model(const CpuL07Model&) = delete; CpuL07Model& operator=(const CpuL07Model&) = delete; ~CpuL07Model() override; void update_actions_state(double /*now*/, double /*delta*/) override{ @@ -62,13 +63,13 @@ public: class NetworkL07Model : public NetworkModel { public: NetworkL07Model(const std::string& name, HostL07Model* hmodel, lmm::System* sys); - NetworkL07Model(const NetworkL07Model&) = delete; + NetworkL07Model(const NetworkL07Model&) = delete; NetworkL07Model& operator=(const NetworkL07Model&) = delete; ~NetworkL07Model() override; StandardLinkImpl* create_link(const std::string& name, const std::vector& bandwidths) final; StandardLinkImpl* create_wifi_link(const std::string& name, const std::vector& bandwidths) override; - Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) override; + Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool streamed) override; void update_actions_state(double /*now*/, double /*delta*/) override{ /* this action is done by HostL07Model which shares the LMM system with the CPU model * Overriding to an empty function here allows us to handle the Cpu07Model as a regular @@ -85,7 +86,7 @@ public: class CpuL07 : public CpuImpl { public: using CpuImpl::CpuImpl; - CpuL07(const CpuL07&) = delete; + CpuL07(const CpuL07&) = delete; CpuL07& operator=(const CpuL07&) = delete; void apply_event(profile::Event* event, double value) override; @@ -104,7 +105,7 @@ protected: class LinkL07 : public StandardLinkImpl { public: LinkL07(const std::string& name, double bandwidth, lmm::System* system); - LinkL07(const LinkL07&) = delete; + LinkL07(const LinkL07&) = delete; LinkL07& operator=(const LinkL07&) = delete; ~LinkL07() override; void apply_event(profile::Event* event, double value) override; @@ -130,7 +131,7 @@ class L07Action : public CpuAction { friend CpuAction* CpuL07::sleep(double duration); friend CpuAction* HostL07Model::execute_parallel(const std::vector& host_list, const double* flops_amount, const double* bytes_amount, double rate); - friend Action* NetworkL07Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate); + friend Action* NetworkL07Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool streamed); /** * @brief Calculate the CPU bound for the parallel task * @@ -151,7 +152,7 @@ public: L07Action() = delete; L07Action(Model* model, const std::vector& host_list, const double* flops_amount, const double* bytes_amount, double rate); - L07Action(const L07Action&) = delete; + L07Action(const L07Action&) = delete; L07Action& operator=(const L07Action&) = delete; ~L07Action() override; diff --git a/src/kernel/resource/profile/Event.hpp b/src/kernel/resource/profile/Event.hpp index 62111e95c5..c1d92395fd 100644 --- a/src/kernel/resource/profile/Event.hpp +++ b/src/kernel/resource/profile/Event.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/kernel/resource/profile/FutureEvtSet.cpp b/src/kernel/resource/profile/FutureEvtSet.cpp index dae5708840..34b4071786 100644 --- a/src/kernel/resource/profile/FutureEvtSet.cpp +++ b/src/kernel/resource/profile/FutureEvtSet.cpp @@ -1,11 +1,13 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/resource/profile/FutureEvtSet.hpp" +#include "src/kernel/resource/Resource.hpp" #include "src/kernel/resource/profile/Event.hpp" #include "src/kernel/resource/profile/Profile.hpp" +#include namespace simgrid::kernel::profile { @@ -23,6 +25,23 @@ FutureEvtSet::~FutureEvtSet() /** @brief Schedules an event to a future date */ void FutureEvtSet::add_event(double date, Event* evt) { + if (heap_.empty()) + s4u::Engine::on_platform_created_cb([this]() { + /* Handle the events of time = 0 right after the platform creation */ + double next_event_date; + while ((next_event_date = this->next_date()) != -1.0) { + if (next_event_date > 0) + break; + + double value = -1.0; + resource::Resource* resource = nullptr; + while (auto* event = this->pop_leq(next_event_date, &value, &resource)) { + if (value >= 0) + resource->apply_event(event, value); + } + } + }); + heap_.emplace(date, evt); } diff --git a/src/kernel/resource/profile/FutureEvtSet.hpp b/src/kernel/resource/profile/FutureEvtSet.hpp index a26afc6119..535325d146 100644 --- a/src/kernel/resource/profile/FutureEvtSet.hpp +++ b/src/kernel/resource/profile/FutureEvtSet.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/kernel/resource/profile/Profile.cpp b/src/kernel/resource/profile/Profile.cpp index 28ec0c7d41..e0f472214e 100644 --- a/src/kernel/resource/profile/Profile.cpp +++ b/src/kernel/resource/profile/Profile.cpp @@ -1,14 +1,13 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/resource/profile/Profile.hpp" -#include "xbt/asserts.h" #include "src/kernel/resource/profile/Event.hpp" #include "src/kernel/resource/profile/FutureEvtSet.hpp" #include "src/kernel/resource/profile/StochasticDatedValue.hpp" -#include "src/surf/surf_interface.hpp" +#include "xbt/asserts.h" #include #include diff --git a/src/kernel/resource/profile/Profile.hpp b/src/kernel/resource/profile/Profile.hpp index 2cc4e3732a..1876a959d7 100644 --- a/src/kernel/resource/profile/Profile.hpp +++ b/src/kernel/resource/profile/Profile.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/kernel/resource/profile/ProfileBuilder.cpp b/src/kernel/resource/profile/ProfileBuilder.cpp index 038a0ea251..83c587d5c3 100644 --- a/src/kernel/resource/profile/ProfileBuilder.cpp +++ b/src/kernel/resource/profile/ProfileBuilder.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,12 +7,14 @@ #include "simgrid/forward.h" #include "src/kernel/resource/profile/Profile.hpp" #include "src/kernel/resource/profile/StochasticDatedValue.hpp" -#include "src/surf/surf_interface.hpp" +#include "xbt/asserts.h" +#include "xbt/file.hpp" #include #include #include #include +#include #include #include @@ -222,23 +224,24 @@ Profile* ProfileBuilder::from_string(const std::string& name, const std::string& return new Profile(name,cb,cb.get_repeat_delay()); } -Profile* ProfileBuilder::from_file(const std::string& path) +Profile* ProfileBuilder::from_file(const std::string& filename) { - xbt_assert(not path.empty(), "Cannot parse a trace from an empty filename"); - auto f = std::unique_ptr(surf_ifsopen(path)); - xbt_assert(not f->fail(), "Cannot open file '%s' (path=%s)", path.c_str(), (boost::join(surf_path, ":")).c_str()); + xbt_assert(not filename.empty(), "Cannot parse a trace from an empty filename"); + auto f = std::unique_ptr(simgrid::xbt::path_ifsopen(filename)); + xbt_assert(not f->fail(), "Cannot open file '%s' (path=%s)", filename.c_str(), + simgrid::xbt::path_to_string().c_str()); std::stringstream buffer; buffer << f->rdbuf(); LegacyUpdateCb cb(buffer.str(), -1); - return new Profile(path,cb,cb.get_repeat_delay()); + return new Profile(filename, cb, cb.get_repeat_delay()); } Profile* ProfileBuilder::from_void() { - static Profile void_profile("__void__", nullptr, -1.0); - return &void_profile; + static auto* void_profile = new Profile("__void__", nullptr, -1.0); + return void_profile; } Profile* ProfileBuilder::from_callback(const std::string& name, const std::function& cb, double repeat_delay) { diff --git a/src/kernel/resource/profile/Profile_test.cpp b/src/kernel/resource/profile/Profile_test.cpp index abcee5aa2e..97ff0ab71d 100644 --- a/src/kernel/resource/profile/Profile_test.cpp +++ b/src/kernel/resource/profile/Profile_test.cpp @@ -1,15 +1,14 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch.hpp" +#include "src/3rd-party/catch.hpp" +#include "simgrid/kernel/ProfileBuilder.hpp" #include "src/kernel/resource/Resource.hpp" #include "src/kernel/resource/profile/Event.hpp" -#include "simgrid/kernel/ProfileBuilder.hpp" #include "src/kernel/resource/profile/StochasticDatedValue.hpp" -#include "src/surf/surf_interface.hpp" #include "xbt/log.h" #include "xbt/misc.h" @@ -45,7 +44,7 @@ static std::vector trace2vector(const char MockedResource daResource; simgrid::kernel::profile::FutureEvtSet fes; - simgrid::kernel::profile::Event* insertedIt = trace->schedule(&fes, &daResource); + const simgrid::kernel::profile::Event* insertedIt = trace->schedule(&fes, &daResource); while (fes.next_date() <= 20.0 && fes.next_date() >= 0) { MockedResource::the_date = fes.next_date(); diff --git a/src/kernel/resource/profile/StochasticDatedValue.cpp b/src/kernel/resource/profile/StochasticDatedValue.cpp index e0579e1983..c1d383ebe7 100644 --- a/src/kernel/resource/profile/StochasticDatedValue.cpp +++ b/src/kernel/resource/profile/StochasticDatedValue.cpp @@ -1,11 +1,13 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/resource/profile/StochasticDatedValue.hpp" -#include "xbt.h" + +#include "xbt/asserts.h" #include "xbt/random.hpp" + #include namespace simgrid::kernel::profile { diff --git a/src/kernel/resource/profile/StochasticDatedValue.hpp b/src/kernel/resource/profile/StochasticDatedValue.hpp index 27203b287e..aaa9978d9c 100644 --- a/src/kernel/resource/profile/StochasticDatedValue.hpp +++ b/src/kernel/resource/profile/StochasticDatedValue.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/kernel/routing/ClusterZone.cpp b/src/kernel/routing/ClusterZone.cpp index df83652863..fa82dd48d0 100644 --- a/src/kernel/routing/ClusterZone.cpp +++ b/src/kernel/routing/ClusterZone.cpp @@ -1,13 +1,14 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "simgrid/s4u/Host.hpp" #include "simgrid/kernel/routing/ClusterZone.hpp" #include "simgrid/kernel/routing/NetPoint.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_cluster, ker_routing, "Kernel Cluster Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_cluster, ker_platform, "Kernel Cluster Routing"); /* This routing is specifically setup to represent clusters, aka homogeneous sets of machines * Note that a router is created, easing the interconnection with the rest of the world. */ @@ -70,9 +71,8 @@ void ClusterBase::fill_leaf_from_cb(unsigned long position, const std::vector dims_array(dimensions.size()); for (auto i = static_cast(dimensions.size() - 1); i >= 0; --i) { - if (index <= 0) { + if (index == 0) break; - } unsigned long value = index % dimensions[i]; dims_array[i] = value; index = (index / dimensions[i]); @@ -83,7 +83,17 @@ void ClusterBase::fill_leaf_from_cb(unsigned long position, const std::vectorget_netpoint(); + gw = netzone->get_gateway(); + } else { + s4u::Host* host = set_callbacks.host(get_iface(), dims, position); + netpoint = host->get_netpoint(); + } + xbt_assert(netpoint, "set_netpoint(elem=%lu): Invalid netpoint (nullptr)", position); if (netpoint->is_netzone()) { xbt_assert(gw && not gw->is_netzone(), diff --git a/src/kernel/routing/DijkstraZone.cpp b/src/kernel/routing/DijkstraZone.cpp index 03fdcbf78b..216961020d 100644 --- a/src/kernel/routing/DijkstraZone.cpp +++ b/src/kernel/routing/DijkstraZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,7 +13,7 @@ #include #include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_dijkstra, ker_routing, "Kernel Dijkstra Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_dijkstra, ker_platform, "Kernel Dijkstra Routing"); namespace simgrid { namespace kernel::routing { diff --git a/src/kernel/routing/DijkstraZone_test.cpp b/src/kernel/routing/DijkstraZone_test.cpp index e741e85627..9a1c89a0de 100644 --- a/src/kernel/routing/DijkstraZone_test.cpp +++ b/src/kernel/routing/DijkstraZone_test.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch.hpp" +#include "src/3rd-party/catch.hpp" #include "simgrid/kernel/routing/DijkstraZone.hpp" #include "simgrid/kernel/routing/NetPoint.hpp" @@ -30,7 +30,6 @@ TEST_CASE("kernel::routing::DijkstraZone: mix new routes and hosts", "") for (int i = 0; i < 10; i++) { std::string cpu_name = "CPU" + std::to_string(i); const simgrid::s4u::Host* cpu = zone->create_host(cpu_name, 1e9)->seal(); - REQUIRE_NOTHROW(zone->add_route(cpu->get_netpoint(), nic->get_netpoint(), nullptr, nullptr, - {simgrid::s4u::LinkInRoute(link)}, true)); + REQUIRE_NOTHROW(zone->add_route(cpu, nic,{link})); } } diff --git a/src/kernel/routing/DragonflyZone.cpp b/src/kernel/routing/DragonflyZone.cpp index e1370f33ac..7afec19616 100644 --- a/src/kernel/routing/DragonflyZone.cpp +++ b/src/kernel/routing/DragonflyZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,7 +12,7 @@ #include #include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_dragonfly, ker_routing, "Kernel Dragonfly Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_dragonfly, ker_platform, "Kernel Dragonfly Routing"); namespace simgrid { namespace kernel::routing { @@ -73,14 +73,14 @@ s4u::DragonflyParams DragonflyZone::parse_topo_parameters(const std::string& top try { n_groups = std::stoi(tmp[0]); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid number of groups:") + tmp[0]); + throw std::invalid_argument("Invalid number of groups:" + tmp[0]); } unsigned int n_blue; try { n_blue = std::stoi(tmp[1]); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid number of links for the blue level:") + tmp[1]); + throw std::invalid_argument("Invalid number of links for the blue level:" + tmp[1]); } // Black network : number of chassis/group, number of links between each router on the black network @@ -92,14 +92,14 @@ s4u::DragonflyParams DragonflyZone::parse_topo_parameters(const std::string& top try { n_chassis = std::stoi(tmp[0]); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid number of chassis:") + tmp[0]); + throw std::invalid_argument("Invalid number of chassis:" + tmp[0]); } unsigned int n_black; try { n_black = std::stoi(tmp[1]); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid number of links for the black level:") + tmp[1]); + throw std::invalid_argument("Invalid number of links for the black level:" + tmp[1]); } // Green network : number of blades/chassis, number of links between each router on the green network @@ -111,14 +111,14 @@ s4u::DragonflyParams DragonflyZone::parse_topo_parameters(const std::string& top try { n_routers = std::stoi(tmp[0]); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid number of routers:") + tmp[0]); + throw std::invalid_argument("Invalid number of routers:" + tmp[0]); } unsigned int n_green; try { n_green = std::stoi(tmp[1]); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid number of links for the green level:") + tmp[1]); + throw std::invalid_argument("Invalid number of links for the green level:" + tmp[1]); } // The last part of topo_parameters should be the number of nodes per blade @@ -126,7 +126,7 @@ s4u::DragonflyParams DragonflyZone::parse_topo_parameters(const std::string& top try { n_nodes = std::stoi(parameters[3]); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Last parameter is not the amount of nodes per blade:") + parameters[3]); + throw std::invalid_argument("Last parameter is not the amount of nodes per blade:" + parameters[3]); } return s4u::DragonflyParams({n_groups, n_blue}, {n_chassis, n_black}, {n_routers, n_green}, n_nodes); } diff --git a/src/kernel/routing/DragonflyZone_test.cpp b/src/kernel/routing/DragonflyZone_test.cpp index 20c4297669..b15282fd5b 100644 --- a/src/kernel/routing/DragonflyZone_test.cpp +++ b/src/kernel/routing/DragonflyZone_test.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch.hpp" +#include "src/3rd-party/catch.hpp" #include "NetZone_test.hpp" // CreateHost callback #include "simgrid/kernel/routing/DragonflyZone.hpp" diff --git a/src/kernel/routing/EmptyZone.cpp b/src/kernel/routing/EmptyZone.cpp index cc4032fb56..fc896829e6 100644 --- a/src/kernel/routing/EmptyZone.cpp +++ b/src/kernel/routing/EmptyZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,7 +9,7 @@ #include "simgrid/kernel/routing/EmptyZone.hpp" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_none, ker_routing, "Kernel No Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_none, ker_platform, "Kernel No Routing"); namespace simgrid { namespace kernel::routing { diff --git a/src/kernel/routing/FatTreeZone.cpp b/src/kernel/routing/FatTreeZone.cpp index 851b1407be..03aed92435 100644 --- a/src/kernel/routing/FatTreeZone.cpp +++ b/src/kernel/routing/FatTreeZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,7 +7,7 @@ #include #include "src/kernel/resource/NetworkModel.hpp" -#include "src/surf/xml/platf.hpp" // surf_parse_error() and surf_parse_assert() +#include "src/kernel/xml/platf.hpp" // simgrid_parse_error() and simgrid_parse_assert() #include #include @@ -17,7 +17,7 @@ #include #include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_fat_tree, ker_routing, "Kernel Fat-Tree Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_fat_tree, ker_platform, "Kernel Fat-Tree Routing"); namespace simgrid { namespace kernel::routing { @@ -77,8 +77,8 @@ void FatTreeZone::get_local_route(const NetPoint* src, const NetPoint* dst, Rout for (unsigned int i = 0; i < currentNode->level; i++) d /= this->num_parents_per_node_[i]; - int k = this->num_parents_per_node_[currentNode->level]; - d = d % k; + int k = this->num_parents_per_node_[currentNode->level] * this->num_port_lower_level_[currentNode->level]; + d = d % k; if (currentNode->limiter_link_) into->link_list_.push_back(currentNode->limiter_link_); @@ -93,7 +93,9 @@ void FatTreeZone::get_local_route(const NetPoint* src, const NetPoint* dst, Rout // Down part while (currentNode != destination) { - for (unsigned int i = 0; i < currentNode->children.size(); i++) { + //pick cable when multiple parallels + int d = source->position % this->num_port_lower_level_[currentNode->level - 1]; + for (unsigned int i = d * this->num_children_per_node_[currentNode->level - 1]; i < currentNode->children.size(); i++) { if (i % this->num_children_per_node_[currentNode->level - 1] == destination->label[currentNode->level - 1]) { add_link_latency(into->link_list_, currentNode->children[i]->down_link_, latency); @@ -230,9 +232,10 @@ void FatTreeZone::generate_switches(const s4u::ClusterCallbacks& set_callbacks) this->nodes_by_level_[0] *= this->num_children_per_node_[i]; if (this->nodes_by_level_[0] != this->nodes_.size()) { - surf_parse_error(std::string("The number of provided nodes does not fit with the wanted topology.") + - " Please check your platform description (We need " + std::to_string(this->nodes_by_level_[0]) + - "nodes, we got " + std::to_string(this->nodes_.size())); + simgrid_parse_error("The number of provided nodes does not fit with the wanted topology." + " Please check your platform description (We need " + + std::to_string(this->nodes_by_level_[0]) + "nodes, we got " + + std::to_string(this->nodes_.size())); } for (unsigned int i = 0; i < this->levels_; i++) { @@ -413,7 +416,7 @@ s4u::FatTreeParams FatTreeZone::parse_topo_parameters(const std::string& topo_pa std::vector count; boost::split(parameters, topo_parameters, boost::is_any_of(";")); - surf_parse_assert( + simgrid_parse_assert( parameters.size() == 4, "Fat trees are defined by the levels number and 3 vectors, see the documentation for more information."); @@ -421,46 +424,46 @@ s4u::FatTreeParams FatTreeZone::parse_topo_parameters(const std::string& topo_pa try { n_lev = std::stoi(parameters[0]); } catch (const std::invalid_argument&) { - surf_parse_error(std::string("First parameter is not the amount of levels: ") + parameters[0]); + simgrid_parse_error("First parameter is not the amount of levels: " + parameters[0]); } // Then, a l-sized vector standing for the children number by level boost::split(tmp, parameters[1], boost::is_any_of(",")); - surf_parse_assert(tmp.size() == n_lev, std::string("You specified ") + std::to_string(n_lev) + - " levels but the child count vector (the first one) contains " + - std::to_string(tmp.size()) + " levels."); + simgrid_parse_assert(tmp.size() == n_lev, "You specified " + std::to_string(n_lev) + + " levels but the child count vector (the first one) contains " + + std::to_string(tmp.size()) + " levels."); for (std::string const& level : tmp) { try { down.push_back(std::stoi(level)); } catch (const std::invalid_argument&) { - surf_parse_error(std::string("Invalid child count: ") + level); + simgrid_parse_error("Invalid child count: " + level); } } // Then, a l-sized vector standing for the parents number by level boost::split(tmp, parameters[2], boost::is_any_of(",")); - surf_parse_assert(tmp.size() == n_lev, std::string("You specified ") + std::to_string(n_lev) + - " levels but the parent count vector (the second one) contains " + - std::to_string(tmp.size()) + " levels."); + simgrid_parse_assert(tmp.size() == n_lev, "You specified " + std::to_string(n_lev) + + " levels but the parent count vector (the second one) contains " + + std::to_string(tmp.size()) + " levels."); for (std::string const& parent : tmp) { try { up.push_back(std::stoi(parent)); } catch (const std::invalid_argument&) { - surf_parse_error(std::string("Invalid parent count: ") + parent); + simgrid_parse_error("Invalid parent count: " + parent); } } // Finally, a l-sized vector standing for the ports number with the lower level boost::split(tmp, parameters[3], boost::is_any_of(",")); - surf_parse_assert(tmp.size() == n_lev, std::string("You specified ") + std::to_string(n_lev) + - " levels but the port count vector (the third one) contains " + - std::to_string(tmp.size()) + " levels."); + simgrid_parse_assert(tmp.size() == n_lev, "You specified " + std::to_string(n_lev) + + " levels but the port count vector (the third one) contains " + + std::to_string(tmp.size()) + " levels."); for (std::string const& port : tmp) { try { count.push_back(std::stoi(port)); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid lower level port number:") + port); + throw std::invalid_argument("Invalid lower level port number:" + port); } } return s4u::FatTreeParams(n_lev, down, up, count); diff --git a/src/kernel/routing/FatTreeZone_test.cpp b/src/kernel/routing/FatTreeZone_test.cpp index 2be4124c1b..14ad3e6d8c 100644 --- a/src/kernel/routing/FatTreeZone_test.cpp +++ b/src/kernel/routing/FatTreeZone_test.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch.hpp" +#include "src/3rd-party/catch.hpp" #include "NetZone_test.hpp" // CreateHost callback #include "simgrid/kernel/routing/FatTreeZone.hpp" diff --git a/src/kernel/routing/FloydZone.cpp b/src/kernel/routing/FloydZone.cpp index 91fc424c0b..350ce04177 100644 --- a/src/kernel/routing/FloydZone.cpp +++ b/src/kernel/routing/FloydZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,7 +11,7 @@ #include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_floyd, ker_routing, "Kernel Floyd Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_floyd, ker_platform, "Kernel Floyd Routing"); namespace simgrid { namespace kernel::routing { diff --git a/src/kernel/routing/FloydZone_test.cpp b/src/kernel/routing/FloydZone_test.cpp index 50fd93ba28..f4fbe4a7d1 100644 --- a/src/kernel/routing/FloydZone_test.cpp +++ b/src/kernel/routing/FloydZone_test.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch.hpp" +#include "src/3rd-party/catch.hpp" #include "simgrid/kernel/routing/FloydZone.hpp" #include "simgrid/kernel/routing/NetPoint.hpp" @@ -24,12 +24,11 @@ TEST_CASE("kernel::routing::FloydZone: mix new routes and hosts", "") simgrid::s4u::Engine e("test"); auto* zone = simgrid::s4u::create_floyd_zone("test"); - const simgrid::s4u::Host* nic = zone->create_host("nic", 1e9)->seal(); - const simgrid::s4u::Link* link = zone->create_link("my_link", 1e6)->seal(); + const simgrid::s4u::Host* nic = zone->create_host("nic", 1e9); + const simgrid::s4u::Link* link = zone->create_link("my_link", 1e6); for (int i = 0; i < 10; i++) { std::string cpu_name = "CPU" + std::to_string(i); - const simgrid::s4u::Host* cpu = zone->create_host(cpu_name, 1e9)->seal(); - REQUIRE_NOTHROW(zone->add_route(cpu->get_netpoint(), nic->get_netpoint(), nullptr, nullptr, - {simgrid::s4u::LinkInRoute(link)}, true)); + const simgrid::s4u::Host* cpu = zone->create_host(cpu_name, 1e9); + REQUIRE_NOTHROW(zone->add_route(cpu, nic, {link})); } } diff --git a/src/kernel/routing/FullZone.cpp b/src/kernel/routing/FullZone.cpp index 96992f6e91..1ae50c5368 100644 --- a/src/kernel/routing/FullZone.cpp +++ b/src/kernel/routing/FullZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,7 +8,7 @@ #include "src/kernel/resource/NetworkModel.hpp" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_full, ker_routing, "Kernel Full Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_full, ker_platform, "Kernel Full Routing"); namespace simgrid { namespace kernel::routing { diff --git a/src/kernel/routing/FullZone_test.cpp b/src/kernel/routing/FullZone_test.cpp index 99db3d3458..9ffcab7e97 100644 --- a/src/kernel/routing/FullZone_test.cpp +++ b/src/kernel/routing/FullZone_test.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch.hpp" +#include "src/3rd-party/catch.hpp" #include "simgrid/kernel/routing/FullZone.hpp" #include "simgrid/kernel/routing/NetPoint.hpp" @@ -24,12 +24,11 @@ TEST_CASE("kernel::routing::FullZone: mix new routes and hosts", "[bug]") simgrid::s4u::Engine e("test"); auto* zone = simgrid::s4u::create_full_zone("test"); - const simgrid::s4u::Host* nic = zone->create_host("nic", 1e9)->seal(); - const simgrid::s4u::Link* link = zone->create_link("my_link", 1e6)->seal(); + const simgrid::s4u::Host* nic = zone->create_host("nic", 1e9); + const simgrid::s4u::Link* link = zone->create_link("my_link", 1e6); for (int i = 0; i < 10; i++) { std::string cpu_name = "CPU" + std::to_string(i); - const simgrid::s4u::Host* cpu = zone->create_host(cpu_name, 1e9)->seal(); - REQUIRE_NOTHROW(zone->add_route(cpu->get_netpoint(), nic->get_netpoint(), nullptr, nullptr, - {simgrid::s4u::LinkInRoute(link)}, true)); + const simgrid::s4u::Host* cpu = zone->create_host(cpu_name, 1e9); + REQUIRE_NOTHROW(zone->add_route(cpu, nic, {link})); } } diff --git a/src/kernel/routing/NetPoint.cpp b/src/kernel/routing/NetPoint.cpp index ff705288a3..ee3d0dac83 100644 --- a/src/kernel/routing/NetPoint.cpp +++ b/src/kernel/routing/NetPoint.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,7 +9,7 @@ #include "simgrid/s4u/Host.hpp" #include "xbt/log.h" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_netpoint, ker_routing, "Kernel implementation of netpoints"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_netpoint, ker_platform, "Kernel implementation of netpoints"); namespace simgrid { diff --git a/src/kernel/routing/NetZoneImpl.cpp b/src/kernel/routing/NetZoneImpl.cpp index 18d00d930d..08df429aca 100644 --- a/src/kernel/routing/NetZoneImpl.cpp +++ b/src/kernel/routing/NetZoneImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,64 +9,22 @@ #include #include -#include "xbt/asserts.hpp" -#include "src/include/simgrid/sg_config.hpp" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/resource/CpuImpl.hpp" #include "src/kernel/resource/DiskImpl.hpp" +#include "src/kernel/resource/HostImpl.hpp" #include "src/kernel/resource/NetworkModel.hpp" #include "src/kernel/resource/SplitDuplexLinkImpl.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" #include "src/kernel/resource/VirtualMachineImpl.hpp" -#include "src/surf/HostImpl.hpp" +#include "src/simgrid/module.hpp" +#include "src/simgrid/sg_config.hpp" +#include "xbt/asserts.hpp" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing, kernel, "Kernel routing-related information"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_platform, kernel, "Kernel platform-related information"); namespace simgrid::kernel::routing { -/* Pick the right models for CPU, net and host, and call their model_init_preparse */ -static void surf_config_models_setup() -{ - std::string host_model_name = simgrid::config::get_value("host/model"); - std::string network_model_name = simgrid::config::get_value("network/model"); - std::string cpu_model_name = simgrid::config::get_value("cpu/model"); - std::string disk_model_name = simgrid::config::get_value("disk/model"); - - /* The compound host model is needed when using non-default net/cpu models */ - if ((not simgrid::config::is_default("network/model") || not simgrid::config::is_default("cpu/model")) && - simgrid::config::is_default("host/model")) { - host_model_name = "compound"; - simgrid::config::set_value("host/model", host_model_name); - } - - XBT_DEBUG("host model: %s", host_model_name.c_str()); - if (host_model_name == "compound") { - xbt_enforce(not cpu_model_name.empty(), "Set a cpu model to use with the 'compound' host model"); - xbt_enforce(not network_model_name.empty(), "Set a network model to use with the 'compound' host model"); - - const auto* cpu_model = find_model_description(surf_cpu_model_description, cpu_model_name); - cpu_model->model_init_preparse(); - - const auto* network_model = find_model_description(surf_network_model_description, network_model_name); - network_model->model_init_preparse(); - } - - XBT_DEBUG("Call host_model_init"); - const auto* host_model = find_model_description(surf_host_model_description, host_model_name); - host_model->model_init_preparse(); - - XBT_DEBUG("Call vm_model_init"); - /* ideally we should get back the pointer to CpuModel from model_init_preparse(), but this - * requires changing the declaration of surf_cpu_model_description. - * To be reviewed in the future */ - surf_vm_model_init_HL13( - simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->get_cpu_pm_model().get()); - - XBT_DEBUG("Call disk_model_init"); - const auto* disk_model = find_model_description(surf_disk_model_description, disk_model_name); - disk_model->model_init_preparse(); -} - xbt::signal const& link_list)> @@ -76,22 +34,23 @@ NetZoneImpl::NetZoneImpl(const std::string& name) : piface_(this), name_(name) { auto* engine = s4u::Engine::get_instance(); /* workaroud: first netzoneImpl will be the root netzone. - * Without globals and with current surf_*_model_description init functions, we need + * Without globals and with current model description init functions (see module.hpp), we need * the root netzone to exist when creating the models. - * This was usually done at sg_platf.cpp, during XML parsing */ + * This is usually done at sg_platf.cpp, during XML parsing */ if (not engine->get_netzone_root()) { engine->set_netzone_root(&piface_); /* root netzone set, initialize models */ simgrid::s4u::Engine::on_platform_creation(); - /* Initialize the surf models. That must be done after we got all config, and before we need the models. + /* Initialize the models. That must be done after we got all config, and before we need the models. * That is, after the last tag, if any, and before the first of cluster|peer|zone|trace|trace_cb * * I'm not sure for and , there may be a bug here * (FIXME: check it out by creating a file beginning with one of these tags) * but cluster and peer come down to zone creations, so putting this verification here is correct. */ - surf_config_models_setup(); + simgrid_host_models().init_from_flag_value(); + simgrid_vm_model_init_HL13(); } xbt_enforce(nullptr == engine->netpoint_by_name_or_null(get_name()), @@ -636,7 +595,7 @@ void NetZoneImpl::get_global_route_with_netzones(const NetPoint* src, const NetP return; /* If src and dst are in the same netzone, life is good */ - if (src_ancestor == dst_ancestor) { /* SURF_ROUTING_BASE */ + if (src_ancestor == dst_ancestor) { /* ROUTING_BASE */ route.link_list_ = std::move(links); common_ancestor->get_local_route(src, dst, &route, latency); links = std::move(route.link_list_); @@ -663,8 +622,8 @@ void NetZoneImpl::get_graph(const s_xbt_graph_t* graph, std::map vertices = get_vertices(); - for (auto const& my_src : vertices) { - for (auto const& my_dst : vertices) { + for (auto const* my_src : vertices) { + for (auto const* my_dst : vertices) { if (my_src == my_dst) continue; @@ -710,6 +669,24 @@ void NetZoneImpl::get_graph(const s_xbt_graph_t* graph, std::mapsecond; +} + void NetZoneImpl::seal() { /* already sealed netzone */ @@ -717,6 +694,10 @@ void NetZoneImpl::seal() return; do_seal(); // derived class' specific sealing procedure + // for zone with a single host, this host is its own default gateway + if (gateways_.empty() && hosts_.size() == 1) + gateways_["default"] = hosts_.begin()->second->get_iface()->get_netpoint(); + /* seals sub-netzones and hosts */ for (auto* host : get_all_hosts()) { host->seal(); diff --git a/src/kernel/routing/NetZone_test.hpp b/src/kernel/routing/NetZone_test.hpp index 304b7b5d36..76a955b54d 100644 --- a/src/kernel/routing/NetZone_test.hpp +++ b/src/kernel/routing/NetZone_test.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,17 +6,16 @@ #ifndef NETZONE_TEST_HPP #define NETZONE_TEST_HPP -#include "simgrid/kernel/routing/NetPoint.hpp" -#include "simgrid/s4u/Host.hpp" #include "simgrid/s4u/NetZone.hpp" +#include "xbt/log.h" +XBT_LOG_EXTERNAL_CATEGORY(ker_platform); // Callback function common to several routing unit tests struct CreateHost { - std::pair - operator()(simgrid::s4u::NetZone* zone, const std::vector& /*coord*/, unsigned long id) const + simgrid::s4u::Host* operator()(simgrid::s4u::NetZone* zone, const std::vector& /*coord*/, + unsigned long id) const { - const simgrid::s4u::Host* host = zone->create_host(std::to_string(id), 1e9)->seal(); - return std::make_pair(host->get_netpoint(), nullptr); + return zone->create_host(std::to_string(id), "1Gf"); } }; diff --git a/src/kernel/routing/RoutedZone.cpp b/src/kernel/routing/RoutedZone.cpp index e7c2c79956..8457254713 100644 --- a/src/kernel/routing/RoutedZone.cpp +++ b/src/kernel/routing/RoutedZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,7 +12,7 @@ #include "xbt/sysdep.h" #include "xbt/asserts.hpp" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_generic, ker_routing, "Kernel Generic Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_generic, ker_platform, "Kernel Generic Routing"); /* ***************************************************************** */ /* *********************** GENERIC METHODS ************************* */ diff --git a/src/kernel/routing/StarZone.cpp b/src/kernel/routing/StarZone.cpp index d698a2f991..3ccb8888ba 100644 --- a/src/kernel/routing/StarZone.cpp +++ b/src/kernel/routing/StarZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,7 +8,7 @@ #include "src/kernel/resource/NetworkModel.hpp" #include "xbt/string.hpp" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_star, ker_routing, "Kernel Star Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_star, ker_platform, "Kernel Star Routing"); namespace simgrid { namespace kernel::routing { diff --git a/src/kernel/routing/StarZone_test.cpp b/src/kernel/routing/StarZone_test.cpp index 63cdc767d6..4c7ff4d992 100644 --- a/src/kernel/routing/StarZone_test.cpp +++ b/src/kernel/routing/StarZone_test.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch.hpp" +#include "src/3rd-party/catch.hpp" #include "simgrid/kernel/routing/NetPoint.hpp" #include "simgrid/kernel/routing/StarZone.hpp" @@ -287,7 +287,6 @@ TEST_CASE("kernel::routing::StarZone: mix new routes and hosts", "") for (int i = 0; i < 10; i++) { std::string cpu_name = "CPU" + std::to_string(i); const simgrid::s4u::Host* cpu = zone->create_host(cpu_name, 1e9)->seal(); - REQUIRE_NOTHROW( - zone->add_route(cpu->get_netpoint(), nullptr, nullptr, nullptr, {simgrid::s4u::LinkInRoute(link)}, true)); + REQUIRE_NOTHROW(zone->add_route(cpu, nullptr, {link})); } } diff --git a/src/kernel/routing/TorusZone.cpp b/src/kernel/routing/TorusZone.cpp index ab645a239d..8019943766 100644 --- a/src/kernel/routing/TorusZone.cpp +++ b/src/kernel/routing/TorusZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,10 +14,10 @@ #include #include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_torus, ker_routing, "Kernel Torus Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_torus, ker_platform, "Kernel Torus Routing"); namespace simgrid { -namespace kernel ::routing { +namespace kernel::routing { void TorusZone::create_torus_links(unsigned long id, int rank, unsigned long position) { diff --git a/src/kernel/routing/TorusZone_test.cpp b/src/kernel/routing/TorusZone_test.cpp index c558d7a0b3..c401bae5f8 100644 --- a/src/kernel/routing/TorusZone_test.cpp +++ b/src/kernel/routing/TorusZone_test.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch.hpp" +#include "src/3rd-party/catch.hpp" #include "NetZone_test.hpp" // CreateHost callback #include "simgrid/kernel/routing/TorusZone.hpp" diff --git a/src/kernel/routing/VivaldiZone.cpp b/src/kernel/routing/VivaldiZone.cpp index a96a9c6f2c..e7429d8555 100644 --- a/src/kernel/routing/VivaldiZone.cpp +++ b/src/kernel/routing/VivaldiZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,7 +12,7 @@ #include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_vivaldi, ker_routing, "Kernel Vivaldi Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_vivaldi, ker_platform, "Kernel Vivaldi Routing"); namespace simgrid { namespace kernel::routing { diff --git a/src/kernel/routing/WifiZone.cpp b/src/kernel/routing/WifiZone.cpp index 70af014c07..b6d40835d8 100644 --- a/src/kernel/routing/WifiZone.cpp +++ b/src/kernel/routing/WifiZone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,7 +8,7 @@ #include "src/kernel/resource/NetworkModel.hpp" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_wifi, ker_routing, "Kernel Wifi Routing"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_wifi, ker_platform, "Kernel Wifi Routing"); namespace simgrid { namespace kernel::routing { diff --git a/src/kernel/timer/Timer.cpp b/src/kernel/timer/Timer.cpp index d6bda284ba..0ea3e76d8f 100644 --- a/src/kernel/timer/Timer.cpp +++ b/src/kernel/timer/Timer.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2021-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/kernel/xml/platf.hpp b/src/kernel/xml/platf.hpp new file mode 100644 index 0000000000..9e3d355383 --- /dev/null +++ b/src/kernel/xml/platf.hpp @@ -0,0 +1,29 @@ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_KERNEL_XML_PARSE_HPP +#define SIMGRID_KERNEL_XML_PARSE_HPP + +#include +#include +#include + +/* Module management functions */ +XBT_PUBLIC void sg_platf_parser_finalize(); + +XBT_PUBLIC void simgrid_parse_open(const std::string& file); +XBT_PUBLIC void simgrid_parse_close(); +XBT_PUBLIC void simgrid_parse_assert(bool cond, const std::string& msg); +XBT_ATTRIB_NORETURN XBT_PUBLIC void simgrid_parse_error(const std::string& msg); +XBT_PUBLIC void simgrid_parse_assert_netpoint(const std::string& hostname, const std::string& pre, + const std::string& post); + +XBT_PUBLIC double simgrid_parse_get_double(const std::string& s); +XBT_PUBLIC int simgrid_parse_get_int(const std::string& s); + +XBT_PUBLIC void simgrid_parse(bool fire_on_platform_created_callback); /* Entry-point to the parser */ +XBT_PUBLIC void parse_platform_file(const std::string& file); + +#endif diff --git a/src/surf/xml/platf_private.hpp b/src/kernel/xml/platf_private.hpp similarity index 89% rename from src/surf/xml/platf_private.hpp rename to src/kernel/xml/platf_private.hpp index 99b2dd15f8..64f16278e2 100644 --- a/src/surf/xml/platf_private.hpp +++ b/src/kernel/xml/platf_private.hpp @@ -1,7 +1,6 @@ /* platf_private.h - Interface to the SimGrid platforms which visibility should be limited to this directory */ -/* Copyright (c) 2004-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,12 +10,15 @@ #include "simgrid/host.h" #include "simgrid/s4u/Link.hpp" -#include "src/surf/xml/simgrid_dtd.h" +#include "src/kernel/xml/simgrid_dtd.h" #include +#include #include #include +extern XBT_PRIVATE std::unordered_map traces_set_list; + namespace simgrid::kernel::routing { /* ***************************************** */ /* @@ -204,20 +206,19 @@ XBT_PUBLIC void sg_platf_new_bypass_route(simgrid::kernel::routing::RouteCreatio XBT_PUBLIC void sg_platf_new_trace(const simgrid::kernel::routing::ProfileCreationArgs* trace); XBT_PUBLIC void sg_platf_new_actor(simgrid::kernel::routing::ActorCreationArgs* actor); -XBT_PRIVATE void sg_platf_trace_connect(simgrid::kernel::routing::TraceConnectCreationArgs* trace_connect); /* Prototypes of the functions offered by flex */ -XBT_PUBLIC int surf_parse_lex(); -XBT_PUBLIC int surf_parse_get_lineno(); -XBT_PUBLIC FILE* surf_parse_get_in(); -XBT_PUBLIC FILE* surf_parse_get_out(); -XBT_PUBLIC int surf_parse_get_leng(); -XBT_PUBLIC char* surf_parse_get_text(); -XBT_PUBLIC void surf_parse_set_lineno(int line_number); -XBT_PUBLIC void surf_parse_set_in(FILE* in_str); -XBT_PUBLIC void surf_parse_set_out(FILE* out_str); -XBT_PUBLIC int surf_parse_get_debug(); -XBT_PUBLIC void surf_parse_set_debug(int bdebug); -XBT_PUBLIC int surf_parse_lex_destroy(); +XBT_PUBLIC int simgrid_parse_lex(); +XBT_PUBLIC int simgrid_parse_get_lineno(); +XBT_PUBLIC FILE* simgrid_parse_get_in(); +XBT_PUBLIC FILE* simgrid_parse_get_out(); +XBT_PUBLIC int simgrid_parse_get_leng(); +XBT_PUBLIC char* simgrid_parse_get_text(); +XBT_PUBLIC void simgrid_parse_set_lineno(int line_number); +XBT_PUBLIC void simgrid_parse_set_in(FILE* in_str); +XBT_PUBLIC void simgrid_parse_set_out(FILE* out_str); +XBT_PUBLIC int simgrid_parse_get_debug(); +XBT_PUBLIC void simgrid_parse_set_debug(int bdebug); +XBT_PUBLIC int simgrid_parse_lex_destroy(); #endif /* SG_PLATF_H */ diff --git a/src/kernel/xml/platf_sax_cb.cpp b/src/kernel/xml/platf_sax_cb.cpp new file mode 100644 index 0000000000..d48b491ea2 --- /dev/null +++ b/src/kernel/xml/platf_sax_cb.cpp @@ -0,0 +1,1063 @@ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include +#include +#include +#include +#include +#include +#include + +#include "src/kernel/resource/LinkImpl.hpp" +#include "src/kernel/resource/profile/FutureEvtSet.hpp" +#include "src/kernel/resource/profile/Profile.hpp" +#include "src/kernel/xml/platf.hpp" +#include "src/kernel/xml/platf_private.hpp" +#include "src/simgrid/sg_config.hpp" + +#include +#include +#include +#include +#include +#include + +#include "simgrid_dtd.c" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(platf_parse, ker_platform, "Logging specific to the parsing of platform files"); + +std::string simgrid_parsed_filename; // Currently parsed file (for the error messages) +static std::vector parsed_link_list; /* temporary store of current link list of a route */ + +static bool fire_on_platform_created_callback; + +/* Helping functions */ +void simgrid_parse_assert(bool cond, const std::string& msg) +{ + if (not cond) + simgrid_parse_error(msg); +} + +void simgrid_parse_error(const std::string& msg) +{ + throw simgrid::ParseError(simgrid_parsed_filename, simgrid_parse_lineno, msg); +} + +void simgrid_parse_assert_netpoint(const std::string& hostname, const std::string& pre, const std::string& post) +{ + if (simgrid::s4u::Engine::get_instance()->netpoint_by_name_or_null(hostname) != nullptr) // found + return; + + std::string msg = pre + hostname + post + " Existing netpoints:\n"; + + std::vector netpoints = + simgrid::s4u::Engine::get_instance()->get_all_netpoints(); + std::sort(netpoints.begin(), netpoints.end(), + [](const simgrid::kernel::routing::NetPoint* a, const simgrid::kernel::routing::NetPoint* b) { + return a->get_name() < b->get_name(); + }); + bool first = true; + for (auto const& np : netpoints) { + if (np->is_netzone()) + continue; + + if (not first) + msg += ","; + first = false; + msg += "'" + np->get_name() + "'"; + if (msg.length() > 4096) { + msg.pop_back(); // remove trailing quote + msg += "...(list truncated)......"; + break; + } + } + simgrid_parse_error(msg); +} + +double simgrid_parse_get_double(const std::string& s) +{ + try { + return std::stod(s); + } catch (const std::invalid_argument&) { + simgrid_parse_error(s + " is not a double"); + } +} + +int simgrid_parse_get_int(const std::string& s) +{ + try { + return std::stoi(s); + } catch (const std::invalid_argument&) { + simgrid_parse_error(s + " is not an int"); + } +} + +/* Turn something like "1-4,6,9-11" into the vector {1,2,3,4,6,9,10,11} */ +static void explodesRadical(const std::string& radicals, std::vector* exploded) +{ + // Make all hosts + std::vector radical_elements; + boost::split(radical_elements, radicals, boost::is_any_of(",")); + for (auto const& group : radical_elements) { + std::vector radical_ends; + boost::split(radical_ends, group, boost::is_any_of("-")); + int start = simgrid_parse_get_int(radical_ends.front()); + int end = 0; + + switch (radical_ends.size()) { + case 1: + end = start; + break; + case 2: + end = simgrid_parse_get_int(radical_ends.back()); + break; + default: + simgrid_parse_error("Malformed radical: " + group); + } + for (int i = start; i <= end; i++) + exploded->push_back(i); + } +} + +/* Trace related stuff */ +XBT_PRIVATE std::unordered_map + traces_set_list; // shown to sg_platf.cpp +static std::unordered_map trace_connect_list_host_avail; +static std::unordered_map trace_connect_list_host_speed; +static std::unordered_map trace_connect_list_link_avail; +static std::unordered_map trace_connect_list_link_bw; +static std::unordered_map trace_connect_list_link_lat; + +static void sg_platf_trace_connect(simgrid::kernel::routing::TraceConnectCreationArgs* trace_connect) +{ + simgrid_parse_assert(traces_set_list.find(trace_connect->trace) != traces_set_list.end(), + "Cannot connect trace " + trace_connect->trace + " to " + trace_connect->element + + ": trace unknown"); + + switch (trace_connect->kind) { + case simgrid::kernel::routing::TraceConnectKind::HOST_AVAIL: + trace_connect_list_host_avail.try_emplace(trace_connect->trace, trace_connect->element); + break; + case simgrid::kernel::routing::TraceConnectKind::SPEED: + trace_connect_list_host_speed.try_emplace(trace_connect->trace, trace_connect->element); + break; + case simgrid::kernel::routing::TraceConnectKind::LINK_AVAIL: + trace_connect_list_link_avail.try_emplace(trace_connect->trace, trace_connect->element); + break; + case simgrid::kernel::routing::TraceConnectKind::BANDWIDTH: + trace_connect_list_link_bw.try_emplace(trace_connect->trace, trace_connect->element); + break; + case simgrid::kernel::routing::TraceConnectKind::LATENCY: + trace_connect_list_link_lat.try_emplace(trace_connect->trace, trace_connect->element); + break; + default: + simgrid_parse_error("Cannot connect trace " + trace_connect->trace + " to " + trace_connect->element + + ": unknown kind of trace"); + } +} + +/* + * All the callback lists that can be overridden anywhere. + * (this list should probably be reduced to the bare minimum to allow the models to work) + */ + +/* make sure these symbols are defined as strong ones in this file so that the linker can resolve them */ + +static std::vector> property_sets; + +static FILE* file_to_parse = nullptr; + +/* Stuff relative to storage */ +void STag_simgrid_parse_storage() +{ + xbt_die(" tag was removed in SimGrid v3.27. Please stop using it now."); +} + +void ETag_simgrid_parse_storage() +{ + /* Won't happen since is now removed since v3.27. */ +} +void STag_simgrid_parse_storage___type() +{ + xbt_die(" tag was removed in SimGrid v3.27. Please stop using it now."); +} +void ETag_simgrid_parse_storage___type() +{ + /* Won't happen since is now removed since v3.27. */ +} + +void STag_simgrid_parse_mount() +{ + xbt_die(" tag was removed in SimGrid v3.27. Please stop using it now."); +} + +void ETag_simgrid_parse_mount() +{ + /* Won't happen since is now removed since v3.27. */ +} + +void STag_simgrid_parse_include() +{ + xbt_die(" tag was removed in SimGrid v3.18. Please stop using it now."); +} + +void ETag_simgrid_parse_include() +{ + /* Won't happen since is now removed since v3.18. */ +} + +/* Stag and Etag parse functions */ +void STag_simgrid_parse_platform() +{ + /* Use fixed point arithmetic to avoid rounding errors ("4.1" for example cannot be represented exactly as a floating + * point number) */ + const long int version = lround(100.0 * simgrid_parse_get_double(A_simgrid_parse_platform_version)); + const std::string version_string = std::to_string(version / 100) + "." + std::to_string(version % 100); + + simgrid_parse_assert(version >= 100L, "******* BIG FAT WARNING *********\n " + "You're using an ancient XML file.\n" + "Since SimGrid 3.1, units are Bytes, Flops, and seconds " + "instead of MBytes, MFlops and seconds.\n" + + "Use simgrid_update_xml to update your file automatically. " + "This program is installed automatically with SimGrid, or " + "available in the tools/ directory of the source archive.\n" + + "Please check also out the SURF section of the ChangeLog for " + "the 3.1 version for more information."); + simgrid_parse_assert(version >= 300L, "******* BIG FAT WARNING *********\n " + "You're using an old XML file.\n" + "Use simgrid_update_xml to update your file automatically. " + "This program is installed automatically with SimGrid, or " + "available in the tools/ directory of the source archive."); + simgrid_parse_assert( + version >= 400L, + "******* THIS FILE IS TOO OLD (v:" + version_string + + ") *********\n " + "Changes introduced in SimGrid 3.13:\n" + " - 'power' attribute of hosts (and others) got renamed to 'speed'.\n" + " - In , attribute kind=\"POWER\" is now kind=\"SPEED\".\n" + " - DOCTYPE now point to the rignt URL.\n" + " - speed, bandwidth and latency attributes now MUST have an explicit unit (f, Bps, s by default)" + "\n\n" + "Use simgrid_update_xml to update your file automatically. " + "This program is installed automatically with SimGrid, or " + "available in the tools/ directory of the source archive."); + if (version < 410L) { + XBT_INFO("You're using a v%s XML file (%s) while the current standard is v4.1 " + "That's fine, the new version is backward compatible. \n\n" + "Use simgrid_update_xml to update your file automatically to get rid of this warning. " + "This program is installed automatically with SimGrid, or " + "available in the tools/ directory of the source archive.", + version_string.c_str(), simgrid_parsed_filename.c_str()); + } + simgrid_parse_assert(version <= 410L, + "******* THIS FILE COMES FROM THE FUTURE (v:" + version_string + + ") *********\n " + "The most recent formalism that this version of SimGrid understands is v4.1.\n" + "Please update your code, or use another, more adapted, file."); +} + +static void add_remote_disks() +{ + for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) { + const char* remote_disk_str = host->get_property("remote_disk"); + if (not remote_disk_str) + continue; + std::vector tokens; + boost::split(tokens, remote_disk_str, boost::is_any_of(":")); + const simgrid::s4u::Host* remote_host = simgrid::s4u::Host::by_name_or_null(tokens[2]); + xbt_assert(remote_host, "You're trying to access a host that does not exist. Please check your platform file"); + + const simgrid::s4u::Disk* disk = nullptr; + for (auto const& d : remote_host->get_disks()) + if (d->get_name() == tokens[1]) { + disk = d; + break; + } + + xbt_assert(disk, "You're trying to mount a disk that does not exist. Please check your platform file"); + host->add_disk(disk); + + XBT_DEBUG("Host '%s' wants to access a remote disk: %s of %s", host->get_cname(), disk->get_cname(), + remote_host->get_cname()); + XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size()); + } +} + +static void remove_remote_disks() +{ + XBT_DEBUG("Simulation is over, time to unregister remote disks if any"); + for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) { + const char* remote_disk_str = host->get_property("remote_disk"); + if (remote_disk_str) { + std::vector tokens; + boost::split(tokens, remote_disk_str, boost::is_any_of(":")); + XBT_DEBUG("Host '%s' wants to unmount a remote disk: %s of %s", host->get_cname(), + tokens[1].c_str(), tokens[2].c_str()); + host->remove_disk(tokens[1]); + XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size()); + } + } +} + +void ETag_simgrid_parse_platform() +{ + simgrid::s4u::Engine::on_platform_created_cb(&add_remote_disks); + simgrid::s4u::Engine::on_simulation_end_cb(&remove_remote_disks); + if (fire_on_platform_created_callback) + simgrid::s4u::Engine::on_platform_created(); +} + +void STag_simgrid_parse_prop() +{ + property_sets.back().try_emplace(A_simgrid_parse_prop_id, A_simgrid_parse_prop_value); + XBT_DEBUG("add prop %s=%s into current property set %p", A_simgrid_parse_prop_id, A_simgrid_parse_prop_value, + &(property_sets.back())); +} + +void STag_simgrid_parse_host() +{ + simgrid::kernel::routing::HostCreationArgs host; + property_sets.emplace_back(); + host.id = A_simgrid_parse_host_id; + + host.speed_per_pstate = xbt_parse_get_all_speeds(simgrid_parsed_filename, simgrid_parse_lineno, + A_simgrid_parse_host_speed, "speed of host " + host.id); + + XBT_DEBUG("pstate: %s", A_simgrid_parse_host_pstate); + host.core_amount = simgrid_parse_get_int(A_simgrid_parse_host_core); + + if (A_simgrid_parse_host_availability___file[0] != '\0') { + XBT_WARN("The availability_file attribute in is now deprecated. Please, use 'speed_file' instead."); + host.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_simgrid_parse_host_availability___file); + } + if (A_simgrid_parse_host_speed___file[0] != '\0') + host.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_simgrid_parse_host_speed___file); + host.state_trace = A_simgrid_parse_host_state___file[0] + ? simgrid::kernel::profile::ProfileBuilder::from_file(A_simgrid_parse_host_state___file) + : nullptr; + host.coord = A_simgrid_parse_host_coordinates; + + sg_platf_new_host_begin(&host); +} + +void ETag_simgrid_parse_host() +{ + sg_platf_new_host_set_properties(property_sets.back()); + property_sets.pop_back(); + + sg_platf_new_host_seal(simgrid_parse_get_int(A_simgrid_parse_host_pstate)); +} + +void STag_simgrid_parse_disk() +{ + property_sets.emplace_back(); +} + +void ETag_simgrid_parse_disk() +{ + simgrid::kernel::routing::DiskCreationArgs disk; + disk.properties = property_sets.back(); + property_sets.pop_back(); + + disk.id = A_simgrid_parse_disk_id; + disk.read_bw = xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_disk_read___bw, + "read_bw of disk " + disk.id); + disk.write_bw = xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, + A_simgrid_parse_disk_write___bw, "write_bw of disk " + disk.id); + + sg_platf_new_disk(&disk); +} + +void STag_simgrid_parse_host___link() +{ + XBT_DEBUG("Create a Host_link for %s", A_simgrid_parse_host___link_id); + simgrid::kernel::routing::HostLinkCreationArgs host_link; + + host_link.id = A_simgrid_parse_host___link_id; + host_link.link_up = A_simgrid_parse_host___link_up; + host_link.link_down = A_simgrid_parse_host___link_down; + sg_platf_new_hostlink(&host_link); +} + +void STag_simgrid_parse_router() +{ + sg_platf_new_router(A_simgrid_parse_router_id, A_simgrid_parse_router_coordinates); +} + +void ETag_simgrid_parse_cluster() +{ + simgrid::kernel::routing::ClusterCreationArgs cluster; + cluster.properties = property_sets.back(); + property_sets.pop_back(); + + cluster.id = A_simgrid_parse_cluster_id; + cluster.prefix = A_simgrid_parse_cluster_prefix; + cluster.suffix = A_simgrid_parse_cluster_suffix; + explodesRadical(A_simgrid_parse_cluster_radical, &cluster.radicals); + + cluster.speeds = xbt_parse_get_all_speeds(simgrid_parsed_filename, simgrid_parse_lineno, + A_simgrid_parse_cluster_speed, "speed of cluster " + cluster.id); + cluster.core_amount = simgrid_parse_get_int(A_simgrid_parse_cluster_core); + cluster.bw = xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_cluster_bw, + "bw of cluster " + cluster.id); + cluster.lat = xbt_parse_get_time(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_cluster_lat, + "lat of cluster " + cluster.id); + if (strcmp(A_simgrid_parse_cluster_bb___bw, "")) + cluster.bb_bw = xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, + A_simgrid_parse_cluster_bb___bw, "bb_bw of cluster " + cluster.id); + if (strcmp(A_simgrid_parse_cluster_bb___lat, "")) + cluster.bb_lat = xbt_parse_get_time(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_cluster_bb___lat, + "bb_lat of cluster " + cluster.id); + if (strcmp(A_simgrid_parse_cluster_limiter___link, "")) + cluster.limiter_link = + xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_cluster_limiter___link, + "limiter_link of cluster " + cluster.id); + if (strcmp(A_simgrid_parse_cluster_loopback___bw, "")) + cluster.loopback_bw = + xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_cluster_loopback___bw, + "loopback_bw of cluster " + cluster.id); + if (strcmp(A_simgrid_parse_cluster_loopback___lat, "")) + cluster.loopback_lat = + xbt_parse_get_time(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_cluster_loopback___lat, + "loopback_lat of cluster " + cluster.id); + + switch (AX_simgrid_parse_cluster_topology) { + case A_simgrid_parse_cluster_topology_FLAT: + cluster.topology = simgrid::kernel::routing::ClusterTopology::FLAT; + break; + case A_simgrid_parse_cluster_topology_TORUS: + cluster.topology = simgrid::kernel::routing::ClusterTopology::TORUS; + break; + case A_simgrid_parse_cluster_topology_FAT___TREE: + cluster.topology = simgrid::kernel::routing::ClusterTopology::FAT_TREE; + break; + case A_simgrid_parse_cluster_topology_DRAGONFLY: + cluster.topology = simgrid::kernel::routing::ClusterTopology::DRAGONFLY; + break; + default: + simgrid_parse_error("Invalid cluster topology for cluster " + cluster.id); + } + cluster.topo_parameters = A_simgrid_parse_cluster_topo___parameters; + cluster.router_id = A_simgrid_parse_cluster_router___id; + + switch (AX_simgrid_parse_cluster_sharing___policy) { + case A_simgrid_parse_cluster_sharing___policy_SHARED: + cluster.sharing_policy = simgrid::s4u::Link::SharingPolicy::SHARED; + break; + case A_simgrid_parse_cluster_sharing___policy_FULLDUPLEX: + XBT_WARN("FULLDUPLEX is now deprecated. Please update your platform file to use SPLITDUPLEX instead."); + cluster.sharing_policy = simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX; + break; + case A_simgrid_parse_cluster_sharing___policy_SPLITDUPLEX: + cluster.sharing_policy = simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX; + break; + case A_simgrid_parse_cluster_sharing___policy_FATPIPE: + cluster.sharing_policy = simgrid::s4u::Link::SharingPolicy::FATPIPE; + break; + default: + simgrid_parse_error("Invalid cluster sharing policy for cluster " + cluster.id); + } + switch (AX_simgrid_parse_cluster_bb___sharing___policy) { + case A_simgrid_parse_cluster_bb___sharing___policy_FATPIPE: + cluster.bb_sharing_policy = simgrid::s4u::Link::SharingPolicy::FATPIPE; + break; + case A_simgrid_parse_cluster_bb___sharing___policy_SHARED: + cluster.bb_sharing_policy = simgrid::s4u::Link::SharingPolicy::SHARED; + break; + default: + simgrid_parse_error("Invalid bb sharing policy in cluster " + cluster.id); + } + + sg_platf_new_tag_cluster(&cluster); +} + +void STag_simgrid_parse_cluster() +{ + property_sets.emplace_back(); +} + +void STag_simgrid_parse_cabinet() +{ + simgrid::kernel::routing::CabinetCreationArgs cabinet; + cabinet.id = A_simgrid_parse_cabinet_id; + cabinet.prefix = A_simgrid_parse_cabinet_prefix; + cabinet.suffix = A_simgrid_parse_cabinet_suffix; + cabinet.speed = xbt_parse_get_speed(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_cabinet_speed, + "speed of cabinet " + cabinet.id); + cabinet.bw = xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_cabinet_bw, + "bw of cabinet " + cabinet.id); + cabinet.lat = xbt_parse_get_time(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_cabinet_lat, + "lat of cabinet " + cabinet.id); + explodesRadical(A_simgrid_parse_cabinet_radical, &cabinet.radicals); + + sg_platf_new_cabinet(&cabinet); +} + +void STag_simgrid_parse_peer() +{ + simgrid::kernel::routing::PeerCreationArgs peer; + + peer.id = A_simgrid_parse_peer_id; + peer.speed = xbt_parse_get_speed(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_peer_speed, + "speed of peer " + peer.id); + peer.bw_in = xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_peer_bw___in, + "bw_in of peer " + peer.id); + peer.bw_out = xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_peer_bw___out, + "bw_out of peer " + peer.id); + peer.coord = A_simgrid_parse_peer_coordinates; + peer.speed_trace = nullptr; + if (A_simgrid_parse_peer_availability___file[0] != '\0') { + XBT_WARN("The availability_file attribute in is now deprecated. Please, use 'speed_file' instead."); + peer.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_simgrid_parse_peer_availability___file); + } + if (A_simgrid_parse_peer_speed___file[0] != '\0') + peer.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_simgrid_parse_peer_speed___file); + peer.state_trace = A_simgrid_parse_peer_state___file[0] + ? simgrid::kernel::profile::ProfileBuilder::from_file(A_simgrid_parse_peer_state___file) + : nullptr; + + if (A_simgrid_parse_peer_lat[0] != '\0') + XBT_WARN("The latency attribute in is now deprecated. Use the z coordinate instead of '%s'.", + A_simgrid_parse_peer_lat); + + sg_platf_new_peer(&peer); +} + +void STag_simgrid_parse_link() +{ + property_sets.emplace_back(); +} + +void ETag_simgrid_parse_link() +{ + simgrid::kernel::routing::LinkCreationArgs link; + + link.properties = property_sets.back(); + property_sets.pop_back(); + + link.id = A_simgrid_parse_link_id; + link.bandwidths = xbt_parse_get_bandwidths(simgrid_parsed_filename, simgrid_parse_lineno, + A_simgrid_parse_link_bandwidth, "bandwidth of link " + link.id); + link.bandwidth_trace = + A_simgrid_parse_link_bandwidth___file[0] + ? simgrid::kernel::profile::ProfileBuilder::from_file(A_simgrid_parse_link_bandwidth___file) + : nullptr; + link.latency = xbt_parse_get_time(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_link_latency, + "latency of link " + link.id); + link.latency_trace = A_simgrid_parse_link_latency___file[0] + ? simgrid::kernel::profile::ProfileBuilder::from_file(A_simgrid_parse_link_latency___file) + : nullptr; + link.state_trace = A_simgrid_parse_link_state___file[0] + ? simgrid::kernel::profile::ProfileBuilder::from_file(A_simgrid_parse_link_state___file) + : nullptr; + + switch (A_simgrid_parse_link_sharing___policy) { + case A_simgrid_parse_link_sharing___policy_SHARED: + link.policy = simgrid::s4u::Link::SharingPolicy::SHARED; + break; + case A_simgrid_parse_link_sharing___policy_FATPIPE: + link.policy = simgrid::s4u::Link::SharingPolicy::FATPIPE; + break; + case A_simgrid_parse_link_sharing___policy_FULLDUPLEX: + XBT_WARN("FULLDUPLEX is now deprecated. Please update your platform file to use SPLITDUPLEX instead."); + link.policy = simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX; + break; + case A_simgrid_parse_link_sharing___policy_SPLITDUPLEX: + link.policy = simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX; + break; + case A_simgrid_parse_link_sharing___policy_WIFI: + link.policy = simgrid::s4u::Link::SharingPolicy::WIFI; + break; + default: + simgrid_parse_error("Invalid sharing policy in link " + link.id); + } + + sg_platf_new_link(&link); +} + +void STag_simgrid_parse_link___ctn() +{ + const auto* engine = simgrid::s4u::Engine::get_instance(); + const simgrid::s4u::Link* link; + simgrid::s4u::LinkInRoute::Direction direction = simgrid::s4u::LinkInRoute::Direction::NONE; + switch (A_simgrid_parse_link___ctn_direction) { + case AU_simgrid_parse_link___ctn_direction: + case A_simgrid_parse_link___ctn_direction_NONE: + link = engine->link_by_name(A_simgrid_parse_link___ctn_id); + break; + case A_simgrid_parse_link___ctn_direction_UP: + link = engine->split_duplex_link_by_name(A_simgrid_parse_link___ctn_id); + direction = simgrid::s4u::LinkInRoute::Direction::UP; + break; + case A_simgrid_parse_link___ctn_direction_DOWN: + link = engine->split_duplex_link_by_name(A_simgrid_parse_link___ctn_id); + direction = simgrid::s4u::LinkInRoute::Direction::DOWN; + break; + default: + simgrid_parse_error(std::string("Invalid direction for link ") + A_simgrid_parse_link___ctn_id); + } + + const char* dirname; + switch (A_simgrid_parse_link___ctn_direction) { + case A_simgrid_parse_link___ctn_direction_UP: + dirname = " (upward)"; + break; + case A_simgrid_parse_link___ctn_direction_DOWN: + dirname = " (downward)"; + break; + default: + dirname = ""; + } + simgrid_parse_assert(link != nullptr, std::string("No such link: '") + A_simgrid_parse_link___ctn_id + "'" + dirname); + parsed_link_list.emplace_back(link, direction); +} + +void ETag_simgrid_parse_backbone() +{ + auto link = std::make_unique(); + + link->id = A_simgrid_parse_backbone_id; + link->bandwidths.push_back(xbt_parse_get_bandwidth(simgrid_parsed_filename, simgrid_parse_lineno, + A_simgrid_parse_backbone_bandwidth, + "bandwidth of backbone " + link->id)); + link->latency = xbt_parse_get_time(simgrid_parsed_filename, simgrid_parse_lineno, A_simgrid_parse_backbone_latency, + "latency of backbone " + link->id); + link->policy = simgrid::s4u::Link::SharingPolicy::SHARED; + + routing_cluster_add_backbone(std::move(link)); +} + +void STag_simgrid_parse_route() +{ + simgrid_parse_assert_netpoint(A_simgrid_parse_route_src, "Route src='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_route_dst, "Route dst='", "' does name a node."); +} + +void STag_simgrid_parse_ASroute() +{ + simgrid_parse_assert_netpoint(A_simgrid_parse_ASroute_src, "ASroute src='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_ASroute_dst, "ASroute dst='", "' does name a node."); + + simgrid_parse_assert_netpoint(A_simgrid_parse_ASroute_gw___src, "ASroute gw_src='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_ASroute_gw___dst, "ASroute gw_dst='", "' does name a node."); +} +void STag_simgrid_parse_zoneRoute() +{ + simgrid_parse_assert_netpoint(A_simgrid_parse_zoneRoute_src, "zoneRoute src='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_zoneRoute_dst, "zoneRoute dst='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_zoneRoute_gw___src, "zoneRoute gw_src='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_zoneRoute_gw___dst, "zoneRoute gw_dst='", "' does name a node."); +} + +void STag_simgrid_parse_bypassRoute() +{ + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassRoute_src, "bypassRoute src='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassRoute_dst, "bypassRoute dst='", "' does name a node."); +} + +void STag_simgrid_parse_bypassASroute() +{ + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassASroute_src, "bypassASroute src='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassASroute_dst, "bypassASroute dst='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassASroute_gw___src, "bypassASroute gw_src='", + "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassASroute_gw___dst, "bypassASroute gw_dst='", + "' does name a node."); +} +void STag_simgrid_parse_bypassZoneRoute() +{ + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassZoneRoute_src, "bypassZoneRoute src='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassZoneRoute_dst, "bypassZoneRoute dst='", "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassZoneRoute_gw___src, "bypassZoneRoute gw_src='", + "' does name a node."); + simgrid_parse_assert_netpoint(A_simgrid_parse_bypassZoneRoute_gw___dst, "bypassZoneRoute gw_dst='", + "' does name a node."); +} + +void ETag_simgrid_parse_route() +{ + simgrid::kernel::routing::RouteCreationArgs route; + + route.src = sg_netpoint_by_name_or_null(A_simgrid_parse_route_src); // tested to not be nullptr in start tag + route.dst = sg_netpoint_by_name_or_null(A_simgrid_parse_route_dst); // tested to not be nullptr in start tag + route.symmetrical = (A_simgrid_parse_route_symmetrical == AU_simgrid_parse_route_symmetrical || + A_simgrid_parse_route_symmetrical == A_simgrid_parse_route_symmetrical_YES || + A_simgrid_parse_route_symmetrical == A_simgrid_parse_route_symmetrical_yes); + + route.link_list.swap(parsed_link_list); + + sg_platf_new_route(&route); +} + +void ETag_simgrid_parse_ASroute() +{ + AX_simgrid_parse_zoneRoute_src = AX_simgrid_parse_ASroute_src; + AX_simgrid_parse_zoneRoute_dst = AX_simgrid_parse_ASroute_dst; + AX_simgrid_parse_zoneRoute_gw___src = AX_simgrid_parse_ASroute_gw___src; + AX_simgrid_parse_zoneRoute_gw___dst = AX_simgrid_parse_ASroute_gw___dst; + AX_simgrid_parse_zoneRoute_symmetrical = (AT_simgrid_parse_zoneRoute_symmetrical)AX_simgrid_parse_ASroute_symmetrical; + ETag_simgrid_parse_zoneRoute(); +} +void ETag_simgrid_parse_zoneRoute() +{ + simgrid::kernel::routing::RouteCreationArgs ASroute; + + ASroute.src = sg_netpoint_by_name_or_null(A_simgrid_parse_zoneRoute_src); // tested to not be nullptr in start tag + ASroute.dst = sg_netpoint_by_name_or_null(A_simgrid_parse_zoneRoute_dst); // tested to not be nullptr in start tag + + ASroute.gw_src = + sg_netpoint_by_name_or_null(A_simgrid_parse_zoneRoute_gw___src); // tested to not be nullptr in start tag + ASroute.gw_dst = + sg_netpoint_by_name_or_null(A_simgrid_parse_zoneRoute_gw___dst); // tested to not be nullptr in start tag + + ASroute.link_list.swap(parsed_link_list); + + ASroute.symmetrical = (A_simgrid_parse_zoneRoute_symmetrical == AU_simgrid_parse_zoneRoute_symmetrical || + A_simgrid_parse_zoneRoute_symmetrical == A_simgrid_parse_zoneRoute_symmetrical_YES || + A_simgrid_parse_zoneRoute_symmetrical == A_simgrid_parse_zoneRoute_symmetrical_yes); + + sg_platf_new_route(&ASroute); +} + +void ETag_simgrid_parse_bypassRoute() +{ + simgrid::kernel::routing::RouteCreationArgs route; + + route.src = sg_netpoint_by_name_or_null(A_simgrid_parse_bypassRoute_src); // tested to not be nullptr in start tag + route.dst = sg_netpoint_by_name_or_null(A_simgrid_parse_bypassRoute_dst); // tested to not be nullptr in start tag + route.symmetrical = false; + + route.link_list.swap(parsed_link_list); + + sg_platf_new_bypass_route(&route); +} + +void ETag_simgrid_parse_bypassASroute() +{ + AX_simgrid_parse_bypassZoneRoute_src = AX_simgrid_parse_bypassASroute_src; + AX_simgrid_parse_bypassZoneRoute_dst = AX_simgrid_parse_bypassASroute_dst; + AX_simgrid_parse_bypassZoneRoute_gw___src = AX_simgrid_parse_bypassASroute_gw___src; + AX_simgrid_parse_bypassZoneRoute_gw___dst = AX_simgrid_parse_bypassASroute_gw___dst; + ETag_simgrid_parse_bypassZoneRoute(); +} +void ETag_simgrid_parse_bypassZoneRoute() +{ + simgrid::kernel::routing::RouteCreationArgs ASroute; + + ASroute.src = sg_netpoint_by_name_or_null(A_simgrid_parse_bypassZoneRoute_src); + ASroute.dst = sg_netpoint_by_name_or_null(A_simgrid_parse_bypassZoneRoute_dst); + ASroute.link_list.swap(parsed_link_list); + + ASroute.symmetrical = false; + + ASroute.gw_src = sg_netpoint_by_name_or_null(A_simgrid_parse_bypassZoneRoute_gw___src); + ASroute.gw_dst = sg_netpoint_by_name_or_null(A_simgrid_parse_bypassZoneRoute_gw___dst); + + sg_platf_new_bypass_route(&ASroute); +} + +void ETag_simgrid_parse_trace() +{ + simgrid::kernel::routing::ProfileCreationArgs trace; + + trace.id = A_simgrid_parse_trace_id; + trace.file = A_simgrid_parse_trace_file; + trace.periodicity = simgrid_parse_get_double(A_simgrid_parse_trace_periodicity); + trace.pc_data = simgrid_parse_pcdata; + + sg_platf_new_trace(&trace); +} + +void STag_simgrid_parse_trace___connect() +{ + simgrid::kernel::routing::TraceConnectCreationArgs trace_connect; + + trace_connect.element = A_simgrid_parse_trace___connect_element; + trace_connect.trace = A_simgrid_parse_trace___connect_trace; + + switch (A_simgrid_parse_trace___connect_kind) { + case AU_simgrid_parse_trace___connect_kind: + case A_simgrid_parse_trace___connect_kind_SPEED: + trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::SPEED; + break; + case A_simgrid_parse_trace___connect_kind_BANDWIDTH: + trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::BANDWIDTH; + break; + case A_simgrid_parse_trace___connect_kind_HOST___AVAIL: + trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::HOST_AVAIL; + break; + case A_simgrid_parse_trace___connect_kind_LATENCY: + trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::LATENCY; + break; + case A_simgrid_parse_trace___connect_kind_LINK___AVAIL: + trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::LINK_AVAIL; + break; + default: + simgrid_parse_error("Invalid trace kind"); + } + sg_platf_trace_connect(&trace_connect); +} + +void STag_simgrid_parse_AS() +{ + AX_simgrid_parse_zone_id = AX_simgrid_parse_AS_id; + AX_simgrid_parse_zone_routing = AX_simgrid_parse_AS_routing; + STag_simgrid_parse_zone(); +} + +void ETag_simgrid_parse_AS() +{ + ETag_simgrid_parse_zone(); +} + +void STag_simgrid_parse_zone() +{ + property_sets.emplace_back(); + simgrid::kernel::routing::ZoneCreationArgs zone; + zone.id = A_simgrid_parse_zone_id; + zone.routing = A_simgrid_parse_zone_routing; + sg_platf_new_zone_begin(&zone); +} + +void ETag_simgrid_parse_zone() +{ + sg_platf_new_zone_set_properties(property_sets.back()); + property_sets.pop_back(); + sg_platf_new_zone_seal(); +} + +void STag_simgrid_parse_config() +{ + property_sets.emplace_back(); + XBT_DEBUG("START configuration name = %s", A_simgrid_parse_config_id); + if (_sg_cfg_init_status == 2) { + simgrid_parse_error( + "All tags must be given before any platform elements (such as , , , " + ", etc)."); + } +} + +void ETag_simgrid_parse_config() +{ + // Sort config elements before applying. + // That's a little waste of time, but not doing so would break the tests + auto current_property_set = property_sets.back(); + + std::vector keys; + for (auto const& [key, _] : current_property_set) { + keys.push_back(key); + } + std::sort(keys.begin(), keys.end()); + for (const std::string& key : keys) { + if (simgrid::config::is_default(key.c_str())) { + std::string cfg = key + ":" + current_property_set.at(key); + simgrid::config::set_parse(cfg); + } else + XBT_INFO("The custom configuration '%s' is already defined by user!", key.c_str()); + } + XBT_DEBUG("End configuration name = %s", A_simgrid_parse_config_id); + + property_sets.pop_back(); +} + +static std::vector arguments; + +void STag_simgrid_parse_process() +{ + AX_simgrid_parse_actor_function = AX_simgrid_parse_process_function; + STag_simgrid_parse_actor(); +} + +void STag_simgrid_parse_actor() +{ + property_sets.emplace_back(); + arguments.assign(1, A_simgrid_parse_actor_function); +} + +void ETag_simgrid_parse_process() +{ + AX_simgrid_parse_actor_host = AX_simgrid_parse_process_host; + AX_simgrid_parse_actor_function = AX_simgrid_parse_process_function; + AX_simgrid_parse_actor_start___time = AX_simgrid_parse_process_start___time; + AX_simgrid_parse_actor_kill___time = AX_simgrid_parse_process_kill___time; + AX_simgrid_parse_actor_on___failure = (AT_simgrid_parse_actor_on___failure)AX_simgrid_parse_process_on___failure; + ETag_simgrid_parse_actor(); +} + +void ETag_simgrid_parse_actor() +{ + simgrid::kernel::routing::ActorCreationArgs actor; + + actor.properties = property_sets.back(); + property_sets.pop_back(); + + actor.args.swap(arguments); + actor.host = A_simgrid_parse_actor_host; + actor.function = A_simgrid_parse_actor_function; + actor.start_time = simgrid_parse_get_double(A_simgrid_parse_actor_start___time); + actor.kill_time = simgrid_parse_get_double(A_simgrid_parse_actor_kill___time); + + switch (A_simgrid_parse_actor_on___failure) { + case AU_simgrid_parse_actor_on___failure: + case A_simgrid_parse_actor_on___failure_DIE: + actor.restart_on_failure = false; + break; + case A_simgrid_parse_actor_on___failure_RESTART: + actor.restart_on_failure = true; + break; + default: + simgrid_parse_error("Invalid on failure behavior"); + } + + sg_platf_new_actor(&actor); +} + +void STag_simgrid_parse_argument() +{ + arguments.emplace_back(A_simgrid_parse_argument_value); +} + +void STag_simgrid_parse_model___prop() +{ + XBT_INFO("Deprecated tag ignored"); +} + +void ETag_simgrid_parse_prop() +{ /* Nothing to do */ +} +void STag_simgrid_parse_random() +{ /* Nothing to do */ +} +void ETag_simgrid_parse_random() +{ /* Nothing to do */ +} +void ETag_simgrid_parse_trace___connect() +{ /* Nothing to do */ +} +void STag_simgrid_parse_trace() +{ /* Nothing to do */ +} +void ETag_simgrid_parse_router() +{ /*Nothing to do*/ +} +void ETag_simgrid_parse_host___link() +{ /* Nothing to do */ +} +void ETag_simgrid_parse_cabinet() +{ /* Nothing to do */ +} +void ETag_simgrid_parse_peer() +{ /* Nothing to do */ +} +void STag_simgrid_parse_backbone() +{ /* Nothing to do */ +} +void ETag_simgrid_parse_link___ctn() +{ /* Nothing to do */ +} +void ETag_simgrid_parse_argument() +{ /* Nothing to do */ +} +void ETag_simgrid_parse_model___prop() +{ /* Nothing to do */ +} + +/* Open and Close parse file */ +static YY_BUFFER_STATE input_buffer; + +void simgrid_parse_open(const std::string& file) +{ + simgrid_parsed_filename = file; + std::string dir = simgrid::xbt::Path(file).get_dir_name(); + simgrid::xbt::path_push(dir); + + file_to_parse = simgrid::xbt::path_fopen(file, "r"); + if (file_to_parse == nullptr) + throw std::invalid_argument("Unable to open '" + file + "' from '" + simgrid::xbt::Path().get_name() + + "'. Does this file exist?"); + input_buffer = simgrid_parse__create_buffer(file_to_parse, YY_BUF_SIZE); + simgrid_parse__switch_to_buffer(input_buffer); + simgrid_parse_lineno = 1; +} + +void simgrid_parse_close() +{ + simgrid::xbt::path_pop(); // remove the dirname of the opened file, that was added in simgrid_parse_open() + + if (file_to_parse) { + simgrid_parse__delete_buffer(input_buffer); + fclose(file_to_parse); + file_to_parse = nullptr; // Must be reset for Bypass + } +} + +/* Call the lexer to parse the currently opened file */ +void simgrid_parse(bool fire_on_platform_created_callback_param) +{ + fire_on_platform_created_callback = fire_on_platform_created_callback_param; + bool err = simgrid_parse_lex(); + simgrid_parse_assert(not err, "Flex returned an error code"); + + /* Actually connect the traces now that every elements are created */ + const auto* engine = simgrid::s4u::Engine::get_instance(); + + for (auto const& [trace, name] : trace_connect_list_host_avail) { + simgrid_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), + ": Trace " + trace + " undefined."); + auto* profile = traces_set_list.at(trace); + + auto* host = engine->host_by_name_or_null(name); + simgrid_parse_assert(host, ": Host " + name + " undefined."); + host->set_state_profile(profile); + } + trace_connect_list_host_avail.clear(); + + for (auto const& [trace, name] : trace_connect_list_host_speed) { + simgrid_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), + ": Trace " + trace + " undefined."); + auto* profile = traces_set_list.at(trace); + + auto* host = engine->host_by_name_or_null(name); + simgrid_parse_assert(host, ": Host " + name + " undefined."); + host->set_speed_profile(profile); + } + trace_connect_list_host_speed.clear(); + + for (auto const& [trace, name] : trace_connect_list_link_avail) { + simgrid_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), + ": Trace " + trace + " undefined."); + auto* profile = traces_set_list.at(trace); + + auto* link = engine->link_by_name_or_null(name); + simgrid_parse_assert(link, ": Link " + name + " undefined."); + link->set_state_profile(profile); + } + trace_connect_list_link_avail.clear(); + + for (auto const& [trace, name] : trace_connect_list_link_bw) { + simgrid_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), + ": Trace " + trace + " undefined."); + auto* profile = traces_set_list.at(trace); + + auto* link = engine->link_by_name_or_null(name); + simgrid_parse_assert(link, ": Link " + name + " undefined."); + link->set_bandwidth_profile(profile); + } + trace_connect_list_link_bw.clear(); + + for (auto const& [trace, name] : trace_connect_list_link_lat) { + simgrid_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), + ": Trace " + trace + " undefined."); + auto* profile = traces_set_list.at(trace); + + auto* link = engine->link_by_name_or_null(name); + simgrid_parse_assert(link, ": Link " + name + " undefined."); + link->set_latency_profile(profile); + } + trace_connect_list_link_lat.clear(); +} diff --git a/src/surf/sg_platf.cpp b/src/kernel/xml/sg_platf.cpp similarity index 90% rename from src/surf/sg_platf.cpp rename to src/kernel/xml/sg_platf.cpp index f7f483788a..d953e005ab 100644 --- a/src/surf/sg_platf.cpp +++ b/src/kernel/xml/sg_platf.cpp @@ -1,8 +1,10 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +/* This file implements the public API to platform parsing */ + #include #include #include @@ -18,18 +20,31 @@ #include #include -#include "simgrid/sg_config.hpp" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/resource/DiskImpl.hpp" +#include "src/kernel/resource/HostImpl.hpp" +#include "src/kernel/resource/StandardLinkImpl.hpp" #include "src/kernel/resource/profile/Profile.hpp" -#include "src/surf/HostImpl.hpp" -#include "src/surf/xml/platf.hpp" -#include "src/surf/xml/platf_private.hpp" +#include "src/kernel/xml/platf.hpp" +#include "src/kernel/xml/platf_private.hpp" +#include "src/simgrid/sg_config.hpp" #include #include -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_parse); +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(platf_parse); + +/* This function acts as a main in the parsing area. */ +void parse_platform_file(const std::string& file) +{ + /* init the flex parser */ + simgrid_parse_open(file); + + /* Do the actual parsing */ + simgrid_parse(true); + + simgrid_parse_close(); +} namespace simgrid::kernel::routing { xbt::signal on_cluster_creation; @@ -40,20 +55,14 @@ static simgrid::kernel::routing::ClusterZoneCreationArgs /** The current NetZone in the parsing */ static simgrid::kernel::routing::NetZoneImpl* current_routing = nullptr; -static simgrid::s4u::Host* current_host = nullptr; - -/** Module management function: creates all internal data structures */ -void sg_platf_init() -{ - // Do nothing: just for symmetry of user code -} +static simgrid::s4u::Host* current_host = nullptr; /** Module management function: frees all internal data structures */ -void sg_platf_exit() +void sg_platf_parser_finalize() { simgrid::kernel::routing::on_cluster_creation.disconnect_slots(); - surf_parse_lex_destroy(); + simgrid_parse_lex_destroy(); } /** @brief Add a host to the current NetZone */ @@ -140,7 +149,7 @@ void sg_platf_new_disk(const simgrid::kernel::routing::DiskCreationArgs* disk) /*************************************************************************************************/ /** @brief Auxiliary function to create hosts */ -static std::pair +static simgrid::s4u::Host* sg_platf_cluster_create_host(const simgrid::kernel::routing::ClusterCreationArgs* cluster, simgrid::s4u::NetZone* zone, const std::vector& /*coord*/, unsigned long id) { @@ -149,13 +158,12 @@ sg_platf_cluster_create_host(const simgrid::kernel::routing::ClusterCreationArgs "(total = %zu). Check the 'radical' parameter in XML", cluster->id.c_str(), id, cluster->radicals.size()); - std::string host_id = std::string(cluster->prefix) + std::to_string(cluster->radicals[id]) + cluster->suffix; + std::string host_id = cluster->prefix + std::to_string(cluster->radicals[id]) + cluster->suffix; XBT_DEBUG("Cluster: creating host=%s speed=%f", host_id.c_str(), cluster->speeds.front()); - const simgrid::s4u::Host* host = zone->create_host(host_id, cluster->speeds) - ->set_core_count(cluster->core_amount) - ->set_properties(cluster->properties) - ->seal(); - return std::make_pair(host->get_netpoint(), nullptr); + simgrid::s4u::Host* host = zone->create_host(host_id, cluster->speeds) + ->set_core_count(cluster->core_amount) + ->set_properties(cluster->properties); + return host; } /** @brief Auxiliary function to create loopback links */ @@ -170,7 +178,7 @@ sg_platf_cluster_create_loopback(const simgrid::kernel::routing::ClusterCreation "(total = %zu). Check the 'radical' parameter in XML", cluster->id.c_str(), id, cluster->radicals.size()); - std::string link_id = std::string(cluster->id) + "_link_" + std::to_string(cluster->radicals[id]) + "_loopback"; + std::string link_id = cluster->id + "_link_" + std::to_string(cluster->radicals[id]) + "_loopback"; XBT_DEBUG("Cluster: creating loopback link=%s bw=%f", link_id.c_str(), cluster->loopback_bw); simgrid::s4u::Link* loopback = zone->create_link(link_id, cluster->loopback_bw) @@ -186,7 +194,7 @@ static simgrid::s4u::Link* sg_platf_cluster_create_limiter(const simgrid::kernel const std::vector& /*coord*/, unsigned long id) { - std::string link_id = std::string(cluster->id) + "_link_" + std::to_string(id) + "_limiter"; + std::string link_id = cluster->id + "_link_" + std::to_string(id) + "_limiter"; XBT_DEBUG("Cluster: creating limiter link=%s bw=%f", link_id.c_str(), cluster->limiter_link); simgrid::s4u::Link* limiter = zone->create_link(link_id, cluster->limiter_link)->seal(); @@ -201,7 +209,8 @@ static void sg_platf_new_cluster_hierarchical(const simgrid::kernel::routing::Cl using simgrid::kernel::routing::FatTreeZone; using simgrid::kernel::routing::TorusZone; - auto set_host = std::bind(sg_platf_cluster_create_host, cluster, _1, _2, _3); + std::function set_host = + std::bind(sg_platf_cluster_create_host, cluster, _1, _2, _3); std::function set_loopback{}; std::function set_limiter{}; @@ -239,7 +248,7 @@ static void sg_platf_new_cluster_hierarchical(const simgrid::kernel::routing::Cl /** @brief Create regular Cluster */ static void sg_platf_new_cluster_flat(simgrid::kernel::routing::ClusterCreationArgs* cluster) { - auto* zone = simgrid::s4u::create_star_zone(cluster->id); + auto* zone = simgrid::s4u::create_star_zone(cluster->id); if (const auto* parent = current_routing ? current_routing->get_iface() : nullptr) zone->set_parent(parent); @@ -250,7 +259,7 @@ static void sg_platf_new_cluster_flat(simgrid::kernel::routing::ClusterCreationA /* Make the backbone */ const simgrid::s4u::Link* backbone = nullptr; if ((cluster->bb_bw > 0) || (cluster->bb_lat > 0)) { - std::string bb_name = std::string(cluster->id) + "_backbone"; + std::string bb_name = cluster->id + "_backbone"; XBT_DEBUG(" ", bb_name.c_str(), cluster->bb_bw, cluster->bb_lat); @@ -261,7 +270,7 @@ static void sg_platf_new_cluster_flat(simgrid::kernel::routing::ClusterCreationA } for (int const& i : cluster->radicals) { - std::string host_id = std::string(cluster->prefix) + std::to_string(i) + cluster->suffix; + std::string host_id = cluster->prefix + std::to_string(i) + cluster->suffix; XBT_DEBUG("", host_id.c_str(), cluster->speeds.front()); const auto* host = zone->create_host(host_id, cluster->speeds) @@ -271,7 +280,7 @@ static void sg_platf_new_cluster_flat(simgrid::kernel::routing::ClusterCreationA XBT_DEBUG(""); - std::string link_id = std::string(cluster->id) + "_link_" + std::to_string(i); + std::string link_id = cluster->id + "_link_" + std::to_string(i); XBT_DEBUG("", link_id.c_str(), cluster->bw, cluster->lat); // add a loopback link @@ -284,14 +293,13 @@ static void sg_platf_new_cluster_flat(simgrid::kernel::routing::ClusterCreationA ->set_latency(cluster->loopback_lat) ->seal(); - zone->add_route(host->get_netpoint(), host->get_netpoint(), nullptr, nullptr, - {simgrid::s4u::LinkInRoute(loopback)}); + zone->add_route(host, host, {simgrid::s4u::LinkInRoute(loopback)}); } // add a limiter link (shared link to account for maximal bandwidth of the node) const simgrid::s4u::Link* limiter = nullptr; if (cluster->limiter_link > 0) { - std::string limiter_name = std::string(link_id) + "_limiter"; + std::string limiter_name = link_id + "_limiter"; XBT_DEBUG("", limiter_name.c_str(), cluster->limiter_link); limiter = zone->create_link(limiter_name, cluster->limiter_link)->seal(); @@ -313,16 +321,15 @@ static void sg_platf_new_cluster_flat(simgrid::kernel::routing::ClusterCreationA if (backbone) links.emplace_back(backbone); - zone->add_route(host->get_netpoint(), nullptr, nullptr, nullptr, links, true); + zone->add_route(host, nullptr, links, true); } // Add a router. XBT_DEBUG(" "); XBT_DEBUG("", cluster->router_id.c_str()); if (cluster->router_id.empty()) - cluster->router_id = std::string(cluster->prefix) + cluster->id + "_router" + cluster->suffix; - auto* router = zone->create_router(cluster->router_id); - zone->add_route(router, nullptr, nullptr, nullptr, {}); + cluster->router_id = cluster->prefix + cluster->id + "_router" + cluster->suffix; + zone->create_router(cluster->router_id); simgrid::kernel::routing::on_cluster_creation(*cluster); } @@ -365,12 +372,12 @@ static void sg_platf_build_hostlink(simgrid::kernel::routing::StarZone* zone, const simgrid::kernel::routing::HostLinkCreationArgs* hostlink, const simgrid::s4u::Link* backbone) { - const auto engine = simgrid::s4u::Engine::get_instance(); - auto netpoint = engine->host_by_name(hostlink->id)->get_netpoint(); + const auto* engine = simgrid::s4u::Engine::get_instance(); + auto* netpoint = engine->host_by_name(hostlink->id)->get_netpoint(); xbt_assert(netpoint, "Host '%s' not found!", hostlink->id.c_str()); - const auto linkUp = engine->link_by_name_or_null(hostlink->link_up); - const auto linkDown = engine->link_by_name_or_null(hostlink->link_down); + const auto* linkUp = engine->link_by_name_or_null(hostlink->link_up); + const auto* linkDown = engine->link_by_name_or_null(hostlink->link_down); xbt_assert(linkUp, "Link '%s' not found!", hostlink->link_up.c_str()); xbt_assert(linkDown, "Link '%s' not found!", hostlink->link_down.c_str()); @@ -442,7 +449,7 @@ void sg_platf_new_bypass_route(simgrid::kernel::routing::RouteCreationArgs* rout void sg_platf_new_actor(simgrid::kernel::routing::ActorCreationArgs* actor) { const auto* engine = simgrid::s4u::Engine::get_instance(); - sg_host_t host = sg_host_by_name(actor->host); + sg_host_t host = sg_host_by_name(actor->host); if (not host) { // The requested host does not exist. Do a nice message to the user std::string msg = std::string("Cannot create actor '") + actor->function + "': host '" + actor->host + diff --git a/src/surf/xml/simgrid.dtd b/src/kernel/xml/simgrid.dtd similarity index 100% rename from src/surf/xml/simgrid.dtd rename to src/kernel/xml/simgrid.dtd diff --git a/src/surf/xml/simgrid_dtd.c b/src/kernel/xml/simgrid_dtd.c similarity index 67% rename from src/surf/xml/simgrid_dtd.c rename to src/kernel/xml/simgrid_dtd.c index c686091e0a..5cc34983c9 100644 --- a/src/surf/xml/simgrid_dtd.c +++ b/src/kernel/xml/simgrid_dtd.c @@ -3,30 +3,30 @@ /* A lexical scanner generated by flex */ -#define yy_create_buffer surf_parse__create_buffer -#define yy_delete_buffer surf_parse__delete_buffer -#define yy_scan_buffer surf_parse__scan_buffer -#define yy_scan_string surf_parse__scan_string -#define yy_scan_bytes surf_parse__scan_bytes -#define yy_init_buffer surf_parse__init_buffer -#define yy_flush_buffer surf_parse__flush_buffer -#define yy_load_buffer_state surf_parse__load_buffer_state -#define yy_switch_to_buffer surf_parse__switch_to_buffer -#define yypush_buffer_state surf_parse_push_buffer_state -#define yypop_buffer_state surf_parse_pop_buffer_state -#define yyensure_buffer_stack surf_parse_ensure_buffer_stack -#define yy_flex_debug surf_parse__flex_debug -#define yyin surf_parse_in -#define yyleng surf_parse_leng -#define yylex surf_parse_lex -#define yylineno surf_parse_lineno -#define yyout surf_parse_out -#define yyrestart surf_parse_restart -#define yytext surf_parse_text -#define yywrap surf_parse_wrap -#define yyalloc surf_parse_alloc -#define yyrealloc surf_parse_realloc -#define yyfree surf_parse_free +#define yy_create_buffer simgrid_parse__create_buffer +#define yy_delete_buffer simgrid_parse__delete_buffer +#define yy_scan_buffer simgrid_parse__scan_buffer +#define yy_scan_string simgrid_parse__scan_string +#define yy_scan_bytes simgrid_parse__scan_bytes +#define yy_init_buffer simgrid_parse__init_buffer +#define yy_flush_buffer simgrid_parse__flush_buffer +#define yy_load_buffer_state simgrid_parse__load_buffer_state +#define yy_switch_to_buffer simgrid_parse__switch_to_buffer +#define yypush_buffer_state simgrid_parse_push_buffer_state +#define yypop_buffer_state simgrid_parse_pop_buffer_state +#define yyensure_buffer_stack simgrid_parse_ensure_buffer_stack +#define yy_flex_debug simgrid_parse__flex_debug +#define yyin simgrid_parse_in +#define yyleng simgrid_parse_leng +#define yylex simgrid_parse_lex +#define yylineno simgrid_parse_lineno +#define yyout simgrid_parse_out +#define yyrestart simgrid_parse_restart +#define yytext simgrid_parse_text +#define yywrap simgrid_parse_wrap +#define yyalloc simgrid_parse_alloc +#define yyrealloc simgrid_parse_realloc +#define yyfree simgrid_parse_free #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 @@ -37,237 +37,237 @@ #endif #ifdef yy_create_buffer -#define surf_parse__create_buffer_ALREADY_DEFINED +#define simgrid_parse__create_buffer_ALREADY_DEFINED #else -#define yy_create_buffer surf_parse__create_buffer +#define yy_create_buffer simgrid_parse__create_buffer #endif #ifdef yy_delete_buffer -#define surf_parse__delete_buffer_ALREADY_DEFINED +#define simgrid_parse__delete_buffer_ALREADY_DEFINED #else -#define yy_delete_buffer surf_parse__delete_buffer +#define yy_delete_buffer simgrid_parse__delete_buffer #endif #ifdef yy_scan_buffer -#define surf_parse__scan_buffer_ALREADY_DEFINED +#define simgrid_parse__scan_buffer_ALREADY_DEFINED #else -#define yy_scan_buffer surf_parse__scan_buffer +#define yy_scan_buffer simgrid_parse__scan_buffer #endif #ifdef yy_scan_string -#define surf_parse__scan_string_ALREADY_DEFINED +#define simgrid_parse__scan_string_ALREADY_DEFINED #else -#define yy_scan_string surf_parse__scan_string +#define yy_scan_string simgrid_parse__scan_string #endif #ifdef yy_scan_bytes -#define surf_parse__scan_bytes_ALREADY_DEFINED +#define simgrid_parse__scan_bytes_ALREADY_DEFINED #else -#define yy_scan_bytes surf_parse__scan_bytes +#define yy_scan_bytes simgrid_parse__scan_bytes #endif #ifdef yy_init_buffer -#define surf_parse__init_buffer_ALREADY_DEFINED +#define simgrid_parse__init_buffer_ALREADY_DEFINED #else -#define yy_init_buffer surf_parse__init_buffer +#define yy_init_buffer simgrid_parse__init_buffer #endif #ifdef yy_flush_buffer -#define surf_parse__flush_buffer_ALREADY_DEFINED +#define simgrid_parse__flush_buffer_ALREADY_DEFINED #else -#define yy_flush_buffer surf_parse__flush_buffer +#define yy_flush_buffer simgrid_parse__flush_buffer #endif #ifdef yy_load_buffer_state -#define surf_parse__load_buffer_state_ALREADY_DEFINED +#define simgrid_parse__load_buffer_state_ALREADY_DEFINED #else -#define yy_load_buffer_state surf_parse__load_buffer_state +#define yy_load_buffer_state simgrid_parse__load_buffer_state #endif #ifdef yy_switch_to_buffer -#define surf_parse__switch_to_buffer_ALREADY_DEFINED +#define simgrid_parse__switch_to_buffer_ALREADY_DEFINED #else -#define yy_switch_to_buffer surf_parse__switch_to_buffer +#define yy_switch_to_buffer simgrid_parse__switch_to_buffer #endif #ifdef yypush_buffer_state -#define surf_parse_push_buffer_state_ALREADY_DEFINED +#define simgrid_parse_push_buffer_state_ALREADY_DEFINED #else -#define yypush_buffer_state surf_parse_push_buffer_state +#define yypush_buffer_state simgrid_parse_push_buffer_state #endif #ifdef yypop_buffer_state -#define surf_parse_pop_buffer_state_ALREADY_DEFINED +#define simgrid_parse_pop_buffer_state_ALREADY_DEFINED #else -#define yypop_buffer_state surf_parse_pop_buffer_state +#define yypop_buffer_state simgrid_parse_pop_buffer_state #endif #ifdef yyensure_buffer_stack -#define surf_parse_ensure_buffer_stack_ALREADY_DEFINED +#define simgrid_parse_ensure_buffer_stack_ALREADY_DEFINED #else -#define yyensure_buffer_stack surf_parse_ensure_buffer_stack +#define yyensure_buffer_stack simgrid_parse_ensure_buffer_stack #endif #ifdef yylex -#define surf_parse_lex_ALREADY_DEFINED +#define simgrid_parse_lex_ALREADY_DEFINED #else -#define yylex surf_parse_lex +#define yylex simgrid_parse_lex #endif #ifdef yyrestart -#define surf_parse_restart_ALREADY_DEFINED +#define simgrid_parse_restart_ALREADY_DEFINED #else -#define yyrestart surf_parse_restart +#define yyrestart simgrid_parse_restart #endif #ifdef yylex_init -#define surf_parse_lex_init_ALREADY_DEFINED +#define simgrid_parse_lex_init_ALREADY_DEFINED #else -#define yylex_init surf_parse_lex_init +#define yylex_init simgrid_parse_lex_init #endif #ifdef yylex_init_extra -#define surf_parse_lex_init_extra_ALREADY_DEFINED +#define simgrid_parse_lex_init_extra_ALREADY_DEFINED #else -#define yylex_init_extra surf_parse_lex_init_extra +#define yylex_init_extra simgrid_parse_lex_init_extra #endif #ifdef yylex_destroy -#define surf_parse_lex_destroy_ALREADY_DEFINED +#define simgrid_parse_lex_destroy_ALREADY_DEFINED #else -#define yylex_destroy surf_parse_lex_destroy +#define yylex_destroy simgrid_parse_lex_destroy #endif #ifdef yyget_debug -#define surf_parse_get_debug_ALREADY_DEFINED +#define simgrid_parse_get_debug_ALREADY_DEFINED #else -#define yyget_debug surf_parse_get_debug +#define yyget_debug simgrid_parse_get_debug #endif #ifdef yyset_debug -#define surf_parse_set_debug_ALREADY_DEFINED +#define simgrid_parse_set_debug_ALREADY_DEFINED #else -#define yyset_debug surf_parse_set_debug +#define yyset_debug simgrid_parse_set_debug #endif #ifdef yyget_extra -#define surf_parse_get_extra_ALREADY_DEFINED +#define simgrid_parse_get_extra_ALREADY_DEFINED #else -#define yyget_extra surf_parse_get_extra +#define yyget_extra simgrid_parse_get_extra #endif #ifdef yyset_extra -#define surf_parse_set_extra_ALREADY_DEFINED +#define simgrid_parse_set_extra_ALREADY_DEFINED #else -#define yyset_extra surf_parse_set_extra +#define yyset_extra simgrid_parse_set_extra #endif #ifdef yyget_in -#define surf_parse_get_in_ALREADY_DEFINED +#define simgrid_parse_get_in_ALREADY_DEFINED #else -#define yyget_in surf_parse_get_in +#define yyget_in simgrid_parse_get_in #endif #ifdef yyset_in -#define surf_parse_set_in_ALREADY_DEFINED +#define simgrid_parse_set_in_ALREADY_DEFINED #else -#define yyset_in surf_parse_set_in +#define yyset_in simgrid_parse_set_in #endif #ifdef yyget_out -#define surf_parse_get_out_ALREADY_DEFINED +#define simgrid_parse_get_out_ALREADY_DEFINED #else -#define yyget_out surf_parse_get_out +#define yyget_out simgrid_parse_get_out #endif #ifdef yyset_out -#define surf_parse_set_out_ALREADY_DEFINED +#define simgrid_parse_set_out_ALREADY_DEFINED #else -#define yyset_out surf_parse_set_out +#define yyset_out simgrid_parse_set_out #endif #ifdef yyget_leng -#define surf_parse_get_leng_ALREADY_DEFINED +#define simgrid_parse_get_leng_ALREADY_DEFINED #else -#define yyget_leng surf_parse_get_leng +#define yyget_leng simgrid_parse_get_leng #endif #ifdef yyget_text -#define surf_parse_get_text_ALREADY_DEFINED +#define simgrid_parse_get_text_ALREADY_DEFINED #else -#define yyget_text surf_parse_get_text +#define yyget_text simgrid_parse_get_text #endif #ifdef yyget_lineno -#define surf_parse_get_lineno_ALREADY_DEFINED +#define simgrid_parse_get_lineno_ALREADY_DEFINED #else -#define yyget_lineno surf_parse_get_lineno +#define yyget_lineno simgrid_parse_get_lineno #endif #ifdef yyset_lineno -#define surf_parse_set_lineno_ALREADY_DEFINED +#define simgrid_parse_set_lineno_ALREADY_DEFINED #else -#define yyset_lineno surf_parse_set_lineno +#define yyset_lineno simgrid_parse_set_lineno #endif #ifdef yywrap -#define surf_parse_wrap_ALREADY_DEFINED +#define simgrid_parse_wrap_ALREADY_DEFINED #else -#define yywrap surf_parse_wrap +#define yywrap simgrid_parse_wrap #endif #ifdef yyalloc -#define surf_parse_alloc_ALREADY_DEFINED +#define simgrid_parse_alloc_ALREADY_DEFINED #else -#define yyalloc surf_parse_alloc +#define yyalloc simgrid_parse_alloc #endif #ifdef yyrealloc -#define surf_parse_realloc_ALREADY_DEFINED +#define simgrid_parse_realloc_ALREADY_DEFINED #else -#define yyrealloc surf_parse_realloc +#define yyrealloc simgrid_parse_realloc #endif #ifdef yyfree -#define surf_parse_free_ALREADY_DEFINED +#define simgrid_parse_free_ALREADY_DEFINED #else -#define yyfree surf_parse_free +#define yyfree simgrid_parse_free #endif #ifdef yytext -#define surf_parse_text_ALREADY_DEFINED +#define simgrid_parse_text_ALREADY_DEFINED #else -#define yytext surf_parse_text +#define yytext simgrid_parse_text #endif #ifdef yyleng -#define surf_parse_leng_ALREADY_DEFINED +#define simgrid_parse_leng_ALREADY_DEFINED #else -#define yyleng surf_parse_leng +#define yyleng simgrid_parse_leng #endif #ifdef yyin -#define surf_parse_in_ALREADY_DEFINED +#define simgrid_parse_in_ALREADY_DEFINED #else -#define yyin surf_parse_in +#define yyin simgrid_parse_in #endif #ifdef yyout -#define surf_parse_out_ALREADY_DEFINED +#define simgrid_parse_out_ALREADY_DEFINED #else -#define yyout surf_parse_out +#define yyout simgrid_parse_out #endif #ifdef yy_flex_debug -#define surf_parse__flex_debug_ALREADY_DEFINED +#define simgrid_parse__flex_debug_ALREADY_DEFINED #else -#define yy_flex_debug surf_parse__flex_debug +#define yy_flex_debug simgrid_parse__flex_debug #endif #ifdef yylineno -#define surf_parse_lineno_ALREADY_DEFINED +#define simgrid_parse_lineno_ALREADY_DEFINED #else -#define yylineno surf_parse_lineno +#define yylineno simgrid_parse_lineno #endif /* First, we deal with platform-specific or compiler-specific issues. */ @@ -599,7 +599,7 @@ void yyfree ( void * ); /* Begin user sect3 */ -#define surf_parse_wrap() (/*CONSTCOND*/1) +#define simgrid_parse_wrap() (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef flex_uint8_t YY_CHAR; @@ -5367,7 +5367,7 @@ int yy_flex_debug = 0; #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -/* Validating XML processor for src/surf/xml/simgrid.dtd. +/* Validating XML processor for src/kernel/xml/simgrid.dtd. * * This program was generated with the FleXML XML processor generator. * FleXML is Copyright (C) 1999-2005 Kristoffer Rose. All rights reserved. @@ -5414,7 +5414,7 @@ char *yytext; */ /* Version strings. */ -const char surfxml_flexml_version[] = "1.9.6"; +const char simgrid_parse_flexml_version[] = "1.9.6"; /* ANSI headers. */ #include /* for realloc() -- needed here when using flex 2.5.4 */ @@ -5446,402 +5446,402 @@ const char surfxml_flexml_version[] = "1.9.6"; /* XML processor api. */ /* FleXML-provided data. */ -int surfxml_pcdata_ix; -extern char *surfxml_bufferstack; -#define surfxml_pcdata (surfxml_bufferstack + surfxml_pcdata_ix) -AT_surfxml_AS_id AX_surfxml_AS_id; -#define A_surfxml_AS_id (surfxml_bufferstack + AX_surfxml_AS_id) -short int surfxml_AS_id_isset; -AT_surfxml_AS_routing AX_surfxml_AS_routing; -#define A_surfxml_AS_routing (surfxml_bufferstack + AX_surfxml_AS_routing) -short int surfxml_AS_routing_isset; -AT_surfxml_ASroute_dst AX_surfxml_ASroute_dst; -#define A_surfxml_ASroute_dst (surfxml_bufferstack + AX_surfxml_ASroute_dst) -short int surfxml_ASroute_dst_isset; -AT_surfxml_ASroute_gw___dst AX_surfxml_ASroute_gw___dst; -#define A_surfxml_ASroute_gw___dst (surfxml_bufferstack + AX_surfxml_ASroute_gw___dst) -short int surfxml_ASroute_gw___dst_isset; -AT_surfxml_ASroute_gw___src AX_surfxml_ASroute_gw___src; -#define A_surfxml_ASroute_gw___src (surfxml_bufferstack + AX_surfxml_ASroute_gw___src) -short int surfxml_ASroute_gw___src_isset; -AT_surfxml_ASroute_src AX_surfxml_ASroute_src; -#define A_surfxml_ASroute_src (surfxml_bufferstack + AX_surfxml_ASroute_src) -short int surfxml_ASroute_src_isset; -AT_surfxml_ASroute_symmetrical AX_surfxml_ASroute_symmetrical; -#define A_surfxml_ASroute_symmetrical AX_surfxml_ASroute_symmetrical -short int surfxml_ASroute_symmetrical_isset; -AT_surfxml_actor_function AX_surfxml_actor_function; -#define A_surfxml_actor_function (surfxml_bufferstack + AX_surfxml_actor_function) -short int surfxml_actor_function_isset; -AT_surfxml_actor_host AX_surfxml_actor_host; -#define A_surfxml_actor_host (surfxml_bufferstack + AX_surfxml_actor_host) -short int surfxml_actor_host_isset; -AT_surfxml_actor_kill___time AX_surfxml_actor_kill___time; -#define A_surfxml_actor_kill___time (surfxml_bufferstack + AX_surfxml_actor_kill___time) -short int surfxml_actor_kill___time_isset; -AT_surfxml_actor_on___failure AX_surfxml_actor_on___failure; -#define A_surfxml_actor_on___failure AX_surfxml_actor_on___failure -short int surfxml_actor_on___failure_isset; -AT_surfxml_actor_start___time AX_surfxml_actor_start___time; -#define A_surfxml_actor_start___time (surfxml_bufferstack + AX_surfxml_actor_start___time) -short int surfxml_actor_start___time_isset; -AT_surfxml_argument_value AX_surfxml_argument_value; -#define A_surfxml_argument_value (surfxml_bufferstack + AX_surfxml_argument_value) -short int surfxml_argument_value_isset; -AT_surfxml_backbone_bandwidth AX_surfxml_backbone_bandwidth; -#define A_surfxml_backbone_bandwidth (surfxml_bufferstack + AX_surfxml_backbone_bandwidth) -short int surfxml_backbone_bandwidth_isset; -AT_surfxml_backbone_id AX_surfxml_backbone_id; -#define A_surfxml_backbone_id (surfxml_bufferstack + AX_surfxml_backbone_id) -short int surfxml_backbone_id_isset; -AT_surfxml_backbone_latency AX_surfxml_backbone_latency; -#define A_surfxml_backbone_latency (surfxml_bufferstack + AX_surfxml_backbone_latency) -short int surfxml_backbone_latency_isset; -AT_surfxml_bypassASroute_dst AX_surfxml_bypassASroute_dst; -#define A_surfxml_bypassASroute_dst (surfxml_bufferstack + AX_surfxml_bypassASroute_dst) -short int surfxml_bypassASroute_dst_isset; -AT_surfxml_bypassASroute_gw___dst AX_surfxml_bypassASroute_gw___dst; -#define A_surfxml_bypassASroute_gw___dst (surfxml_bufferstack + AX_surfxml_bypassASroute_gw___dst) -short int surfxml_bypassASroute_gw___dst_isset; -AT_surfxml_bypassASroute_gw___src AX_surfxml_bypassASroute_gw___src; -#define A_surfxml_bypassASroute_gw___src (surfxml_bufferstack + AX_surfxml_bypassASroute_gw___src) -short int surfxml_bypassASroute_gw___src_isset; -AT_surfxml_bypassASroute_src AX_surfxml_bypassASroute_src; -#define A_surfxml_bypassASroute_src (surfxml_bufferstack + AX_surfxml_bypassASroute_src) -short int surfxml_bypassASroute_src_isset; -AT_surfxml_bypassRoute_dst AX_surfxml_bypassRoute_dst; -#define A_surfxml_bypassRoute_dst (surfxml_bufferstack + AX_surfxml_bypassRoute_dst) -short int surfxml_bypassRoute_dst_isset; -AT_surfxml_bypassRoute_src AX_surfxml_bypassRoute_src; -#define A_surfxml_bypassRoute_src (surfxml_bufferstack + AX_surfxml_bypassRoute_src) -short int surfxml_bypassRoute_src_isset; -AT_surfxml_bypassZoneRoute_dst AX_surfxml_bypassZoneRoute_dst; -#define A_surfxml_bypassZoneRoute_dst (surfxml_bufferstack + AX_surfxml_bypassZoneRoute_dst) -short int surfxml_bypassZoneRoute_dst_isset; -AT_surfxml_bypassZoneRoute_gw___dst AX_surfxml_bypassZoneRoute_gw___dst; -#define A_surfxml_bypassZoneRoute_gw___dst (surfxml_bufferstack + AX_surfxml_bypassZoneRoute_gw___dst) -short int surfxml_bypassZoneRoute_gw___dst_isset; -AT_surfxml_bypassZoneRoute_gw___src AX_surfxml_bypassZoneRoute_gw___src; -#define A_surfxml_bypassZoneRoute_gw___src (surfxml_bufferstack + AX_surfxml_bypassZoneRoute_gw___src) -short int surfxml_bypassZoneRoute_gw___src_isset; -AT_surfxml_bypassZoneRoute_src AX_surfxml_bypassZoneRoute_src; -#define A_surfxml_bypassZoneRoute_src (surfxml_bufferstack + AX_surfxml_bypassZoneRoute_src) -short int surfxml_bypassZoneRoute_src_isset; -AT_surfxml_cabinet_bw AX_surfxml_cabinet_bw; -#define A_surfxml_cabinet_bw (surfxml_bufferstack + AX_surfxml_cabinet_bw) -short int surfxml_cabinet_bw_isset; -AT_surfxml_cabinet_id AX_surfxml_cabinet_id; -#define A_surfxml_cabinet_id (surfxml_bufferstack + AX_surfxml_cabinet_id) -short int surfxml_cabinet_id_isset; -AT_surfxml_cabinet_lat AX_surfxml_cabinet_lat; -#define A_surfxml_cabinet_lat (surfxml_bufferstack + AX_surfxml_cabinet_lat) -short int surfxml_cabinet_lat_isset; -AT_surfxml_cabinet_prefix AX_surfxml_cabinet_prefix; -#define A_surfxml_cabinet_prefix (surfxml_bufferstack + AX_surfxml_cabinet_prefix) -short int surfxml_cabinet_prefix_isset; -AT_surfxml_cabinet_radical AX_surfxml_cabinet_radical; -#define A_surfxml_cabinet_radical (surfxml_bufferstack + AX_surfxml_cabinet_radical) -short int surfxml_cabinet_radical_isset; -AT_surfxml_cabinet_speed AX_surfxml_cabinet_speed; -#define A_surfxml_cabinet_speed (surfxml_bufferstack + AX_surfxml_cabinet_speed) -short int surfxml_cabinet_speed_isset; -AT_surfxml_cabinet_suffix AX_surfxml_cabinet_suffix; -#define A_surfxml_cabinet_suffix (surfxml_bufferstack + AX_surfxml_cabinet_suffix) -short int surfxml_cabinet_suffix_isset; -AT_surfxml_cluster_bb___bw AX_surfxml_cluster_bb___bw; -#define A_surfxml_cluster_bb___bw (surfxml_bufferstack + AX_surfxml_cluster_bb___bw) -short int surfxml_cluster_bb___bw_isset; -AT_surfxml_cluster_bb___lat AX_surfxml_cluster_bb___lat; -#define A_surfxml_cluster_bb___lat (surfxml_bufferstack + AX_surfxml_cluster_bb___lat) -short int surfxml_cluster_bb___lat_isset; -AT_surfxml_cluster_bb___sharing___policy AX_surfxml_cluster_bb___sharing___policy; -#define A_surfxml_cluster_bb___sharing___policy AX_surfxml_cluster_bb___sharing___policy -short int surfxml_cluster_bb___sharing___policy_isset; -AT_surfxml_cluster_bw AX_surfxml_cluster_bw; -#define A_surfxml_cluster_bw (surfxml_bufferstack + AX_surfxml_cluster_bw) -short int surfxml_cluster_bw_isset; -AT_surfxml_cluster_core AX_surfxml_cluster_core; -#define A_surfxml_cluster_core (surfxml_bufferstack + AX_surfxml_cluster_core) -short int surfxml_cluster_core_isset; -AT_surfxml_cluster_id AX_surfxml_cluster_id; -#define A_surfxml_cluster_id (surfxml_bufferstack + AX_surfxml_cluster_id) -short int surfxml_cluster_id_isset; -AT_surfxml_cluster_lat AX_surfxml_cluster_lat; -#define A_surfxml_cluster_lat (surfxml_bufferstack + AX_surfxml_cluster_lat) -short int surfxml_cluster_lat_isset; -AT_surfxml_cluster_limiter___link AX_surfxml_cluster_limiter___link; -#define A_surfxml_cluster_limiter___link (surfxml_bufferstack + AX_surfxml_cluster_limiter___link) -short int surfxml_cluster_limiter___link_isset; -AT_surfxml_cluster_loopback___bw AX_surfxml_cluster_loopback___bw; -#define A_surfxml_cluster_loopback___bw (surfxml_bufferstack + AX_surfxml_cluster_loopback___bw) -short int surfxml_cluster_loopback___bw_isset; -AT_surfxml_cluster_loopback___lat AX_surfxml_cluster_loopback___lat; -#define A_surfxml_cluster_loopback___lat (surfxml_bufferstack + AX_surfxml_cluster_loopback___lat) -short int surfxml_cluster_loopback___lat_isset; -AT_surfxml_cluster_prefix AX_surfxml_cluster_prefix; -#define A_surfxml_cluster_prefix (surfxml_bufferstack + AX_surfxml_cluster_prefix) -short int surfxml_cluster_prefix_isset; -AT_surfxml_cluster_radical AX_surfxml_cluster_radical; -#define A_surfxml_cluster_radical (surfxml_bufferstack + AX_surfxml_cluster_radical) -short int surfxml_cluster_radical_isset; -AT_surfxml_cluster_router___id AX_surfxml_cluster_router___id; -#define A_surfxml_cluster_router___id (surfxml_bufferstack + AX_surfxml_cluster_router___id) -short int surfxml_cluster_router___id_isset; -AT_surfxml_cluster_sharing___policy AX_surfxml_cluster_sharing___policy; -#define A_surfxml_cluster_sharing___policy AX_surfxml_cluster_sharing___policy -short int surfxml_cluster_sharing___policy_isset; -AT_surfxml_cluster_speed AX_surfxml_cluster_speed; -#define A_surfxml_cluster_speed (surfxml_bufferstack + AX_surfxml_cluster_speed) -short int surfxml_cluster_speed_isset; -AT_surfxml_cluster_suffix AX_surfxml_cluster_suffix; -#define A_surfxml_cluster_suffix (surfxml_bufferstack + AX_surfxml_cluster_suffix) -short int surfxml_cluster_suffix_isset; -AT_surfxml_cluster_topo___parameters AX_surfxml_cluster_topo___parameters; -#define A_surfxml_cluster_topo___parameters (surfxml_bufferstack + AX_surfxml_cluster_topo___parameters) -short int surfxml_cluster_topo___parameters_isset; -AT_surfxml_cluster_topology AX_surfxml_cluster_topology; -#define A_surfxml_cluster_topology AX_surfxml_cluster_topology -short int surfxml_cluster_topology_isset; -AT_surfxml_config_id AX_surfxml_config_id; -#define A_surfxml_config_id (surfxml_bufferstack + AX_surfxml_config_id) -short int surfxml_config_id_isset; -AT_surfxml_disk_id AX_surfxml_disk_id; -#define A_surfxml_disk_id (surfxml_bufferstack + AX_surfxml_disk_id) -short int surfxml_disk_id_isset; -AT_surfxml_disk_read___bw AX_surfxml_disk_read___bw; -#define A_surfxml_disk_read___bw (surfxml_bufferstack + AX_surfxml_disk_read___bw) -short int surfxml_disk_read___bw_isset; -AT_surfxml_disk_write___bw AX_surfxml_disk_write___bw; -#define A_surfxml_disk_write___bw (surfxml_bufferstack + AX_surfxml_disk_write___bw) -short int surfxml_disk_write___bw_isset; -AT_surfxml_host_availability___file AX_surfxml_host_availability___file; -#define A_surfxml_host_availability___file (surfxml_bufferstack + AX_surfxml_host_availability___file) -short int surfxml_host_availability___file_isset; -AT_surfxml_host_coordinates AX_surfxml_host_coordinates; -#define A_surfxml_host_coordinates (surfxml_bufferstack + AX_surfxml_host_coordinates) -short int surfxml_host_coordinates_isset; -AT_surfxml_host_core AX_surfxml_host_core; -#define A_surfxml_host_core (surfxml_bufferstack + AX_surfxml_host_core) -short int surfxml_host_core_isset; -AT_surfxml_host_id AX_surfxml_host_id; -#define A_surfxml_host_id (surfxml_bufferstack + AX_surfxml_host_id) -short int surfxml_host_id_isset; -AT_surfxml_host_pstate AX_surfxml_host_pstate; -#define A_surfxml_host_pstate (surfxml_bufferstack + AX_surfxml_host_pstate) -short int surfxml_host_pstate_isset; -AT_surfxml_host_speed AX_surfxml_host_speed; -#define A_surfxml_host_speed (surfxml_bufferstack + AX_surfxml_host_speed) -short int surfxml_host_speed_isset; -AT_surfxml_host_speed___file AX_surfxml_host_speed___file; -#define A_surfxml_host_speed___file (surfxml_bufferstack + AX_surfxml_host_speed___file) -short int surfxml_host_speed___file_isset; -AT_surfxml_host_state___file AX_surfxml_host_state___file; -#define A_surfxml_host_state___file (surfxml_bufferstack + AX_surfxml_host_state___file) -short int surfxml_host_state___file_isset; -AT_surfxml_host___link_down AX_surfxml_host___link_down; -#define A_surfxml_host___link_down (surfxml_bufferstack + AX_surfxml_host___link_down) -short int surfxml_host___link_down_isset; -AT_surfxml_host___link_id AX_surfxml_host___link_id; -#define A_surfxml_host___link_id (surfxml_bufferstack + AX_surfxml_host___link_id) -short int surfxml_host___link_id_isset; -AT_surfxml_host___link_up AX_surfxml_host___link_up; -#define A_surfxml_host___link_up (surfxml_bufferstack + AX_surfxml_host___link_up) -short int surfxml_host___link_up_isset; -AT_surfxml_include_file AX_surfxml_include_file; -#define A_surfxml_include_file (surfxml_bufferstack + AX_surfxml_include_file) -short int surfxml_include_file_isset; -AT_surfxml_link_bandwidth AX_surfxml_link_bandwidth; -#define A_surfxml_link_bandwidth (surfxml_bufferstack + AX_surfxml_link_bandwidth) -short int surfxml_link_bandwidth_isset; -AT_surfxml_link_bandwidth___file AX_surfxml_link_bandwidth___file; -#define A_surfxml_link_bandwidth___file (surfxml_bufferstack + AX_surfxml_link_bandwidth___file) -short int surfxml_link_bandwidth___file_isset; -AT_surfxml_link_id AX_surfxml_link_id; -#define A_surfxml_link_id (surfxml_bufferstack + AX_surfxml_link_id) -short int surfxml_link_id_isset; -AT_surfxml_link_latency AX_surfxml_link_latency; -#define A_surfxml_link_latency (surfxml_bufferstack + AX_surfxml_link_latency) -short int surfxml_link_latency_isset; -AT_surfxml_link_latency___file AX_surfxml_link_latency___file; -#define A_surfxml_link_latency___file (surfxml_bufferstack + AX_surfxml_link_latency___file) -short int surfxml_link_latency___file_isset; -AT_surfxml_link_sharing___policy AX_surfxml_link_sharing___policy; -#define A_surfxml_link_sharing___policy AX_surfxml_link_sharing___policy -short int surfxml_link_sharing___policy_isset; -AT_surfxml_link_state___file AX_surfxml_link_state___file; -#define A_surfxml_link_state___file (surfxml_bufferstack + AX_surfxml_link_state___file) -short int surfxml_link_state___file_isset; -AT_surfxml_link___ctn_direction AX_surfxml_link___ctn_direction; -#define A_surfxml_link___ctn_direction AX_surfxml_link___ctn_direction -short int surfxml_link___ctn_direction_isset; -AT_surfxml_link___ctn_id AX_surfxml_link___ctn_id; -#define A_surfxml_link___ctn_id (surfxml_bufferstack + AX_surfxml_link___ctn_id) -short int surfxml_link___ctn_id_isset; -AT_surfxml_model___prop_id AX_surfxml_model___prop_id; -#define A_surfxml_model___prop_id (surfxml_bufferstack + AX_surfxml_model___prop_id) -short int surfxml_model___prop_id_isset; -AT_surfxml_model___prop_value AX_surfxml_model___prop_value; -#define A_surfxml_model___prop_value (surfxml_bufferstack + AX_surfxml_model___prop_value) -short int surfxml_model___prop_value_isset; -AT_surfxml_mount_name AX_surfxml_mount_name; -#define A_surfxml_mount_name (surfxml_bufferstack + AX_surfxml_mount_name) -short int surfxml_mount_name_isset; -AT_surfxml_mount_storageId AX_surfxml_mount_storageId; -#define A_surfxml_mount_storageId (surfxml_bufferstack + AX_surfxml_mount_storageId) -short int surfxml_mount_storageId_isset; -AT_surfxml_peer_availability___file AX_surfxml_peer_availability___file; -#define A_surfxml_peer_availability___file (surfxml_bufferstack + AX_surfxml_peer_availability___file) -short int surfxml_peer_availability___file_isset; -AT_surfxml_peer_bw___in AX_surfxml_peer_bw___in; -#define A_surfxml_peer_bw___in (surfxml_bufferstack + AX_surfxml_peer_bw___in) -short int surfxml_peer_bw___in_isset; -AT_surfxml_peer_bw___out AX_surfxml_peer_bw___out; -#define A_surfxml_peer_bw___out (surfxml_bufferstack + AX_surfxml_peer_bw___out) -short int surfxml_peer_bw___out_isset; -AT_surfxml_peer_coordinates AX_surfxml_peer_coordinates; -#define A_surfxml_peer_coordinates (surfxml_bufferstack + AX_surfxml_peer_coordinates) -short int surfxml_peer_coordinates_isset; -AT_surfxml_peer_id AX_surfxml_peer_id; -#define A_surfxml_peer_id (surfxml_bufferstack + AX_surfxml_peer_id) -short int surfxml_peer_id_isset; -AT_surfxml_peer_lat AX_surfxml_peer_lat; -#define A_surfxml_peer_lat (surfxml_bufferstack + AX_surfxml_peer_lat) -short int surfxml_peer_lat_isset; -AT_surfxml_peer_speed AX_surfxml_peer_speed; -#define A_surfxml_peer_speed (surfxml_bufferstack + AX_surfxml_peer_speed) -short int surfxml_peer_speed_isset; -AT_surfxml_peer_speed___file AX_surfxml_peer_speed___file; -#define A_surfxml_peer_speed___file (surfxml_bufferstack + AX_surfxml_peer_speed___file) -short int surfxml_peer_speed___file_isset; -AT_surfxml_peer_state___file AX_surfxml_peer_state___file; -#define A_surfxml_peer_state___file (surfxml_bufferstack + AX_surfxml_peer_state___file) -short int surfxml_peer_state___file_isset; -AT_surfxml_platform_version AX_surfxml_platform_version; -#define A_surfxml_platform_version (surfxml_bufferstack + AX_surfxml_platform_version) -short int surfxml_platform_version_isset; -AT_surfxml_process_function AX_surfxml_process_function; -#define A_surfxml_process_function (surfxml_bufferstack + AX_surfxml_process_function) -short int surfxml_process_function_isset; -AT_surfxml_process_host AX_surfxml_process_host; -#define A_surfxml_process_host (surfxml_bufferstack + AX_surfxml_process_host) -short int surfxml_process_host_isset; -AT_surfxml_process_kill___time AX_surfxml_process_kill___time; -#define A_surfxml_process_kill___time (surfxml_bufferstack + AX_surfxml_process_kill___time) -short int surfxml_process_kill___time_isset; -AT_surfxml_process_on___failure AX_surfxml_process_on___failure; -#define A_surfxml_process_on___failure AX_surfxml_process_on___failure -short int surfxml_process_on___failure_isset; -AT_surfxml_process_start___time AX_surfxml_process_start___time; -#define A_surfxml_process_start___time (surfxml_bufferstack + AX_surfxml_process_start___time) -short int surfxml_process_start___time_isset; -AT_surfxml_prop_id AX_surfxml_prop_id; -#define A_surfxml_prop_id (surfxml_bufferstack + AX_surfxml_prop_id) -short int surfxml_prop_id_isset; -AT_surfxml_prop_value AX_surfxml_prop_value; -#define A_surfxml_prop_value (surfxml_bufferstack + AX_surfxml_prop_value) -short int surfxml_prop_value_isset; -AT_surfxml_random_generator AX_surfxml_random_generator; -#define A_surfxml_random_generator AX_surfxml_random_generator -short int surfxml_random_generator_isset; -AT_surfxml_random_id AX_surfxml_random_id; -#define A_surfxml_random_id (surfxml_bufferstack + AX_surfxml_random_id) -short int surfxml_random_id_isset; -AT_surfxml_random_max AX_surfxml_random_max; -#define A_surfxml_random_max (surfxml_bufferstack + AX_surfxml_random_max) -short int surfxml_random_max_isset; -AT_surfxml_random_mean AX_surfxml_random_mean; -#define A_surfxml_random_mean (surfxml_bufferstack + AX_surfxml_random_mean) -short int surfxml_random_mean_isset; -AT_surfxml_random_min AX_surfxml_random_min; -#define A_surfxml_random_min (surfxml_bufferstack + AX_surfxml_random_min) -short int surfxml_random_min_isset; -AT_surfxml_random_radical AX_surfxml_random_radical; -#define A_surfxml_random_radical (surfxml_bufferstack + AX_surfxml_random_radical) -short int surfxml_random_radical_isset; -AT_surfxml_random_seed AX_surfxml_random_seed; -#define A_surfxml_random_seed (surfxml_bufferstack + AX_surfxml_random_seed) -short int surfxml_random_seed_isset; -AT_surfxml_random_std___deviation AX_surfxml_random_std___deviation; -#define A_surfxml_random_std___deviation (surfxml_bufferstack + AX_surfxml_random_std___deviation) -short int surfxml_random_std___deviation_isset; -AT_surfxml_route_dst AX_surfxml_route_dst; -#define A_surfxml_route_dst (surfxml_bufferstack + AX_surfxml_route_dst) -short int surfxml_route_dst_isset; -AT_surfxml_route_src AX_surfxml_route_src; -#define A_surfxml_route_src (surfxml_bufferstack + AX_surfxml_route_src) -short int surfxml_route_src_isset; -AT_surfxml_route_symmetrical AX_surfxml_route_symmetrical; -#define A_surfxml_route_symmetrical AX_surfxml_route_symmetrical -short int surfxml_route_symmetrical_isset; -AT_surfxml_router_coordinates AX_surfxml_router_coordinates; -#define A_surfxml_router_coordinates (surfxml_bufferstack + AX_surfxml_router_coordinates) -short int surfxml_router_coordinates_isset; -AT_surfxml_router_id AX_surfxml_router_id; -#define A_surfxml_router_id (surfxml_bufferstack + AX_surfxml_router_id) -short int surfxml_router_id_isset; -AT_surfxml_storage_attach AX_surfxml_storage_attach; -#define A_surfxml_storage_attach (surfxml_bufferstack + AX_surfxml_storage_attach) -short int surfxml_storage_attach_isset; -AT_surfxml_storage_content AX_surfxml_storage_content; -#define A_surfxml_storage_content (surfxml_bufferstack + AX_surfxml_storage_content) -short int surfxml_storage_content_isset; -AT_surfxml_storage_id AX_surfxml_storage_id; -#define A_surfxml_storage_id (surfxml_bufferstack + AX_surfxml_storage_id) -short int surfxml_storage_id_isset; -AT_surfxml_storage_typeId AX_surfxml_storage_typeId; -#define A_surfxml_storage_typeId (surfxml_bufferstack + AX_surfxml_storage_typeId) -short int surfxml_storage_typeId_isset; -AT_surfxml_storage___type_content AX_surfxml_storage___type_content; -#define A_surfxml_storage___type_content (surfxml_bufferstack + AX_surfxml_storage___type_content) -short int surfxml_storage___type_content_isset; -AT_surfxml_storage___type_id AX_surfxml_storage___type_id; -#define A_surfxml_storage___type_id (surfxml_bufferstack + AX_surfxml_storage___type_id) -short int surfxml_storage___type_id_isset; -AT_surfxml_storage___type_model AX_surfxml_storage___type_model; -#define A_surfxml_storage___type_model (surfxml_bufferstack + AX_surfxml_storage___type_model) -short int surfxml_storage___type_model_isset; -AT_surfxml_storage___type_size AX_surfxml_storage___type_size; -#define A_surfxml_storage___type_size (surfxml_bufferstack + AX_surfxml_storage___type_size) -short int surfxml_storage___type_size_isset; -AT_surfxml_trace_file AX_surfxml_trace_file; -#define A_surfxml_trace_file (surfxml_bufferstack + AX_surfxml_trace_file) -short int surfxml_trace_file_isset; -AT_surfxml_trace_id AX_surfxml_trace_id; -#define A_surfxml_trace_id (surfxml_bufferstack + AX_surfxml_trace_id) -short int surfxml_trace_id_isset; -AT_surfxml_trace_periodicity AX_surfxml_trace_periodicity; -#define A_surfxml_trace_periodicity (surfxml_bufferstack + AX_surfxml_trace_periodicity) -short int surfxml_trace_periodicity_isset; -AT_surfxml_trace___connect_element AX_surfxml_trace___connect_element; -#define A_surfxml_trace___connect_element (surfxml_bufferstack + AX_surfxml_trace___connect_element) -short int surfxml_trace___connect_element_isset; -AT_surfxml_trace___connect_kind AX_surfxml_trace___connect_kind; -#define A_surfxml_trace___connect_kind AX_surfxml_trace___connect_kind -short int surfxml_trace___connect_kind_isset; -AT_surfxml_trace___connect_trace AX_surfxml_trace___connect_trace; -#define A_surfxml_trace___connect_trace (surfxml_bufferstack + AX_surfxml_trace___connect_trace) -short int surfxml_trace___connect_trace_isset; -AT_surfxml_zone_id AX_surfxml_zone_id; -#define A_surfxml_zone_id (surfxml_bufferstack + AX_surfxml_zone_id) -short int surfxml_zone_id_isset; -AT_surfxml_zone_routing AX_surfxml_zone_routing; -#define A_surfxml_zone_routing (surfxml_bufferstack + AX_surfxml_zone_routing) -short int surfxml_zone_routing_isset; -AT_surfxml_zoneRoute_dst AX_surfxml_zoneRoute_dst; -#define A_surfxml_zoneRoute_dst (surfxml_bufferstack + AX_surfxml_zoneRoute_dst) -short int surfxml_zoneRoute_dst_isset; -AT_surfxml_zoneRoute_gw___dst AX_surfxml_zoneRoute_gw___dst; -#define A_surfxml_zoneRoute_gw___dst (surfxml_bufferstack + AX_surfxml_zoneRoute_gw___dst) -short int surfxml_zoneRoute_gw___dst_isset; -AT_surfxml_zoneRoute_gw___src AX_surfxml_zoneRoute_gw___src; -#define A_surfxml_zoneRoute_gw___src (surfxml_bufferstack + AX_surfxml_zoneRoute_gw___src) -short int surfxml_zoneRoute_gw___src_isset; -AT_surfxml_zoneRoute_src AX_surfxml_zoneRoute_src; -#define A_surfxml_zoneRoute_src (surfxml_bufferstack + AX_surfxml_zoneRoute_src) -short int surfxml_zoneRoute_src_isset; -AT_surfxml_zoneRoute_symmetrical AX_surfxml_zoneRoute_symmetrical; -#define A_surfxml_zoneRoute_symmetrical AX_surfxml_zoneRoute_symmetrical -short int surfxml_zoneRoute_symmetrical_isset; +int simgrid_parse_pcdata_ix; +extern char *simgrid_parse_bufferstack; +#define simgrid_parse_pcdata (simgrid_parse_bufferstack + simgrid_parse_pcdata_ix) +AT_simgrid_parse_AS_id AX_simgrid_parse_AS_id; +#define A_simgrid_parse_AS_id (simgrid_parse_bufferstack + AX_simgrid_parse_AS_id) +short int simgrid_parse_AS_id_isset; +AT_simgrid_parse_AS_routing AX_simgrid_parse_AS_routing; +#define A_simgrid_parse_AS_routing (simgrid_parse_bufferstack + AX_simgrid_parse_AS_routing) +short int simgrid_parse_AS_routing_isset; +AT_simgrid_parse_ASroute_dst AX_simgrid_parse_ASroute_dst; +#define A_simgrid_parse_ASroute_dst (simgrid_parse_bufferstack + AX_simgrid_parse_ASroute_dst) +short int simgrid_parse_ASroute_dst_isset; +AT_simgrid_parse_ASroute_gw___dst AX_simgrid_parse_ASroute_gw___dst; +#define A_simgrid_parse_ASroute_gw___dst (simgrid_parse_bufferstack + AX_simgrid_parse_ASroute_gw___dst) +short int simgrid_parse_ASroute_gw___dst_isset; +AT_simgrid_parse_ASroute_gw___src AX_simgrid_parse_ASroute_gw___src; +#define A_simgrid_parse_ASroute_gw___src (simgrid_parse_bufferstack + AX_simgrid_parse_ASroute_gw___src) +short int simgrid_parse_ASroute_gw___src_isset; +AT_simgrid_parse_ASroute_src AX_simgrid_parse_ASroute_src; +#define A_simgrid_parse_ASroute_src (simgrid_parse_bufferstack + AX_simgrid_parse_ASroute_src) +short int simgrid_parse_ASroute_src_isset; +AT_simgrid_parse_ASroute_symmetrical AX_simgrid_parse_ASroute_symmetrical; +#define A_simgrid_parse_ASroute_symmetrical AX_simgrid_parse_ASroute_symmetrical +short int simgrid_parse_ASroute_symmetrical_isset; +AT_simgrid_parse_actor_function AX_simgrid_parse_actor_function; +#define A_simgrid_parse_actor_function (simgrid_parse_bufferstack + AX_simgrid_parse_actor_function) +short int simgrid_parse_actor_function_isset; +AT_simgrid_parse_actor_host AX_simgrid_parse_actor_host; +#define A_simgrid_parse_actor_host (simgrid_parse_bufferstack + AX_simgrid_parse_actor_host) +short int simgrid_parse_actor_host_isset; +AT_simgrid_parse_actor_kill___time AX_simgrid_parse_actor_kill___time; +#define A_simgrid_parse_actor_kill___time (simgrid_parse_bufferstack + AX_simgrid_parse_actor_kill___time) +short int simgrid_parse_actor_kill___time_isset; +AT_simgrid_parse_actor_on___failure AX_simgrid_parse_actor_on___failure; +#define A_simgrid_parse_actor_on___failure AX_simgrid_parse_actor_on___failure +short int simgrid_parse_actor_on___failure_isset; +AT_simgrid_parse_actor_start___time AX_simgrid_parse_actor_start___time; +#define A_simgrid_parse_actor_start___time (simgrid_parse_bufferstack + AX_simgrid_parse_actor_start___time) +short int simgrid_parse_actor_start___time_isset; +AT_simgrid_parse_argument_value AX_simgrid_parse_argument_value; +#define A_simgrid_parse_argument_value (simgrid_parse_bufferstack + AX_simgrid_parse_argument_value) +short int simgrid_parse_argument_value_isset; +AT_simgrid_parse_backbone_bandwidth AX_simgrid_parse_backbone_bandwidth; +#define A_simgrid_parse_backbone_bandwidth (simgrid_parse_bufferstack + AX_simgrid_parse_backbone_bandwidth) +short int simgrid_parse_backbone_bandwidth_isset; +AT_simgrid_parse_backbone_id AX_simgrid_parse_backbone_id; +#define A_simgrid_parse_backbone_id (simgrid_parse_bufferstack + AX_simgrid_parse_backbone_id) +short int simgrid_parse_backbone_id_isset; +AT_simgrid_parse_backbone_latency AX_simgrid_parse_backbone_latency; +#define A_simgrid_parse_backbone_latency (simgrid_parse_bufferstack + AX_simgrid_parse_backbone_latency) +short int simgrid_parse_backbone_latency_isset; +AT_simgrid_parse_bypassASroute_dst AX_simgrid_parse_bypassASroute_dst; +#define A_simgrid_parse_bypassASroute_dst (simgrid_parse_bufferstack + AX_simgrid_parse_bypassASroute_dst) +short int simgrid_parse_bypassASroute_dst_isset; +AT_simgrid_parse_bypassASroute_gw___dst AX_simgrid_parse_bypassASroute_gw___dst; +#define A_simgrid_parse_bypassASroute_gw___dst (simgrid_parse_bufferstack + AX_simgrid_parse_bypassASroute_gw___dst) +short int simgrid_parse_bypassASroute_gw___dst_isset; +AT_simgrid_parse_bypassASroute_gw___src AX_simgrid_parse_bypassASroute_gw___src; +#define A_simgrid_parse_bypassASroute_gw___src (simgrid_parse_bufferstack + AX_simgrid_parse_bypassASroute_gw___src) +short int simgrid_parse_bypassASroute_gw___src_isset; +AT_simgrid_parse_bypassASroute_src AX_simgrid_parse_bypassASroute_src; +#define A_simgrid_parse_bypassASroute_src (simgrid_parse_bufferstack + AX_simgrid_parse_bypassASroute_src) +short int simgrid_parse_bypassASroute_src_isset; +AT_simgrid_parse_bypassRoute_dst AX_simgrid_parse_bypassRoute_dst; +#define A_simgrid_parse_bypassRoute_dst (simgrid_parse_bufferstack + AX_simgrid_parse_bypassRoute_dst) +short int simgrid_parse_bypassRoute_dst_isset; +AT_simgrid_parse_bypassRoute_src AX_simgrid_parse_bypassRoute_src; +#define A_simgrid_parse_bypassRoute_src (simgrid_parse_bufferstack + AX_simgrid_parse_bypassRoute_src) +short int simgrid_parse_bypassRoute_src_isset; +AT_simgrid_parse_bypassZoneRoute_dst AX_simgrid_parse_bypassZoneRoute_dst; +#define A_simgrid_parse_bypassZoneRoute_dst (simgrid_parse_bufferstack + AX_simgrid_parse_bypassZoneRoute_dst) +short int simgrid_parse_bypassZoneRoute_dst_isset; +AT_simgrid_parse_bypassZoneRoute_gw___dst AX_simgrid_parse_bypassZoneRoute_gw___dst; +#define A_simgrid_parse_bypassZoneRoute_gw___dst (simgrid_parse_bufferstack + AX_simgrid_parse_bypassZoneRoute_gw___dst) +short int simgrid_parse_bypassZoneRoute_gw___dst_isset; +AT_simgrid_parse_bypassZoneRoute_gw___src AX_simgrid_parse_bypassZoneRoute_gw___src; +#define A_simgrid_parse_bypassZoneRoute_gw___src (simgrid_parse_bufferstack + AX_simgrid_parse_bypassZoneRoute_gw___src) +short int simgrid_parse_bypassZoneRoute_gw___src_isset; +AT_simgrid_parse_bypassZoneRoute_src AX_simgrid_parse_bypassZoneRoute_src; +#define A_simgrid_parse_bypassZoneRoute_src (simgrid_parse_bufferstack + AX_simgrid_parse_bypassZoneRoute_src) +short int simgrid_parse_bypassZoneRoute_src_isset; +AT_simgrid_parse_cabinet_bw AX_simgrid_parse_cabinet_bw; +#define A_simgrid_parse_cabinet_bw (simgrid_parse_bufferstack + AX_simgrid_parse_cabinet_bw) +short int simgrid_parse_cabinet_bw_isset; +AT_simgrid_parse_cabinet_id AX_simgrid_parse_cabinet_id; +#define A_simgrid_parse_cabinet_id (simgrid_parse_bufferstack + AX_simgrid_parse_cabinet_id) +short int simgrid_parse_cabinet_id_isset; +AT_simgrid_parse_cabinet_lat AX_simgrid_parse_cabinet_lat; +#define A_simgrid_parse_cabinet_lat (simgrid_parse_bufferstack + AX_simgrid_parse_cabinet_lat) +short int simgrid_parse_cabinet_lat_isset; +AT_simgrid_parse_cabinet_prefix AX_simgrid_parse_cabinet_prefix; +#define A_simgrid_parse_cabinet_prefix (simgrid_parse_bufferstack + AX_simgrid_parse_cabinet_prefix) +short int simgrid_parse_cabinet_prefix_isset; +AT_simgrid_parse_cabinet_radical AX_simgrid_parse_cabinet_radical; +#define A_simgrid_parse_cabinet_radical (simgrid_parse_bufferstack + AX_simgrid_parse_cabinet_radical) +short int simgrid_parse_cabinet_radical_isset; +AT_simgrid_parse_cabinet_speed AX_simgrid_parse_cabinet_speed; +#define A_simgrid_parse_cabinet_speed (simgrid_parse_bufferstack + AX_simgrid_parse_cabinet_speed) +short int simgrid_parse_cabinet_speed_isset; +AT_simgrid_parse_cabinet_suffix AX_simgrid_parse_cabinet_suffix; +#define A_simgrid_parse_cabinet_suffix (simgrid_parse_bufferstack + AX_simgrid_parse_cabinet_suffix) +short int simgrid_parse_cabinet_suffix_isset; +AT_simgrid_parse_cluster_bb___bw AX_simgrid_parse_cluster_bb___bw; +#define A_simgrid_parse_cluster_bb___bw (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_bb___bw) +short int simgrid_parse_cluster_bb___bw_isset; +AT_simgrid_parse_cluster_bb___lat AX_simgrid_parse_cluster_bb___lat; +#define A_simgrid_parse_cluster_bb___lat (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_bb___lat) +short int simgrid_parse_cluster_bb___lat_isset; +AT_simgrid_parse_cluster_bb___sharing___policy AX_simgrid_parse_cluster_bb___sharing___policy; +#define A_simgrid_parse_cluster_bb___sharing___policy AX_simgrid_parse_cluster_bb___sharing___policy +short int simgrid_parse_cluster_bb___sharing___policy_isset; +AT_simgrid_parse_cluster_bw AX_simgrid_parse_cluster_bw; +#define A_simgrid_parse_cluster_bw (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_bw) +short int simgrid_parse_cluster_bw_isset; +AT_simgrid_parse_cluster_core AX_simgrid_parse_cluster_core; +#define A_simgrid_parse_cluster_core (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_core) +short int simgrid_parse_cluster_core_isset; +AT_simgrid_parse_cluster_id AX_simgrid_parse_cluster_id; +#define A_simgrid_parse_cluster_id (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_id) +short int simgrid_parse_cluster_id_isset; +AT_simgrid_parse_cluster_lat AX_simgrid_parse_cluster_lat; +#define A_simgrid_parse_cluster_lat (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_lat) +short int simgrid_parse_cluster_lat_isset; +AT_simgrid_parse_cluster_limiter___link AX_simgrid_parse_cluster_limiter___link; +#define A_simgrid_parse_cluster_limiter___link (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_limiter___link) +short int simgrid_parse_cluster_limiter___link_isset; +AT_simgrid_parse_cluster_loopback___bw AX_simgrid_parse_cluster_loopback___bw; +#define A_simgrid_parse_cluster_loopback___bw (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_loopback___bw) +short int simgrid_parse_cluster_loopback___bw_isset; +AT_simgrid_parse_cluster_loopback___lat AX_simgrid_parse_cluster_loopback___lat; +#define A_simgrid_parse_cluster_loopback___lat (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_loopback___lat) +short int simgrid_parse_cluster_loopback___lat_isset; +AT_simgrid_parse_cluster_prefix AX_simgrid_parse_cluster_prefix; +#define A_simgrid_parse_cluster_prefix (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_prefix) +short int simgrid_parse_cluster_prefix_isset; +AT_simgrid_parse_cluster_radical AX_simgrid_parse_cluster_radical; +#define A_simgrid_parse_cluster_radical (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_radical) +short int simgrid_parse_cluster_radical_isset; +AT_simgrid_parse_cluster_router___id AX_simgrid_parse_cluster_router___id; +#define A_simgrid_parse_cluster_router___id (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_router___id) +short int simgrid_parse_cluster_router___id_isset; +AT_simgrid_parse_cluster_sharing___policy AX_simgrid_parse_cluster_sharing___policy; +#define A_simgrid_parse_cluster_sharing___policy AX_simgrid_parse_cluster_sharing___policy +short int simgrid_parse_cluster_sharing___policy_isset; +AT_simgrid_parse_cluster_speed AX_simgrid_parse_cluster_speed; +#define A_simgrid_parse_cluster_speed (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_speed) +short int simgrid_parse_cluster_speed_isset; +AT_simgrid_parse_cluster_suffix AX_simgrid_parse_cluster_suffix; +#define A_simgrid_parse_cluster_suffix (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_suffix) +short int simgrid_parse_cluster_suffix_isset; +AT_simgrid_parse_cluster_topo___parameters AX_simgrid_parse_cluster_topo___parameters; +#define A_simgrid_parse_cluster_topo___parameters (simgrid_parse_bufferstack + AX_simgrid_parse_cluster_topo___parameters) +short int simgrid_parse_cluster_topo___parameters_isset; +AT_simgrid_parse_cluster_topology AX_simgrid_parse_cluster_topology; +#define A_simgrid_parse_cluster_topology AX_simgrid_parse_cluster_topology +short int simgrid_parse_cluster_topology_isset; +AT_simgrid_parse_config_id AX_simgrid_parse_config_id; +#define A_simgrid_parse_config_id (simgrid_parse_bufferstack + AX_simgrid_parse_config_id) +short int simgrid_parse_config_id_isset; +AT_simgrid_parse_disk_id AX_simgrid_parse_disk_id; +#define A_simgrid_parse_disk_id (simgrid_parse_bufferstack + AX_simgrid_parse_disk_id) +short int simgrid_parse_disk_id_isset; +AT_simgrid_parse_disk_read___bw AX_simgrid_parse_disk_read___bw; +#define A_simgrid_parse_disk_read___bw (simgrid_parse_bufferstack + AX_simgrid_parse_disk_read___bw) +short int simgrid_parse_disk_read___bw_isset; +AT_simgrid_parse_disk_write___bw AX_simgrid_parse_disk_write___bw; +#define A_simgrid_parse_disk_write___bw (simgrid_parse_bufferstack + AX_simgrid_parse_disk_write___bw) +short int simgrid_parse_disk_write___bw_isset; +AT_simgrid_parse_host_availability___file AX_simgrid_parse_host_availability___file; +#define A_simgrid_parse_host_availability___file (simgrid_parse_bufferstack + AX_simgrid_parse_host_availability___file) +short int simgrid_parse_host_availability___file_isset; +AT_simgrid_parse_host_coordinates AX_simgrid_parse_host_coordinates; +#define A_simgrid_parse_host_coordinates (simgrid_parse_bufferstack + AX_simgrid_parse_host_coordinates) +short int simgrid_parse_host_coordinates_isset; +AT_simgrid_parse_host_core AX_simgrid_parse_host_core; +#define A_simgrid_parse_host_core (simgrid_parse_bufferstack + AX_simgrid_parse_host_core) +short int simgrid_parse_host_core_isset; +AT_simgrid_parse_host_id AX_simgrid_parse_host_id; +#define A_simgrid_parse_host_id (simgrid_parse_bufferstack + AX_simgrid_parse_host_id) +short int simgrid_parse_host_id_isset; +AT_simgrid_parse_host_pstate AX_simgrid_parse_host_pstate; +#define A_simgrid_parse_host_pstate (simgrid_parse_bufferstack + AX_simgrid_parse_host_pstate) +short int simgrid_parse_host_pstate_isset; +AT_simgrid_parse_host_speed AX_simgrid_parse_host_speed; +#define A_simgrid_parse_host_speed (simgrid_parse_bufferstack + AX_simgrid_parse_host_speed) +short int simgrid_parse_host_speed_isset; +AT_simgrid_parse_host_speed___file AX_simgrid_parse_host_speed___file; +#define A_simgrid_parse_host_speed___file (simgrid_parse_bufferstack + AX_simgrid_parse_host_speed___file) +short int simgrid_parse_host_speed___file_isset; +AT_simgrid_parse_host_state___file AX_simgrid_parse_host_state___file; +#define A_simgrid_parse_host_state___file (simgrid_parse_bufferstack + AX_simgrid_parse_host_state___file) +short int simgrid_parse_host_state___file_isset; +AT_simgrid_parse_host___link_down AX_simgrid_parse_host___link_down; +#define A_simgrid_parse_host___link_down (simgrid_parse_bufferstack + AX_simgrid_parse_host___link_down) +short int simgrid_parse_host___link_down_isset; +AT_simgrid_parse_host___link_id AX_simgrid_parse_host___link_id; +#define A_simgrid_parse_host___link_id (simgrid_parse_bufferstack + AX_simgrid_parse_host___link_id) +short int simgrid_parse_host___link_id_isset; +AT_simgrid_parse_host___link_up AX_simgrid_parse_host___link_up; +#define A_simgrid_parse_host___link_up (simgrid_parse_bufferstack + AX_simgrid_parse_host___link_up) +short int simgrid_parse_host___link_up_isset; +AT_simgrid_parse_include_file AX_simgrid_parse_include_file; +#define A_simgrid_parse_include_file (simgrid_parse_bufferstack + AX_simgrid_parse_include_file) +short int simgrid_parse_include_file_isset; +AT_simgrid_parse_link_bandwidth AX_simgrid_parse_link_bandwidth; +#define A_simgrid_parse_link_bandwidth (simgrid_parse_bufferstack + AX_simgrid_parse_link_bandwidth) +short int simgrid_parse_link_bandwidth_isset; +AT_simgrid_parse_link_bandwidth___file AX_simgrid_parse_link_bandwidth___file; +#define A_simgrid_parse_link_bandwidth___file (simgrid_parse_bufferstack + AX_simgrid_parse_link_bandwidth___file) +short int simgrid_parse_link_bandwidth___file_isset; +AT_simgrid_parse_link_id AX_simgrid_parse_link_id; +#define A_simgrid_parse_link_id (simgrid_parse_bufferstack + AX_simgrid_parse_link_id) +short int simgrid_parse_link_id_isset; +AT_simgrid_parse_link_latency AX_simgrid_parse_link_latency; +#define A_simgrid_parse_link_latency (simgrid_parse_bufferstack + AX_simgrid_parse_link_latency) +short int simgrid_parse_link_latency_isset; +AT_simgrid_parse_link_latency___file AX_simgrid_parse_link_latency___file; +#define A_simgrid_parse_link_latency___file (simgrid_parse_bufferstack + AX_simgrid_parse_link_latency___file) +short int simgrid_parse_link_latency___file_isset; +AT_simgrid_parse_link_sharing___policy AX_simgrid_parse_link_sharing___policy; +#define A_simgrid_parse_link_sharing___policy AX_simgrid_parse_link_sharing___policy +short int simgrid_parse_link_sharing___policy_isset; +AT_simgrid_parse_link_state___file AX_simgrid_parse_link_state___file; +#define A_simgrid_parse_link_state___file (simgrid_parse_bufferstack + AX_simgrid_parse_link_state___file) +short int simgrid_parse_link_state___file_isset; +AT_simgrid_parse_link___ctn_direction AX_simgrid_parse_link___ctn_direction; +#define A_simgrid_parse_link___ctn_direction AX_simgrid_parse_link___ctn_direction +short int simgrid_parse_link___ctn_direction_isset; +AT_simgrid_parse_link___ctn_id AX_simgrid_parse_link___ctn_id; +#define A_simgrid_parse_link___ctn_id (simgrid_parse_bufferstack + AX_simgrid_parse_link___ctn_id) +short int simgrid_parse_link___ctn_id_isset; +AT_simgrid_parse_model___prop_id AX_simgrid_parse_model___prop_id; +#define A_simgrid_parse_model___prop_id (simgrid_parse_bufferstack + AX_simgrid_parse_model___prop_id) +short int simgrid_parse_model___prop_id_isset; +AT_simgrid_parse_model___prop_value AX_simgrid_parse_model___prop_value; +#define A_simgrid_parse_model___prop_value (simgrid_parse_bufferstack + AX_simgrid_parse_model___prop_value) +short int simgrid_parse_model___prop_value_isset; +AT_simgrid_parse_mount_name AX_simgrid_parse_mount_name; +#define A_simgrid_parse_mount_name (simgrid_parse_bufferstack + AX_simgrid_parse_mount_name) +short int simgrid_parse_mount_name_isset; +AT_simgrid_parse_mount_storageId AX_simgrid_parse_mount_storageId; +#define A_simgrid_parse_mount_storageId (simgrid_parse_bufferstack + AX_simgrid_parse_mount_storageId) +short int simgrid_parse_mount_storageId_isset; +AT_simgrid_parse_peer_availability___file AX_simgrid_parse_peer_availability___file; +#define A_simgrid_parse_peer_availability___file (simgrid_parse_bufferstack + AX_simgrid_parse_peer_availability___file) +short int simgrid_parse_peer_availability___file_isset; +AT_simgrid_parse_peer_bw___in AX_simgrid_parse_peer_bw___in; +#define A_simgrid_parse_peer_bw___in (simgrid_parse_bufferstack + AX_simgrid_parse_peer_bw___in) +short int simgrid_parse_peer_bw___in_isset; +AT_simgrid_parse_peer_bw___out AX_simgrid_parse_peer_bw___out; +#define A_simgrid_parse_peer_bw___out (simgrid_parse_bufferstack + AX_simgrid_parse_peer_bw___out) +short int simgrid_parse_peer_bw___out_isset; +AT_simgrid_parse_peer_coordinates AX_simgrid_parse_peer_coordinates; +#define A_simgrid_parse_peer_coordinates (simgrid_parse_bufferstack + AX_simgrid_parse_peer_coordinates) +short int simgrid_parse_peer_coordinates_isset; +AT_simgrid_parse_peer_id AX_simgrid_parse_peer_id; +#define A_simgrid_parse_peer_id (simgrid_parse_bufferstack + AX_simgrid_parse_peer_id) +short int simgrid_parse_peer_id_isset; +AT_simgrid_parse_peer_lat AX_simgrid_parse_peer_lat; +#define A_simgrid_parse_peer_lat (simgrid_parse_bufferstack + AX_simgrid_parse_peer_lat) +short int simgrid_parse_peer_lat_isset; +AT_simgrid_parse_peer_speed AX_simgrid_parse_peer_speed; +#define A_simgrid_parse_peer_speed (simgrid_parse_bufferstack + AX_simgrid_parse_peer_speed) +short int simgrid_parse_peer_speed_isset; +AT_simgrid_parse_peer_speed___file AX_simgrid_parse_peer_speed___file; +#define A_simgrid_parse_peer_speed___file (simgrid_parse_bufferstack + AX_simgrid_parse_peer_speed___file) +short int simgrid_parse_peer_speed___file_isset; +AT_simgrid_parse_peer_state___file AX_simgrid_parse_peer_state___file; +#define A_simgrid_parse_peer_state___file (simgrid_parse_bufferstack + AX_simgrid_parse_peer_state___file) +short int simgrid_parse_peer_state___file_isset; +AT_simgrid_parse_platform_version AX_simgrid_parse_platform_version; +#define A_simgrid_parse_platform_version (simgrid_parse_bufferstack + AX_simgrid_parse_platform_version) +short int simgrid_parse_platform_version_isset; +AT_simgrid_parse_process_function AX_simgrid_parse_process_function; +#define A_simgrid_parse_process_function (simgrid_parse_bufferstack + AX_simgrid_parse_process_function) +short int simgrid_parse_process_function_isset; +AT_simgrid_parse_process_host AX_simgrid_parse_process_host; +#define A_simgrid_parse_process_host (simgrid_parse_bufferstack + AX_simgrid_parse_process_host) +short int simgrid_parse_process_host_isset; +AT_simgrid_parse_process_kill___time AX_simgrid_parse_process_kill___time; +#define A_simgrid_parse_process_kill___time (simgrid_parse_bufferstack + AX_simgrid_parse_process_kill___time) +short int simgrid_parse_process_kill___time_isset; +AT_simgrid_parse_process_on___failure AX_simgrid_parse_process_on___failure; +#define A_simgrid_parse_process_on___failure AX_simgrid_parse_process_on___failure +short int simgrid_parse_process_on___failure_isset; +AT_simgrid_parse_process_start___time AX_simgrid_parse_process_start___time; +#define A_simgrid_parse_process_start___time (simgrid_parse_bufferstack + AX_simgrid_parse_process_start___time) +short int simgrid_parse_process_start___time_isset; +AT_simgrid_parse_prop_id AX_simgrid_parse_prop_id; +#define A_simgrid_parse_prop_id (simgrid_parse_bufferstack + AX_simgrid_parse_prop_id) +short int simgrid_parse_prop_id_isset; +AT_simgrid_parse_prop_value AX_simgrid_parse_prop_value; +#define A_simgrid_parse_prop_value (simgrid_parse_bufferstack + AX_simgrid_parse_prop_value) +short int simgrid_parse_prop_value_isset; +AT_simgrid_parse_random_generator AX_simgrid_parse_random_generator; +#define A_simgrid_parse_random_generator AX_simgrid_parse_random_generator +short int simgrid_parse_random_generator_isset; +AT_simgrid_parse_random_id AX_simgrid_parse_random_id; +#define A_simgrid_parse_random_id (simgrid_parse_bufferstack + AX_simgrid_parse_random_id) +short int simgrid_parse_random_id_isset; +AT_simgrid_parse_random_max AX_simgrid_parse_random_max; +#define A_simgrid_parse_random_max (simgrid_parse_bufferstack + AX_simgrid_parse_random_max) +short int simgrid_parse_random_max_isset; +AT_simgrid_parse_random_mean AX_simgrid_parse_random_mean; +#define A_simgrid_parse_random_mean (simgrid_parse_bufferstack + AX_simgrid_parse_random_mean) +short int simgrid_parse_random_mean_isset; +AT_simgrid_parse_random_min AX_simgrid_parse_random_min; +#define A_simgrid_parse_random_min (simgrid_parse_bufferstack + AX_simgrid_parse_random_min) +short int simgrid_parse_random_min_isset; +AT_simgrid_parse_random_radical AX_simgrid_parse_random_radical; +#define A_simgrid_parse_random_radical (simgrid_parse_bufferstack + AX_simgrid_parse_random_radical) +short int simgrid_parse_random_radical_isset; +AT_simgrid_parse_random_seed AX_simgrid_parse_random_seed; +#define A_simgrid_parse_random_seed (simgrid_parse_bufferstack + AX_simgrid_parse_random_seed) +short int simgrid_parse_random_seed_isset; +AT_simgrid_parse_random_std___deviation AX_simgrid_parse_random_std___deviation; +#define A_simgrid_parse_random_std___deviation (simgrid_parse_bufferstack + AX_simgrid_parse_random_std___deviation) +short int simgrid_parse_random_std___deviation_isset; +AT_simgrid_parse_route_dst AX_simgrid_parse_route_dst; +#define A_simgrid_parse_route_dst (simgrid_parse_bufferstack + AX_simgrid_parse_route_dst) +short int simgrid_parse_route_dst_isset; +AT_simgrid_parse_route_src AX_simgrid_parse_route_src; +#define A_simgrid_parse_route_src (simgrid_parse_bufferstack + AX_simgrid_parse_route_src) +short int simgrid_parse_route_src_isset; +AT_simgrid_parse_route_symmetrical AX_simgrid_parse_route_symmetrical; +#define A_simgrid_parse_route_symmetrical AX_simgrid_parse_route_symmetrical +short int simgrid_parse_route_symmetrical_isset; +AT_simgrid_parse_router_coordinates AX_simgrid_parse_router_coordinates; +#define A_simgrid_parse_router_coordinates (simgrid_parse_bufferstack + AX_simgrid_parse_router_coordinates) +short int simgrid_parse_router_coordinates_isset; +AT_simgrid_parse_router_id AX_simgrid_parse_router_id; +#define A_simgrid_parse_router_id (simgrid_parse_bufferstack + AX_simgrid_parse_router_id) +short int simgrid_parse_router_id_isset; +AT_simgrid_parse_storage_attach AX_simgrid_parse_storage_attach; +#define A_simgrid_parse_storage_attach (simgrid_parse_bufferstack + AX_simgrid_parse_storage_attach) +short int simgrid_parse_storage_attach_isset; +AT_simgrid_parse_storage_content AX_simgrid_parse_storage_content; +#define A_simgrid_parse_storage_content (simgrid_parse_bufferstack + AX_simgrid_parse_storage_content) +short int simgrid_parse_storage_content_isset; +AT_simgrid_parse_storage_id AX_simgrid_parse_storage_id; +#define A_simgrid_parse_storage_id (simgrid_parse_bufferstack + AX_simgrid_parse_storage_id) +short int simgrid_parse_storage_id_isset; +AT_simgrid_parse_storage_typeId AX_simgrid_parse_storage_typeId; +#define A_simgrid_parse_storage_typeId (simgrid_parse_bufferstack + AX_simgrid_parse_storage_typeId) +short int simgrid_parse_storage_typeId_isset; +AT_simgrid_parse_storage___type_content AX_simgrid_parse_storage___type_content; +#define A_simgrid_parse_storage___type_content (simgrid_parse_bufferstack + AX_simgrid_parse_storage___type_content) +short int simgrid_parse_storage___type_content_isset; +AT_simgrid_parse_storage___type_id AX_simgrid_parse_storage___type_id; +#define A_simgrid_parse_storage___type_id (simgrid_parse_bufferstack + AX_simgrid_parse_storage___type_id) +short int simgrid_parse_storage___type_id_isset; +AT_simgrid_parse_storage___type_model AX_simgrid_parse_storage___type_model; +#define A_simgrid_parse_storage___type_model (simgrid_parse_bufferstack + AX_simgrid_parse_storage___type_model) +short int simgrid_parse_storage___type_model_isset; +AT_simgrid_parse_storage___type_size AX_simgrid_parse_storage___type_size; +#define A_simgrid_parse_storage___type_size (simgrid_parse_bufferstack + AX_simgrid_parse_storage___type_size) +short int simgrid_parse_storage___type_size_isset; +AT_simgrid_parse_trace_file AX_simgrid_parse_trace_file; +#define A_simgrid_parse_trace_file (simgrid_parse_bufferstack + AX_simgrid_parse_trace_file) +short int simgrid_parse_trace_file_isset; +AT_simgrid_parse_trace_id AX_simgrid_parse_trace_id; +#define A_simgrid_parse_trace_id (simgrid_parse_bufferstack + AX_simgrid_parse_trace_id) +short int simgrid_parse_trace_id_isset; +AT_simgrid_parse_trace_periodicity AX_simgrid_parse_trace_periodicity; +#define A_simgrid_parse_trace_periodicity (simgrid_parse_bufferstack + AX_simgrid_parse_trace_periodicity) +short int simgrid_parse_trace_periodicity_isset; +AT_simgrid_parse_trace___connect_element AX_simgrid_parse_trace___connect_element; +#define A_simgrid_parse_trace___connect_element (simgrid_parse_bufferstack + AX_simgrid_parse_trace___connect_element) +short int simgrid_parse_trace___connect_element_isset; +AT_simgrid_parse_trace___connect_kind AX_simgrid_parse_trace___connect_kind; +#define A_simgrid_parse_trace___connect_kind AX_simgrid_parse_trace___connect_kind +short int simgrid_parse_trace___connect_kind_isset; +AT_simgrid_parse_trace___connect_trace AX_simgrid_parse_trace___connect_trace; +#define A_simgrid_parse_trace___connect_trace (simgrid_parse_bufferstack + AX_simgrid_parse_trace___connect_trace) +short int simgrid_parse_trace___connect_trace_isset; +AT_simgrid_parse_zone_id AX_simgrid_parse_zone_id; +#define A_simgrid_parse_zone_id (simgrid_parse_bufferstack + AX_simgrid_parse_zone_id) +short int simgrid_parse_zone_id_isset; +AT_simgrid_parse_zone_routing AX_simgrid_parse_zone_routing; +#define A_simgrid_parse_zone_routing (simgrid_parse_bufferstack + AX_simgrid_parse_zone_routing) +short int simgrid_parse_zone_routing_isset; +AT_simgrid_parse_zoneRoute_dst AX_simgrid_parse_zoneRoute_dst; +#define A_simgrid_parse_zoneRoute_dst (simgrid_parse_bufferstack + AX_simgrid_parse_zoneRoute_dst) +short int simgrid_parse_zoneRoute_dst_isset; +AT_simgrid_parse_zoneRoute_gw___dst AX_simgrid_parse_zoneRoute_gw___dst; +#define A_simgrid_parse_zoneRoute_gw___dst (simgrid_parse_bufferstack + AX_simgrid_parse_zoneRoute_gw___dst) +short int simgrid_parse_zoneRoute_gw___dst_isset; +AT_simgrid_parse_zoneRoute_gw___src AX_simgrid_parse_zoneRoute_gw___src; +#define A_simgrid_parse_zoneRoute_gw___src (simgrid_parse_bufferstack + AX_simgrid_parse_zoneRoute_gw___src) +short int simgrid_parse_zoneRoute_gw___src_isset; +AT_simgrid_parse_zoneRoute_src AX_simgrid_parse_zoneRoute_src; +#define A_simgrid_parse_zoneRoute_src (simgrid_parse_bufferstack + AX_simgrid_parse_zoneRoute_src) +short int simgrid_parse_zoneRoute_src_isset; +AT_simgrid_parse_zoneRoute_symmetrical AX_simgrid_parse_zoneRoute_symmetrical; +#define A_simgrid_parse_zoneRoute_symmetrical AX_simgrid_parse_zoneRoute_symmetrical +short int simgrid_parse_zoneRoute_symmetrical_isset; /* XML state. */ #ifdef FLEX_DEBUG @@ -5866,11 +5866,11 @@ static int fail(const char*, ...); enum {flexml_max_err_msg_size = 512}; static char flexml_err_msg[flexml_max_err_msg_size]; -const char * surfxml_parse_err_msg() +const char * simgrid_parse_parse_err_msg() { return flexml_err_msg; } -static void reset_surfxml_parse_err_msg() +static void reset_simgrid_parse_parse_err_msg() { flexml_err_msg[0] = '\0'; } @@ -5880,7 +5880,7 @@ static void cleanup(void); #define CLEANUP cleanup() /* Text buffer stack handling. */ -char *surfxml_bufferstack = NULL; +char *simgrid_parse_bufferstack = NULL; static int blimit = FLEXML_BUFFERSTACKSIZE; static int bnext = 1; @@ -5889,10 +5889,10 @@ static int ilimit = FLEXML_INDEXSTACKSIZE; static int inext = 1; #define BUFFERSET(P) (P = bnext) -#define BUFFERPUTC(C) (ck_blimit(), surfxml_bufferstack[bnext++] = (C)) +#define BUFFERPUTC(C) (ck_blimit(), simgrid_parse_bufferstack[bnext++] = (C)) #define BUFFERDONE (BUFFERPUTC('\0')) -#define BUFFERLITERAL(C, P) surfxml_bufferliteral(C, &(P), yytext) +#define BUFFERLITERAL(C, P) simgrid_parse_bufferliteral(C, &(P), yytext) /* after this is called, there are at least 2 slots left in the stack */ static int ck_blimit() @@ -5900,9 +5900,9 @@ static int ck_blimit() if (bnext >= blimit) { blimit += FLEXML_BUFFERSTACKSIZE + 2; { - char *temp = (char *) realloc(surfxml_bufferstack, blimit); + char *temp = (char *) realloc(simgrid_parse_bufferstack, blimit); assert(temp); - surfxml_bufferstack = temp; + simgrid_parse_bufferstack = temp; } } return 0; @@ -5923,7 +5923,7 @@ static int ck_ilimit() } #ifdef FLEXML_NEED_BUFFERLIT -static void surfxml_bufferliteral(char c, int* pp, const char* text) +static void simgrid_parse_bufferliteral(char c, int* pp, const char* text) { BUFFERSET(*pp); if (c) { @@ -5989,7 +5989,7 @@ static int popbuffer(void) */ /* State names. */ -const char* *surfxml_statenames=NULL; +const char* *simgrid_parse_statenames=NULL; #define INITIAL 0 #define PROLOG 1 @@ -6000,162 +6000,162 @@ const char* *surfxml_statenames=NULL; #define VALUE1 6 #define VALUE2 7 #define CDATA 8 -#define AL_surfxml_AS 9 -#define S_surfxml_AS 10 -#define S_surfxml_AS_1 11 -#define S_surfxml_AS_2 12 -#define S_surfxml_AS_3 13 -#define S_surfxml_AS_4 14 -#define S_surfxml_AS_5 15 -#define S_surfxml_AS_6 16 -#define S_surfxml_AS_7 17 -#define S_surfxml_AS_8 18 -#define S_surfxml_AS_9 19 -#define S_surfxml_AS_10 20 -#define S_surfxml_AS_11 21 -#define S_surfxml_AS_12 22 -#define S_surfxml_AS_13 23 -#define S_surfxml_AS_14 24 -#define S_surfxml_AS_15 25 -#define S_surfxml_AS_16 26 -#define E_surfxml_AS 27 -#define AL_surfxml_ASroute 28 -#define S_surfxml_ASroute 29 -#define S_surfxml_ASroute_1 30 -#define S_surfxml_ASroute_2 31 -#define E_surfxml_ASroute 32 -#define AL_surfxml_actor 33 -#define S_surfxml_actor 34 -#define S_surfxml_actor_1 35 -#define S_surfxml_actor_2 36 -#define E_surfxml_actor 37 -#define AL_surfxml_argument 38 -#define E_surfxml_argument 39 -#define AL_surfxml_backbone 40 -#define E_surfxml_backbone 41 -#define AL_surfxml_bypassASroute 42 -#define S_surfxml_bypassASroute 43 -#define S_surfxml_bypassASroute_1 44 -#define S_surfxml_bypassASroute_2 45 -#define E_surfxml_bypassASroute 46 -#define AL_surfxml_bypassRoute 47 -#define S_surfxml_bypassRoute 48 -#define S_surfxml_bypassRoute_1 49 -#define S_surfxml_bypassRoute_2 50 -#define E_surfxml_bypassRoute 51 -#define AL_surfxml_bypassZoneRoute 52 -#define S_surfxml_bypassZoneRoute 53 -#define S_surfxml_bypassZoneRoute_1 54 -#define S_surfxml_bypassZoneRoute_2 55 -#define E_surfxml_bypassZoneRoute 56 -#define AL_surfxml_cabinet 57 -#define E_surfxml_cabinet 58 -#define AL_surfxml_cluster 59 -#define S_surfxml_cluster 60 -#define S_surfxml_cluster_1 61 -#define S_surfxml_cluster_2 62 -#define E_surfxml_cluster 63 -#define AL_surfxml_config 64 -#define S_surfxml_config 65 -#define S_surfxml_config_1 66 -#define S_surfxml_config_2 67 -#define E_surfxml_config 68 -#define AL_surfxml_disk 69 -#define S_surfxml_disk 70 -#define S_surfxml_disk_1 71 -#define S_surfxml_disk_2 72 -#define E_surfxml_disk 73 -#define AL_surfxml_host 74 -#define S_surfxml_host 75 -#define S_surfxml_host_1 76 -#define S_surfxml_host_2 77 -#define E_surfxml_host 78 -#define AL_surfxml_host___link 79 -#define E_surfxml_host___link 80 -#define AL_surfxml_include 81 -#define S_surfxml_include 82 -#define S_surfxml_include_1 83 -#define S_surfxml_include_2 84 -#define E_surfxml_include 85 -#define AL_surfxml_link 86 -#define S_surfxml_link 87 -#define S_surfxml_link_1 88 -#define S_surfxml_link_2 89 -#define E_surfxml_link 90 -#define AL_surfxml_link___ctn 91 -#define E_surfxml_link___ctn 92 -#define AL_surfxml_model___prop 93 -#define E_surfxml_model___prop 94 -#define AL_surfxml_mount 95 -#define E_surfxml_mount 96 -#define AL_surfxml_peer 97 -#define E_surfxml_peer 98 -#define ROOT_surfxml_platform 99 -#define AL_surfxml_platform 100 -#define S_surfxml_platform 101 -#define S_surfxml_platform_1 102 -#define S_surfxml_platform_2 103 -#define S_surfxml_platform_3 104 -#define S_surfxml_platform_4 105 -#define S_surfxml_platform_5 106 -#define S_surfxml_platform_6 107 -#define S_surfxml_platform_7 108 -#define S_surfxml_platform_8 109 -#define E_surfxml_platform 110 -#define AL_surfxml_process 111 -#define S_surfxml_process 112 -#define S_surfxml_process_1 113 -#define S_surfxml_process_2 114 -#define E_surfxml_process 115 -#define AL_surfxml_prop 116 -#define E_surfxml_prop 117 -#define AL_surfxml_random 118 -#define E_surfxml_random 119 -#define AL_surfxml_route 120 -#define S_surfxml_route 121 -#define S_surfxml_route_1 122 -#define S_surfxml_route_2 123 -#define E_surfxml_route 124 -#define AL_surfxml_router 125 -#define E_surfxml_router 126 -#define AL_surfxml_storage 127 -#define S_surfxml_storage 128 -#define S_surfxml_storage_1 129 -#define S_surfxml_storage_2 130 -#define E_surfxml_storage 131 -#define AL_surfxml_storage___type 132 -#define S_surfxml_storage___type 133 -#define S_surfxml_storage___type_1 134 -#define S_surfxml_storage___type_2 135 -#define E_surfxml_storage___type 136 -#define AL_surfxml_trace 137 +#define AL_simgrid_parse_AS 9 +#define S_simgrid_parse_AS 10 +#define S_simgrid_parse_AS_1 11 +#define S_simgrid_parse_AS_2 12 +#define S_simgrid_parse_AS_3 13 +#define S_simgrid_parse_AS_4 14 +#define S_simgrid_parse_AS_5 15 +#define S_simgrid_parse_AS_6 16 +#define S_simgrid_parse_AS_7 17 +#define S_simgrid_parse_AS_8 18 +#define S_simgrid_parse_AS_9 19 +#define S_simgrid_parse_AS_10 20 +#define S_simgrid_parse_AS_11 21 +#define S_simgrid_parse_AS_12 22 +#define S_simgrid_parse_AS_13 23 +#define S_simgrid_parse_AS_14 24 +#define S_simgrid_parse_AS_15 25 +#define S_simgrid_parse_AS_16 26 +#define E_simgrid_parse_AS 27 +#define AL_simgrid_parse_ASroute 28 +#define S_simgrid_parse_ASroute 29 +#define S_simgrid_parse_ASroute_1 30 +#define S_simgrid_parse_ASroute_2 31 +#define E_simgrid_parse_ASroute 32 +#define AL_simgrid_parse_actor 33 +#define S_simgrid_parse_actor 34 +#define S_simgrid_parse_actor_1 35 +#define S_simgrid_parse_actor_2 36 +#define E_simgrid_parse_actor 37 +#define AL_simgrid_parse_argument 38 +#define E_simgrid_parse_argument 39 +#define AL_simgrid_parse_backbone 40 +#define E_simgrid_parse_backbone 41 +#define AL_simgrid_parse_bypassASroute 42 +#define S_simgrid_parse_bypassASroute 43 +#define S_simgrid_parse_bypassASroute_1 44 +#define S_simgrid_parse_bypassASroute_2 45 +#define E_simgrid_parse_bypassASroute 46 +#define AL_simgrid_parse_bypassRoute 47 +#define S_simgrid_parse_bypassRoute 48 +#define S_simgrid_parse_bypassRoute_1 49 +#define S_simgrid_parse_bypassRoute_2 50 +#define E_simgrid_parse_bypassRoute 51 +#define AL_simgrid_parse_bypassZoneRoute 52 +#define S_simgrid_parse_bypassZoneRoute 53 +#define S_simgrid_parse_bypassZoneRoute_1 54 +#define S_simgrid_parse_bypassZoneRoute_2 55 +#define E_simgrid_parse_bypassZoneRoute 56 +#define AL_simgrid_parse_cabinet 57 +#define E_simgrid_parse_cabinet 58 +#define AL_simgrid_parse_cluster 59 +#define S_simgrid_parse_cluster 60 +#define S_simgrid_parse_cluster_1 61 +#define S_simgrid_parse_cluster_2 62 +#define E_simgrid_parse_cluster 63 +#define AL_simgrid_parse_config 64 +#define S_simgrid_parse_config 65 +#define S_simgrid_parse_config_1 66 +#define S_simgrid_parse_config_2 67 +#define E_simgrid_parse_config 68 +#define AL_simgrid_parse_disk 69 +#define S_simgrid_parse_disk 70 +#define S_simgrid_parse_disk_1 71 +#define S_simgrid_parse_disk_2 72 +#define E_simgrid_parse_disk 73 +#define AL_simgrid_parse_host 74 +#define S_simgrid_parse_host 75 +#define S_simgrid_parse_host_1 76 +#define S_simgrid_parse_host_2 77 +#define E_simgrid_parse_host 78 +#define AL_simgrid_parse_host___link 79 +#define E_simgrid_parse_host___link 80 +#define AL_simgrid_parse_include 81 +#define S_simgrid_parse_include 82 +#define S_simgrid_parse_include_1 83 +#define S_simgrid_parse_include_2 84 +#define E_simgrid_parse_include 85 +#define AL_simgrid_parse_link 86 +#define S_simgrid_parse_link 87 +#define S_simgrid_parse_link_1 88 +#define S_simgrid_parse_link_2 89 +#define E_simgrid_parse_link 90 +#define AL_simgrid_parse_link___ctn 91 +#define E_simgrid_parse_link___ctn 92 +#define AL_simgrid_parse_model___prop 93 +#define E_simgrid_parse_model___prop 94 +#define AL_simgrid_parse_mount 95 +#define E_simgrid_parse_mount 96 +#define AL_simgrid_parse_peer 97 +#define E_simgrid_parse_peer 98 +#define ROOT_simgrid_parse_platform 99 +#define AL_simgrid_parse_platform 100 +#define S_simgrid_parse_platform 101 +#define S_simgrid_parse_platform_1 102 +#define S_simgrid_parse_platform_2 103 +#define S_simgrid_parse_platform_3 104 +#define S_simgrid_parse_platform_4 105 +#define S_simgrid_parse_platform_5 106 +#define S_simgrid_parse_platform_6 107 +#define S_simgrid_parse_platform_7 108 +#define S_simgrid_parse_platform_8 109 +#define E_simgrid_parse_platform 110 +#define AL_simgrid_parse_process 111 +#define S_simgrid_parse_process 112 +#define S_simgrid_parse_process_1 113 +#define S_simgrid_parse_process_2 114 +#define E_simgrid_parse_process 115 +#define AL_simgrid_parse_prop 116 +#define E_simgrid_parse_prop 117 +#define AL_simgrid_parse_random 118 +#define E_simgrid_parse_random 119 +#define AL_simgrid_parse_route 120 +#define S_simgrid_parse_route 121 +#define S_simgrid_parse_route_1 122 +#define S_simgrid_parse_route_2 123 +#define E_simgrid_parse_route 124 +#define AL_simgrid_parse_router 125 +#define E_simgrid_parse_router 126 +#define AL_simgrid_parse_storage 127 +#define S_simgrid_parse_storage 128 +#define S_simgrid_parse_storage_1 129 +#define S_simgrid_parse_storage_2 130 +#define E_simgrid_parse_storage 131 +#define AL_simgrid_parse_storage___type 132 +#define S_simgrid_parse_storage___type 133 +#define S_simgrid_parse_storage___type_1 134 +#define S_simgrid_parse_storage___type_2 135 +#define E_simgrid_parse_storage___type 136 +#define AL_simgrid_parse_trace 137 #define IN_trace 138 -#define AL_surfxml_trace___connect 139 -#define E_surfxml_trace___connect 140 -#define AL_surfxml_zone 141 -#define S_surfxml_zone 142 -#define S_surfxml_zone_1 143 -#define S_surfxml_zone_2 144 -#define S_surfxml_zone_3 145 -#define S_surfxml_zone_4 146 -#define S_surfxml_zone_5 147 -#define S_surfxml_zone_6 148 -#define S_surfxml_zone_7 149 -#define S_surfxml_zone_8 150 -#define S_surfxml_zone_9 151 -#define S_surfxml_zone_10 152 -#define S_surfxml_zone_11 153 -#define S_surfxml_zone_12 154 -#define S_surfxml_zone_13 155 -#define S_surfxml_zone_14 156 -#define S_surfxml_zone_15 157 -#define S_surfxml_zone_16 158 -#define E_surfxml_zone 159 -#define AL_surfxml_zoneRoute 160 -#define S_surfxml_zoneRoute 161 -#define S_surfxml_zoneRoute_1 162 -#define S_surfxml_zoneRoute_2 163 -#define E_surfxml_zoneRoute 164 +#define AL_simgrid_parse_trace___connect 139 +#define E_simgrid_parse_trace___connect 140 +#define AL_simgrid_parse_zone 141 +#define S_simgrid_parse_zone 142 +#define S_simgrid_parse_zone_1 143 +#define S_simgrid_parse_zone_2 144 +#define S_simgrid_parse_zone_3 145 +#define S_simgrid_parse_zone_4 146 +#define S_simgrid_parse_zone_5 147 +#define S_simgrid_parse_zone_6 148 +#define S_simgrid_parse_zone_7 149 +#define S_simgrid_parse_zone_8 150 +#define S_simgrid_parse_zone_9 151 +#define S_simgrid_parse_zone_10 152 +#define S_simgrid_parse_zone_11 153 +#define S_simgrid_parse_zone_12 154 +#define S_simgrid_parse_zone_13 155 +#define S_simgrid_parse_zone_14 156 +#define S_simgrid_parse_zone_15 157 +#define S_simgrid_parse_zone_16 158 +#define E_simgrid_parse_zone 159 +#define AL_simgrid_parse_zoneRoute 160 +#define S_simgrid_parse_zoneRoute 161 +#define S_simgrid_parse_zoneRoute_1 162 +#define S_simgrid_parse_zoneRoute_2 163 +#define E_simgrid_parse_zoneRoute 164 #define IMPOSSIBLE 165 #ifndef YY_NO_UNISTD_H @@ -6163,14 +6163,7 @@ const char* *surfxml_statenames=NULL; * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ -#if defined(_WIN32) -# ifndef __STRICT_ANSI__ -# include -# include -# endif -#else -# include -#endif +#include #endif #ifndef YY_EXTRA_TYPE @@ -6387,201 +6380,201 @@ YY_DECL /* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */ SET(PROLOG); - reset_surfxml_parse_err_msg(); - surfxml_bufferstack = (char *) malloc(FLEXML_BUFFERSTACKSIZE); - assert(surfxml_bufferstack); + reset_simgrid_parse_parse_err_msg(); + simgrid_parse_bufferstack = (char *) malloc(FLEXML_BUFFERSTACKSIZE); + assert(simgrid_parse_bufferstack); #ifdef FLEX_DEBUG { int i; for (i = 0; i < blimit; i++) { - surfxml_bufferstack[i] = '\377'; + simgrid_parse_bufferstack[i] = '\377'; } } #endif - surfxml_bufferstack[0] = '\0'; + simgrid_parse_bufferstack[0] = '\0'; indexstack = (int *) malloc(FLEXML_INDEXSTACKSIZE * sizeof(int)); assert(indexstack); indexstack[0] = 0; /* FleXML_init */ bnext = inext = 1; - surfxml_bufferliteral('\0', &bnext, "0.0"); - surfxml_bufferliteral('\0', &bnext, "2147483647"); - surfxml_bufferliteral('\0', &bnext, "N11"); - surfxml_bufferliteral('\0', &bnext, "1"); - surfxml_bufferliteral('\0', &bnext, "0.0"); - surfxml_bufferliteral('\0', &bnext, "/"); - surfxml_bufferliteral('\0', &bnext, "1"); - surfxml_bufferliteral('\0', &bnext, "0s"); - surfxml_bufferliteral('\0', &bnext, "-1.0"); - surfxml_bufferliteral('\0', &bnext, "-1.0"); - surfxml_bufferliteral('\0', &bnext, "-1.0"); - surfxml_bufferliteral('\0', &bnext, "-1.0"); - if(!surfxml_statenames) {surfxml_statenames= (const char **)calloc(IMPOSSIBLE,sizeof(char*)); - surfxml_statenames[PROLOG] = NULL; - surfxml_statenames[DOCTYPE] = NULL; - surfxml_statenames[EPILOG] = NULL; - surfxml_statenames[INCOMMENT] = NULL; - surfxml_statenames[INPI] = NULL; - surfxml_statenames[VALUE1] = NULL; - surfxml_statenames[VALUE2] = NULL; - surfxml_statenames[CDATA] = NULL; - surfxml_statenames[AL_surfxml_AS] = NULL; - surfxml_statenames[S_surfxml_AS] = "AS"; - surfxml_statenames[S_surfxml_AS_1] = "AS"; - surfxml_statenames[S_surfxml_AS_2] = "AS"; - surfxml_statenames[S_surfxml_AS_3] = "AS"; - surfxml_statenames[S_surfxml_AS_4] = "AS"; - surfxml_statenames[S_surfxml_AS_5] = "AS"; - surfxml_statenames[S_surfxml_AS_6] = "AS"; - surfxml_statenames[S_surfxml_AS_7] = "AS"; - surfxml_statenames[S_surfxml_AS_8] = "AS"; - surfxml_statenames[S_surfxml_AS_9] = "AS"; - surfxml_statenames[S_surfxml_AS_10] = "AS"; - surfxml_statenames[S_surfxml_AS_11] = "AS"; - surfxml_statenames[S_surfxml_AS_12] = "AS"; - surfxml_statenames[S_surfxml_AS_13] = "AS"; - surfxml_statenames[S_surfxml_AS_14] = "AS"; - surfxml_statenames[S_surfxml_AS_15] = "AS"; - surfxml_statenames[S_surfxml_AS_16] = "AS"; - surfxml_statenames[E_surfxml_AS] = "AS"; - surfxml_statenames[AL_surfxml_ASroute] = NULL; - surfxml_statenames[S_surfxml_ASroute] = "ASroute"; - surfxml_statenames[S_surfxml_ASroute_1] = "ASroute"; - surfxml_statenames[S_surfxml_ASroute_2] = "ASroute"; - surfxml_statenames[E_surfxml_ASroute] = "ASroute"; - surfxml_statenames[AL_surfxml_actor] = NULL; - surfxml_statenames[S_surfxml_actor] = "actor"; - surfxml_statenames[S_surfxml_actor_1] = "actor"; - surfxml_statenames[S_surfxml_actor_2] = "actor"; - surfxml_statenames[E_surfxml_actor] = "actor"; - surfxml_statenames[AL_surfxml_argument] = NULL; - surfxml_statenames[E_surfxml_argument] = "argument"; - surfxml_statenames[AL_surfxml_backbone] = NULL; - surfxml_statenames[E_surfxml_backbone] = "backbone"; - surfxml_statenames[AL_surfxml_bypassASroute] = NULL; - surfxml_statenames[S_surfxml_bypassASroute] = "bypassASroute"; - surfxml_statenames[S_surfxml_bypassASroute_1] = "bypassASroute"; - surfxml_statenames[S_surfxml_bypassASroute_2] = "bypassASroute"; - surfxml_statenames[E_surfxml_bypassASroute] = "bypassASroute"; - surfxml_statenames[AL_surfxml_bypassRoute] = NULL; - surfxml_statenames[S_surfxml_bypassRoute] = "bypassRoute"; - surfxml_statenames[S_surfxml_bypassRoute_1] = "bypassRoute"; - surfxml_statenames[S_surfxml_bypassRoute_2] = "bypassRoute"; - surfxml_statenames[E_surfxml_bypassRoute] = "bypassRoute"; - surfxml_statenames[AL_surfxml_bypassZoneRoute] = NULL; - surfxml_statenames[S_surfxml_bypassZoneRoute] = "bypassZoneRoute"; - surfxml_statenames[S_surfxml_bypassZoneRoute_1] = "bypassZoneRoute"; - surfxml_statenames[S_surfxml_bypassZoneRoute_2] = "bypassZoneRoute"; - surfxml_statenames[E_surfxml_bypassZoneRoute] = "bypassZoneRoute"; - surfxml_statenames[AL_surfxml_cabinet] = NULL; - surfxml_statenames[E_surfxml_cabinet] = "cabinet"; - surfxml_statenames[AL_surfxml_cluster] = NULL; - surfxml_statenames[S_surfxml_cluster] = "cluster"; - surfxml_statenames[S_surfxml_cluster_1] = "cluster"; - surfxml_statenames[S_surfxml_cluster_2] = "cluster"; - surfxml_statenames[E_surfxml_cluster] = "cluster"; - surfxml_statenames[AL_surfxml_config] = NULL; - surfxml_statenames[S_surfxml_config] = "config"; - surfxml_statenames[S_surfxml_config_1] = "config"; - surfxml_statenames[S_surfxml_config_2] = "config"; - surfxml_statenames[E_surfxml_config] = "config"; - surfxml_statenames[AL_surfxml_disk] = NULL; - surfxml_statenames[S_surfxml_disk] = "disk"; - surfxml_statenames[S_surfxml_disk_1] = "disk"; - surfxml_statenames[S_surfxml_disk_2] = "disk"; - surfxml_statenames[E_surfxml_disk] = "disk"; - surfxml_statenames[AL_surfxml_host] = NULL; - surfxml_statenames[S_surfxml_host] = "host"; - surfxml_statenames[S_surfxml_host_1] = "host"; - surfxml_statenames[S_surfxml_host_2] = "host"; - surfxml_statenames[E_surfxml_host] = "host"; - surfxml_statenames[AL_surfxml_host___link] = NULL; - surfxml_statenames[E_surfxml_host___link] = "host_link"; - surfxml_statenames[AL_surfxml_include] = NULL; - surfxml_statenames[S_surfxml_include] = "include"; - surfxml_statenames[S_surfxml_include_1] = "include"; - surfxml_statenames[S_surfxml_include_2] = "include"; - surfxml_statenames[E_surfxml_include] = "include"; - surfxml_statenames[AL_surfxml_link] = NULL; - surfxml_statenames[S_surfxml_link] = "link"; - surfxml_statenames[S_surfxml_link_1] = "link"; - surfxml_statenames[S_surfxml_link_2] = "link"; - surfxml_statenames[E_surfxml_link] = "link"; - surfxml_statenames[AL_surfxml_link___ctn] = NULL; - surfxml_statenames[E_surfxml_link___ctn] = "link_ctn"; - surfxml_statenames[AL_surfxml_model___prop] = NULL; - surfxml_statenames[E_surfxml_model___prop] = "model_prop"; - surfxml_statenames[AL_surfxml_mount] = NULL; - surfxml_statenames[E_surfxml_mount] = "mount"; - surfxml_statenames[AL_surfxml_peer] = NULL; - surfxml_statenames[E_surfxml_peer] = "peer"; - surfxml_statenames[ROOT_surfxml_platform] = NULL; - surfxml_statenames[AL_surfxml_platform] = NULL; - surfxml_statenames[S_surfxml_platform] = "platform"; - surfxml_statenames[S_surfxml_platform_1] = "platform"; - surfxml_statenames[S_surfxml_platform_2] = "platform"; - surfxml_statenames[S_surfxml_platform_3] = "platform"; - surfxml_statenames[S_surfxml_platform_4] = "platform"; - surfxml_statenames[S_surfxml_platform_5] = "platform"; - surfxml_statenames[S_surfxml_platform_6] = "platform"; - surfxml_statenames[S_surfxml_platform_7] = "platform"; - surfxml_statenames[S_surfxml_platform_8] = "platform"; - surfxml_statenames[E_surfxml_platform] = "platform"; - surfxml_statenames[AL_surfxml_process] = NULL; - surfxml_statenames[S_surfxml_process] = "process"; - surfxml_statenames[S_surfxml_process_1] = "process"; - surfxml_statenames[S_surfxml_process_2] = "process"; - surfxml_statenames[E_surfxml_process] = "process"; - surfxml_statenames[AL_surfxml_prop] = NULL; - surfxml_statenames[E_surfxml_prop] = "prop"; - surfxml_statenames[AL_surfxml_random] = NULL; - surfxml_statenames[E_surfxml_random] = "random"; - surfxml_statenames[AL_surfxml_route] = NULL; - surfxml_statenames[S_surfxml_route] = "route"; - surfxml_statenames[S_surfxml_route_1] = "route"; - surfxml_statenames[S_surfxml_route_2] = "route"; - surfxml_statenames[E_surfxml_route] = "route"; - surfxml_statenames[AL_surfxml_router] = NULL; - surfxml_statenames[E_surfxml_router] = "router"; - surfxml_statenames[AL_surfxml_storage] = NULL; - surfxml_statenames[S_surfxml_storage] = "storage"; - surfxml_statenames[S_surfxml_storage_1] = "storage"; - surfxml_statenames[S_surfxml_storage_2] = "storage"; - surfxml_statenames[E_surfxml_storage] = "storage"; - surfxml_statenames[AL_surfxml_storage___type] = NULL; - surfxml_statenames[S_surfxml_storage___type] = "storage_type"; - surfxml_statenames[S_surfxml_storage___type_1] = "storage_type"; - surfxml_statenames[S_surfxml_storage___type_2] = "storage_type"; - surfxml_statenames[E_surfxml_storage___type] = "storage_type"; - surfxml_statenames[AL_surfxml_trace] = NULL; - surfxml_statenames[IN_trace] = "trace"; - surfxml_statenames[AL_surfxml_trace___connect] = NULL; - surfxml_statenames[E_surfxml_trace___connect] = "trace_connect"; - surfxml_statenames[AL_surfxml_zone] = NULL; - surfxml_statenames[S_surfxml_zone] = "zone"; - surfxml_statenames[S_surfxml_zone_1] = "zone"; - surfxml_statenames[S_surfxml_zone_2] = "zone"; - surfxml_statenames[S_surfxml_zone_3] = "zone"; - surfxml_statenames[S_surfxml_zone_4] = "zone"; - surfxml_statenames[S_surfxml_zone_5] = "zone"; - surfxml_statenames[S_surfxml_zone_6] = "zone"; - surfxml_statenames[S_surfxml_zone_7] = "zone"; - surfxml_statenames[S_surfxml_zone_8] = "zone"; - surfxml_statenames[S_surfxml_zone_9] = "zone"; - surfxml_statenames[S_surfxml_zone_10] = "zone"; - surfxml_statenames[S_surfxml_zone_11] = "zone"; - surfxml_statenames[S_surfxml_zone_12] = "zone"; - surfxml_statenames[S_surfxml_zone_13] = "zone"; - surfxml_statenames[S_surfxml_zone_14] = "zone"; - surfxml_statenames[S_surfxml_zone_15] = "zone"; - surfxml_statenames[S_surfxml_zone_16] = "zone"; - surfxml_statenames[E_surfxml_zone] = "zone"; - surfxml_statenames[AL_surfxml_zoneRoute] = NULL; - surfxml_statenames[S_surfxml_zoneRoute] = "zoneRoute"; - surfxml_statenames[S_surfxml_zoneRoute_1] = "zoneRoute"; - surfxml_statenames[S_surfxml_zoneRoute_2] = "zoneRoute"; - surfxml_statenames[E_surfxml_zoneRoute] = "zoneRoute"; + simgrid_parse_bufferliteral('\0', &bnext, "0.0"); + simgrid_parse_bufferliteral('\0', &bnext, "2147483647"); + simgrid_parse_bufferliteral('\0', &bnext, "N11"); + simgrid_parse_bufferliteral('\0', &bnext, "1"); + simgrid_parse_bufferliteral('\0', &bnext, "0.0"); + simgrid_parse_bufferliteral('\0', &bnext, "/"); + simgrid_parse_bufferliteral('\0', &bnext, "1"); + simgrid_parse_bufferliteral('\0', &bnext, "0s"); + simgrid_parse_bufferliteral('\0', &bnext, "-1.0"); + simgrid_parse_bufferliteral('\0', &bnext, "-1.0"); + simgrid_parse_bufferliteral('\0', &bnext, "-1.0"); + simgrid_parse_bufferliteral('\0', &bnext, "-1.0"); + if(!simgrid_parse_statenames) {simgrid_parse_statenames= (const char **)calloc(IMPOSSIBLE,sizeof(char*)); + simgrid_parse_statenames[PROLOG] = NULL; + simgrid_parse_statenames[DOCTYPE] = NULL; + simgrid_parse_statenames[EPILOG] = NULL; + simgrid_parse_statenames[INCOMMENT] = NULL; + simgrid_parse_statenames[INPI] = NULL; + simgrid_parse_statenames[VALUE1] = NULL; + simgrid_parse_statenames[VALUE2] = NULL; + simgrid_parse_statenames[CDATA] = NULL; + simgrid_parse_statenames[AL_simgrid_parse_AS] = NULL; + simgrid_parse_statenames[S_simgrid_parse_AS] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_1] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_2] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_3] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_4] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_5] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_6] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_7] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_8] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_9] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_10] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_11] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_12] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_13] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_14] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_15] = "AS"; + simgrid_parse_statenames[S_simgrid_parse_AS_16] = "AS"; + simgrid_parse_statenames[E_simgrid_parse_AS] = "AS"; + simgrid_parse_statenames[AL_simgrid_parse_ASroute] = NULL; + simgrid_parse_statenames[S_simgrid_parse_ASroute] = "ASroute"; + simgrid_parse_statenames[S_simgrid_parse_ASroute_1] = "ASroute"; + simgrid_parse_statenames[S_simgrid_parse_ASroute_2] = "ASroute"; + simgrid_parse_statenames[E_simgrid_parse_ASroute] = "ASroute"; + simgrid_parse_statenames[AL_simgrid_parse_actor] = NULL; + simgrid_parse_statenames[S_simgrid_parse_actor] = "actor"; + simgrid_parse_statenames[S_simgrid_parse_actor_1] = "actor"; + simgrid_parse_statenames[S_simgrid_parse_actor_2] = "actor"; + simgrid_parse_statenames[E_simgrid_parse_actor] = "actor"; + simgrid_parse_statenames[AL_simgrid_parse_argument] = NULL; + simgrid_parse_statenames[E_simgrid_parse_argument] = "argument"; + simgrid_parse_statenames[AL_simgrid_parse_backbone] = NULL; + simgrid_parse_statenames[E_simgrid_parse_backbone] = "backbone"; + simgrid_parse_statenames[AL_simgrid_parse_bypassASroute] = NULL; + simgrid_parse_statenames[S_simgrid_parse_bypassASroute] = "bypassASroute"; + simgrid_parse_statenames[S_simgrid_parse_bypassASroute_1] = "bypassASroute"; + simgrid_parse_statenames[S_simgrid_parse_bypassASroute_2] = "bypassASroute"; + simgrid_parse_statenames[E_simgrid_parse_bypassASroute] = "bypassASroute"; + simgrid_parse_statenames[AL_simgrid_parse_bypassRoute] = NULL; + simgrid_parse_statenames[S_simgrid_parse_bypassRoute] = "bypassRoute"; + simgrid_parse_statenames[S_simgrid_parse_bypassRoute_1] = "bypassRoute"; + simgrid_parse_statenames[S_simgrid_parse_bypassRoute_2] = "bypassRoute"; + simgrid_parse_statenames[E_simgrid_parse_bypassRoute] = "bypassRoute"; + simgrid_parse_statenames[AL_simgrid_parse_bypassZoneRoute] = NULL; + simgrid_parse_statenames[S_simgrid_parse_bypassZoneRoute] = "bypassZoneRoute"; + simgrid_parse_statenames[S_simgrid_parse_bypassZoneRoute_1] = "bypassZoneRoute"; + simgrid_parse_statenames[S_simgrid_parse_bypassZoneRoute_2] = "bypassZoneRoute"; + simgrid_parse_statenames[E_simgrid_parse_bypassZoneRoute] = "bypassZoneRoute"; + simgrid_parse_statenames[AL_simgrid_parse_cabinet] = NULL; + simgrid_parse_statenames[E_simgrid_parse_cabinet] = "cabinet"; + simgrid_parse_statenames[AL_simgrid_parse_cluster] = NULL; + simgrid_parse_statenames[S_simgrid_parse_cluster] = "cluster"; + simgrid_parse_statenames[S_simgrid_parse_cluster_1] = "cluster"; + simgrid_parse_statenames[S_simgrid_parse_cluster_2] = "cluster"; + simgrid_parse_statenames[E_simgrid_parse_cluster] = "cluster"; + simgrid_parse_statenames[AL_simgrid_parse_config] = NULL; + simgrid_parse_statenames[S_simgrid_parse_config] = "config"; + simgrid_parse_statenames[S_simgrid_parse_config_1] = "config"; + simgrid_parse_statenames[S_simgrid_parse_config_2] = "config"; + simgrid_parse_statenames[E_simgrid_parse_config] = "config"; + simgrid_parse_statenames[AL_simgrid_parse_disk] = NULL; + simgrid_parse_statenames[S_simgrid_parse_disk] = "disk"; + simgrid_parse_statenames[S_simgrid_parse_disk_1] = "disk"; + simgrid_parse_statenames[S_simgrid_parse_disk_2] = "disk"; + simgrid_parse_statenames[E_simgrid_parse_disk] = "disk"; + simgrid_parse_statenames[AL_simgrid_parse_host] = NULL; + simgrid_parse_statenames[S_simgrid_parse_host] = "host"; + simgrid_parse_statenames[S_simgrid_parse_host_1] = "host"; + simgrid_parse_statenames[S_simgrid_parse_host_2] = "host"; + simgrid_parse_statenames[E_simgrid_parse_host] = "host"; + simgrid_parse_statenames[AL_simgrid_parse_host___link] = NULL; + simgrid_parse_statenames[E_simgrid_parse_host___link] = "host_link"; + simgrid_parse_statenames[AL_simgrid_parse_include] = NULL; + simgrid_parse_statenames[S_simgrid_parse_include] = "include"; + simgrid_parse_statenames[S_simgrid_parse_include_1] = "include"; + simgrid_parse_statenames[S_simgrid_parse_include_2] = "include"; + simgrid_parse_statenames[E_simgrid_parse_include] = "include"; + simgrid_parse_statenames[AL_simgrid_parse_link] = NULL; + simgrid_parse_statenames[S_simgrid_parse_link] = "link"; + simgrid_parse_statenames[S_simgrid_parse_link_1] = "link"; + simgrid_parse_statenames[S_simgrid_parse_link_2] = "link"; + simgrid_parse_statenames[E_simgrid_parse_link] = "link"; + simgrid_parse_statenames[AL_simgrid_parse_link___ctn] = NULL; + simgrid_parse_statenames[E_simgrid_parse_link___ctn] = "link_ctn"; + simgrid_parse_statenames[AL_simgrid_parse_model___prop] = NULL; + simgrid_parse_statenames[E_simgrid_parse_model___prop] = "model_prop"; + simgrid_parse_statenames[AL_simgrid_parse_mount] = NULL; + simgrid_parse_statenames[E_simgrid_parse_mount] = "mount"; + simgrid_parse_statenames[AL_simgrid_parse_peer] = NULL; + simgrid_parse_statenames[E_simgrid_parse_peer] = "peer"; + simgrid_parse_statenames[ROOT_simgrid_parse_platform] = NULL; + simgrid_parse_statenames[AL_simgrid_parse_platform] = NULL; + simgrid_parse_statenames[S_simgrid_parse_platform] = "platform"; + simgrid_parse_statenames[S_simgrid_parse_platform_1] = "platform"; + simgrid_parse_statenames[S_simgrid_parse_platform_2] = "platform"; + simgrid_parse_statenames[S_simgrid_parse_platform_3] = "platform"; + simgrid_parse_statenames[S_simgrid_parse_platform_4] = "platform"; + simgrid_parse_statenames[S_simgrid_parse_platform_5] = "platform"; + simgrid_parse_statenames[S_simgrid_parse_platform_6] = "platform"; + simgrid_parse_statenames[S_simgrid_parse_platform_7] = "platform"; + simgrid_parse_statenames[S_simgrid_parse_platform_8] = "platform"; + simgrid_parse_statenames[E_simgrid_parse_platform] = "platform"; + simgrid_parse_statenames[AL_simgrid_parse_process] = NULL; + simgrid_parse_statenames[S_simgrid_parse_process] = "process"; + simgrid_parse_statenames[S_simgrid_parse_process_1] = "process"; + simgrid_parse_statenames[S_simgrid_parse_process_2] = "process"; + simgrid_parse_statenames[E_simgrid_parse_process] = "process"; + simgrid_parse_statenames[AL_simgrid_parse_prop] = NULL; + simgrid_parse_statenames[E_simgrid_parse_prop] = "prop"; + simgrid_parse_statenames[AL_simgrid_parse_random] = NULL; + simgrid_parse_statenames[E_simgrid_parse_random] = "random"; + simgrid_parse_statenames[AL_simgrid_parse_route] = NULL; + simgrid_parse_statenames[S_simgrid_parse_route] = "route"; + simgrid_parse_statenames[S_simgrid_parse_route_1] = "route"; + simgrid_parse_statenames[S_simgrid_parse_route_2] = "route"; + simgrid_parse_statenames[E_simgrid_parse_route] = "route"; + simgrid_parse_statenames[AL_simgrid_parse_router] = NULL; + simgrid_parse_statenames[E_simgrid_parse_router] = "router"; + simgrid_parse_statenames[AL_simgrid_parse_storage] = NULL; + simgrid_parse_statenames[S_simgrid_parse_storage] = "storage"; + simgrid_parse_statenames[S_simgrid_parse_storage_1] = "storage"; + simgrid_parse_statenames[S_simgrid_parse_storage_2] = "storage"; + simgrid_parse_statenames[E_simgrid_parse_storage] = "storage"; + simgrid_parse_statenames[AL_simgrid_parse_storage___type] = NULL; + simgrid_parse_statenames[S_simgrid_parse_storage___type] = "storage_type"; + simgrid_parse_statenames[S_simgrid_parse_storage___type_1] = "storage_type"; + simgrid_parse_statenames[S_simgrid_parse_storage___type_2] = "storage_type"; + simgrid_parse_statenames[E_simgrid_parse_storage___type] = "storage_type"; + simgrid_parse_statenames[AL_simgrid_parse_trace] = NULL; + simgrid_parse_statenames[IN_trace] = "trace"; + simgrid_parse_statenames[AL_simgrid_parse_trace___connect] = NULL; + simgrid_parse_statenames[E_simgrid_parse_trace___connect] = "trace_connect"; + simgrid_parse_statenames[AL_simgrid_parse_zone] = NULL; + simgrid_parse_statenames[S_simgrid_parse_zone] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_1] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_2] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_3] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_4] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_5] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_6] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_7] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_8] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_9] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_10] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_11] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_12] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_13] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_14] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_15] = "zone"; + simgrid_parse_statenames[S_simgrid_parse_zone_16] = "zone"; + simgrid_parse_statenames[E_simgrid_parse_zone] = "zone"; + simgrid_parse_statenames[AL_simgrid_parse_zoneRoute] = NULL; + simgrid_parse_statenames[S_simgrid_parse_zoneRoute] = "zoneRoute"; + simgrid_parse_statenames[S_simgrid_parse_zoneRoute_1] = "zoneRoute"; + simgrid_parse_statenames[S_simgrid_parse_zoneRoute_2] = "zoneRoute"; + simgrid_parse_statenames[E_simgrid_parse_zoneRoute] = "zoneRoute"; } /* COMMENTS and PIs: handled uniformly for efficiency. */ @@ -6711,12 +6704,12 @@ FAIL("Bad declaration %s.\nIf you are using an XML v3 file (check the version at case 13: /* rule 13 can match eol */ YY_RULE_SETUP -SET(ROOT_surfxml_platform); +SET(ROOT_simgrid_parse_platform); YY_BREAK case 14: /* rule 14 can match eol */ YY_RULE_SETUP -SET(ROOT_surfxml_platform); +SET(ROOT_simgrid_parse_platform); YY_BREAK case 15: /* rule 15 can match eol */ @@ -6748,53 +6741,53 @@ case 18: /* rule 18 can match eol */ YY_RULE_SETUP { - AX_surfxml_AS_id = 0; - surfxml_AS_id_isset = 0; - AX_surfxml_AS_routing = 0; - surfxml_AS_routing_isset = 0; - ENTER(AL_surfxml_AS); pushbuffer(0); + AX_simgrid_parse_AS_id = 0; + simgrid_parse_AS_id_isset = 0; + AX_simgrid_parse_AS_routing = 0; + simgrid_parse_AS_routing_isset = 0; + ENTER(AL_simgrid_parse_AS); pushbuffer(0); } YY_BREAK case 19: /* rule 19 can match eol */ YY_RULE_SETUP -if (surfxml_AS_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_AS_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_AS_id); +if (simgrid_parse_AS_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_AS_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_AS_id); YY_BREAK case 20: /* rule 20 can match eol */ YY_RULE_SETUP -if (surfxml_AS_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_AS_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_AS_id); +if (simgrid_parse_AS_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_AS_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_AS_id); YY_BREAK case 21: /* rule 21 can match eol */ YY_RULE_SETUP -if (surfxml_AS_routing_isset != 0) {FAIL("Multiple definition of attribute routing in ");} surfxml_AS_routing_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_AS_routing); +if (simgrid_parse_AS_routing_isset != 0) {FAIL("Multiple definition of attribute routing in ");} simgrid_parse_AS_routing_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_AS_routing); YY_BREAK case 22: /* rule 22 can match eol */ YY_RULE_SETUP -if (surfxml_AS_routing_isset != 0) {FAIL("Multiple definition of attribute routing in ");} surfxml_AS_routing_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_AS_routing); +if (simgrid_parse_AS_routing_isset != 0) {FAIL("Multiple definition of attribute routing in ");} simgrid_parse_AS_routing_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_AS_routing); YY_BREAK case 23: YY_RULE_SETUP { - if (!AX_surfxml_AS_id) FAIL("Required attribute `id' not set for `AS' element."); - if (!AX_surfxml_AS_routing) FAIL("Required attribute `routing' not set for `AS' element."); - LEAVE; STag_surfxml_AS();surfxml_pcdata_ix = 0; ENTER(S_surfxml_AS); + if (!AX_simgrid_parse_AS_id) FAIL("Required attribute `id' not set for `AS' element."); + if (!AX_simgrid_parse_AS_routing) FAIL("Required attribute `routing' not set for `AS' element."); + LEAVE; STag_simgrid_parse_AS();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_AS); } YY_BREAK case 24: YY_RULE_SETUP { - if (!AX_surfxml_AS_id) FAIL("Required attribute `id' not set for `AS' element."); - if (!AX_surfxml_AS_routing) FAIL("Required attribute `routing' not set for `AS' element."); - LEAVE; STag_surfxml_AS(); surfxml_pcdata_ix = 0; ETag_surfxml_AS(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_AS_id) FAIL("Required attribute `id' not set for `AS' element."); + if (!AX_simgrid_parse_AS_routing) FAIL("Required attribute `routing' not set for `AS' element."); + LEAVE; STag_simgrid_parse_AS(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_AS(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -6806,7 +6799,7 @@ case 26: YY_RULE_SETUP FAIL("Bad attribute `%s' in `AS' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_AS): +case YY_STATE_EOF(AL_simgrid_parse_AS): FAIL("EOF in attribute list of `AS' element."); YY_BREAK @@ -6815,13 +6808,13 @@ case 27: YY_RULE_SETUP { LEAVE; - ETag_surfxml_AS(); + ETag_simgrid_parse_AS(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -6834,18 +6827,18 @@ case 29: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_AS): -case YY_STATE_EOF(S_surfxml_AS): -case YY_STATE_EOF(S_surfxml_AS_1): -case YY_STATE_EOF(S_surfxml_AS_11): -case YY_STATE_EOF(S_surfxml_AS_12): -case YY_STATE_EOF(S_surfxml_AS_14): -case YY_STATE_EOF(S_surfxml_AS_16): -case YY_STATE_EOF(S_surfxml_AS_3): -case YY_STATE_EOF(S_surfxml_AS_4): -case YY_STATE_EOF(S_surfxml_AS_6): -case YY_STATE_EOF(S_surfxml_AS_7): -case YY_STATE_EOF(S_surfxml_AS_9): +case YY_STATE_EOF(E_simgrid_parse_AS): +case YY_STATE_EOF(S_simgrid_parse_AS): +case YY_STATE_EOF(S_simgrid_parse_AS_1): +case YY_STATE_EOF(S_simgrid_parse_AS_11): +case YY_STATE_EOF(S_simgrid_parse_AS_12): +case YY_STATE_EOF(S_simgrid_parse_AS_14): +case YY_STATE_EOF(S_simgrid_parse_AS_16): +case YY_STATE_EOF(S_simgrid_parse_AS_3): +case YY_STATE_EOF(S_simgrid_parse_AS_4): +case YY_STATE_EOF(S_simgrid_parse_AS_6): +case YY_STATE_EOF(S_simgrid_parse_AS_7): +case YY_STATE_EOF(S_simgrid_parse_AS_9): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -6859,109 +6852,109 @@ case 31: /* rule 31 can match eol */ YY_RULE_SETUP { - AX_surfxml_ASroute_dst = 0; - surfxml_ASroute_dst_isset = 0; - AX_surfxml_ASroute_gw___dst = 0; - surfxml_ASroute_gw___dst_isset = 0; - AX_surfxml_ASroute_gw___src = 0; - surfxml_ASroute_gw___src_isset = 0; - AX_surfxml_ASroute_src = 0; - surfxml_ASroute_src_isset = 0; - AX_surfxml_ASroute_symmetrical = A_surfxml_ASroute_symmetrical_YES; - surfxml_ASroute_symmetrical_isset = 0; - ENTER(AL_surfxml_ASroute); pushbuffer(0); + AX_simgrid_parse_ASroute_dst = 0; + simgrid_parse_ASroute_dst_isset = 0; + AX_simgrid_parse_ASroute_gw___dst = 0; + simgrid_parse_ASroute_gw___dst_isset = 0; + AX_simgrid_parse_ASroute_gw___src = 0; + simgrid_parse_ASroute_gw___src_isset = 0; + AX_simgrid_parse_ASroute_src = 0; + simgrid_parse_ASroute_src_isset = 0; + AX_simgrid_parse_ASroute_symmetrical = A_simgrid_parse_ASroute_symmetrical_YES; + simgrid_parse_ASroute_symmetrical_isset = 0; + ENTER(AL_simgrid_parse_ASroute); pushbuffer(0); } YY_BREAK case 32: /* rule 32 can match eol */ YY_RULE_SETUP -if (surfxml_ASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_ASroute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_ASroute_dst); +if (simgrid_parse_ASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_ASroute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_ASroute_dst); YY_BREAK case 33: /* rule 33 can match eol */ YY_RULE_SETUP -if (surfxml_ASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_ASroute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_ASroute_dst); +if (simgrid_parse_ASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_ASroute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_ASroute_dst); YY_BREAK case 34: /* rule 34 can match eol */ YY_RULE_SETUP -if (surfxml_ASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} surfxml_ASroute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_ASroute_gw___dst); +if (simgrid_parse_ASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} simgrid_parse_ASroute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_ASroute_gw___dst); YY_BREAK case 35: /* rule 35 can match eol */ YY_RULE_SETUP -if (surfxml_ASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} surfxml_ASroute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_ASroute_gw___dst); +if (simgrid_parse_ASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} simgrid_parse_ASroute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_ASroute_gw___dst); YY_BREAK case 36: /* rule 36 can match eol */ YY_RULE_SETUP -if (surfxml_ASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} surfxml_ASroute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_ASroute_gw___src); +if (simgrid_parse_ASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} simgrid_parse_ASroute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_ASroute_gw___src); YY_BREAK case 37: /* rule 37 can match eol */ YY_RULE_SETUP -if (surfxml_ASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} surfxml_ASroute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_ASroute_gw___src); +if (simgrid_parse_ASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} simgrid_parse_ASroute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_ASroute_gw___src); YY_BREAK case 38: /* rule 38 can match eol */ YY_RULE_SETUP -if (surfxml_ASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_ASroute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_ASroute_src); +if (simgrid_parse_ASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_ASroute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_ASroute_src); YY_BREAK case 39: /* rule 39 can match eol */ YY_RULE_SETUP -if (surfxml_ASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_ASroute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_ASroute_src); +if (simgrid_parse_ASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_ASroute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_ASroute_src); YY_BREAK case 40: /* rule 40 can match eol */ case 41: /* rule 41 can match eol */ YY_RULE_SETUP -A_surfxml_ASroute_symmetrical = A_surfxml_ASroute_symmetrical_YES; +A_simgrid_parse_ASroute_symmetrical = A_simgrid_parse_ASroute_symmetrical_YES; YY_BREAK case 42: /* rule 42 can match eol */ case 43: /* rule 43 can match eol */ YY_RULE_SETUP -A_surfxml_ASroute_symmetrical = A_surfxml_ASroute_symmetrical_NO; +A_simgrid_parse_ASroute_symmetrical = A_simgrid_parse_ASroute_symmetrical_NO; YY_BREAK case 44: /* rule 44 can match eol */ case 45: /* rule 45 can match eol */ YY_RULE_SETUP -A_surfxml_ASroute_symmetrical = A_surfxml_ASroute_symmetrical_yes; +A_simgrid_parse_ASroute_symmetrical = A_simgrid_parse_ASroute_symmetrical_yes; YY_BREAK case 46: /* rule 46 can match eol */ case 47: /* rule 47 can match eol */ YY_RULE_SETUP -A_surfxml_ASroute_symmetrical = A_surfxml_ASroute_symmetrical_no; +A_simgrid_parse_ASroute_symmetrical = A_simgrid_parse_ASroute_symmetrical_no; YY_BREAK case 48: YY_RULE_SETUP { - if (!AX_surfxml_ASroute_dst) FAIL("Required attribute `dst' not set for `ASroute' element."); - if (!AX_surfxml_ASroute_gw___dst) FAIL("Required attribute `gw_dst' not set for `ASroute' element."); - if (!AX_surfxml_ASroute_gw___src) FAIL("Required attribute `gw_src' not set for `ASroute' element."); - if (!AX_surfxml_ASroute_src) FAIL("Required attribute `src' not set for `ASroute' element."); - LEAVE; STag_surfxml_ASroute();surfxml_pcdata_ix = 0; ENTER(S_surfxml_ASroute); + if (!AX_simgrid_parse_ASroute_dst) FAIL("Required attribute `dst' not set for `ASroute' element."); + if (!AX_simgrid_parse_ASroute_gw___dst) FAIL("Required attribute `gw_dst' not set for `ASroute' element."); + if (!AX_simgrid_parse_ASroute_gw___src) FAIL("Required attribute `gw_src' not set for `ASroute' element."); + if (!AX_simgrid_parse_ASroute_src) FAIL("Required attribute `src' not set for `ASroute' element."); + LEAVE; STag_simgrid_parse_ASroute();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_ASroute); } YY_BREAK case 49: YY_RULE_SETUP { - if (!AX_surfxml_ASroute_dst) FAIL("Required attribute `dst' not set for `ASroute' element."); - if (!AX_surfxml_ASroute_gw___dst) FAIL("Required attribute `gw_dst' not set for `ASroute' element."); - if (!AX_surfxml_ASroute_gw___src) FAIL("Required attribute `gw_src' not set for `ASroute' element."); - if (!AX_surfxml_ASroute_src) FAIL("Required attribute `src' not set for `ASroute' element."); - LEAVE; STag_surfxml_ASroute(); surfxml_pcdata_ix = 0; ETag_surfxml_ASroute(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_ASroute_dst) FAIL("Required attribute `dst' not set for `ASroute' element."); + if (!AX_simgrid_parse_ASroute_gw___dst) FAIL("Required attribute `gw_dst' not set for `ASroute' element."); + if (!AX_simgrid_parse_ASroute_gw___src) FAIL("Required attribute `gw_src' not set for `ASroute' element."); + if (!AX_simgrid_parse_ASroute_src) FAIL("Required attribute `src' not set for `ASroute' element."); + LEAVE; STag_simgrid_parse_ASroute(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_ASroute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_8: case S_surfxml_AS_9: SET(S_surfxml_AS_9); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_8: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_8: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -6973,7 +6966,7 @@ case 51: YY_RULE_SETUP FAIL("Bad attribute `%s' in `ASroute' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_ASroute): +case YY_STATE_EOF(AL_simgrid_parse_ASroute): FAIL("EOF in attribute list of `ASroute' element."); YY_BREAK @@ -6982,11 +6975,11 @@ case 52: YY_RULE_SETUP { LEAVE; - ETag_surfxml_ASroute(); + ETag_simgrid_parse_ASroute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_8: case S_surfxml_AS_9: SET(S_surfxml_AS_9); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_8: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_8: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -6999,9 +6992,9 @@ case 54: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_ASroute): -case YY_STATE_EOF(S_surfxml_ASroute): -case YY_STATE_EOF(S_surfxml_ASroute_2): +case YY_STATE_EOF(E_simgrid_parse_ASroute): +case YY_STATE_EOF(S_simgrid_parse_ASroute): +case YY_STATE_EOF(S_simgrid_parse_ASroute_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -7014,90 +7007,90 @@ case 56: /* rule 56 can match eol */ YY_RULE_SETUP { - AX_surfxml_actor_function = 0; - surfxml_actor_function_isset = 0; - AX_surfxml_actor_host = 0; - surfxml_actor_host_isset = 0; - AX_surfxml_actor_kill___time = 48; - surfxml_actor_kill___time_isset = 0; - AX_surfxml_actor_on___failure = A_surfxml_actor_on___failure_DIE; - surfxml_actor_on___failure_isset = 0; - AX_surfxml_actor_start___time = 43; - surfxml_actor_start___time_isset = 0; - ENTER(AL_surfxml_actor); pushbuffer(0); + AX_simgrid_parse_actor_function = 0; + simgrid_parse_actor_function_isset = 0; + AX_simgrid_parse_actor_host = 0; + simgrid_parse_actor_host_isset = 0; + AX_simgrid_parse_actor_kill___time = 48; + simgrid_parse_actor_kill___time_isset = 0; + AX_simgrid_parse_actor_on___failure = A_simgrid_parse_actor_on___failure_DIE; + simgrid_parse_actor_on___failure_isset = 0; + AX_simgrid_parse_actor_start___time = 43; + simgrid_parse_actor_start___time_isset = 0; + ENTER(AL_simgrid_parse_actor); pushbuffer(0); } YY_BREAK case 57: /* rule 57 can match eol */ YY_RULE_SETUP -if (surfxml_actor_function_isset != 0) {FAIL("Multiple definition of attribute function in ");} surfxml_actor_function_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_actor_function); +if (simgrid_parse_actor_function_isset != 0) {FAIL("Multiple definition of attribute function in ");} simgrid_parse_actor_function_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_actor_function); YY_BREAK case 58: /* rule 58 can match eol */ YY_RULE_SETUP -if (surfxml_actor_function_isset != 0) {FAIL("Multiple definition of attribute function in ");} surfxml_actor_function_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_actor_function); +if (simgrid_parse_actor_function_isset != 0) {FAIL("Multiple definition of attribute function in ");} simgrid_parse_actor_function_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_actor_function); YY_BREAK case 59: /* rule 59 can match eol */ YY_RULE_SETUP -if (surfxml_actor_host_isset != 0) {FAIL("Multiple definition of attribute host in ");} surfxml_actor_host_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_actor_host); +if (simgrid_parse_actor_host_isset != 0) {FAIL("Multiple definition of attribute host in ");} simgrid_parse_actor_host_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_actor_host); YY_BREAK case 60: /* rule 60 can match eol */ YY_RULE_SETUP -if (surfxml_actor_host_isset != 0) {FAIL("Multiple definition of attribute host in ");} surfxml_actor_host_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_actor_host); +if (simgrid_parse_actor_host_isset != 0) {FAIL("Multiple definition of attribute host in ");} simgrid_parse_actor_host_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_actor_host); YY_BREAK case 61: /* rule 61 can match eol */ YY_RULE_SETUP -if (surfxml_actor_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in ");} surfxml_actor_kill___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_actor_kill___time); +if (simgrid_parse_actor_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in ");} simgrid_parse_actor_kill___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_actor_kill___time); YY_BREAK case 62: /* rule 62 can match eol */ YY_RULE_SETUP -if (surfxml_actor_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in ");} surfxml_actor_kill___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_actor_kill___time); +if (simgrid_parse_actor_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in ");} simgrid_parse_actor_kill___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_actor_kill___time); YY_BREAK case 63: /* rule 63 can match eol */ case 64: /* rule 64 can match eol */ YY_RULE_SETUP -A_surfxml_actor_on___failure = A_surfxml_actor_on___failure_DIE; +A_simgrid_parse_actor_on___failure = A_simgrid_parse_actor_on___failure_DIE; YY_BREAK case 65: /* rule 65 can match eol */ case 66: /* rule 66 can match eol */ YY_RULE_SETUP -A_surfxml_actor_on___failure = A_surfxml_actor_on___failure_RESTART; +A_simgrid_parse_actor_on___failure = A_simgrid_parse_actor_on___failure_RESTART; YY_BREAK case 67: /* rule 67 can match eol */ YY_RULE_SETUP -if (surfxml_actor_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in ");} surfxml_actor_start___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_actor_start___time); +if (simgrid_parse_actor_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in ");} simgrid_parse_actor_start___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_actor_start___time); YY_BREAK case 68: /* rule 68 can match eol */ YY_RULE_SETUP -if (surfxml_actor_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in ");} surfxml_actor_start___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_actor_start___time); +if (simgrid_parse_actor_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in ");} simgrid_parse_actor_start___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_actor_start___time); YY_BREAK case 69: YY_RULE_SETUP { - if (!AX_surfxml_actor_function) FAIL("Required attribute `function' not set for `actor' element."); - if (!AX_surfxml_actor_host) FAIL("Required attribute `host' not set for `actor' element."); - LEAVE; STag_surfxml_actor();surfxml_pcdata_ix = 0; ENTER(S_surfxml_actor); + if (!AX_simgrid_parse_actor_function) FAIL("Required attribute `function' not set for `actor' element."); + if (!AX_simgrid_parse_actor_host) FAIL("Required attribute `host' not set for `actor' element."); + LEAVE; STag_simgrid_parse_actor();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_actor); } YY_BREAK case 70: YY_RULE_SETUP { - if (!AX_surfxml_actor_function) FAIL("Required attribute `function' not set for `actor' element."); - if (!AX_surfxml_actor_host) FAIL("Required attribute `host' not set for `actor' element."); - LEAVE; STag_surfxml_actor(); surfxml_pcdata_ix = 0; ETag_surfxml_actor(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_actor_function) FAIL("Required attribute `function' not set for `actor' element."); + if (!AX_simgrid_parse_actor_host) FAIL("Required attribute `host' not set for `actor' element."); + LEAVE; STag_simgrid_parse_actor(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_actor(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_4: case S_surfxml_platform_6: case S_surfxml_platform_7: case S_surfxml_platform_8: SET(S_surfxml_platform_8); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_4: case S_simgrid_parse_platform_6: case S_simgrid_parse_platform_7: case S_simgrid_parse_platform_8: SET(S_simgrid_parse_platform_8); break; } } YY_BREAK @@ -7109,7 +7102,7 @@ case 72: YY_RULE_SETUP FAIL("Bad attribute `%s' in `actor' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_actor): +case YY_STATE_EOF(AL_simgrid_parse_actor): FAIL("EOF in attribute list of `actor' element."); YY_BREAK @@ -7118,10 +7111,10 @@ case 73: YY_RULE_SETUP { LEAVE; - ETag_surfxml_actor(); + ETag_simgrid_parse_actor(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_4: case S_surfxml_platform_6: case S_surfxml_platform_7: case S_surfxml_platform_8: SET(S_surfxml_platform_8); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_4: case S_simgrid_parse_platform_6: case S_simgrid_parse_platform_7: case S_simgrid_parse_platform_8: SET(S_simgrid_parse_platform_8); break; } } YY_BREAK @@ -7134,9 +7127,9 @@ case 75: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_actor): -case YY_STATE_EOF(S_surfxml_actor): -case YY_STATE_EOF(S_surfxml_actor_2): +case YY_STATE_EOF(E_simgrid_parse_actor): +case YY_STATE_EOF(S_simgrid_parse_actor): +case YY_STATE_EOF(S_simgrid_parse_actor_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -7149,37 +7142,37 @@ case 77: /* rule 77 can match eol */ YY_RULE_SETUP { - AX_surfxml_argument_value = 0; - surfxml_argument_value_isset = 0; - ENTER(AL_surfxml_argument); pushbuffer(0); + AX_simgrid_parse_argument_value = 0; + simgrid_parse_argument_value_isset = 0; + ENTER(AL_simgrid_parse_argument); pushbuffer(0); } YY_BREAK case 78: /* rule 78 can match eol */ YY_RULE_SETUP -if (surfxml_argument_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} surfxml_argument_value_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_argument_value); +if (simgrid_parse_argument_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} simgrid_parse_argument_value_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_argument_value); YY_BREAK case 79: /* rule 79 can match eol */ YY_RULE_SETUP -if (surfxml_argument_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} surfxml_argument_value_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_argument_value); +if (simgrid_parse_argument_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} simgrid_parse_argument_value_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_argument_value); YY_BREAK case 80: YY_RULE_SETUP { - if (!AX_surfxml_argument_value) FAIL("Required attribute `value' not set for `argument' element."); - LEAVE; STag_surfxml_argument();surfxml_pcdata_ix = 0; ENTER(E_surfxml_argument); + if (!AX_simgrid_parse_argument_value) FAIL("Required attribute `value' not set for `argument' element."); + LEAVE; STag_simgrid_parse_argument();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_argument); } YY_BREAK case 81: YY_RULE_SETUP { - if (!AX_surfxml_argument_value) FAIL("Required attribute `value' not set for `argument' element."); - LEAVE; STag_surfxml_argument(); surfxml_pcdata_ix = 0; ETag_surfxml_argument(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_argument_value) FAIL("Required attribute `value' not set for `argument' element."); + LEAVE; STag_simgrid_parse_argument(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_argument(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_actor: case S_surfxml_actor_1: case S_surfxml_actor_2: SET(S_surfxml_actor_2); break; - case S_surfxml_process: case S_surfxml_process_1: case S_surfxml_process_2: SET(S_surfxml_process_2); break; + case S_simgrid_parse_actor: case S_simgrid_parse_actor_1: case S_simgrid_parse_actor_2: SET(S_simgrid_parse_actor_2); break; + case S_simgrid_parse_process: case S_simgrid_parse_process_1: case S_simgrid_parse_process_2: SET(S_simgrid_parse_process_2); break; } } YY_BREAK @@ -7191,7 +7184,7 @@ case 83: YY_RULE_SETUP FAIL("Bad attribute `%s' in `argument' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_argument): +case YY_STATE_EOF(AL_simgrid_parse_argument): FAIL("EOF in attribute list of `argument' element."); YY_BREAK @@ -7200,11 +7193,11 @@ case 84: YY_RULE_SETUP { LEAVE; - ETag_surfxml_argument(); + ETag_simgrid_parse_argument(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_actor: case S_surfxml_actor_1: case S_surfxml_actor_2: SET(S_surfxml_actor_2); break; - case S_surfxml_process: case S_surfxml_process_1: case S_surfxml_process_2: SET(S_surfxml_process_2); break; + case S_simgrid_parse_actor: case S_simgrid_parse_actor_1: case S_simgrid_parse_actor_2: SET(S_simgrid_parse_actor_2); break; + case S_simgrid_parse_process: case S_simgrid_parse_process_1: case S_simgrid_parse_process_2: SET(S_simgrid_parse_process_2); break; } } YY_BREAK @@ -7217,7 +7210,7 @@ case 86: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_argument): +case YY_STATE_EOF(E_simgrid_parse_argument): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -7230,67 +7223,67 @@ case 88: /* rule 88 can match eol */ YY_RULE_SETUP { - AX_surfxml_backbone_bandwidth = 0; - surfxml_backbone_bandwidth_isset = 0; - AX_surfxml_backbone_id = 0; - surfxml_backbone_id_isset = 0; - AX_surfxml_backbone_latency = 0; - surfxml_backbone_latency_isset = 0; - ENTER(AL_surfxml_backbone); pushbuffer(0); + AX_simgrid_parse_backbone_bandwidth = 0; + simgrid_parse_backbone_bandwidth_isset = 0; + AX_simgrid_parse_backbone_id = 0; + simgrid_parse_backbone_id_isset = 0; + AX_simgrid_parse_backbone_latency = 0; + simgrid_parse_backbone_latency_isset = 0; + ENTER(AL_simgrid_parse_backbone); pushbuffer(0); } YY_BREAK case 89: /* rule 89 can match eol */ YY_RULE_SETUP -if (surfxml_backbone_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in ");} surfxml_backbone_bandwidth_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_backbone_bandwidth); +if (simgrid_parse_backbone_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in ");} simgrid_parse_backbone_bandwidth_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_backbone_bandwidth); YY_BREAK case 90: /* rule 90 can match eol */ YY_RULE_SETUP -if (surfxml_backbone_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in ");} surfxml_backbone_bandwidth_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_backbone_bandwidth); +if (simgrid_parse_backbone_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in ");} simgrid_parse_backbone_bandwidth_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_backbone_bandwidth); YY_BREAK case 91: /* rule 91 can match eol */ YY_RULE_SETUP -if (surfxml_backbone_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_backbone_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_backbone_id); +if (simgrid_parse_backbone_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_backbone_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_backbone_id); YY_BREAK case 92: /* rule 92 can match eol */ YY_RULE_SETUP -if (surfxml_backbone_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_backbone_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_backbone_id); +if (simgrid_parse_backbone_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_backbone_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_backbone_id); YY_BREAK case 93: /* rule 93 can match eol */ YY_RULE_SETUP -if (surfxml_backbone_latency_isset != 0) {FAIL("Multiple definition of attribute latency in ");} surfxml_backbone_latency_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_backbone_latency); +if (simgrid_parse_backbone_latency_isset != 0) {FAIL("Multiple definition of attribute latency in ");} simgrid_parse_backbone_latency_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_backbone_latency); YY_BREAK case 94: /* rule 94 can match eol */ YY_RULE_SETUP -if (surfxml_backbone_latency_isset != 0) {FAIL("Multiple definition of attribute latency in ");} surfxml_backbone_latency_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_backbone_latency); +if (simgrid_parse_backbone_latency_isset != 0) {FAIL("Multiple definition of attribute latency in ");} simgrid_parse_backbone_latency_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_backbone_latency); YY_BREAK case 95: YY_RULE_SETUP { - if (!AX_surfxml_backbone_bandwidth) FAIL("Required attribute `bandwidth' not set for `backbone' element."); - if (!AX_surfxml_backbone_id) FAIL("Required attribute `id' not set for `backbone' element."); - if (!AX_surfxml_backbone_latency) FAIL("Required attribute `latency' not set for `backbone' element."); - LEAVE; STag_surfxml_backbone();surfxml_pcdata_ix = 0; ENTER(E_surfxml_backbone); + if (!AX_simgrid_parse_backbone_bandwidth) FAIL("Required attribute `bandwidth' not set for `backbone' element."); + if (!AX_simgrid_parse_backbone_id) FAIL("Required attribute `id' not set for `backbone' element."); + if (!AX_simgrid_parse_backbone_latency) FAIL("Required attribute `latency' not set for `backbone' element."); + LEAVE; STag_simgrid_parse_backbone();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_backbone); } YY_BREAK case 96: YY_RULE_SETUP { - if (!AX_surfxml_backbone_bandwidth) FAIL("Required attribute `bandwidth' not set for `backbone' element."); - if (!AX_surfxml_backbone_id) FAIL("Required attribute `id' not set for `backbone' element."); - if (!AX_surfxml_backbone_latency) FAIL("Required attribute `latency' not set for `backbone' element."); - LEAVE; STag_surfxml_backbone(); surfxml_pcdata_ix = 0; ETag_surfxml_backbone(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_backbone_bandwidth) FAIL("Required attribute `bandwidth' not set for `backbone' element."); + if (!AX_simgrid_parse_backbone_id) FAIL("Required attribute `id' not set for `backbone' element."); + if (!AX_simgrid_parse_backbone_latency) FAIL("Required attribute `latency' not set for `backbone' element."); + LEAVE; STag_simgrid_parse_backbone(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_backbone(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -7302,7 +7295,7 @@ case 98: YY_RULE_SETUP FAIL("Bad attribute `%s' in `backbone' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_backbone): +case YY_STATE_EOF(AL_simgrid_parse_backbone): FAIL("EOF in attribute list of `backbone' element."); YY_BREAK @@ -7311,13 +7304,13 @@ case 99: YY_RULE_SETUP { LEAVE; - ETag_surfxml_backbone(); + ETag_simgrid_parse_backbone(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -7330,7 +7323,7 @@ case 101: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_backbone): +case YY_STATE_EOF(E_simgrid_parse_backbone): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -7343,79 +7336,79 @@ case 103: /* rule 103 can match eol */ YY_RULE_SETUP { - AX_surfxml_bypassASroute_dst = 0; - surfxml_bypassASroute_dst_isset = 0; - AX_surfxml_bypassASroute_gw___dst = 0; - surfxml_bypassASroute_gw___dst_isset = 0; - AX_surfxml_bypassASroute_gw___src = 0; - surfxml_bypassASroute_gw___src_isset = 0; - AX_surfxml_bypassASroute_src = 0; - surfxml_bypassASroute_src_isset = 0; - ENTER(AL_surfxml_bypassASroute); pushbuffer(0); + AX_simgrid_parse_bypassASroute_dst = 0; + simgrid_parse_bypassASroute_dst_isset = 0; + AX_simgrid_parse_bypassASroute_gw___dst = 0; + simgrid_parse_bypassASroute_gw___dst_isset = 0; + AX_simgrid_parse_bypassASroute_gw___src = 0; + simgrid_parse_bypassASroute_gw___src_isset = 0; + AX_simgrid_parse_bypassASroute_src = 0; + simgrid_parse_bypassASroute_src_isset = 0; + ENTER(AL_simgrid_parse_bypassASroute); pushbuffer(0); } YY_BREAK case 104: /* rule 104 can match eol */ YY_RULE_SETUP -if (surfxml_bypassASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_bypassASroute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassASroute_dst); +if (simgrid_parse_bypassASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_bypassASroute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassASroute_dst); YY_BREAK case 105: /* rule 105 can match eol */ YY_RULE_SETUP -if (surfxml_bypassASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_bypassASroute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassASroute_dst); +if (simgrid_parse_bypassASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_bypassASroute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassASroute_dst); YY_BREAK case 106: /* rule 106 can match eol */ YY_RULE_SETUP -if (surfxml_bypassASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} surfxml_bypassASroute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassASroute_gw___dst); +if (simgrid_parse_bypassASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} simgrid_parse_bypassASroute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassASroute_gw___dst); YY_BREAK case 107: /* rule 107 can match eol */ YY_RULE_SETUP -if (surfxml_bypassASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} surfxml_bypassASroute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassASroute_gw___dst); +if (simgrid_parse_bypassASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} simgrid_parse_bypassASroute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassASroute_gw___dst); YY_BREAK case 108: /* rule 108 can match eol */ YY_RULE_SETUP -if (surfxml_bypassASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} surfxml_bypassASroute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassASroute_gw___src); +if (simgrid_parse_bypassASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} simgrid_parse_bypassASroute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassASroute_gw___src); YY_BREAK case 109: /* rule 109 can match eol */ YY_RULE_SETUP -if (surfxml_bypassASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} surfxml_bypassASroute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassASroute_gw___src); +if (simgrid_parse_bypassASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} simgrid_parse_bypassASroute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassASroute_gw___src); YY_BREAK case 110: /* rule 110 can match eol */ YY_RULE_SETUP -if (surfxml_bypassASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_bypassASroute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassASroute_src); +if (simgrid_parse_bypassASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_bypassASroute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassASroute_src); YY_BREAK case 111: /* rule 111 can match eol */ YY_RULE_SETUP -if (surfxml_bypassASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_bypassASroute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassASroute_src); +if (simgrid_parse_bypassASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_bypassASroute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassASroute_src); YY_BREAK case 112: YY_RULE_SETUP { - if (!AX_surfxml_bypassASroute_dst) FAIL("Required attribute `dst' not set for `bypassASroute' element."); - if (!AX_surfxml_bypassASroute_gw___dst) FAIL("Required attribute `gw_dst' not set for `bypassASroute' element."); - if (!AX_surfxml_bypassASroute_gw___src) FAIL("Required attribute `gw_src' not set for `bypassASroute' element."); - if (!AX_surfxml_bypassASroute_src) FAIL("Required attribute `src' not set for `bypassASroute' element."); - LEAVE; STag_surfxml_bypassASroute();surfxml_pcdata_ix = 0; ENTER(S_surfxml_bypassASroute); + if (!AX_simgrid_parse_bypassASroute_dst) FAIL("Required attribute `dst' not set for `bypassASroute' element."); + if (!AX_simgrid_parse_bypassASroute_gw___dst) FAIL("Required attribute `gw_dst' not set for `bypassASroute' element."); + if (!AX_simgrid_parse_bypassASroute_gw___src) FAIL("Required attribute `gw_src' not set for `bypassASroute' element."); + if (!AX_simgrid_parse_bypassASroute_src) FAIL("Required attribute `src' not set for `bypassASroute' element."); + LEAVE; STag_simgrid_parse_bypassASroute();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_bypassASroute); } YY_BREAK case 113: YY_RULE_SETUP { - if (!AX_surfxml_bypassASroute_dst) FAIL("Required attribute `dst' not set for `bypassASroute' element."); - if (!AX_surfxml_bypassASroute_gw___dst) FAIL("Required attribute `gw_dst' not set for `bypassASroute' element."); - if (!AX_surfxml_bypassASroute_gw___src) FAIL("Required attribute `gw_src' not set for `bypassASroute' element."); - if (!AX_surfxml_bypassASroute_src) FAIL("Required attribute `src' not set for `bypassASroute' element."); - LEAVE; STag_surfxml_bypassASroute(); surfxml_pcdata_ix = 0; ETag_surfxml_bypassASroute(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_bypassASroute_dst) FAIL("Required attribute `dst' not set for `bypassASroute' element."); + if (!AX_simgrid_parse_bypassASroute_gw___dst) FAIL("Required attribute `gw_dst' not set for `bypassASroute' element."); + if (!AX_simgrid_parse_bypassASroute_gw___src) FAIL("Required attribute `gw_src' not set for `bypassASroute' element."); + if (!AX_simgrid_parse_bypassASroute_src) FAIL("Required attribute `src' not set for `bypassASroute' element."); + LEAVE; STag_simgrid_parse_bypassASroute(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_bypassASroute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_8: case S_surfxml_AS_9: SET(S_surfxml_AS_9); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_8: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_8: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -7427,7 +7420,7 @@ case 115: YY_RULE_SETUP FAIL("Bad attribute `%s' in `bypassASroute' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_bypassASroute): +case YY_STATE_EOF(AL_simgrid_parse_bypassASroute): FAIL("EOF in attribute list of `bypassASroute' element."); YY_BREAK @@ -7436,11 +7429,11 @@ case 116: YY_RULE_SETUP { LEAVE; - ETag_surfxml_bypassASroute(); + ETag_simgrid_parse_bypassASroute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_8: case S_surfxml_AS_9: SET(S_surfxml_AS_9); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_8: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_8: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -7453,9 +7446,9 @@ case 118: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_bypassASroute): -case YY_STATE_EOF(S_surfxml_bypassASroute): -case YY_STATE_EOF(S_surfxml_bypassASroute_2): +case YY_STATE_EOF(E_simgrid_parse_bypassASroute): +case YY_STATE_EOF(S_simgrid_parse_bypassASroute): +case YY_STATE_EOF(S_simgrid_parse_bypassASroute_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -7468,51 +7461,51 @@ case 120: /* rule 120 can match eol */ YY_RULE_SETUP { - AX_surfxml_bypassRoute_dst = 0; - surfxml_bypassRoute_dst_isset = 0; - AX_surfxml_bypassRoute_src = 0; - surfxml_bypassRoute_src_isset = 0; - ENTER(AL_surfxml_bypassRoute); pushbuffer(0); + AX_simgrid_parse_bypassRoute_dst = 0; + simgrid_parse_bypassRoute_dst_isset = 0; + AX_simgrid_parse_bypassRoute_src = 0; + simgrid_parse_bypassRoute_src_isset = 0; + ENTER(AL_simgrid_parse_bypassRoute); pushbuffer(0); } YY_BREAK case 121: /* rule 121 can match eol */ YY_RULE_SETUP -if (surfxml_bypassRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_bypassRoute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassRoute_dst); +if (simgrid_parse_bypassRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_bypassRoute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassRoute_dst); YY_BREAK case 122: /* rule 122 can match eol */ YY_RULE_SETUP -if (surfxml_bypassRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_bypassRoute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassRoute_dst); +if (simgrid_parse_bypassRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_bypassRoute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassRoute_dst); YY_BREAK case 123: /* rule 123 can match eol */ YY_RULE_SETUP -if (surfxml_bypassRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_bypassRoute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassRoute_src); +if (simgrid_parse_bypassRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_bypassRoute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassRoute_src); YY_BREAK case 124: /* rule 124 can match eol */ YY_RULE_SETUP -if (surfxml_bypassRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_bypassRoute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassRoute_src); +if (simgrid_parse_bypassRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_bypassRoute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassRoute_src); YY_BREAK case 125: YY_RULE_SETUP { - if (!AX_surfxml_bypassRoute_dst) FAIL("Required attribute `dst' not set for `bypassRoute' element."); - if (!AX_surfxml_bypassRoute_src) FAIL("Required attribute `src' not set for `bypassRoute' element."); - LEAVE; STag_surfxml_bypassRoute();surfxml_pcdata_ix = 0; ENTER(S_surfxml_bypassRoute); + if (!AX_simgrid_parse_bypassRoute_dst) FAIL("Required attribute `dst' not set for `bypassRoute' element."); + if (!AX_simgrid_parse_bypassRoute_src) FAIL("Required attribute `src' not set for `bypassRoute' element."); + LEAVE; STag_simgrid_parse_bypassRoute();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_bypassRoute); } YY_BREAK case 126: YY_RULE_SETUP { - if (!AX_surfxml_bypassRoute_dst) FAIL("Required attribute `dst' not set for `bypassRoute' element."); - if (!AX_surfxml_bypassRoute_src) FAIL("Required attribute `src' not set for `bypassRoute' element."); - LEAVE; STag_surfxml_bypassRoute(); surfxml_pcdata_ix = 0; ETag_surfxml_bypassRoute(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_bypassRoute_dst) FAIL("Required attribute `dst' not set for `bypassRoute' element."); + if (!AX_simgrid_parse_bypassRoute_src) FAIL("Required attribute `src' not set for `bypassRoute' element."); + LEAVE; STag_simgrid_parse_bypassRoute(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_bypassRoute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_12: case S_surfxml_AS_14: case S_surfxml_AS_15: case S_surfxml_AS_16: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_16); break; - case S_surfxml_zone: case S_surfxml_zone_12: case S_surfxml_zone_14: case S_surfxml_zone_15: case S_surfxml_zone_16: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_16); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_12: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_15: case S_simgrid_parse_AS_16: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_16); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_12: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_15: case S_simgrid_parse_zone_16: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_16); break; } } YY_BREAK @@ -7524,7 +7517,7 @@ case 128: YY_RULE_SETUP FAIL("Bad attribute `%s' in `bypassRoute' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_bypassRoute): +case YY_STATE_EOF(AL_simgrid_parse_bypassRoute): FAIL("EOF in attribute list of `bypassRoute' element."); YY_BREAK @@ -7533,11 +7526,11 @@ case 129: YY_RULE_SETUP { LEAVE; - ETag_surfxml_bypassRoute(); + ETag_simgrid_parse_bypassRoute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_12: case S_surfxml_AS_14: case S_surfxml_AS_15: case S_surfxml_AS_16: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_16); break; - case S_surfxml_zone: case S_surfxml_zone_12: case S_surfxml_zone_14: case S_surfxml_zone_15: case S_surfxml_zone_16: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_16); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_12: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_15: case S_simgrid_parse_AS_16: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_16); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_12: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_15: case S_simgrid_parse_zone_16: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_16); break; } } YY_BREAK @@ -7550,9 +7543,9 @@ case 131: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_bypassRoute): -case YY_STATE_EOF(S_surfxml_bypassRoute): -case YY_STATE_EOF(S_surfxml_bypassRoute_2): +case YY_STATE_EOF(E_simgrid_parse_bypassRoute): +case YY_STATE_EOF(S_simgrid_parse_bypassRoute): +case YY_STATE_EOF(S_simgrid_parse_bypassRoute_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -7565,79 +7558,79 @@ case 133: /* rule 133 can match eol */ YY_RULE_SETUP { - AX_surfxml_bypassZoneRoute_dst = 0; - surfxml_bypassZoneRoute_dst_isset = 0; - AX_surfxml_bypassZoneRoute_gw___dst = 0; - surfxml_bypassZoneRoute_gw___dst_isset = 0; - AX_surfxml_bypassZoneRoute_gw___src = 0; - surfxml_bypassZoneRoute_gw___src_isset = 0; - AX_surfxml_bypassZoneRoute_src = 0; - surfxml_bypassZoneRoute_src_isset = 0; - ENTER(AL_surfxml_bypassZoneRoute); pushbuffer(0); + AX_simgrid_parse_bypassZoneRoute_dst = 0; + simgrid_parse_bypassZoneRoute_dst_isset = 0; + AX_simgrid_parse_bypassZoneRoute_gw___dst = 0; + simgrid_parse_bypassZoneRoute_gw___dst_isset = 0; + AX_simgrid_parse_bypassZoneRoute_gw___src = 0; + simgrid_parse_bypassZoneRoute_gw___src_isset = 0; + AX_simgrid_parse_bypassZoneRoute_src = 0; + simgrid_parse_bypassZoneRoute_src_isset = 0; + ENTER(AL_simgrid_parse_bypassZoneRoute); pushbuffer(0); } YY_BREAK case 134: /* rule 134 can match eol */ YY_RULE_SETUP -if (surfxml_bypassZoneRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_bypassZoneRoute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassZoneRoute_dst); +if (simgrid_parse_bypassZoneRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_bypassZoneRoute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassZoneRoute_dst); YY_BREAK case 135: /* rule 135 can match eol */ YY_RULE_SETUP -if (surfxml_bypassZoneRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_bypassZoneRoute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassZoneRoute_dst); +if (simgrid_parse_bypassZoneRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_bypassZoneRoute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassZoneRoute_dst); YY_BREAK case 136: /* rule 136 can match eol */ YY_RULE_SETUP -if (surfxml_bypassZoneRoute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} surfxml_bypassZoneRoute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassZoneRoute_gw___dst); +if (simgrid_parse_bypassZoneRoute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} simgrid_parse_bypassZoneRoute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassZoneRoute_gw___dst); YY_BREAK case 137: /* rule 137 can match eol */ YY_RULE_SETUP -if (surfxml_bypassZoneRoute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} surfxml_bypassZoneRoute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassZoneRoute_gw___dst); +if (simgrid_parse_bypassZoneRoute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} simgrid_parse_bypassZoneRoute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassZoneRoute_gw___dst); YY_BREAK case 138: /* rule 138 can match eol */ YY_RULE_SETUP -if (surfxml_bypassZoneRoute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} surfxml_bypassZoneRoute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassZoneRoute_gw___src); +if (simgrid_parse_bypassZoneRoute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} simgrid_parse_bypassZoneRoute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassZoneRoute_gw___src); YY_BREAK case 139: /* rule 139 can match eol */ YY_RULE_SETUP -if (surfxml_bypassZoneRoute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} surfxml_bypassZoneRoute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassZoneRoute_gw___src); +if (simgrid_parse_bypassZoneRoute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} simgrid_parse_bypassZoneRoute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassZoneRoute_gw___src); YY_BREAK case 140: /* rule 140 can match eol */ YY_RULE_SETUP -if (surfxml_bypassZoneRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_bypassZoneRoute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassZoneRoute_src); +if (simgrid_parse_bypassZoneRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_bypassZoneRoute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_bypassZoneRoute_src); YY_BREAK case 141: /* rule 141 can match eol */ YY_RULE_SETUP -if (surfxml_bypassZoneRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_bypassZoneRoute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassZoneRoute_src); +if (simgrid_parse_bypassZoneRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_bypassZoneRoute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_bypassZoneRoute_src); YY_BREAK case 142: YY_RULE_SETUP { - if (!AX_surfxml_bypassZoneRoute_dst) FAIL("Required attribute `dst' not set for `bypassZoneRoute' element."); - if (!AX_surfxml_bypassZoneRoute_gw___dst) FAIL("Required attribute `gw_dst' not set for `bypassZoneRoute' element."); - if (!AX_surfxml_bypassZoneRoute_gw___src) FAIL("Required attribute `gw_src' not set for `bypassZoneRoute' element."); - if (!AX_surfxml_bypassZoneRoute_src) FAIL("Required attribute `src' not set for `bypassZoneRoute' element."); - LEAVE; STag_surfxml_bypassZoneRoute();surfxml_pcdata_ix = 0; ENTER(S_surfxml_bypassZoneRoute); + if (!AX_simgrid_parse_bypassZoneRoute_dst) FAIL("Required attribute `dst' not set for `bypassZoneRoute' element."); + if (!AX_simgrid_parse_bypassZoneRoute_gw___dst) FAIL("Required attribute `gw_dst' not set for `bypassZoneRoute' element."); + if (!AX_simgrid_parse_bypassZoneRoute_gw___src) FAIL("Required attribute `gw_src' not set for `bypassZoneRoute' element."); + if (!AX_simgrid_parse_bypassZoneRoute_src) FAIL("Required attribute `src' not set for `bypassZoneRoute' element."); + LEAVE; STag_simgrid_parse_bypassZoneRoute();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_bypassZoneRoute); } YY_BREAK case 143: YY_RULE_SETUP { - if (!AX_surfxml_bypassZoneRoute_dst) FAIL("Required attribute `dst' not set for `bypassZoneRoute' element."); - if (!AX_surfxml_bypassZoneRoute_gw___dst) FAIL("Required attribute `gw_dst' not set for `bypassZoneRoute' element."); - if (!AX_surfxml_bypassZoneRoute_gw___src) FAIL("Required attribute `gw_src' not set for `bypassZoneRoute' element."); - if (!AX_surfxml_bypassZoneRoute_src) FAIL("Required attribute `src' not set for `bypassZoneRoute' element."); - LEAVE; STag_surfxml_bypassZoneRoute(); surfxml_pcdata_ix = 0; ETag_surfxml_bypassZoneRoute(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_bypassZoneRoute_dst) FAIL("Required attribute `dst' not set for `bypassZoneRoute' element."); + if (!AX_simgrid_parse_bypassZoneRoute_gw___dst) FAIL("Required attribute `gw_dst' not set for `bypassZoneRoute' element."); + if (!AX_simgrid_parse_bypassZoneRoute_gw___src) FAIL("Required attribute `gw_src' not set for `bypassZoneRoute' element."); + if (!AX_simgrid_parse_bypassZoneRoute_src) FAIL("Required attribute `src' not set for `bypassZoneRoute' element."); + LEAVE; STag_simgrid_parse_bypassZoneRoute(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_bypassZoneRoute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_8: case S_surfxml_AS_9: SET(S_surfxml_AS_9); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_8: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_8: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -7649,7 +7642,7 @@ case 145: YY_RULE_SETUP FAIL("Bad attribute `%s' in `bypassZoneRoute' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_bypassZoneRoute): +case YY_STATE_EOF(AL_simgrid_parse_bypassZoneRoute): FAIL("EOF in attribute list of `bypassZoneRoute' element."); YY_BREAK @@ -7658,11 +7651,11 @@ case 146: YY_RULE_SETUP { LEAVE; - ETag_surfxml_bypassZoneRoute(); + ETag_simgrid_parse_bypassZoneRoute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_8: case S_surfxml_AS_9: SET(S_surfxml_AS_9); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_8: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_8: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -7675,9 +7668,9 @@ case 148: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_bypassZoneRoute): -case YY_STATE_EOF(S_surfxml_bypassZoneRoute): -case YY_STATE_EOF(S_surfxml_bypassZoneRoute_2): +case YY_STATE_EOF(E_simgrid_parse_bypassZoneRoute): +case YY_STATE_EOF(S_simgrid_parse_bypassZoneRoute): +case YY_STATE_EOF(S_simgrid_parse_bypassZoneRoute_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -7690,124 +7683,124 @@ case 150: /* rule 150 can match eol */ YY_RULE_SETUP { - AX_surfxml_cabinet_bw = 0; - surfxml_cabinet_bw_isset = 0; - AX_surfxml_cabinet_id = 0; - surfxml_cabinet_id_isset = 0; - AX_surfxml_cabinet_lat = 0; - surfxml_cabinet_lat_isset = 0; - AX_surfxml_cabinet_prefix = 0; - surfxml_cabinet_prefix_isset = 0; - AX_surfxml_cabinet_radical = 0; - surfxml_cabinet_radical_isset = 0; - AX_surfxml_cabinet_speed = 0; - surfxml_cabinet_speed_isset = 0; - AX_surfxml_cabinet_suffix = 0; - surfxml_cabinet_suffix_isset = 0; - ENTER(AL_surfxml_cabinet); pushbuffer(0); + AX_simgrid_parse_cabinet_bw = 0; + simgrid_parse_cabinet_bw_isset = 0; + AX_simgrid_parse_cabinet_id = 0; + simgrid_parse_cabinet_id_isset = 0; + AX_simgrid_parse_cabinet_lat = 0; + simgrid_parse_cabinet_lat_isset = 0; + AX_simgrid_parse_cabinet_prefix = 0; + simgrid_parse_cabinet_prefix_isset = 0; + AX_simgrid_parse_cabinet_radical = 0; + simgrid_parse_cabinet_radical_isset = 0; + AX_simgrid_parse_cabinet_speed = 0; + simgrid_parse_cabinet_speed_isset = 0; + AX_simgrid_parse_cabinet_suffix = 0; + simgrid_parse_cabinet_suffix_isset = 0; + ENTER(AL_simgrid_parse_cabinet); pushbuffer(0); } YY_BREAK case 151: /* rule 151 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_bw_isset != 0) {FAIL("Multiple definition of attribute bw in ");} surfxml_cabinet_bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_bw); +if (simgrid_parse_cabinet_bw_isset != 0) {FAIL("Multiple definition of attribute bw in ");} simgrid_parse_cabinet_bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cabinet_bw); YY_BREAK case 152: /* rule 152 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_bw_isset != 0) {FAIL("Multiple definition of attribute bw in ");} surfxml_cabinet_bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_bw); +if (simgrid_parse_cabinet_bw_isset != 0) {FAIL("Multiple definition of attribute bw in ");} simgrid_parse_cabinet_bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cabinet_bw); YY_BREAK case 153: /* rule 153 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_cabinet_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_id); +if (simgrid_parse_cabinet_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_cabinet_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cabinet_id); YY_BREAK case 154: /* rule 154 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_cabinet_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_id); +if (simgrid_parse_cabinet_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_cabinet_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cabinet_id); YY_BREAK case 155: /* rule 155 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} surfxml_cabinet_lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_lat); +if (simgrid_parse_cabinet_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} simgrid_parse_cabinet_lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cabinet_lat); YY_BREAK case 156: /* rule 156 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} surfxml_cabinet_lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_lat); +if (simgrid_parse_cabinet_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} simgrid_parse_cabinet_lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cabinet_lat); YY_BREAK case 157: /* rule 157 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in ");} surfxml_cabinet_prefix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_prefix); +if (simgrid_parse_cabinet_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in ");} simgrid_parse_cabinet_prefix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cabinet_prefix); YY_BREAK case 158: /* rule 158 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in ");} surfxml_cabinet_prefix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_prefix); +if (simgrid_parse_cabinet_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in ");} simgrid_parse_cabinet_prefix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cabinet_prefix); YY_BREAK case 159: /* rule 159 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} surfxml_cabinet_radical_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_radical); +if (simgrid_parse_cabinet_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} simgrid_parse_cabinet_radical_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cabinet_radical); YY_BREAK case 160: /* rule 160 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} surfxml_cabinet_radical_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_radical); +if (simgrid_parse_cabinet_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} simgrid_parse_cabinet_radical_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cabinet_radical); YY_BREAK case 161: /* rule 161 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} surfxml_cabinet_speed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_speed); +if (simgrid_parse_cabinet_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} simgrid_parse_cabinet_speed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cabinet_speed); YY_BREAK case 162: /* rule 162 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} surfxml_cabinet_speed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_speed); +if (simgrid_parse_cabinet_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} simgrid_parse_cabinet_speed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cabinet_speed); YY_BREAK case 163: /* rule 163 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in ");} surfxml_cabinet_suffix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_suffix); +if (simgrid_parse_cabinet_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in ");} simgrid_parse_cabinet_suffix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cabinet_suffix); YY_BREAK case 164: /* rule 164 can match eol */ YY_RULE_SETUP -if (surfxml_cabinet_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in ");} surfxml_cabinet_suffix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_suffix); +if (simgrid_parse_cabinet_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in ");} simgrid_parse_cabinet_suffix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cabinet_suffix); YY_BREAK case 165: YY_RULE_SETUP { - if (!AX_surfxml_cabinet_bw) FAIL("Required attribute `bw' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_id) FAIL("Required attribute `id' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_lat) FAIL("Required attribute `lat' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_prefix) FAIL("Required attribute `prefix' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_radical) FAIL("Required attribute `radical' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_speed) FAIL("Required attribute `speed' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_suffix) FAIL("Required attribute `suffix' not set for `cabinet' element."); - LEAVE; STag_surfxml_cabinet();surfxml_pcdata_ix = 0; ENTER(E_surfxml_cabinet); + if (!AX_simgrid_parse_cabinet_bw) FAIL("Required attribute `bw' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_id) FAIL("Required attribute `id' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_lat) FAIL("Required attribute `lat' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_prefix) FAIL("Required attribute `prefix' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_radical) FAIL("Required attribute `radical' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_speed) FAIL("Required attribute `speed' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_suffix) FAIL("Required attribute `suffix' not set for `cabinet' element."); + LEAVE; STag_simgrid_parse_cabinet();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_cabinet); } YY_BREAK case 166: YY_RULE_SETUP { - if (!AX_surfxml_cabinet_bw) FAIL("Required attribute `bw' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_id) FAIL("Required attribute `id' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_lat) FAIL("Required attribute `lat' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_prefix) FAIL("Required attribute `prefix' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_radical) FAIL("Required attribute `radical' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_speed) FAIL("Required attribute `speed' not set for `cabinet' element."); - if (!AX_surfxml_cabinet_suffix) FAIL("Required attribute `suffix' not set for `cabinet' element."); - LEAVE; STag_surfxml_cabinet(); surfxml_pcdata_ix = 0; ETag_surfxml_cabinet(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_cabinet_bw) FAIL("Required attribute `bw' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_id) FAIL("Required attribute `id' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_lat) FAIL("Required attribute `lat' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_prefix) FAIL("Required attribute `prefix' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_radical) FAIL("Required attribute `radical' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_speed) FAIL("Required attribute `speed' not set for `cabinet' element."); + if (!AX_simgrid_parse_cabinet_suffix) FAIL("Required attribute `suffix' not set for `cabinet' element."); + LEAVE; STag_simgrid_parse_cabinet(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_cabinet(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -7819,7 +7812,7 @@ case 168: YY_RULE_SETUP FAIL("Bad attribute `%s' in `cabinet' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_cabinet): +case YY_STATE_EOF(AL_simgrid_parse_cabinet): FAIL("EOF in attribute list of `cabinet' element."); YY_BREAK @@ -7828,14 +7821,14 @@ case 169: YY_RULE_SETUP { LEAVE; - ETag_surfxml_cabinet(); + ETag_simgrid_parse_cabinet(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -7848,7 +7841,7 @@ case 171: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_cabinet): +case YY_STATE_EOF(E_simgrid_parse_cabinet): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -7861,295 +7854,295 @@ case 173: /* rule 173 can match eol */ YY_RULE_SETUP { - AX_surfxml_cluster_bb___bw = 0; - surfxml_cluster_bb___bw_isset = 0; - AX_surfxml_cluster_bb___lat = 30; - surfxml_cluster_bb___lat_isset = 0; - AX_surfxml_cluster_bb___sharing___policy = A_surfxml_cluster_bb___sharing___policy_SHARED; - surfxml_cluster_bb___sharing___policy_isset = 0; - AX_surfxml_cluster_bw = 0; - surfxml_cluster_bw_isset = 0; - AX_surfxml_cluster_core = 28; - surfxml_cluster_core_isset = 0; - AX_surfxml_cluster_id = 0; - surfxml_cluster_id_isset = 0; - AX_surfxml_cluster_lat = 0; - surfxml_cluster_lat_isset = 0; - AX_surfxml_cluster_limiter___link = 0; - surfxml_cluster_limiter___link_isset = 0; - AX_surfxml_cluster_loopback___bw = 0; - surfxml_cluster_loopback___bw_isset = 0; - AX_surfxml_cluster_loopback___lat = 0; - surfxml_cluster_loopback___lat_isset = 0; - AX_surfxml_cluster_prefix = 0; - surfxml_cluster_prefix_isset = 0; - AX_surfxml_cluster_radical = 0; - surfxml_cluster_radical_isset = 0; - AX_surfxml_cluster_router___id = 0; - surfxml_cluster_router___id_isset = 0; - AX_surfxml_cluster_sharing___policy = A_surfxml_cluster_sharing___policy_SPLITDUPLEX; - surfxml_cluster_sharing___policy_isset = 0; - AX_surfxml_cluster_speed = 0; - surfxml_cluster_speed_isset = 0; - AX_surfxml_cluster_suffix = 0; - surfxml_cluster_suffix_isset = 0; - AX_surfxml_cluster_topo___parameters = 0; - surfxml_cluster_topo___parameters_isset = 0; - AX_surfxml_cluster_topology = A_surfxml_cluster_topology_FLAT; - surfxml_cluster_topology_isset = 0; - ENTER(AL_surfxml_cluster); pushbuffer(0); + AX_simgrid_parse_cluster_bb___bw = 0; + simgrid_parse_cluster_bb___bw_isset = 0; + AX_simgrid_parse_cluster_bb___lat = 30; + simgrid_parse_cluster_bb___lat_isset = 0; + AX_simgrid_parse_cluster_bb___sharing___policy = A_simgrid_parse_cluster_bb___sharing___policy_SHARED; + simgrid_parse_cluster_bb___sharing___policy_isset = 0; + AX_simgrid_parse_cluster_bw = 0; + simgrid_parse_cluster_bw_isset = 0; + AX_simgrid_parse_cluster_core = 28; + simgrid_parse_cluster_core_isset = 0; + AX_simgrid_parse_cluster_id = 0; + simgrid_parse_cluster_id_isset = 0; + AX_simgrid_parse_cluster_lat = 0; + simgrid_parse_cluster_lat_isset = 0; + AX_simgrid_parse_cluster_limiter___link = 0; + simgrid_parse_cluster_limiter___link_isset = 0; + AX_simgrid_parse_cluster_loopback___bw = 0; + simgrid_parse_cluster_loopback___bw_isset = 0; + AX_simgrid_parse_cluster_loopback___lat = 0; + simgrid_parse_cluster_loopback___lat_isset = 0; + AX_simgrid_parse_cluster_prefix = 0; + simgrid_parse_cluster_prefix_isset = 0; + AX_simgrid_parse_cluster_radical = 0; + simgrid_parse_cluster_radical_isset = 0; + AX_simgrid_parse_cluster_router___id = 0; + simgrid_parse_cluster_router___id_isset = 0; + AX_simgrid_parse_cluster_sharing___policy = A_simgrid_parse_cluster_sharing___policy_SPLITDUPLEX; + simgrid_parse_cluster_sharing___policy_isset = 0; + AX_simgrid_parse_cluster_speed = 0; + simgrid_parse_cluster_speed_isset = 0; + AX_simgrid_parse_cluster_suffix = 0; + simgrid_parse_cluster_suffix_isset = 0; + AX_simgrid_parse_cluster_topo___parameters = 0; + simgrid_parse_cluster_topo___parameters_isset = 0; + AX_simgrid_parse_cluster_topology = A_simgrid_parse_cluster_topology_FLAT; + simgrid_parse_cluster_topology_isset = 0; + ENTER(AL_simgrid_parse_cluster); pushbuffer(0); } YY_BREAK case 174: /* rule 174 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_bb___bw_isset != 0) {FAIL("Multiple definition of attribute bb_bw in ");} surfxml_cluster_bb___bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_bb___bw); +if (simgrid_parse_cluster_bb___bw_isset != 0) {FAIL("Multiple definition of attribute bb_bw in ");} simgrid_parse_cluster_bb___bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_bb___bw); YY_BREAK case 175: /* rule 175 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_bb___bw_isset != 0) {FAIL("Multiple definition of attribute bb_bw in ");} surfxml_cluster_bb___bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_bb___bw); +if (simgrid_parse_cluster_bb___bw_isset != 0) {FAIL("Multiple definition of attribute bb_bw in ");} simgrid_parse_cluster_bb___bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_bb___bw); YY_BREAK case 176: /* rule 176 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_bb___lat_isset != 0) {FAIL("Multiple definition of attribute bb_lat in ");} surfxml_cluster_bb___lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_bb___lat); +if (simgrid_parse_cluster_bb___lat_isset != 0) {FAIL("Multiple definition of attribute bb_lat in ");} simgrid_parse_cluster_bb___lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_bb___lat); YY_BREAK case 177: /* rule 177 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_bb___lat_isset != 0) {FAIL("Multiple definition of attribute bb_lat in ");} surfxml_cluster_bb___lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_bb___lat); +if (simgrid_parse_cluster_bb___lat_isset != 0) {FAIL("Multiple definition of attribute bb_lat in ");} simgrid_parse_cluster_bb___lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_bb___lat); YY_BREAK case 178: /* rule 178 can match eol */ case 179: /* rule 179 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_bb___sharing___policy = A_surfxml_cluster_bb___sharing___policy_SHARED; +A_simgrid_parse_cluster_bb___sharing___policy = A_simgrid_parse_cluster_bb___sharing___policy_SHARED; YY_BREAK case 180: /* rule 180 can match eol */ case 181: /* rule 181 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_bb___sharing___policy = A_surfxml_cluster_bb___sharing___policy_FATPIPE; +A_simgrid_parse_cluster_bb___sharing___policy = A_simgrid_parse_cluster_bb___sharing___policy_FATPIPE; YY_BREAK case 182: /* rule 182 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_bw_isset != 0) {FAIL("Multiple definition of attribute bw in ");} surfxml_cluster_bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_bw); +if (simgrid_parse_cluster_bw_isset != 0) {FAIL("Multiple definition of attribute bw in ");} simgrid_parse_cluster_bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_bw); YY_BREAK case 183: /* rule 183 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_bw_isset != 0) {FAIL("Multiple definition of attribute bw in ");} surfxml_cluster_bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_bw); +if (simgrid_parse_cluster_bw_isset != 0) {FAIL("Multiple definition of attribute bw in ");} simgrid_parse_cluster_bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_bw); YY_BREAK case 184: /* rule 184 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_core_isset != 0) {FAIL("Multiple definition of attribute core in ");} surfxml_cluster_core_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_core); +if (simgrid_parse_cluster_core_isset != 0) {FAIL("Multiple definition of attribute core in ");} simgrid_parse_cluster_core_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_core); YY_BREAK case 185: /* rule 185 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_core_isset != 0) {FAIL("Multiple definition of attribute core in ");} surfxml_cluster_core_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_core); +if (simgrid_parse_cluster_core_isset != 0) {FAIL("Multiple definition of attribute core in ");} simgrid_parse_cluster_core_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_core); YY_BREAK case 186: /* rule 186 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_cluster_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_id); +if (simgrid_parse_cluster_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_cluster_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_id); YY_BREAK case 187: /* rule 187 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_cluster_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_id); +if (simgrid_parse_cluster_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_cluster_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_id); YY_BREAK case 188: /* rule 188 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} surfxml_cluster_lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_lat); +if (simgrid_parse_cluster_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} simgrid_parse_cluster_lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_lat); YY_BREAK case 189: /* rule 189 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} surfxml_cluster_lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_lat); +if (simgrid_parse_cluster_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} simgrid_parse_cluster_lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_lat); YY_BREAK case 190: /* rule 190 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_limiter___link_isset != 0) {FAIL("Multiple definition of attribute limiter_link in ");} surfxml_cluster_limiter___link_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_limiter___link); +if (simgrid_parse_cluster_limiter___link_isset != 0) {FAIL("Multiple definition of attribute limiter_link in ");} simgrid_parse_cluster_limiter___link_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_limiter___link); YY_BREAK case 191: /* rule 191 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_limiter___link_isset != 0) {FAIL("Multiple definition of attribute limiter_link in ");} surfxml_cluster_limiter___link_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_limiter___link); +if (simgrid_parse_cluster_limiter___link_isset != 0) {FAIL("Multiple definition of attribute limiter_link in ");} simgrid_parse_cluster_limiter___link_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_limiter___link); YY_BREAK case 192: /* rule 192 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_loopback___bw_isset != 0) {FAIL("Multiple definition of attribute loopback_bw in ");} surfxml_cluster_loopback___bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_loopback___bw); +if (simgrid_parse_cluster_loopback___bw_isset != 0) {FAIL("Multiple definition of attribute loopback_bw in ");} simgrid_parse_cluster_loopback___bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_loopback___bw); YY_BREAK case 193: /* rule 193 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_loopback___bw_isset != 0) {FAIL("Multiple definition of attribute loopback_bw in ");} surfxml_cluster_loopback___bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_loopback___bw); +if (simgrid_parse_cluster_loopback___bw_isset != 0) {FAIL("Multiple definition of attribute loopback_bw in ");} simgrid_parse_cluster_loopback___bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_loopback___bw); YY_BREAK case 194: /* rule 194 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_loopback___lat_isset != 0) {FAIL("Multiple definition of attribute loopback_lat in ");} surfxml_cluster_loopback___lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_loopback___lat); +if (simgrid_parse_cluster_loopback___lat_isset != 0) {FAIL("Multiple definition of attribute loopback_lat in ");} simgrid_parse_cluster_loopback___lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_loopback___lat); YY_BREAK case 195: /* rule 195 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_loopback___lat_isset != 0) {FAIL("Multiple definition of attribute loopback_lat in ");} surfxml_cluster_loopback___lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_loopback___lat); +if (simgrid_parse_cluster_loopback___lat_isset != 0) {FAIL("Multiple definition of attribute loopback_lat in ");} simgrid_parse_cluster_loopback___lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_loopback___lat); YY_BREAK case 196: /* rule 196 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in ");} surfxml_cluster_prefix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_prefix); +if (simgrid_parse_cluster_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in ");} simgrid_parse_cluster_prefix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_prefix); YY_BREAK case 197: /* rule 197 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in ");} surfxml_cluster_prefix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_prefix); +if (simgrid_parse_cluster_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in ");} simgrid_parse_cluster_prefix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_prefix); YY_BREAK case 198: /* rule 198 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} surfxml_cluster_radical_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_radical); +if (simgrid_parse_cluster_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} simgrid_parse_cluster_radical_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_radical); YY_BREAK case 199: /* rule 199 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} surfxml_cluster_radical_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_radical); +if (simgrid_parse_cluster_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} simgrid_parse_cluster_radical_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_radical); YY_BREAK case 200: /* rule 200 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_router___id_isset != 0) {FAIL("Multiple definition of attribute router_id in ");} surfxml_cluster_router___id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_router___id); +if (simgrid_parse_cluster_router___id_isset != 0) {FAIL("Multiple definition of attribute router_id in ");} simgrid_parse_cluster_router___id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_router___id); YY_BREAK case 201: /* rule 201 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_router___id_isset != 0) {FAIL("Multiple definition of attribute router_id in ");} surfxml_cluster_router___id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_router___id); +if (simgrid_parse_cluster_router___id_isset != 0) {FAIL("Multiple definition of attribute router_id in ");} simgrid_parse_cluster_router___id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_router___id); YY_BREAK case 202: /* rule 202 can match eol */ case 203: /* rule 203 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_sharing___policy = A_surfxml_cluster_sharing___policy_SHARED; +A_simgrid_parse_cluster_sharing___policy = A_simgrid_parse_cluster_sharing___policy_SHARED; YY_BREAK case 204: /* rule 204 can match eol */ case 205: /* rule 205 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_sharing___policy = A_surfxml_cluster_sharing___policy_SPLITDUPLEX; +A_simgrid_parse_cluster_sharing___policy = A_simgrid_parse_cluster_sharing___policy_SPLITDUPLEX; YY_BREAK case 206: /* rule 206 can match eol */ case 207: /* rule 207 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_sharing___policy = A_surfxml_cluster_sharing___policy_FULLDUPLEX; +A_simgrid_parse_cluster_sharing___policy = A_simgrid_parse_cluster_sharing___policy_FULLDUPLEX; YY_BREAK case 208: /* rule 208 can match eol */ case 209: /* rule 209 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_sharing___policy = A_surfxml_cluster_sharing___policy_FATPIPE; +A_simgrid_parse_cluster_sharing___policy = A_simgrid_parse_cluster_sharing___policy_FATPIPE; YY_BREAK case 210: /* rule 210 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} surfxml_cluster_speed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_speed); +if (simgrid_parse_cluster_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} simgrid_parse_cluster_speed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_speed); YY_BREAK case 211: /* rule 211 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} surfxml_cluster_speed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_speed); +if (simgrid_parse_cluster_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} simgrid_parse_cluster_speed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_speed); YY_BREAK case 212: /* rule 212 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in ");} surfxml_cluster_suffix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_suffix); +if (simgrid_parse_cluster_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in ");} simgrid_parse_cluster_suffix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_suffix); YY_BREAK case 213: /* rule 213 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in ");} surfxml_cluster_suffix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_suffix); +if (simgrid_parse_cluster_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in ");} simgrid_parse_cluster_suffix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_suffix); YY_BREAK case 214: /* rule 214 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_topo___parameters_isset != 0) {FAIL("Multiple definition of attribute topo_parameters in ");} surfxml_cluster_topo___parameters_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_topo___parameters); +if (simgrid_parse_cluster_topo___parameters_isset != 0) {FAIL("Multiple definition of attribute topo_parameters in ");} simgrid_parse_cluster_topo___parameters_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_cluster_topo___parameters); YY_BREAK case 215: /* rule 215 can match eol */ YY_RULE_SETUP -if (surfxml_cluster_topo___parameters_isset != 0) {FAIL("Multiple definition of attribute topo_parameters in ");} surfxml_cluster_topo___parameters_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_topo___parameters); +if (simgrid_parse_cluster_topo___parameters_isset != 0) {FAIL("Multiple definition of attribute topo_parameters in ");} simgrid_parse_cluster_topo___parameters_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_cluster_topo___parameters); YY_BREAK case 216: /* rule 216 can match eol */ case 217: /* rule 217 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_topology = A_surfxml_cluster_topology_FLAT; +A_simgrid_parse_cluster_topology = A_simgrid_parse_cluster_topology_FLAT; YY_BREAK case 218: /* rule 218 can match eol */ case 219: /* rule 219 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_topology = A_surfxml_cluster_topology_TORUS; +A_simgrid_parse_cluster_topology = A_simgrid_parse_cluster_topology_TORUS; YY_BREAK case 220: /* rule 220 can match eol */ case 221: /* rule 221 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_topology = A_surfxml_cluster_topology_FAT___TREE; +A_simgrid_parse_cluster_topology = A_simgrid_parse_cluster_topology_FAT___TREE; YY_BREAK case 222: /* rule 222 can match eol */ case 223: /* rule 223 can match eol */ YY_RULE_SETUP -A_surfxml_cluster_topology = A_surfxml_cluster_topology_DRAGONFLY; +A_simgrid_parse_cluster_topology = A_simgrid_parse_cluster_topology_DRAGONFLY; YY_BREAK case 224: YY_RULE_SETUP { - if (!AX_surfxml_cluster_bw) FAIL("Required attribute `bw' not set for `cluster' element."); - if (!AX_surfxml_cluster_id) FAIL("Required attribute `id' not set for `cluster' element."); - if (!AX_surfxml_cluster_lat) FAIL("Required attribute `lat' not set for `cluster' element."); - if (!AX_surfxml_cluster_prefix) FAIL("Required attribute `prefix' not set for `cluster' element."); - if (!AX_surfxml_cluster_radical) FAIL("Required attribute `radical' not set for `cluster' element."); - if (!AX_surfxml_cluster_speed) FAIL("Required attribute `speed' not set for `cluster' element."); - if (!AX_surfxml_cluster_suffix) FAIL("Required attribute `suffix' not set for `cluster' element."); - LEAVE; STag_surfxml_cluster();surfxml_pcdata_ix = 0; ENTER(S_surfxml_cluster); + if (!AX_simgrid_parse_cluster_bw) FAIL("Required attribute `bw' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_id) FAIL("Required attribute `id' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_lat) FAIL("Required attribute `lat' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_prefix) FAIL("Required attribute `prefix' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_radical) FAIL("Required attribute `radical' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_speed) FAIL("Required attribute `speed' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_suffix) FAIL("Required attribute `suffix' not set for `cluster' element."); + LEAVE; STag_simgrid_parse_cluster();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_cluster); } YY_BREAK case 225: YY_RULE_SETUP { - if (!AX_surfxml_cluster_bw) FAIL("Required attribute `bw' not set for `cluster' element."); - if (!AX_surfxml_cluster_id) FAIL("Required attribute `id' not set for `cluster' element."); - if (!AX_surfxml_cluster_lat) FAIL("Required attribute `lat' not set for `cluster' element."); - if (!AX_surfxml_cluster_prefix) FAIL("Required attribute `prefix' not set for `cluster' element."); - if (!AX_surfxml_cluster_radical) FAIL("Required attribute `radical' not set for `cluster' element."); - if (!AX_surfxml_cluster_speed) FAIL("Required attribute `speed' not set for `cluster' element."); - if (!AX_surfxml_cluster_suffix) FAIL("Required attribute `suffix' not set for `cluster' element."); - LEAVE; STag_surfxml_cluster(); surfxml_pcdata_ix = 0; ETag_surfxml_cluster(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_cluster_bw) FAIL("Required attribute `bw' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_id) FAIL("Required attribute `id' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_lat) FAIL("Required attribute `lat' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_prefix) FAIL("Required attribute `prefix' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_radical) FAIL("Required attribute `radical' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_speed) FAIL("Required attribute `speed' not set for `cluster' element."); + if (!AX_simgrid_parse_cluster_suffix) FAIL("Required attribute `suffix' not set for `cluster' element."); + LEAVE; STag_simgrid_parse_cluster(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_cluster(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -8161,7 +8154,7 @@ case 227: YY_RULE_SETUP FAIL("Bad attribute `%s' in `cluster' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_cluster): +case YY_STATE_EOF(AL_simgrid_parse_cluster): FAIL("EOF in attribute list of `cluster' element."); YY_BREAK @@ -8170,13 +8163,13 @@ case 228: YY_RULE_SETUP { LEAVE; - ETag_surfxml_cluster(); + ETag_simgrid_parse_cluster(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -8189,9 +8182,9 @@ case 230: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_cluster): -case YY_STATE_EOF(S_surfxml_cluster): -case YY_STATE_EOF(S_surfxml_cluster_2): +case YY_STATE_EOF(E_simgrid_parse_cluster): +case YY_STATE_EOF(S_simgrid_parse_cluster): +case YY_STATE_EOF(S_simgrid_parse_cluster_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -8204,34 +8197,34 @@ case 232: /* rule 232 can match eol */ YY_RULE_SETUP { - AX_surfxml_config_id = 0; - surfxml_config_id_isset = 0; - ENTER(AL_surfxml_config); pushbuffer(0); + AX_simgrid_parse_config_id = 0; + simgrid_parse_config_id_isset = 0; + ENTER(AL_simgrid_parse_config); pushbuffer(0); } YY_BREAK case 233: /* rule 233 can match eol */ YY_RULE_SETUP -if (surfxml_config_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_config_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_config_id); +if (simgrid_parse_config_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_config_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_config_id); YY_BREAK case 234: /* rule 234 can match eol */ YY_RULE_SETUP -if (surfxml_config_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_config_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_config_id); +if (simgrid_parse_config_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_config_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_config_id); YY_BREAK case 235: YY_RULE_SETUP { - LEAVE; STag_surfxml_config();surfxml_pcdata_ix = 0; ENTER(S_surfxml_config); + LEAVE; STag_simgrid_parse_config();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_config); } YY_BREAK case 236: YY_RULE_SETUP { - LEAVE; STag_surfxml_config(); surfxml_pcdata_ix = 0; ETag_surfxml_config(); popbuffer(); /* attribute */ + LEAVE; STag_simgrid_parse_config(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_config(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_platform: case S_surfxml_platform_2: case S_surfxml_platform_3: SET(S_surfxml_platform_3); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_2: case S_simgrid_parse_platform_3: SET(S_simgrid_parse_platform_3); break; } } YY_BREAK @@ -8243,7 +8236,7 @@ case 238: YY_RULE_SETUP FAIL("Bad attribute `%s' in `config' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_config): +case YY_STATE_EOF(AL_simgrid_parse_config): FAIL("EOF in attribute list of `config' element."); YY_BREAK @@ -8252,10 +8245,10 @@ case 239: YY_RULE_SETUP { LEAVE; - ETag_surfxml_config(); + ETag_simgrid_parse_config(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_platform: case S_surfxml_platform_2: case S_surfxml_platform_3: SET(S_surfxml_platform_3); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_2: case S_simgrid_parse_platform_3: SET(S_simgrid_parse_platform_3); break; } } YY_BREAK @@ -8268,9 +8261,9 @@ case 241: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_config): -case YY_STATE_EOF(S_surfxml_config): -case YY_STATE_EOF(S_surfxml_config_2): +case YY_STATE_EOF(E_simgrid_parse_config): +case YY_STATE_EOF(S_simgrid_parse_config): +case YY_STATE_EOF(S_simgrid_parse_config_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -8283,62 +8276,62 @@ case 243: /* rule 243 can match eol */ YY_RULE_SETUP { - AX_surfxml_disk_id = 26; - surfxml_disk_id_isset = 0; - AX_surfxml_disk_read___bw = 0; - surfxml_disk_read___bw_isset = 0; - AX_surfxml_disk_write___bw = 0; - surfxml_disk_write___bw_isset = 0; - ENTER(AL_surfxml_disk); pushbuffer(0); + AX_simgrid_parse_disk_id = 26; + simgrid_parse_disk_id_isset = 0; + AX_simgrid_parse_disk_read___bw = 0; + simgrid_parse_disk_read___bw_isset = 0; + AX_simgrid_parse_disk_write___bw = 0; + simgrid_parse_disk_write___bw_isset = 0; + ENTER(AL_simgrid_parse_disk); pushbuffer(0); } YY_BREAK case 244: /* rule 244 can match eol */ YY_RULE_SETUP -if (surfxml_disk_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_disk_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_disk_id); +if (simgrid_parse_disk_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_disk_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_disk_id); YY_BREAK case 245: /* rule 245 can match eol */ YY_RULE_SETUP -if (surfxml_disk_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_disk_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_disk_id); +if (simgrid_parse_disk_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_disk_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_disk_id); YY_BREAK case 246: /* rule 246 can match eol */ YY_RULE_SETUP -if (surfxml_disk_read___bw_isset != 0) {FAIL("Multiple definition of attribute read_bw in ");} surfxml_disk_read___bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_disk_read___bw); +if (simgrid_parse_disk_read___bw_isset != 0) {FAIL("Multiple definition of attribute read_bw in ");} simgrid_parse_disk_read___bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_disk_read___bw); YY_BREAK case 247: /* rule 247 can match eol */ YY_RULE_SETUP -if (surfxml_disk_read___bw_isset != 0) {FAIL("Multiple definition of attribute read_bw in ");} surfxml_disk_read___bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_disk_read___bw); +if (simgrid_parse_disk_read___bw_isset != 0) {FAIL("Multiple definition of attribute read_bw in ");} simgrid_parse_disk_read___bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_disk_read___bw); YY_BREAK case 248: /* rule 248 can match eol */ YY_RULE_SETUP -if (surfxml_disk_write___bw_isset != 0) {FAIL("Multiple definition of attribute write_bw in ");} surfxml_disk_write___bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_disk_write___bw); +if (simgrid_parse_disk_write___bw_isset != 0) {FAIL("Multiple definition of attribute write_bw in ");} simgrid_parse_disk_write___bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_disk_write___bw); YY_BREAK case 249: /* rule 249 can match eol */ YY_RULE_SETUP -if (surfxml_disk_write___bw_isset != 0) {FAIL("Multiple definition of attribute write_bw in ");} surfxml_disk_write___bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_disk_write___bw); +if (simgrid_parse_disk_write___bw_isset != 0) {FAIL("Multiple definition of attribute write_bw in ");} simgrid_parse_disk_write___bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_disk_write___bw); YY_BREAK case 250: YY_RULE_SETUP { - if (!AX_surfxml_disk_read___bw) FAIL("Required attribute `read_bw' not set for `disk' element."); - if (!AX_surfxml_disk_write___bw) FAIL("Required attribute `write_bw' not set for `disk' element."); - LEAVE; STag_surfxml_disk();surfxml_pcdata_ix = 0; ENTER(S_surfxml_disk); + if (!AX_simgrid_parse_disk_read___bw) FAIL("Required attribute `read_bw' not set for `disk' element."); + if (!AX_simgrid_parse_disk_write___bw) FAIL("Required attribute `write_bw' not set for `disk' element."); + LEAVE; STag_simgrid_parse_disk();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_disk); } YY_BREAK case 251: YY_RULE_SETUP { - if (!AX_surfxml_disk_read___bw) FAIL("Required attribute `read_bw' not set for `disk' element."); - if (!AX_surfxml_disk_write___bw) FAIL("Required attribute `write_bw' not set for `disk' element."); - LEAVE; STag_surfxml_disk(); surfxml_pcdata_ix = 0; ETag_surfxml_disk(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_disk_read___bw) FAIL("Required attribute `read_bw' not set for `disk' element."); + if (!AX_simgrid_parse_disk_write___bw) FAIL("Required attribute `write_bw' not set for `disk' element."); + LEAVE; STag_simgrid_parse_disk(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_disk(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_host: case S_surfxml_host_1: case S_surfxml_host_2: SET(S_surfxml_host_2); break; + case S_simgrid_parse_host: case S_simgrid_parse_host_1: case S_simgrid_parse_host_2: SET(S_simgrid_parse_host_2); break; } } YY_BREAK @@ -8350,7 +8343,7 @@ case 253: YY_RULE_SETUP FAIL("Bad attribute `%s' in `disk' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_disk): +case YY_STATE_EOF(AL_simgrid_parse_disk): FAIL("EOF in attribute list of `disk' element."); YY_BREAK @@ -8359,10 +8352,10 @@ case 254: YY_RULE_SETUP { LEAVE; - ETag_surfxml_disk(); + ETag_simgrid_parse_disk(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_host: case S_surfxml_host_1: case S_surfxml_host_2: SET(S_surfxml_host_2); break; + case S_simgrid_parse_host: case S_simgrid_parse_host_1: case S_simgrid_parse_host_2: SET(S_simgrid_parse_host_2); break; } } YY_BREAK @@ -8375,9 +8368,9 @@ case 256: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_disk): -case YY_STATE_EOF(S_surfxml_disk): -case YY_STATE_EOF(S_surfxml_disk_2): +case YY_STATE_EOF(E_simgrid_parse_disk): +case YY_STATE_EOF(S_simgrid_parse_disk): +case YY_STATE_EOF(S_simgrid_parse_disk_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -8392,123 +8385,123 @@ case 258: /* rule 258 can match eol */ YY_RULE_SETUP { - AX_surfxml_host_availability___file = 0; - surfxml_host_availability___file_isset = 0; - AX_surfxml_host_coordinates = 0; - surfxml_host_coordinates_isset = 0; - AX_surfxml_host_core = 20; - surfxml_host_core_isset = 0; - AX_surfxml_host_id = 0; - surfxml_host_id_isset = 0; - AX_surfxml_host_pstate = 22; - surfxml_host_pstate_isset = 0; - AX_surfxml_host_speed = 0; - surfxml_host_speed_isset = 0; - AX_surfxml_host_speed___file = 0; - surfxml_host_speed___file_isset = 0; - AX_surfxml_host_state___file = 0; - surfxml_host_state___file_isset = 0; - ENTER(AL_surfxml_host); pushbuffer(0); + AX_simgrid_parse_host_availability___file = 0; + simgrid_parse_host_availability___file_isset = 0; + AX_simgrid_parse_host_coordinates = 0; + simgrid_parse_host_coordinates_isset = 0; + AX_simgrid_parse_host_core = 20; + simgrid_parse_host_core_isset = 0; + AX_simgrid_parse_host_id = 0; + simgrid_parse_host_id_isset = 0; + AX_simgrid_parse_host_pstate = 22; + simgrid_parse_host_pstate_isset = 0; + AX_simgrid_parse_host_speed = 0; + simgrid_parse_host_speed_isset = 0; + AX_simgrid_parse_host_speed___file = 0; + simgrid_parse_host_speed___file_isset = 0; + AX_simgrid_parse_host_state___file = 0; + simgrid_parse_host_state___file_isset = 0; + ENTER(AL_simgrid_parse_host); pushbuffer(0); } YY_BREAK case 259: /* rule 259 can match eol */ YY_RULE_SETUP -if (surfxml_host_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in ");} surfxml_host_availability___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host_availability___file); +if (simgrid_parse_host_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in ");} simgrid_parse_host_availability___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host_availability___file); YY_BREAK case 260: /* rule 260 can match eol */ YY_RULE_SETUP -if (surfxml_host_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in ");} surfxml_host_availability___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host_availability___file); +if (simgrid_parse_host_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in ");} simgrid_parse_host_availability___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host_availability___file); YY_BREAK case 261: /* rule 261 can match eol */ YY_RULE_SETUP -if (surfxml_host_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} surfxml_host_coordinates_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host_coordinates); +if (simgrid_parse_host_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} simgrid_parse_host_coordinates_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host_coordinates); YY_BREAK case 262: /* rule 262 can match eol */ YY_RULE_SETUP -if (surfxml_host_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} surfxml_host_coordinates_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host_coordinates); +if (simgrid_parse_host_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} simgrid_parse_host_coordinates_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host_coordinates); YY_BREAK case 263: /* rule 263 can match eol */ YY_RULE_SETUP -if (surfxml_host_core_isset != 0) {FAIL("Multiple definition of attribute core in ");} surfxml_host_core_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host_core); +if (simgrid_parse_host_core_isset != 0) {FAIL("Multiple definition of attribute core in ");} simgrid_parse_host_core_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host_core); YY_BREAK case 264: /* rule 264 can match eol */ YY_RULE_SETUP -if (surfxml_host_core_isset != 0) {FAIL("Multiple definition of attribute core in ");} surfxml_host_core_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host_core); +if (simgrid_parse_host_core_isset != 0) {FAIL("Multiple definition of attribute core in ");} simgrid_parse_host_core_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host_core); YY_BREAK case 265: /* rule 265 can match eol */ YY_RULE_SETUP -if (surfxml_host_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_host_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host_id); +if (simgrid_parse_host_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_host_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host_id); YY_BREAK case 266: /* rule 266 can match eol */ YY_RULE_SETUP -if (surfxml_host_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_host_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host_id); +if (simgrid_parse_host_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_host_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host_id); YY_BREAK case 267: /* rule 267 can match eol */ YY_RULE_SETUP -if (surfxml_host_pstate_isset != 0) {FAIL("Multiple definition of attribute pstate in ");} surfxml_host_pstate_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host_pstate); +if (simgrid_parse_host_pstate_isset != 0) {FAIL("Multiple definition of attribute pstate in ");} simgrid_parse_host_pstate_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host_pstate); YY_BREAK case 268: /* rule 268 can match eol */ YY_RULE_SETUP -if (surfxml_host_pstate_isset != 0) {FAIL("Multiple definition of attribute pstate in ");} surfxml_host_pstate_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host_pstate); +if (simgrid_parse_host_pstate_isset != 0) {FAIL("Multiple definition of attribute pstate in ");} simgrid_parse_host_pstate_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host_pstate); YY_BREAK case 269: /* rule 269 can match eol */ YY_RULE_SETUP -if (surfxml_host_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} surfxml_host_speed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host_speed); +if (simgrid_parse_host_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} simgrid_parse_host_speed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host_speed); YY_BREAK case 270: /* rule 270 can match eol */ YY_RULE_SETUP -if (surfxml_host_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} surfxml_host_speed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host_speed); +if (simgrid_parse_host_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} simgrid_parse_host_speed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host_speed); YY_BREAK case 271: /* rule 271 can match eol */ YY_RULE_SETUP -if (surfxml_host_speed___file_isset != 0) {FAIL("Multiple definition of attribute speed_file in ");} surfxml_host_speed___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host_speed___file); +if (simgrid_parse_host_speed___file_isset != 0) {FAIL("Multiple definition of attribute speed_file in ");} simgrid_parse_host_speed___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host_speed___file); YY_BREAK case 272: /* rule 272 can match eol */ YY_RULE_SETUP -if (surfxml_host_speed___file_isset != 0) {FAIL("Multiple definition of attribute speed_file in ");} surfxml_host_speed___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host_speed___file); +if (simgrid_parse_host_speed___file_isset != 0) {FAIL("Multiple definition of attribute speed_file in ");} simgrid_parse_host_speed___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host_speed___file); YY_BREAK case 273: /* rule 273 can match eol */ YY_RULE_SETUP -if (surfxml_host_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} surfxml_host_state___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host_state___file); +if (simgrid_parse_host_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} simgrid_parse_host_state___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host_state___file); YY_BREAK case 274: /* rule 274 can match eol */ YY_RULE_SETUP -if (surfxml_host_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} surfxml_host_state___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host_state___file); +if (simgrid_parse_host_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} simgrid_parse_host_state___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host_state___file); YY_BREAK case 275: YY_RULE_SETUP { - if (!AX_surfxml_host_id) FAIL("Required attribute `id' not set for `host' element."); - if (!AX_surfxml_host_speed) FAIL("Required attribute `speed' not set for `host' element."); - LEAVE; STag_surfxml_host();surfxml_pcdata_ix = 0; ENTER(S_surfxml_host); + if (!AX_simgrid_parse_host_id) FAIL("Required attribute `id' not set for `host' element."); + if (!AX_simgrid_parse_host_speed) FAIL("Required attribute `speed' not set for `host' element."); + LEAVE; STag_simgrid_parse_host();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_host); } YY_BREAK case 276: YY_RULE_SETUP { - if (!AX_surfxml_host_id) FAIL("Required attribute `id' not set for `host' element."); - if (!AX_surfxml_host_speed) FAIL("Required attribute `speed' not set for `host' element."); - LEAVE; STag_surfxml_host(); surfxml_pcdata_ix = 0; ETag_surfxml_host(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_host_id) FAIL("Required attribute `id' not set for `host' element."); + if (!AX_simgrid_parse_host_speed) FAIL("Required attribute `speed' not set for `host' element."); + LEAVE; STag_simgrid_parse_host(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_host(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -8520,7 +8513,7 @@ case 278: YY_RULE_SETUP FAIL("Bad attribute `%s' in `host' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_host): +case YY_STATE_EOF(AL_simgrid_parse_host): FAIL("EOF in attribute list of `host' element."); YY_BREAK @@ -8529,11 +8522,11 @@ case 279: YY_RULE_SETUP { LEAVE; - ETag_surfxml_host(); + ETag_simgrid_parse_host(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -8546,9 +8539,9 @@ case 281: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_host): -case YY_STATE_EOF(S_surfxml_host): -case YY_STATE_EOF(S_surfxml_host_2): +case YY_STATE_EOF(E_simgrid_parse_host): +case YY_STATE_EOF(S_simgrid_parse_host): +case YY_STATE_EOF(S_simgrid_parse_host_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -8561,65 +8554,65 @@ case 283: /* rule 283 can match eol */ YY_RULE_SETUP { - AX_surfxml_host___link_down = 0; - surfxml_host___link_down_isset = 0; - AX_surfxml_host___link_id = 0; - surfxml_host___link_id_isset = 0; - AX_surfxml_host___link_up = 0; - surfxml_host___link_up_isset = 0; - ENTER(AL_surfxml_host___link); pushbuffer(0); + AX_simgrid_parse_host___link_down = 0; + simgrid_parse_host___link_down_isset = 0; + AX_simgrid_parse_host___link_id = 0; + simgrid_parse_host___link_id_isset = 0; + AX_simgrid_parse_host___link_up = 0; + simgrid_parse_host___link_up_isset = 0; + ENTER(AL_simgrid_parse_host___link); pushbuffer(0); } YY_BREAK case 284: /* rule 284 can match eol */ YY_RULE_SETUP -if (surfxml_host___link_down_isset != 0) {FAIL("Multiple definition of attribute down in ");} surfxml_host___link_down_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host___link_down); +if (simgrid_parse_host___link_down_isset != 0) {FAIL("Multiple definition of attribute down in ");} simgrid_parse_host___link_down_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host___link_down); YY_BREAK case 285: /* rule 285 can match eol */ YY_RULE_SETUP -if (surfxml_host___link_down_isset != 0) {FAIL("Multiple definition of attribute down in ");} surfxml_host___link_down_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host___link_down); +if (simgrid_parse_host___link_down_isset != 0) {FAIL("Multiple definition of attribute down in ");} simgrid_parse_host___link_down_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host___link_down); YY_BREAK case 286: /* rule 286 can match eol */ YY_RULE_SETUP -if (surfxml_host___link_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_host___link_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host___link_id); +if (simgrid_parse_host___link_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_host___link_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host___link_id); YY_BREAK case 287: /* rule 287 can match eol */ YY_RULE_SETUP -if (surfxml_host___link_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_host___link_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host___link_id); +if (simgrid_parse_host___link_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_host___link_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host___link_id); YY_BREAK case 288: /* rule 288 can match eol */ YY_RULE_SETUP -if (surfxml_host___link_up_isset != 0) {FAIL("Multiple definition of attribute up in ");} surfxml_host___link_up_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_host___link_up); +if (simgrid_parse_host___link_up_isset != 0) {FAIL("Multiple definition of attribute up in ");} simgrid_parse_host___link_up_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_host___link_up); YY_BREAK case 289: /* rule 289 can match eol */ YY_RULE_SETUP -if (surfxml_host___link_up_isset != 0) {FAIL("Multiple definition of attribute up in ");} surfxml_host___link_up_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_host___link_up); +if (simgrid_parse_host___link_up_isset != 0) {FAIL("Multiple definition of attribute up in ");} simgrid_parse_host___link_up_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_host___link_up); YY_BREAK case 290: YY_RULE_SETUP { - if (!AX_surfxml_host___link_down) FAIL("Required attribute `down' not set for `host_link' element."); - if (!AX_surfxml_host___link_id) FAIL("Required attribute `id' not set for `host_link' element."); - if (!AX_surfxml_host___link_up) FAIL("Required attribute `up' not set for `host_link' element."); - LEAVE; STag_surfxml_host___link();surfxml_pcdata_ix = 0; ENTER(E_surfxml_host___link); + if (!AX_simgrid_parse_host___link_down) FAIL("Required attribute `down' not set for `host_link' element."); + if (!AX_simgrid_parse_host___link_id) FAIL("Required attribute `id' not set for `host_link' element."); + if (!AX_simgrid_parse_host___link_up) FAIL("Required attribute `up' not set for `host_link' element."); + LEAVE; STag_simgrid_parse_host___link();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_host___link); } YY_BREAK case 291: YY_RULE_SETUP { - if (!AX_surfxml_host___link_down) FAIL("Required attribute `down' not set for `host_link' element."); - if (!AX_surfxml_host___link_id) FAIL("Required attribute `id' not set for `host_link' element."); - if (!AX_surfxml_host___link_up) FAIL("Required attribute `up' not set for `host_link' element."); - LEAVE; STag_surfxml_host___link(); surfxml_pcdata_ix = 0; ETag_surfxml_host___link(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_host___link_down) FAIL("Required attribute `down' not set for `host_link' element."); + if (!AX_simgrid_parse_host___link_id) FAIL("Required attribute `id' not set for `host_link' element."); + if (!AX_simgrid_parse_host___link_up) FAIL("Required attribute `up' not set for `host_link' element."); + LEAVE; STag_simgrid_parse_host___link(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_host___link(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -8631,7 +8624,7 @@ case 293: YY_RULE_SETUP FAIL("Bad attribute `%s' in `host_link' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_host___link): +case YY_STATE_EOF(AL_simgrid_parse_host___link): FAIL("EOF in attribute list of `host_link' element."); YY_BREAK @@ -8640,11 +8633,11 @@ case 294: YY_RULE_SETUP { LEAVE; - ETag_surfxml_host___link(); + ETag_simgrid_parse_host___link(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -8657,7 +8650,7 @@ case 296: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_host___link): +case YY_STATE_EOF(E_simgrid_parse_host___link): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -8671,41 +8664,41 @@ case 298: /* rule 298 can match eol */ YY_RULE_SETUP { - AX_surfxml_include_file = 0; - surfxml_include_file_isset = 0; - ENTER(AL_surfxml_include); pushbuffer(0); + AX_simgrid_parse_include_file = 0; + simgrid_parse_include_file_isset = 0; + ENTER(AL_simgrid_parse_include); pushbuffer(0); } YY_BREAK case 299: /* rule 299 can match eol */ YY_RULE_SETUP -if (surfxml_include_file_isset != 0) {FAIL("Multiple definition of attribute file in ");} surfxml_include_file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_include_file); +if (simgrid_parse_include_file_isset != 0) {FAIL("Multiple definition of attribute file in ");} simgrid_parse_include_file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_include_file); YY_BREAK case 300: /* rule 300 can match eol */ YY_RULE_SETUP -if (surfxml_include_file_isset != 0) {FAIL("Multiple definition of attribute file in ");} surfxml_include_file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_include_file); +if (simgrid_parse_include_file_isset != 0) {FAIL("Multiple definition of attribute file in ");} simgrid_parse_include_file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_include_file); YY_BREAK case 301: YY_RULE_SETUP { - if (!AX_surfxml_include_file) FAIL("Required attribute `file' not set for `include' element."); - LEAVE; STag_surfxml_include();surfxml_pcdata_ix = 0; ENTER(S_surfxml_include); + if (!AX_simgrid_parse_include_file) FAIL("Required attribute `file' not set for `include' element."); + LEAVE; STag_simgrid_parse_include();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_include); } YY_BREAK case 302: YY_RULE_SETUP { - if (!AX_surfxml_include_file) FAIL("Required attribute `file' not set for `include' element."); - LEAVE; STag_surfxml_include(); surfxml_pcdata_ix = 0; ETag_surfxml_include(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_include_file) FAIL("Required attribute `file' not set for `include' element."); + LEAVE; STag_simgrid_parse_include(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_include(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -8717,7 +8710,7 @@ case 304: YY_RULE_SETUP FAIL("Bad attribute `%s' in `include' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_include): +case YY_STATE_EOF(AL_simgrid_parse_include): FAIL("EOF in attribute list of `include' element."); YY_BREAK @@ -8726,15 +8719,15 @@ case 305: YY_RULE_SETUP { LEAVE; - ETag_surfxml_include(); + ETag_simgrid_parse_include(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -8747,9 +8740,9 @@ case 307: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_include): -case YY_STATE_EOF(S_surfxml_include): -case YY_STATE_EOF(S_surfxml_include_2): +case YY_STATE_EOF(E_simgrid_parse_include): +case YY_STATE_EOF(S_simgrid_parse_include): +case YY_STATE_EOF(S_simgrid_parse_include_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -8762,138 +8755,138 @@ case 309: /* rule 309 can match eol */ YY_RULE_SETUP { - AX_surfxml_link_bandwidth = 0; - surfxml_link_bandwidth_isset = 0; - AX_surfxml_link_bandwidth___file = 0; - surfxml_link_bandwidth___file_isset = 0; - AX_surfxml_link_id = 0; - surfxml_link_id_isset = 0; - AX_surfxml_link_latency = 0; - surfxml_link_latency_isset = 0; - AX_surfxml_link_latency___file = 0; - surfxml_link_latency___file_isset = 0; - AX_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_SHARED; - surfxml_link_sharing___policy_isset = 0; - AX_surfxml_link_state___file = 0; - surfxml_link_state___file_isset = 0; - ENTER(AL_surfxml_link); pushbuffer(0); + AX_simgrid_parse_link_bandwidth = 0; + simgrid_parse_link_bandwidth_isset = 0; + AX_simgrid_parse_link_bandwidth___file = 0; + simgrid_parse_link_bandwidth___file_isset = 0; + AX_simgrid_parse_link_id = 0; + simgrid_parse_link_id_isset = 0; + AX_simgrid_parse_link_latency = 0; + simgrid_parse_link_latency_isset = 0; + AX_simgrid_parse_link_latency___file = 0; + simgrid_parse_link_latency___file_isset = 0; + AX_simgrid_parse_link_sharing___policy = A_simgrid_parse_link_sharing___policy_SHARED; + simgrid_parse_link_sharing___policy_isset = 0; + AX_simgrid_parse_link_state___file = 0; + simgrid_parse_link_state___file_isset = 0; + ENTER(AL_simgrid_parse_link); pushbuffer(0); } YY_BREAK case 310: /* rule 310 can match eol */ YY_RULE_SETUP -if (surfxml_link_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in ");} surfxml_link_bandwidth_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_bandwidth); +if (simgrid_parse_link_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in ");} simgrid_parse_link_bandwidth_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_link_bandwidth); YY_BREAK case 311: /* rule 311 can match eol */ YY_RULE_SETUP -if (surfxml_link_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in ");} surfxml_link_bandwidth_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_bandwidth); +if (simgrid_parse_link_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in ");} simgrid_parse_link_bandwidth_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_link_bandwidth); YY_BREAK case 312: /* rule 312 can match eol */ YY_RULE_SETUP -if (surfxml_link_bandwidth___file_isset != 0) {FAIL("Multiple definition of attribute bandwidth_file in ");} surfxml_link_bandwidth___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_bandwidth___file); +if (simgrid_parse_link_bandwidth___file_isset != 0) {FAIL("Multiple definition of attribute bandwidth_file in ");} simgrid_parse_link_bandwidth___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_link_bandwidth___file); YY_BREAK case 313: /* rule 313 can match eol */ YY_RULE_SETUP -if (surfxml_link_bandwidth___file_isset != 0) {FAIL("Multiple definition of attribute bandwidth_file in ");} surfxml_link_bandwidth___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_bandwidth___file); +if (simgrid_parse_link_bandwidth___file_isset != 0) {FAIL("Multiple definition of attribute bandwidth_file in ");} simgrid_parse_link_bandwidth___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_link_bandwidth___file); YY_BREAK case 314: /* rule 314 can match eol */ YY_RULE_SETUP -if (surfxml_link_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_link_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_id); +if (simgrid_parse_link_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_link_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_link_id); YY_BREAK case 315: /* rule 315 can match eol */ YY_RULE_SETUP -if (surfxml_link_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_link_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_id); +if (simgrid_parse_link_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_link_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_link_id); YY_BREAK case 316: /* rule 316 can match eol */ YY_RULE_SETUP -if (surfxml_link_latency_isset != 0) {FAIL("Multiple definition of attribute latency in ");} surfxml_link_latency_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_latency); +if (simgrid_parse_link_latency_isset != 0) {FAIL("Multiple definition of attribute latency in ");} simgrid_parse_link_latency_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_link_latency); YY_BREAK case 317: /* rule 317 can match eol */ YY_RULE_SETUP -if (surfxml_link_latency_isset != 0) {FAIL("Multiple definition of attribute latency in ");} surfxml_link_latency_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_latency); +if (simgrid_parse_link_latency_isset != 0) {FAIL("Multiple definition of attribute latency in ");} simgrid_parse_link_latency_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_link_latency); YY_BREAK case 318: /* rule 318 can match eol */ YY_RULE_SETUP -if (surfxml_link_latency___file_isset != 0) {FAIL("Multiple definition of attribute latency_file in ");} surfxml_link_latency___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_latency___file); +if (simgrid_parse_link_latency___file_isset != 0) {FAIL("Multiple definition of attribute latency_file in ");} simgrid_parse_link_latency___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_link_latency___file); YY_BREAK case 319: /* rule 319 can match eol */ YY_RULE_SETUP -if (surfxml_link_latency___file_isset != 0) {FAIL("Multiple definition of attribute latency_file in ");} surfxml_link_latency___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_latency___file); +if (simgrid_parse_link_latency___file_isset != 0) {FAIL("Multiple definition of attribute latency_file in ");} simgrid_parse_link_latency___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_link_latency___file); YY_BREAK case 320: /* rule 320 can match eol */ case 321: /* rule 321 can match eol */ YY_RULE_SETUP -A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_SHARED; +A_simgrid_parse_link_sharing___policy = A_simgrid_parse_link_sharing___policy_SHARED; YY_BREAK case 322: /* rule 322 can match eol */ case 323: /* rule 323 can match eol */ YY_RULE_SETUP -A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_SPLITDUPLEX; +A_simgrid_parse_link_sharing___policy = A_simgrid_parse_link_sharing___policy_SPLITDUPLEX; YY_BREAK case 324: /* rule 324 can match eol */ case 325: /* rule 325 can match eol */ YY_RULE_SETUP -A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_FULLDUPLEX; +A_simgrid_parse_link_sharing___policy = A_simgrid_parse_link_sharing___policy_FULLDUPLEX; YY_BREAK case 326: /* rule 326 can match eol */ case 327: /* rule 327 can match eol */ YY_RULE_SETUP -A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_FATPIPE; +A_simgrid_parse_link_sharing___policy = A_simgrid_parse_link_sharing___policy_FATPIPE; YY_BREAK case 328: /* rule 328 can match eol */ case 329: /* rule 329 can match eol */ YY_RULE_SETUP -A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_WIFI; +A_simgrid_parse_link_sharing___policy = A_simgrid_parse_link_sharing___policy_WIFI; YY_BREAK case 330: /* rule 330 can match eol */ YY_RULE_SETUP -if (surfxml_link_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} surfxml_link_state___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_state___file); +if (simgrid_parse_link_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} simgrid_parse_link_state___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_link_state___file); YY_BREAK case 331: /* rule 331 can match eol */ YY_RULE_SETUP -if (surfxml_link_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} surfxml_link_state___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_state___file); +if (simgrid_parse_link_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} simgrid_parse_link_state___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_link_state___file); YY_BREAK case 332: YY_RULE_SETUP { - if (!AX_surfxml_link_bandwidth) FAIL("Required attribute `bandwidth' not set for `link' element."); - if (!AX_surfxml_link_id) FAIL("Required attribute `id' not set for `link' element."); - LEAVE; STag_surfxml_link();surfxml_pcdata_ix = 0; ENTER(S_surfxml_link); + if (!AX_simgrid_parse_link_bandwidth) FAIL("Required attribute `bandwidth' not set for `link' element."); + if (!AX_simgrid_parse_link_id) FAIL("Required attribute `id' not set for `link' element."); + LEAVE; STag_simgrid_parse_link();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_link); } YY_BREAK case 333: YY_RULE_SETUP { - if (!AX_surfxml_link_bandwidth) FAIL("Required attribute `bandwidth' not set for `link' element."); - if (!AX_surfxml_link_id) FAIL("Required attribute `id' not set for `link' element."); - LEAVE; STag_surfxml_link(); surfxml_pcdata_ix = 0; ETag_surfxml_link(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_link_bandwidth) FAIL("Required attribute `bandwidth' not set for `link' element."); + if (!AX_simgrid_parse_link_id) FAIL("Required attribute `id' not set for `link' element."); + LEAVE; STag_simgrid_parse_link(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_link(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -8905,7 +8898,7 @@ case 335: YY_RULE_SETUP FAIL("Bad attribute `%s' in `link' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_link): +case YY_STATE_EOF(AL_simgrid_parse_link): FAIL("EOF in attribute list of `link' element."); YY_BREAK @@ -8914,13 +8907,13 @@ case 336: YY_RULE_SETUP { LEAVE; - ETag_surfxml_link(); + ETag_simgrid_parse_link(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -8933,9 +8926,9 @@ case 338: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_link): -case YY_STATE_EOF(S_surfxml_link): -case YY_STATE_EOF(S_surfxml_link_2): +case YY_STATE_EOF(E_simgrid_parse_link): +case YY_STATE_EOF(S_simgrid_parse_link): +case YY_STATE_EOF(S_simgrid_parse_link_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -8948,11 +8941,11 @@ case 340: /* rule 340 can match eol */ YY_RULE_SETUP { - AX_surfxml_link___ctn_direction = A_surfxml_link___ctn_direction_NONE; - surfxml_link___ctn_direction_isset = 0; - AX_surfxml_link___ctn_id = 0; - surfxml_link___ctn_id_isset = 0; - ENTER(AL_surfxml_link___ctn); pushbuffer(0); + AX_simgrid_parse_link___ctn_direction = A_simgrid_parse_link___ctn_direction_NONE; + simgrid_parse_link___ctn_direction_isset = 0; + AX_simgrid_parse_link___ctn_id = 0; + simgrid_parse_link___ctn_id_isset = 0; + ENTER(AL_simgrid_parse_link___ctn); pushbuffer(0); } YY_BREAK @@ -8961,51 +8954,51 @@ case 341: case 342: /* rule 342 can match eol */ YY_RULE_SETUP -A_surfxml_link___ctn_direction = A_surfxml_link___ctn_direction_UP; +A_simgrid_parse_link___ctn_direction = A_simgrid_parse_link___ctn_direction_UP; YY_BREAK case 343: /* rule 343 can match eol */ case 344: /* rule 344 can match eol */ YY_RULE_SETUP -A_surfxml_link___ctn_direction = A_surfxml_link___ctn_direction_DOWN; +A_simgrid_parse_link___ctn_direction = A_simgrid_parse_link___ctn_direction_DOWN; YY_BREAK case 345: /* rule 345 can match eol */ case 346: /* rule 346 can match eol */ YY_RULE_SETUP -A_surfxml_link___ctn_direction = A_surfxml_link___ctn_direction_NONE; +A_simgrid_parse_link___ctn_direction = A_simgrid_parse_link___ctn_direction_NONE; YY_BREAK case 347: /* rule 347 can match eol */ YY_RULE_SETUP -if (surfxml_link___ctn_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_link___ctn_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link___ctn_id); +if (simgrid_parse_link___ctn_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_link___ctn_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_link___ctn_id); YY_BREAK case 348: /* rule 348 can match eol */ YY_RULE_SETUP -if (surfxml_link___ctn_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_link___ctn_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link___ctn_id); +if (simgrid_parse_link___ctn_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_link___ctn_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_link___ctn_id); YY_BREAK case 349: YY_RULE_SETUP { - if (!AX_surfxml_link___ctn_id) FAIL("Required attribute `id' not set for `link_ctn' element."); - LEAVE; STag_surfxml_link___ctn();surfxml_pcdata_ix = 0; ENTER(E_surfxml_link___ctn); + if (!AX_simgrid_parse_link___ctn_id) FAIL("Required attribute `id' not set for `link_ctn' element."); + LEAVE; STag_simgrid_parse_link___ctn();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_link___ctn); } YY_BREAK case 350: YY_RULE_SETUP { - if (!AX_surfxml_link___ctn_id) FAIL("Required attribute `id' not set for `link_ctn' element."); - LEAVE; STag_surfxml_link___ctn(); surfxml_pcdata_ix = 0; ETag_surfxml_link___ctn(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_link___ctn_id) FAIL("Required attribute `id' not set for `link_ctn' element."); + LEAVE; STag_simgrid_parse_link___ctn(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_link___ctn(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_ASroute: case S_surfxml_ASroute_1: case S_surfxml_ASroute_2: SET(S_surfxml_ASroute_2); break; - case S_surfxml_bypassASroute: case S_surfxml_bypassASroute_1: case S_surfxml_bypassASroute_2: SET(S_surfxml_bypassASroute_2); break; - case S_surfxml_bypassRoute: case S_surfxml_bypassRoute_1: case S_surfxml_bypassRoute_2: SET(S_surfxml_bypassRoute_2); break; - case S_surfxml_bypassZoneRoute: case S_surfxml_bypassZoneRoute_1: case S_surfxml_bypassZoneRoute_2: SET(S_surfxml_bypassZoneRoute_2); break; - case S_surfxml_route: case S_surfxml_route_1: case S_surfxml_route_2: SET(S_surfxml_route_2); break; - case S_surfxml_zoneRoute: case S_surfxml_zoneRoute_1: case S_surfxml_zoneRoute_2: SET(S_surfxml_zoneRoute_2); break; + case S_simgrid_parse_ASroute: case S_simgrid_parse_ASroute_1: case S_simgrid_parse_ASroute_2: SET(S_simgrid_parse_ASroute_2); break; + case S_simgrid_parse_bypassASroute: case S_simgrid_parse_bypassASroute_1: case S_simgrid_parse_bypassASroute_2: SET(S_simgrid_parse_bypassASroute_2); break; + case S_simgrid_parse_bypassRoute: case S_simgrid_parse_bypassRoute_1: case S_simgrid_parse_bypassRoute_2: SET(S_simgrid_parse_bypassRoute_2); break; + case S_simgrid_parse_bypassZoneRoute: case S_simgrid_parse_bypassZoneRoute_1: case S_simgrid_parse_bypassZoneRoute_2: SET(S_simgrid_parse_bypassZoneRoute_2); break; + case S_simgrid_parse_route: case S_simgrid_parse_route_1: case S_simgrid_parse_route_2: SET(S_simgrid_parse_route_2); break; + case S_simgrid_parse_zoneRoute: case S_simgrid_parse_zoneRoute_1: case S_simgrid_parse_zoneRoute_2: SET(S_simgrid_parse_zoneRoute_2); break; } } YY_BREAK @@ -9017,7 +9010,7 @@ case 352: YY_RULE_SETUP FAIL("Bad attribute `%s' in `link_ctn' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_link___ctn): +case YY_STATE_EOF(AL_simgrid_parse_link___ctn): FAIL("EOF in attribute list of `link_ctn' element."); YY_BREAK @@ -9026,15 +9019,15 @@ case 353: YY_RULE_SETUP { LEAVE; - ETag_surfxml_link___ctn(); + ETag_simgrid_parse_link___ctn(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_ASroute: case S_surfxml_ASroute_1: case S_surfxml_ASroute_2: SET(S_surfxml_ASroute_2); break; - case S_surfxml_bypassASroute: case S_surfxml_bypassASroute_1: case S_surfxml_bypassASroute_2: SET(S_surfxml_bypassASroute_2); break; - case S_surfxml_bypassRoute: case S_surfxml_bypassRoute_1: case S_surfxml_bypassRoute_2: SET(S_surfxml_bypassRoute_2); break; - case S_surfxml_bypassZoneRoute: case S_surfxml_bypassZoneRoute_1: case S_surfxml_bypassZoneRoute_2: SET(S_surfxml_bypassZoneRoute_2); break; - case S_surfxml_route: case S_surfxml_route_1: case S_surfxml_route_2: SET(S_surfxml_route_2); break; - case S_surfxml_zoneRoute: case S_surfxml_zoneRoute_1: case S_surfxml_zoneRoute_2: SET(S_surfxml_zoneRoute_2); break; + case S_simgrid_parse_ASroute: case S_simgrid_parse_ASroute_1: case S_simgrid_parse_ASroute_2: SET(S_simgrid_parse_ASroute_2); break; + case S_simgrid_parse_bypassASroute: case S_simgrid_parse_bypassASroute_1: case S_simgrid_parse_bypassASroute_2: SET(S_simgrid_parse_bypassASroute_2); break; + case S_simgrid_parse_bypassRoute: case S_simgrid_parse_bypassRoute_1: case S_simgrid_parse_bypassRoute_2: SET(S_simgrid_parse_bypassRoute_2); break; + case S_simgrid_parse_bypassZoneRoute: case S_simgrid_parse_bypassZoneRoute_1: case S_simgrid_parse_bypassZoneRoute_2: SET(S_simgrid_parse_bypassZoneRoute_2); break; + case S_simgrid_parse_route: case S_simgrid_parse_route_1: case S_simgrid_parse_route_2: SET(S_simgrid_parse_route_2); break; + case S_simgrid_parse_zoneRoute: case S_simgrid_parse_zoneRoute_1: case S_simgrid_parse_zoneRoute_2: SET(S_simgrid_parse_zoneRoute_2); break; } } YY_BREAK @@ -9047,7 +9040,7 @@ case 355: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_link___ctn): +case YY_STATE_EOF(E_simgrid_parse_link___ctn): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -9062,50 +9055,50 @@ case 357: /* rule 357 can match eol */ YY_RULE_SETUP { - AX_surfxml_model___prop_id = 0; - surfxml_model___prop_id_isset = 0; - AX_surfxml_model___prop_value = 0; - surfxml_model___prop_value_isset = 0; - ENTER(AL_surfxml_model___prop); pushbuffer(0); + AX_simgrid_parse_model___prop_id = 0; + simgrid_parse_model___prop_id_isset = 0; + AX_simgrid_parse_model___prop_value = 0; + simgrid_parse_model___prop_value_isset = 0; + ENTER(AL_simgrid_parse_model___prop); pushbuffer(0); } YY_BREAK case 358: /* rule 358 can match eol */ YY_RULE_SETUP -if (surfxml_model___prop_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_model___prop_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_model___prop_id); +if (simgrid_parse_model___prop_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_model___prop_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_model___prop_id); YY_BREAK case 359: /* rule 359 can match eol */ YY_RULE_SETUP -if (surfxml_model___prop_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_model___prop_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_model___prop_id); +if (simgrid_parse_model___prop_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_model___prop_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_model___prop_id); YY_BREAK case 360: /* rule 360 can match eol */ YY_RULE_SETUP -if (surfxml_model___prop_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} surfxml_model___prop_value_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_model___prop_value); +if (simgrid_parse_model___prop_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} simgrid_parse_model___prop_value_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_model___prop_value); YY_BREAK case 361: /* rule 361 can match eol */ YY_RULE_SETUP -if (surfxml_model___prop_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} surfxml_model___prop_value_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_model___prop_value); +if (simgrid_parse_model___prop_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} simgrid_parse_model___prop_value_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_model___prop_value); YY_BREAK case 362: YY_RULE_SETUP { - if (!AX_surfxml_model___prop_id) FAIL("Required attribute `id' not set for `model_prop' element."); - if (!AX_surfxml_model___prop_value) FAIL("Required attribute `value' not set for `model_prop' element."); - LEAVE; STag_surfxml_model___prop();surfxml_pcdata_ix = 0; ENTER(E_surfxml_model___prop); + if (!AX_simgrid_parse_model___prop_id) FAIL("Required attribute `id' not set for `model_prop' element."); + if (!AX_simgrid_parse_model___prop_value) FAIL("Required attribute `value' not set for `model_prop' element."); + LEAVE; STag_simgrid_parse_model___prop();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_model___prop); } YY_BREAK case 363: YY_RULE_SETUP { - if (!AX_surfxml_model___prop_id) FAIL("Required attribute `id' not set for `model_prop' element."); - if (!AX_surfxml_model___prop_value) FAIL("Required attribute `value' not set for `model_prop' element."); - LEAVE; STag_surfxml_model___prop(); surfxml_pcdata_ix = 0; ETag_surfxml_model___prop(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_model___prop_id) FAIL("Required attribute `id' not set for `model_prop' element."); + if (!AX_simgrid_parse_model___prop_value) FAIL("Required attribute `value' not set for `model_prop' element."); + LEAVE; STag_simgrid_parse_model___prop(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_model___prop(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_storage___type: case S_surfxml_storage___type_1: case S_surfxml_storage___type_2: SET(S_surfxml_storage___type_2); break; + case S_simgrid_parse_storage___type: case S_simgrid_parse_storage___type_1: case S_simgrid_parse_storage___type_2: SET(S_simgrid_parse_storage___type_2); break; } } YY_BREAK @@ -9117,7 +9110,7 @@ case 365: YY_RULE_SETUP FAIL("Bad attribute `%s' in `model_prop' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_model___prop): +case YY_STATE_EOF(AL_simgrid_parse_model___prop): FAIL("EOF in attribute list of `model_prop' element."); YY_BREAK @@ -9126,10 +9119,10 @@ case 366: YY_RULE_SETUP { LEAVE; - ETag_surfxml_model___prop(); + ETag_simgrid_parse_model___prop(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_storage___type: case S_surfxml_storage___type_1: case S_surfxml_storage___type_2: SET(S_surfxml_storage___type_2); break; + case S_simgrid_parse_storage___type: case S_simgrid_parse_storage___type_1: case S_simgrid_parse_storage___type_2: SET(S_simgrid_parse_storage___type_2); break; } } YY_BREAK @@ -9142,7 +9135,7 @@ case 368: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_model___prop): +case YY_STATE_EOF(E_simgrid_parse_model___prop): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -9155,50 +9148,50 @@ case 370: /* rule 370 can match eol */ YY_RULE_SETUP { - AX_surfxml_mount_name = 0; - surfxml_mount_name_isset = 0; - AX_surfxml_mount_storageId = 0; - surfxml_mount_storageId_isset = 0; - ENTER(AL_surfxml_mount); pushbuffer(0); + AX_simgrid_parse_mount_name = 0; + simgrid_parse_mount_name_isset = 0; + AX_simgrid_parse_mount_storageId = 0; + simgrid_parse_mount_storageId_isset = 0; + ENTER(AL_simgrid_parse_mount); pushbuffer(0); } YY_BREAK case 371: /* rule 371 can match eol */ YY_RULE_SETUP -if (surfxml_mount_name_isset != 0) {FAIL("Multiple definition of attribute name in ");} surfxml_mount_name_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_mount_name); +if (simgrid_parse_mount_name_isset != 0) {FAIL("Multiple definition of attribute name in ");} simgrid_parse_mount_name_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_mount_name); YY_BREAK case 372: /* rule 372 can match eol */ YY_RULE_SETUP -if (surfxml_mount_name_isset != 0) {FAIL("Multiple definition of attribute name in ");} surfxml_mount_name_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_mount_name); +if (simgrid_parse_mount_name_isset != 0) {FAIL("Multiple definition of attribute name in ");} simgrid_parse_mount_name_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_mount_name); YY_BREAK case 373: /* rule 373 can match eol */ YY_RULE_SETUP -if (surfxml_mount_storageId_isset != 0) {FAIL("Multiple definition of attribute storageId in ");} surfxml_mount_storageId_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_mount_storageId); +if (simgrid_parse_mount_storageId_isset != 0) {FAIL("Multiple definition of attribute storageId in ");} simgrid_parse_mount_storageId_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_mount_storageId); YY_BREAK case 374: /* rule 374 can match eol */ YY_RULE_SETUP -if (surfxml_mount_storageId_isset != 0) {FAIL("Multiple definition of attribute storageId in ");} surfxml_mount_storageId_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_mount_storageId); +if (simgrid_parse_mount_storageId_isset != 0) {FAIL("Multiple definition of attribute storageId in ");} simgrid_parse_mount_storageId_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_mount_storageId); YY_BREAK case 375: YY_RULE_SETUP { - if (!AX_surfxml_mount_name) FAIL("Required attribute `name' not set for `mount' element."); - if (!AX_surfxml_mount_storageId) FAIL("Required attribute `storageId' not set for `mount' element."); - LEAVE; STag_surfxml_mount();surfxml_pcdata_ix = 0; ENTER(E_surfxml_mount); + if (!AX_simgrid_parse_mount_name) FAIL("Required attribute `name' not set for `mount' element."); + if (!AX_simgrid_parse_mount_storageId) FAIL("Required attribute `storageId' not set for `mount' element."); + LEAVE; STag_simgrid_parse_mount();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_mount); } YY_BREAK case 376: YY_RULE_SETUP { - if (!AX_surfxml_mount_name) FAIL("Required attribute `name' not set for `mount' element."); - if (!AX_surfxml_mount_storageId) FAIL("Required attribute `storageId' not set for `mount' element."); - LEAVE; STag_surfxml_mount(); surfxml_pcdata_ix = 0; ETag_surfxml_mount(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_mount_name) FAIL("Required attribute `name' not set for `mount' element."); + if (!AX_simgrid_parse_mount_storageId) FAIL("Required attribute `storageId' not set for `mount' element."); + LEAVE; STag_simgrid_parse_mount(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_mount(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_host: case S_surfxml_host_1: case S_surfxml_host_2: SET(S_surfxml_host_2); break; + case S_simgrid_parse_host: case S_simgrid_parse_host_1: case S_simgrid_parse_host_2: SET(S_simgrid_parse_host_2); break; } } YY_BREAK @@ -9210,7 +9203,7 @@ case 378: YY_RULE_SETUP FAIL("Bad attribute `%s' in `mount' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_mount): +case YY_STATE_EOF(AL_simgrid_parse_mount): FAIL("EOF in attribute list of `mount' element."); YY_BREAK @@ -9219,10 +9212,10 @@ case 379: YY_RULE_SETUP { LEAVE; - ETag_surfxml_mount(); + ETag_simgrid_parse_mount(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_host: case S_surfxml_host_1: case S_surfxml_host_2: SET(S_surfxml_host_2); break; + case S_simgrid_parse_host: case S_simgrid_parse_host_1: case S_simgrid_parse_host_2: SET(S_simgrid_parse_host_2); break; } } YY_BREAK @@ -9235,7 +9228,7 @@ case 381: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_mount): +case YY_STATE_EOF(E_simgrid_parse_mount): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -9250,141 +9243,141 @@ case 383: /* rule 383 can match eol */ YY_RULE_SETUP { - AX_surfxml_peer_availability___file = 0; - surfxml_peer_availability___file_isset = 0; - AX_surfxml_peer_bw___in = 0; - surfxml_peer_bw___in_isset = 0; - AX_surfxml_peer_bw___out = 0; - surfxml_peer_bw___out_isset = 0; - AX_surfxml_peer_coordinates = 0; - surfxml_peer_coordinates_isset = 0; - AX_surfxml_peer_id = 0; - surfxml_peer_id_isset = 0; - AX_surfxml_peer_lat = 0; - surfxml_peer_lat_isset = 0; - AX_surfxml_peer_speed = 0; - surfxml_peer_speed_isset = 0; - AX_surfxml_peer_speed___file = 0; - surfxml_peer_speed___file_isset = 0; - AX_surfxml_peer_state___file = 0; - surfxml_peer_state___file_isset = 0; - ENTER(AL_surfxml_peer); pushbuffer(0); + AX_simgrid_parse_peer_availability___file = 0; + simgrid_parse_peer_availability___file_isset = 0; + AX_simgrid_parse_peer_bw___in = 0; + simgrid_parse_peer_bw___in_isset = 0; + AX_simgrid_parse_peer_bw___out = 0; + simgrid_parse_peer_bw___out_isset = 0; + AX_simgrid_parse_peer_coordinates = 0; + simgrid_parse_peer_coordinates_isset = 0; + AX_simgrid_parse_peer_id = 0; + simgrid_parse_peer_id_isset = 0; + AX_simgrid_parse_peer_lat = 0; + simgrid_parse_peer_lat_isset = 0; + AX_simgrid_parse_peer_speed = 0; + simgrid_parse_peer_speed_isset = 0; + AX_simgrid_parse_peer_speed___file = 0; + simgrid_parse_peer_speed___file_isset = 0; + AX_simgrid_parse_peer_state___file = 0; + simgrid_parse_peer_state___file_isset = 0; + ENTER(AL_simgrid_parse_peer); pushbuffer(0); } YY_BREAK case 384: /* rule 384 can match eol */ YY_RULE_SETUP -if (surfxml_peer_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in ");} surfxml_peer_availability___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_availability___file); +if (simgrid_parse_peer_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in ");} simgrid_parse_peer_availability___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_peer_availability___file); YY_BREAK case 385: /* rule 385 can match eol */ YY_RULE_SETUP -if (surfxml_peer_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in ");} surfxml_peer_availability___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_availability___file); +if (simgrid_parse_peer_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in ");} simgrid_parse_peer_availability___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_peer_availability___file); YY_BREAK case 386: /* rule 386 can match eol */ YY_RULE_SETUP -if (surfxml_peer_bw___in_isset != 0) {FAIL("Multiple definition of attribute bw_in in ");} surfxml_peer_bw___in_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_bw___in); +if (simgrid_parse_peer_bw___in_isset != 0) {FAIL("Multiple definition of attribute bw_in in ");} simgrid_parse_peer_bw___in_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_peer_bw___in); YY_BREAK case 387: /* rule 387 can match eol */ YY_RULE_SETUP -if (surfxml_peer_bw___in_isset != 0) {FAIL("Multiple definition of attribute bw_in in ");} surfxml_peer_bw___in_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_bw___in); +if (simgrid_parse_peer_bw___in_isset != 0) {FAIL("Multiple definition of attribute bw_in in ");} simgrid_parse_peer_bw___in_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_peer_bw___in); YY_BREAK case 388: /* rule 388 can match eol */ YY_RULE_SETUP -if (surfxml_peer_bw___out_isset != 0) {FAIL("Multiple definition of attribute bw_out in ");} surfxml_peer_bw___out_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_bw___out); +if (simgrid_parse_peer_bw___out_isset != 0) {FAIL("Multiple definition of attribute bw_out in ");} simgrid_parse_peer_bw___out_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_peer_bw___out); YY_BREAK case 389: /* rule 389 can match eol */ YY_RULE_SETUP -if (surfxml_peer_bw___out_isset != 0) {FAIL("Multiple definition of attribute bw_out in ");} surfxml_peer_bw___out_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_bw___out); +if (simgrid_parse_peer_bw___out_isset != 0) {FAIL("Multiple definition of attribute bw_out in ");} simgrid_parse_peer_bw___out_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_peer_bw___out); YY_BREAK case 390: /* rule 390 can match eol */ YY_RULE_SETUP -if (surfxml_peer_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} surfxml_peer_coordinates_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_coordinates); +if (simgrid_parse_peer_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} simgrid_parse_peer_coordinates_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_peer_coordinates); YY_BREAK case 391: /* rule 391 can match eol */ YY_RULE_SETUP -if (surfxml_peer_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} surfxml_peer_coordinates_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_coordinates); +if (simgrid_parse_peer_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} simgrid_parse_peer_coordinates_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_peer_coordinates); YY_BREAK case 392: /* rule 392 can match eol */ YY_RULE_SETUP -if (surfxml_peer_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_peer_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_id); +if (simgrid_parse_peer_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_peer_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_peer_id); YY_BREAK case 393: /* rule 393 can match eol */ YY_RULE_SETUP -if (surfxml_peer_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_peer_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_id); +if (simgrid_parse_peer_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_peer_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_peer_id); YY_BREAK case 394: /* rule 394 can match eol */ YY_RULE_SETUP -if (surfxml_peer_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} surfxml_peer_lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_lat); +if (simgrid_parse_peer_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} simgrid_parse_peer_lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_peer_lat); YY_BREAK case 395: /* rule 395 can match eol */ YY_RULE_SETUP -if (surfxml_peer_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} surfxml_peer_lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_lat); +if (simgrid_parse_peer_lat_isset != 0) {FAIL("Multiple definition of attribute lat in ");} simgrid_parse_peer_lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_peer_lat); YY_BREAK case 396: /* rule 396 can match eol */ YY_RULE_SETUP -if (surfxml_peer_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} surfxml_peer_speed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_speed); +if (simgrid_parse_peer_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} simgrid_parse_peer_speed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_peer_speed); YY_BREAK case 397: /* rule 397 can match eol */ YY_RULE_SETUP -if (surfxml_peer_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} surfxml_peer_speed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_speed); +if (simgrid_parse_peer_speed_isset != 0) {FAIL("Multiple definition of attribute speed in ");} simgrid_parse_peer_speed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_peer_speed); YY_BREAK case 398: /* rule 398 can match eol */ YY_RULE_SETUP -if (surfxml_peer_speed___file_isset != 0) {FAIL("Multiple definition of attribute speed_file in ");} surfxml_peer_speed___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_speed___file); +if (simgrid_parse_peer_speed___file_isset != 0) {FAIL("Multiple definition of attribute speed_file in ");} simgrid_parse_peer_speed___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_peer_speed___file); YY_BREAK case 399: /* rule 399 can match eol */ YY_RULE_SETUP -if (surfxml_peer_speed___file_isset != 0) {FAIL("Multiple definition of attribute speed_file in ");} surfxml_peer_speed___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_speed___file); +if (simgrid_parse_peer_speed___file_isset != 0) {FAIL("Multiple definition of attribute speed_file in ");} simgrid_parse_peer_speed___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_peer_speed___file); YY_BREAK case 400: /* rule 400 can match eol */ YY_RULE_SETUP -if (surfxml_peer_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} surfxml_peer_state___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_state___file); +if (simgrid_parse_peer_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} simgrid_parse_peer_state___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_peer_state___file); YY_BREAK case 401: /* rule 401 can match eol */ YY_RULE_SETUP -if (surfxml_peer_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} surfxml_peer_state___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_state___file); +if (simgrid_parse_peer_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in ");} simgrid_parse_peer_state___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_peer_state___file); YY_BREAK case 402: YY_RULE_SETUP { - if (!AX_surfxml_peer_bw___in) FAIL("Required attribute `bw_in' not set for `peer' element."); - if (!AX_surfxml_peer_bw___out) FAIL("Required attribute `bw_out' not set for `peer' element."); - if (!AX_surfxml_peer_id) FAIL("Required attribute `id' not set for `peer' element."); - if (!AX_surfxml_peer_speed) FAIL("Required attribute `speed' not set for `peer' element."); - LEAVE; STag_surfxml_peer();surfxml_pcdata_ix = 0; ENTER(E_surfxml_peer); + if (!AX_simgrid_parse_peer_bw___in) FAIL("Required attribute `bw_in' not set for `peer' element."); + if (!AX_simgrid_parse_peer_bw___out) FAIL("Required attribute `bw_out' not set for `peer' element."); + if (!AX_simgrid_parse_peer_id) FAIL("Required attribute `id' not set for `peer' element."); + if (!AX_simgrid_parse_peer_speed) FAIL("Required attribute `speed' not set for `peer' element."); + LEAVE; STag_simgrid_parse_peer();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_peer); } YY_BREAK case 403: YY_RULE_SETUP { - if (!AX_surfxml_peer_bw___in) FAIL("Required attribute `bw_in' not set for `peer' element."); - if (!AX_surfxml_peer_bw___out) FAIL("Required attribute `bw_out' not set for `peer' element."); - if (!AX_surfxml_peer_id) FAIL("Required attribute `id' not set for `peer' element."); - if (!AX_surfxml_peer_speed) FAIL("Required attribute `speed' not set for `peer' element."); - LEAVE; STag_surfxml_peer(); surfxml_pcdata_ix = 0; ETag_surfxml_peer(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_peer_bw___in) FAIL("Required attribute `bw_in' not set for `peer' element."); + if (!AX_simgrid_parse_peer_bw___out) FAIL("Required attribute `bw_out' not set for `peer' element."); + if (!AX_simgrid_parse_peer_id) FAIL("Required attribute `id' not set for `peer' element."); + if (!AX_simgrid_parse_peer_speed) FAIL("Required attribute `speed' not set for `peer' element."); + LEAVE; STag_simgrid_parse_peer(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_peer(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -9396,7 +9389,7 @@ case 405: YY_RULE_SETUP FAIL("Bad attribute `%s' in `peer' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_peer): +case YY_STATE_EOF(AL_simgrid_parse_peer): FAIL("EOF in attribute list of `peer' element."); YY_BREAK @@ -9405,13 +9398,13 @@ case 406: YY_RULE_SETUP { LEAVE; - ETag_surfxml_peer(); + ETag_simgrid_parse_peer(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -9424,7 +9417,7 @@ case 408: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_peer): +case YY_STATE_EOF(E_simgrid_parse_peer): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -9497,34 +9490,34 @@ case 410: /* rule 410 can match eol */ YY_RULE_SETUP { - AX_surfxml_platform_version = 1; - surfxml_platform_version_isset = 0; - ENTER(AL_surfxml_platform); pushbuffer(0); + AX_simgrid_parse_platform_version = 1; + simgrid_parse_platform_version_isset = 0; + ENTER(AL_simgrid_parse_platform); pushbuffer(0); } YY_BREAK case 411: /* rule 411 can match eol */ YY_RULE_SETUP -if (surfxml_platform_version_isset != 0) {FAIL("Multiple definition of attribute version in ");} surfxml_platform_version_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_platform_version); +if (simgrid_parse_platform_version_isset != 0) {FAIL("Multiple definition of attribute version in ");} simgrid_parse_platform_version_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_platform_version); YY_BREAK case 412: /* rule 412 can match eol */ YY_RULE_SETUP -if (surfxml_platform_version_isset != 0) {FAIL("Multiple definition of attribute version in ");} surfxml_platform_version_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_platform_version); +if (simgrid_parse_platform_version_isset != 0) {FAIL("Multiple definition of attribute version in ");} simgrid_parse_platform_version_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_platform_version); YY_BREAK case 413: YY_RULE_SETUP { - LEAVE; STag_surfxml_platform();surfxml_pcdata_ix = 0; ENTER(S_surfxml_platform); + LEAVE; STag_simgrid_parse_platform();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_platform); } YY_BREAK case 414: YY_RULE_SETUP { - LEAVE; STag_surfxml_platform(); surfxml_pcdata_ix = 0; ETag_surfxml_platform(); popbuffer(); /* attribute */ + LEAVE; STag_simgrid_parse_platform(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_platform(); popbuffer(); /* attribute */ switch (YY_START) { - case ROOT_surfxml_platform: SET(EPILOG); break; + case ROOT_simgrid_parse_platform: SET(EPILOG); break; } } YY_BREAK @@ -9536,7 +9529,7 @@ case 416: YY_RULE_SETUP FAIL("Bad attribute `%s' in `platform' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_platform): +case YY_STATE_EOF(AL_simgrid_parse_platform): FAIL("EOF in attribute list of `platform' element."); YY_BREAK @@ -9545,10 +9538,10 @@ case 417: YY_RULE_SETUP { LEAVE; - ETag_surfxml_platform(); + ETag_simgrid_parse_platform(); popbuffer(); /* attribute */ switch (YY_START) { - case ROOT_surfxml_platform: SET(EPILOG); break; + case ROOT_simgrid_parse_platform: SET(EPILOG); break; } } YY_BREAK @@ -9561,13 +9554,13 @@ case 419: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_platform): -case YY_STATE_EOF(S_surfxml_platform): -case YY_STATE_EOF(S_surfxml_platform_1): -case YY_STATE_EOF(S_surfxml_platform_3): -case YY_STATE_EOF(S_surfxml_platform_4): -case YY_STATE_EOF(S_surfxml_platform_6): -case YY_STATE_EOF(S_surfxml_platform_8): +case YY_STATE_EOF(E_simgrid_parse_platform): +case YY_STATE_EOF(S_simgrid_parse_platform): +case YY_STATE_EOF(S_simgrid_parse_platform_1): +case YY_STATE_EOF(S_simgrid_parse_platform_3): +case YY_STATE_EOF(S_simgrid_parse_platform_4): +case YY_STATE_EOF(S_simgrid_parse_platform_6): +case YY_STATE_EOF(S_simgrid_parse_platform_8): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -9581,90 +9574,90 @@ case 421: /* rule 421 can match eol */ YY_RULE_SETUP { - AX_surfxml_process_function = 0; - surfxml_process_function_isset = 0; - AX_surfxml_process_host = 0; - surfxml_process_host_isset = 0; - AX_surfxml_process_kill___time = 38; - surfxml_process_kill___time_isset = 0; - AX_surfxml_process_on___failure = A_surfxml_process_on___failure_DIE; - surfxml_process_on___failure_isset = 0; - AX_surfxml_process_start___time = 33; - surfxml_process_start___time_isset = 0; - ENTER(AL_surfxml_process); pushbuffer(0); + AX_simgrid_parse_process_function = 0; + simgrid_parse_process_function_isset = 0; + AX_simgrid_parse_process_host = 0; + simgrid_parse_process_host_isset = 0; + AX_simgrid_parse_process_kill___time = 38; + simgrid_parse_process_kill___time_isset = 0; + AX_simgrid_parse_process_on___failure = A_simgrid_parse_process_on___failure_DIE; + simgrid_parse_process_on___failure_isset = 0; + AX_simgrid_parse_process_start___time = 33; + simgrid_parse_process_start___time_isset = 0; + ENTER(AL_simgrid_parse_process); pushbuffer(0); } YY_BREAK case 422: /* rule 422 can match eol */ YY_RULE_SETUP -if (surfxml_process_function_isset != 0) {FAIL("Multiple definition of attribute function in ");} surfxml_process_function_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_process_function); +if (simgrid_parse_process_function_isset != 0) {FAIL("Multiple definition of attribute function in ");} simgrid_parse_process_function_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_process_function); YY_BREAK case 423: /* rule 423 can match eol */ YY_RULE_SETUP -if (surfxml_process_function_isset != 0) {FAIL("Multiple definition of attribute function in ");} surfxml_process_function_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_process_function); +if (simgrid_parse_process_function_isset != 0) {FAIL("Multiple definition of attribute function in ");} simgrid_parse_process_function_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_process_function); YY_BREAK case 424: /* rule 424 can match eol */ YY_RULE_SETUP -if (surfxml_process_host_isset != 0) {FAIL("Multiple definition of attribute host in ");} surfxml_process_host_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_process_host); +if (simgrid_parse_process_host_isset != 0) {FAIL("Multiple definition of attribute host in ");} simgrid_parse_process_host_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_process_host); YY_BREAK case 425: /* rule 425 can match eol */ YY_RULE_SETUP -if (surfxml_process_host_isset != 0) {FAIL("Multiple definition of attribute host in ");} surfxml_process_host_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_process_host); +if (simgrid_parse_process_host_isset != 0) {FAIL("Multiple definition of attribute host in ");} simgrid_parse_process_host_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_process_host); YY_BREAK case 426: /* rule 426 can match eol */ YY_RULE_SETUP -if (surfxml_process_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in ");} surfxml_process_kill___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_process_kill___time); +if (simgrid_parse_process_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in ");} simgrid_parse_process_kill___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_process_kill___time); YY_BREAK case 427: /* rule 427 can match eol */ YY_RULE_SETUP -if (surfxml_process_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in ");} surfxml_process_kill___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_process_kill___time); +if (simgrid_parse_process_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in ");} simgrid_parse_process_kill___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_process_kill___time); YY_BREAK case 428: /* rule 428 can match eol */ case 429: /* rule 429 can match eol */ YY_RULE_SETUP -A_surfxml_process_on___failure = A_surfxml_process_on___failure_DIE; +A_simgrid_parse_process_on___failure = A_simgrid_parse_process_on___failure_DIE; YY_BREAK case 430: /* rule 430 can match eol */ case 431: /* rule 431 can match eol */ YY_RULE_SETUP -A_surfxml_process_on___failure = A_surfxml_process_on___failure_RESTART; +A_simgrid_parse_process_on___failure = A_simgrid_parse_process_on___failure_RESTART; YY_BREAK case 432: /* rule 432 can match eol */ YY_RULE_SETUP -if (surfxml_process_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in ");} surfxml_process_start___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_process_start___time); +if (simgrid_parse_process_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in ");} simgrid_parse_process_start___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_process_start___time); YY_BREAK case 433: /* rule 433 can match eol */ YY_RULE_SETUP -if (surfxml_process_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in ");} surfxml_process_start___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_process_start___time); +if (simgrid_parse_process_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in ");} simgrid_parse_process_start___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_process_start___time); YY_BREAK case 434: YY_RULE_SETUP { - if (!AX_surfxml_process_function) FAIL("Required attribute `function' not set for `process' element."); - if (!AX_surfxml_process_host) FAIL("Required attribute `host' not set for `process' element."); - LEAVE; STag_surfxml_process();surfxml_pcdata_ix = 0; ENTER(S_surfxml_process); + if (!AX_simgrid_parse_process_function) FAIL("Required attribute `function' not set for `process' element."); + if (!AX_simgrid_parse_process_host) FAIL("Required attribute `host' not set for `process' element."); + LEAVE; STag_simgrid_parse_process();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_process); } YY_BREAK case 435: YY_RULE_SETUP { - if (!AX_surfxml_process_function) FAIL("Required attribute `function' not set for `process' element."); - if (!AX_surfxml_process_host) FAIL("Required attribute `host' not set for `process' element."); - LEAVE; STag_surfxml_process(); surfxml_pcdata_ix = 0; ETag_surfxml_process(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_process_function) FAIL("Required attribute `function' not set for `process' element."); + if (!AX_simgrid_parse_process_host) FAIL("Required attribute `host' not set for `process' element."); + LEAVE; STag_simgrid_parse_process(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_process(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_4: case S_surfxml_platform_6: case S_surfxml_platform_7: case S_surfxml_platform_8: SET(S_surfxml_platform_8); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_4: case S_simgrid_parse_platform_6: case S_simgrid_parse_platform_7: case S_simgrid_parse_platform_8: SET(S_simgrid_parse_platform_8); break; } } YY_BREAK @@ -9676,7 +9669,7 @@ case 437: YY_RULE_SETUP FAIL("Bad attribute `%s' in `process' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_process): +case YY_STATE_EOF(AL_simgrid_parse_process): FAIL("EOF in attribute list of `process' element."); YY_BREAK @@ -9685,10 +9678,10 @@ case 438: YY_RULE_SETUP { LEAVE; - ETag_surfxml_process(); + ETag_simgrid_parse_process(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_4: case S_surfxml_platform_6: case S_surfxml_platform_7: case S_surfxml_platform_8: SET(S_surfxml_platform_8); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_4: case S_simgrid_parse_platform_6: case S_simgrid_parse_platform_7: case S_simgrid_parse_platform_8: SET(S_simgrid_parse_platform_8); break; } } YY_BREAK @@ -9701,9 +9694,9 @@ case 440: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_process): -case YY_STATE_EOF(S_surfxml_process): -case YY_STATE_EOF(S_surfxml_process_2): +case YY_STATE_EOF(E_simgrid_parse_process): +case YY_STATE_EOF(S_simgrid_parse_process): +case YY_STATE_EOF(S_simgrid_parse_process_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -9718,60 +9711,60 @@ case 442: /* rule 442 can match eol */ YY_RULE_SETUP { - AX_surfxml_prop_id = 0; - surfxml_prop_id_isset = 0; - AX_surfxml_prop_value = 0; - surfxml_prop_value_isset = 0; - ENTER(AL_surfxml_prop); pushbuffer(0); + AX_simgrid_parse_prop_id = 0; + simgrid_parse_prop_id_isset = 0; + AX_simgrid_parse_prop_value = 0; + simgrid_parse_prop_value_isset = 0; + ENTER(AL_simgrid_parse_prop); pushbuffer(0); } YY_BREAK case 443: /* rule 443 can match eol */ YY_RULE_SETUP -if (surfxml_prop_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_prop_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_prop_id); +if (simgrid_parse_prop_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_prop_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_prop_id); YY_BREAK case 444: /* rule 444 can match eol */ YY_RULE_SETUP -if (surfxml_prop_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_prop_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_prop_id); +if (simgrid_parse_prop_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_prop_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_prop_id); YY_BREAK case 445: /* rule 445 can match eol */ YY_RULE_SETUP -if (surfxml_prop_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} surfxml_prop_value_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_prop_value); +if (simgrid_parse_prop_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} simgrid_parse_prop_value_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_prop_value); YY_BREAK case 446: /* rule 446 can match eol */ YY_RULE_SETUP -if (surfxml_prop_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} surfxml_prop_value_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_prop_value); +if (simgrid_parse_prop_value_isset != 0) {FAIL("Multiple definition of attribute value in ");} simgrid_parse_prop_value_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_prop_value); YY_BREAK case 447: YY_RULE_SETUP { - if (!AX_surfxml_prop_id) FAIL("Required attribute `id' not set for `prop' element."); - if (!AX_surfxml_prop_value) FAIL("Required attribute `value' not set for `prop' element."); - LEAVE; STag_surfxml_prop();surfxml_pcdata_ix = 0; ENTER(E_surfxml_prop); + if (!AX_simgrid_parse_prop_id) FAIL("Required attribute `id' not set for `prop' element."); + if (!AX_simgrid_parse_prop_value) FAIL("Required attribute `value' not set for `prop' element."); + LEAVE; STag_simgrid_parse_prop();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_prop); } YY_BREAK case 448: YY_RULE_SETUP { - if (!AX_surfxml_prop_id) FAIL("Required attribute `id' not set for `prop' element."); - if (!AX_surfxml_prop_value) FAIL("Required attribute `value' not set for `prop' element."); - LEAVE; STag_surfxml_prop(); surfxml_pcdata_ix = 0; ETag_surfxml_prop(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_prop_id) FAIL("Required attribute `id' not set for `prop' element."); + if (!AX_simgrid_parse_prop_value) FAIL("Required attribute `value' not set for `prop' element."); + LEAVE; STag_simgrid_parse_prop(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_prop(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break; - case S_surfxml_actor: case S_surfxml_actor_1: case S_surfxml_actor_2: SET(S_surfxml_actor_2); break; - case S_surfxml_cluster: case S_surfxml_cluster_1: case S_surfxml_cluster_2: SET(S_surfxml_cluster_2); break; - case S_surfxml_config: case S_surfxml_config_1: case S_surfxml_config_2: SET(S_surfxml_config_2); break; - case S_surfxml_disk: case S_surfxml_disk_1: case S_surfxml_disk_2: SET(S_surfxml_disk_2); break; - case S_surfxml_host: case S_surfxml_host_1: case S_surfxml_host_2: SET(S_surfxml_host_2); break; - case S_surfxml_link: case S_surfxml_link_1: case S_surfxml_link_2: SET(S_surfxml_link_2); break; - case S_surfxml_process: case S_surfxml_process_1: case S_surfxml_process_2: SET(S_surfxml_process_2); break; - case S_surfxml_storage: case S_surfxml_storage_1: case S_surfxml_storage_2: SET(S_surfxml_storage_2); break; - case S_surfxml_storage___type: case S_surfxml_storage___type_1: case S_surfxml_storage___type_2: SET(S_surfxml_storage___type_2); break; - case S_surfxml_zone: case S_surfxml_zone_2: case S_surfxml_zone_3: SET(S_surfxml_zone_3); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_2: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_3); break; + case S_simgrid_parse_actor: case S_simgrid_parse_actor_1: case S_simgrid_parse_actor_2: SET(S_simgrid_parse_actor_2); break; + case S_simgrid_parse_cluster: case S_simgrid_parse_cluster_1: case S_simgrid_parse_cluster_2: SET(S_simgrid_parse_cluster_2); break; + case S_simgrid_parse_config: case S_simgrid_parse_config_1: case S_simgrid_parse_config_2: SET(S_simgrid_parse_config_2); break; + case S_simgrid_parse_disk: case S_simgrid_parse_disk_1: case S_simgrid_parse_disk_2: SET(S_simgrid_parse_disk_2); break; + case S_simgrid_parse_host: case S_simgrid_parse_host_1: case S_simgrid_parse_host_2: SET(S_simgrid_parse_host_2); break; + case S_simgrid_parse_link: case S_simgrid_parse_link_1: case S_simgrid_parse_link_2: SET(S_simgrid_parse_link_2); break; + case S_simgrid_parse_process: case S_simgrid_parse_process_1: case S_simgrid_parse_process_2: SET(S_simgrid_parse_process_2); break; + case S_simgrid_parse_storage: case S_simgrid_parse_storage_1: case S_simgrid_parse_storage_2: SET(S_simgrid_parse_storage_2); break; + case S_simgrid_parse_storage___type: case S_simgrid_parse_storage___type_1: case S_simgrid_parse_storage___type_2: SET(S_simgrid_parse_storage___type_2); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_2: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_3); break; } } YY_BREAK @@ -9783,7 +9776,7 @@ case 450: YY_RULE_SETUP FAIL("Bad attribute `%s' in `prop' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_prop): +case YY_STATE_EOF(AL_simgrid_parse_prop): FAIL("EOF in attribute list of `prop' element."); YY_BREAK @@ -9792,20 +9785,20 @@ case 451: YY_RULE_SETUP { LEAVE; - ETag_surfxml_prop(); + ETag_simgrid_parse_prop(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break; - case S_surfxml_actor: case S_surfxml_actor_1: case S_surfxml_actor_2: SET(S_surfxml_actor_2); break; - case S_surfxml_cluster: case S_surfxml_cluster_1: case S_surfxml_cluster_2: SET(S_surfxml_cluster_2); break; - case S_surfxml_config: case S_surfxml_config_1: case S_surfxml_config_2: SET(S_surfxml_config_2); break; - case S_surfxml_disk: case S_surfxml_disk_1: case S_surfxml_disk_2: SET(S_surfxml_disk_2); break; - case S_surfxml_host: case S_surfxml_host_1: case S_surfxml_host_2: SET(S_surfxml_host_2); break; - case S_surfxml_link: case S_surfxml_link_1: case S_surfxml_link_2: SET(S_surfxml_link_2); break; - case S_surfxml_process: case S_surfxml_process_1: case S_surfxml_process_2: SET(S_surfxml_process_2); break; - case S_surfxml_storage: case S_surfxml_storage_1: case S_surfxml_storage_2: SET(S_surfxml_storage_2); break; - case S_surfxml_storage___type: case S_surfxml_storage___type_1: case S_surfxml_storage___type_2: SET(S_surfxml_storage___type_2); break; - case S_surfxml_zone: case S_surfxml_zone_2: case S_surfxml_zone_3: SET(S_surfxml_zone_3); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_2: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_3); break; + case S_simgrid_parse_actor: case S_simgrid_parse_actor_1: case S_simgrid_parse_actor_2: SET(S_simgrid_parse_actor_2); break; + case S_simgrid_parse_cluster: case S_simgrid_parse_cluster_1: case S_simgrid_parse_cluster_2: SET(S_simgrid_parse_cluster_2); break; + case S_simgrid_parse_config: case S_simgrid_parse_config_1: case S_simgrid_parse_config_2: SET(S_simgrid_parse_config_2); break; + case S_simgrid_parse_disk: case S_simgrid_parse_disk_1: case S_simgrid_parse_disk_2: SET(S_simgrid_parse_disk_2); break; + case S_simgrid_parse_host: case S_simgrid_parse_host_1: case S_simgrid_parse_host_2: SET(S_simgrid_parse_host_2); break; + case S_simgrid_parse_link: case S_simgrid_parse_link_1: case S_simgrid_parse_link_2: SET(S_simgrid_parse_link_2); break; + case S_simgrid_parse_process: case S_simgrid_parse_process_1: case S_simgrid_parse_process_2: SET(S_simgrid_parse_process_2); break; + case S_simgrid_parse_storage: case S_simgrid_parse_storage_1: case S_simgrid_parse_storage_2: SET(S_simgrid_parse_storage_2); break; + case S_simgrid_parse_storage___type: case S_simgrid_parse_storage___type_1: case S_simgrid_parse_storage___type_2: SET(S_simgrid_parse_storage___type_2); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_2: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_3); break; } } YY_BREAK @@ -9818,7 +9811,7 @@ case 453: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_prop): +case YY_STATE_EOF(E_simgrid_parse_prop): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -9832,23 +9825,23 @@ case 455: /* rule 455 can match eol */ YY_RULE_SETUP { - AX_surfxml_random_generator = A_surfxml_random_generator_DRAND48; - surfxml_random_generator_isset = 0; - AX_surfxml_random_id = 0; - surfxml_random_id_isset = 0; - AX_surfxml_random_max = 0; - surfxml_random_max_isset = 0; - AX_surfxml_random_mean = 0; - surfxml_random_mean_isset = 0; - AX_surfxml_random_min = 0; - surfxml_random_min_isset = 0; - AX_surfxml_random_radical = 0; - surfxml_random_radical_isset = 0; - AX_surfxml_random_seed = 5; - surfxml_random_seed_isset = 0; - AX_surfxml_random_std___deviation = 0; - surfxml_random_std___deviation_isset = 0; - ENTER(AL_surfxml_random); pushbuffer(0); + AX_simgrid_parse_random_generator = A_simgrid_parse_random_generator_DRAND48; + simgrid_parse_random_generator_isset = 0; + AX_simgrid_parse_random_id = 0; + simgrid_parse_random_id_isset = 0; + AX_simgrid_parse_random_max = 0; + simgrid_parse_random_max_isset = 0; + AX_simgrid_parse_random_mean = 0; + simgrid_parse_random_mean_isset = 0; + AX_simgrid_parse_random_min = 0; + simgrid_parse_random_min_isset = 0; + AX_simgrid_parse_random_radical = 0; + simgrid_parse_random_radical_isset = 0; + AX_simgrid_parse_random_seed = 5; + simgrid_parse_random_seed_isset = 0; + AX_simgrid_parse_random_std___deviation = 0; + simgrid_parse_random_std___deviation_isset = 0; + ENTER(AL_simgrid_parse_random); pushbuffer(0); } YY_BREAK @@ -9857,121 +9850,121 @@ case 456: case 457: /* rule 457 can match eol */ YY_RULE_SETUP -A_surfxml_random_generator = A_surfxml_random_generator_DRAND48; +A_simgrid_parse_random_generator = A_simgrid_parse_random_generator_DRAND48; YY_BREAK case 458: /* rule 458 can match eol */ case 459: /* rule 459 can match eol */ YY_RULE_SETUP -A_surfxml_random_generator = A_surfxml_random_generator_RAND; +A_simgrid_parse_random_generator = A_simgrid_parse_random_generator_RAND; YY_BREAK case 460: /* rule 460 can match eol */ case 461: /* rule 461 can match eol */ YY_RULE_SETUP -A_surfxml_random_generator = A_surfxml_random_generator_RNGSTREAM; +A_simgrid_parse_random_generator = A_simgrid_parse_random_generator_RNGSTREAM; YY_BREAK case 462: /* rule 462 can match eol */ case 463: /* rule 463 can match eol */ YY_RULE_SETUP -A_surfxml_random_generator = A_surfxml_random_generator_NONE; +A_simgrid_parse_random_generator = A_simgrid_parse_random_generator_NONE; YY_BREAK case 464: /* rule 464 can match eol */ YY_RULE_SETUP -if (surfxml_random_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_random_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_random_id); +if (simgrid_parse_random_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_random_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_random_id); YY_BREAK case 465: /* rule 465 can match eol */ YY_RULE_SETUP -if (surfxml_random_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_random_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_random_id); +if (simgrid_parse_random_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_random_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_random_id); YY_BREAK case 466: /* rule 466 can match eol */ YY_RULE_SETUP -if (surfxml_random_max_isset != 0) {FAIL("Multiple definition of attribute max in ");} surfxml_random_max_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_random_max); +if (simgrid_parse_random_max_isset != 0) {FAIL("Multiple definition of attribute max in ");} simgrid_parse_random_max_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_random_max); YY_BREAK case 467: /* rule 467 can match eol */ YY_RULE_SETUP -if (surfxml_random_max_isset != 0) {FAIL("Multiple definition of attribute max in ");} surfxml_random_max_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_random_max); +if (simgrid_parse_random_max_isset != 0) {FAIL("Multiple definition of attribute max in ");} simgrid_parse_random_max_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_random_max); YY_BREAK case 468: /* rule 468 can match eol */ YY_RULE_SETUP -if (surfxml_random_mean_isset != 0) {FAIL("Multiple definition of attribute mean in ");} surfxml_random_mean_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_random_mean); +if (simgrid_parse_random_mean_isset != 0) {FAIL("Multiple definition of attribute mean in ");} simgrid_parse_random_mean_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_random_mean); YY_BREAK case 469: /* rule 469 can match eol */ YY_RULE_SETUP -if (surfxml_random_mean_isset != 0) {FAIL("Multiple definition of attribute mean in ");} surfxml_random_mean_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_random_mean); +if (simgrid_parse_random_mean_isset != 0) {FAIL("Multiple definition of attribute mean in ");} simgrid_parse_random_mean_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_random_mean); YY_BREAK case 470: /* rule 470 can match eol */ YY_RULE_SETUP -if (surfxml_random_min_isset != 0) {FAIL("Multiple definition of attribute min in ");} surfxml_random_min_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_random_min); +if (simgrid_parse_random_min_isset != 0) {FAIL("Multiple definition of attribute min in ");} simgrid_parse_random_min_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_random_min); YY_BREAK case 471: /* rule 471 can match eol */ YY_RULE_SETUP -if (surfxml_random_min_isset != 0) {FAIL("Multiple definition of attribute min in ");} surfxml_random_min_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_random_min); +if (simgrid_parse_random_min_isset != 0) {FAIL("Multiple definition of attribute min in ");} simgrid_parse_random_min_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_random_min); YY_BREAK case 472: /* rule 472 can match eol */ YY_RULE_SETUP -if (surfxml_random_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} surfxml_random_radical_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_random_radical); +if (simgrid_parse_random_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} simgrid_parse_random_radical_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_random_radical); YY_BREAK case 473: /* rule 473 can match eol */ YY_RULE_SETUP -if (surfxml_random_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} surfxml_random_radical_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_random_radical); +if (simgrid_parse_random_radical_isset != 0) {FAIL("Multiple definition of attribute radical in ");} simgrid_parse_random_radical_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_random_radical); YY_BREAK case 474: /* rule 474 can match eol */ YY_RULE_SETUP -if (surfxml_random_seed_isset != 0) {FAIL("Multiple definition of attribute seed in ");} surfxml_random_seed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_random_seed); +if (simgrid_parse_random_seed_isset != 0) {FAIL("Multiple definition of attribute seed in ");} simgrid_parse_random_seed_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_random_seed); YY_BREAK case 475: /* rule 475 can match eol */ YY_RULE_SETUP -if (surfxml_random_seed_isset != 0) {FAIL("Multiple definition of attribute seed in ");} surfxml_random_seed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_random_seed); +if (simgrid_parse_random_seed_isset != 0) {FAIL("Multiple definition of attribute seed in ");} simgrid_parse_random_seed_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_random_seed); YY_BREAK case 476: /* rule 476 can match eol */ YY_RULE_SETUP -if (surfxml_random_std___deviation_isset != 0) {FAIL("Multiple definition of attribute std_deviation in ");} surfxml_random_std___deviation_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_random_std___deviation); +if (simgrid_parse_random_std___deviation_isset != 0) {FAIL("Multiple definition of attribute std_deviation in ");} simgrid_parse_random_std___deviation_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_random_std___deviation); YY_BREAK case 477: /* rule 477 can match eol */ YY_RULE_SETUP -if (surfxml_random_std___deviation_isset != 0) {FAIL("Multiple definition of attribute std_deviation in ");} surfxml_random_std___deviation_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_random_std___deviation); +if (simgrid_parse_random_std___deviation_isset != 0) {FAIL("Multiple definition of attribute std_deviation in ");} simgrid_parse_random_std___deviation_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_random_std___deviation); YY_BREAK case 478: YY_RULE_SETUP { - if (!AX_surfxml_random_id) FAIL("Required attribute `id' not set for `random' element."); - if (!AX_surfxml_random_max) FAIL("Required attribute `max' not set for `random' element."); - if (!AX_surfxml_random_mean) FAIL("Required attribute `mean' not set for `random' element."); - if (!AX_surfxml_random_min) FAIL("Required attribute `min' not set for `random' element."); - if (!AX_surfxml_random_std___deviation) FAIL("Required attribute `std_deviation' not set for `random' element."); - LEAVE; STag_surfxml_random();surfxml_pcdata_ix = 0; ENTER(E_surfxml_random); + if (!AX_simgrid_parse_random_id) FAIL("Required attribute `id' not set for `random' element."); + if (!AX_simgrid_parse_random_max) FAIL("Required attribute `max' not set for `random' element."); + if (!AX_simgrid_parse_random_mean) FAIL("Required attribute `mean' not set for `random' element."); + if (!AX_simgrid_parse_random_min) FAIL("Required attribute `min' not set for `random' element."); + if (!AX_simgrid_parse_random_std___deviation) FAIL("Required attribute `std_deviation' not set for `random' element."); + LEAVE; STag_simgrid_parse_random();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_random); } YY_BREAK case 479: YY_RULE_SETUP { - if (!AX_surfxml_random_id) FAIL("Required attribute `id' not set for `random' element."); - if (!AX_surfxml_random_max) FAIL("Required attribute `max' not set for `random' element."); - if (!AX_surfxml_random_mean) FAIL("Required attribute `mean' not set for `random' element."); - if (!AX_surfxml_random_min) FAIL("Required attribute `min' not set for `random' element."); - if (!AX_surfxml_random_std___deviation) FAIL("Required attribute `std_deviation' not set for `random' element."); - LEAVE; STag_surfxml_random(); surfxml_pcdata_ix = 0; ETag_surfxml_random(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_random_id) FAIL("Required attribute `id' not set for `random' element."); + if (!AX_simgrid_parse_random_max) FAIL("Required attribute `max' not set for `random' element."); + if (!AX_simgrid_parse_random_mean) FAIL("Required attribute `mean' not set for `random' element."); + if (!AX_simgrid_parse_random_min) FAIL("Required attribute `min' not set for `random' element."); + if (!AX_simgrid_parse_random_std___deviation) FAIL("Required attribute `std_deviation' not set for `random' element."); + LEAVE; STag_simgrid_parse_random(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_random(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_platform: case S_surfxml_platform_2: case S_surfxml_platform_3: SET(S_surfxml_platform_3); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_2: case S_simgrid_parse_platform_3: SET(S_simgrid_parse_platform_3); break; } } YY_BREAK @@ -9983,7 +9976,7 @@ case 481: YY_RULE_SETUP FAIL("Bad attribute `%s' in `random' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_random): +case YY_STATE_EOF(AL_simgrid_parse_random): FAIL("EOF in attribute list of `random' element."); YY_BREAK @@ -9992,10 +9985,10 @@ case 482: YY_RULE_SETUP { LEAVE; - ETag_surfxml_random(); + ETag_simgrid_parse_random(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_platform: case S_surfxml_platform_2: case S_surfxml_platform_3: SET(S_surfxml_platform_3); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_2: case S_simgrid_parse_platform_3: SET(S_simgrid_parse_platform_3); break; } } YY_BREAK @@ -10008,7 +10001,7 @@ case 484: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_random): +case YY_STATE_EOF(E_simgrid_parse_random): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -10021,81 +10014,81 @@ case 486: /* rule 486 can match eol */ YY_RULE_SETUP { - AX_surfxml_route_dst = 0; - surfxml_route_dst_isset = 0; - AX_surfxml_route_src = 0; - surfxml_route_src_isset = 0; - AX_surfxml_route_symmetrical = A_surfxml_route_symmetrical_YES; - surfxml_route_symmetrical_isset = 0; - ENTER(AL_surfxml_route); pushbuffer(0); + AX_simgrid_parse_route_dst = 0; + simgrid_parse_route_dst_isset = 0; + AX_simgrid_parse_route_src = 0; + simgrid_parse_route_src_isset = 0; + AX_simgrid_parse_route_symmetrical = A_simgrid_parse_route_symmetrical_YES; + simgrid_parse_route_symmetrical_isset = 0; + ENTER(AL_simgrid_parse_route); pushbuffer(0); } YY_BREAK case 487: /* rule 487 can match eol */ YY_RULE_SETUP -if (surfxml_route_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_route_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_route_dst); +if (simgrid_parse_route_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_route_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_route_dst); YY_BREAK case 488: /* rule 488 can match eol */ YY_RULE_SETUP -if (surfxml_route_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_route_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_route_dst); +if (simgrid_parse_route_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_route_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_route_dst); YY_BREAK case 489: /* rule 489 can match eol */ YY_RULE_SETUP -if (surfxml_route_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_route_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_route_src); +if (simgrid_parse_route_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_route_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_route_src); YY_BREAK case 490: /* rule 490 can match eol */ YY_RULE_SETUP -if (surfxml_route_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_route_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_route_src); +if (simgrid_parse_route_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_route_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_route_src); YY_BREAK case 491: /* rule 491 can match eol */ case 492: /* rule 492 can match eol */ YY_RULE_SETUP -A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_YES; +A_simgrid_parse_route_symmetrical = A_simgrid_parse_route_symmetrical_YES; YY_BREAK case 493: /* rule 493 can match eol */ case 494: /* rule 494 can match eol */ YY_RULE_SETUP -A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO; +A_simgrid_parse_route_symmetrical = A_simgrid_parse_route_symmetrical_NO; YY_BREAK case 495: /* rule 495 can match eol */ case 496: /* rule 496 can match eol */ YY_RULE_SETUP -A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_yes; +A_simgrid_parse_route_symmetrical = A_simgrid_parse_route_symmetrical_yes; YY_BREAK case 497: /* rule 497 can match eol */ case 498: /* rule 498 can match eol */ YY_RULE_SETUP -A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_no; +A_simgrid_parse_route_symmetrical = A_simgrid_parse_route_symmetrical_no; YY_BREAK case 499: YY_RULE_SETUP { - if (!AX_surfxml_route_dst) FAIL("Required attribute `dst' not set for `route' element."); - if (!AX_surfxml_route_src) FAIL("Required attribute `src' not set for `route' element."); - LEAVE; STag_surfxml_route();surfxml_pcdata_ix = 0; ENTER(S_surfxml_route); + if (!AX_simgrid_parse_route_dst) FAIL("Required attribute `dst' not set for `route' element."); + if (!AX_simgrid_parse_route_src) FAIL("Required attribute `src' not set for `route' element."); + LEAVE; STag_simgrid_parse_route();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_route); } YY_BREAK case 500: YY_RULE_SETUP { - if (!AX_surfxml_route_dst) FAIL("Required attribute `dst' not set for `route' element."); - if (!AX_surfxml_route_src) FAIL("Required attribute `src' not set for `route' element."); - LEAVE; STag_surfxml_route(); surfxml_pcdata_ix = 0; ETag_surfxml_route(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_route_dst) FAIL("Required attribute `dst' not set for `route' element."); + if (!AX_simgrid_parse_route_src) FAIL("Required attribute `src' not set for `route' element."); + LEAVE; STag_simgrid_parse_route(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_route(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_12: case S_surfxml_AS_14: case S_surfxml_AS_15: case S_surfxml_AS_16: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_16); break; - case S_surfxml_zone: case S_surfxml_zone_12: case S_surfxml_zone_14: case S_surfxml_zone_15: case S_surfxml_zone_16: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_16); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_12: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_15: case S_simgrid_parse_AS_16: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_16); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_12: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_15: case S_simgrid_parse_zone_16: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_16); break; } } YY_BREAK @@ -10107,7 +10100,7 @@ case 502: YY_RULE_SETUP FAIL("Bad attribute `%s' in `route' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_route): +case YY_STATE_EOF(AL_simgrid_parse_route): FAIL("EOF in attribute list of `route' element."); YY_BREAK @@ -10116,11 +10109,11 @@ case 503: YY_RULE_SETUP { LEAVE; - ETag_surfxml_route(); + ETag_simgrid_parse_route(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_12: case S_surfxml_AS_14: case S_surfxml_AS_15: case S_surfxml_AS_16: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_16); break; - case S_surfxml_zone: case S_surfxml_zone_12: case S_surfxml_zone_14: case S_surfxml_zone_15: case S_surfxml_zone_16: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_16); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_12: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_15: case S_simgrid_parse_AS_16: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_16); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_12: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_15: case S_simgrid_parse_zone_16: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_16); break; } } YY_BREAK @@ -10133,9 +10126,9 @@ case 505: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_route): -case YY_STATE_EOF(S_surfxml_route): -case YY_STATE_EOF(S_surfxml_route_2): +case YY_STATE_EOF(E_simgrid_parse_route): +case YY_STATE_EOF(S_simgrid_parse_route): +case YY_STATE_EOF(S_simgrid_parse_route_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -10148,49 +10141,49 @@ case 507: /* rule 507 can match eol */ YY_RULE_SETUP { - AX_surfxml_router_coordinates = 0; - surfxml_router_coordinates_isset = 0; - AX_surfxml_router_id = 0; - surfxml_router_id_isset = 0; - ENTER(AL_surfxml_router); pushbuffer(0); + AX_simgrid_parse_router_coordinates = 0; + simgrid_parse_router_coordinates_isset = 0; + AX_simgrid_parse_router_id = 0; + simgrid_parse_router_id_isset = 0; + ENTER(AL_simgrid_parse_router); pushbuffer(0); } YY_BREAK case 508: /* rule 508 can match eol */ YY_RULE_SETUP -if (surfxml_router_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} surfxml_router_coordinates_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_router_coordinates); +if (simgrid_parse_router_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} simgrid_parse_router_coordinates_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_router_coordinates); YY_BREAK case 509: /* rule 509 can match eol */ YY_RULE_SETUP -if (surfxml_router_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} surfxml_router_coordinates_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_router_coordinates); +if (simgrid_parse_router_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in ");} simgrid_parse_router_coordinates_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_router_coordinates); YY_BREAK case 510: /* rule 510 can match eol */ YY_RULE_SETUP -if (surfxml_router_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_router_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_router_id); +if (simgrid_parse_router_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_router_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_router_id); YY_BREAK case 511: /* rule 511 can match eol */ YY_RULE_SETUP -if (surfxml_router_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_router_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_router_id); +if (simgrid_parse_router_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_router_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_router_id); YY_BREAK case 512: YY_RULE_SETUP { - if (!AX_surfxml_router_id) FAIL("Required attribute `id' not set for `router' element."); - LEAVE; STag_surfxml_router();surfxml_pcdata_ix = 0; ENTER(E_surfxml_router); + if (!AX_simgrid_parse_router_id) FAIL("Required attribute `id' not set for `router' element."); + LEAVE; STag_simgrid_parse_router();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_router); } YY_BREAK case 513: YY_RULE_SETUP { - if (!AX_surfxml_router_id) FAIL("Required attribute `id' not set for `router' element."); - LEAVE; STag_surfxml_router(); surfxml_pcdata_ix = 0; ETag_surfxml_router(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_router_id) FAIL("Required attribute `id' not set for `router' element."); + LEAVE; STag_simgrid_parse_router(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_router(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -10202,7 +10195,7 @@ case 515: YY_RULE_SETUP FAIL("Bad attribute `%s' in `router' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_router): +case YY_STATE_EOF(AL_simgrid_parse_router): FAIL("EOF in attribute list of `router' element."); YY_BREAK @@ -10211,11 +10204,11 @@ case 516: YY_RULE_SETUP { LEAVE; - ETag_surfxml_router(); + ETag_simgrid_parse_router(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -10228,7 +10221,7 @@ case 518: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_router): +case YY_STATE_EOF(E_simgrid_parse_router): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -10241,77 +10234,77 @@ case 520: /* rule 520 can match eol */ YY_RULE_SETUP { - AX_surfxml_storage_attach = 0; - surfxml_storage_attach_isset = 0; - AX_surfxml_storage_content = 0; - surfxml_storage_content_isset = 0; - AX_surfxml_storage_id = 0; - surfxml_storage_id_isset = 0; - AX_surfxml_storage_typeId = 0; - surfxml_storage_typeId_isset = 0; - ENTER(AL_surfxml_storage); pushbuffer(0); + AX_simgrid_parse_storage_attach = 0; + simgrid_parse_storage_attach_isset = 0; + AX_simgrid_parse_storage_content = 0; + simgrid_parse_storage_content_isset = 0; + AX_simgrid_parse_storage_id = 0; + simgrid_parse_storage_id_isset = 0; + AX_simgrid_parse_storage_typeId = 0; + simgrid_parse_storage_typeId_isset = 0; + ENTER(AL_simgrid_parse_storage); pushbuffer(0); } YY_BREAK case 521: /* rule 521 can match eol */ YY_RULE_SETUP -if (surfxml_storage_attach_isset != 0) {FAIL("Multiple definition of attribute attach in ");} surfxml_storage_attach_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_storage_attach); +if (simgrid_parse_storage_attach_isset != 0) {FAIL("Multiple definition of attribute attach in ");} simgrid_parse_storage_attach_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_storage_attach); YY_BREAK case 522: /* rule 522 can match eol */ YY_RULE_SETUP -if (surfxml_storage_attach_isset != 0) {FAIL("Multiple definition of attribute attach in ");} surfxml_storage_attach_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_storage_attach); +if (simgrid_parse_storage_attach_isset != 0) {FAIL("Multiple definition of attribute attach in ");} simgrid_parse_storage_attach_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_storage_attach); YY_BREAK case 523: /* rule 523 can match eol */ YY_RULE_SETUP -if (surfxml_storage_content_isset != 0) {FAIL("Multiple definition of attribute content in ");} surfxml_storage_content_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_storage_content); +if (simgrid_parse_storage_content_isset != 0) {FAIL("Multiple definition of attribute content in ");} simgrid_parse_storage_content_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_storage_content); YY_BREAK case 524: /* rule 524 can match eol */ YY_RULE_SETUP -if (surfxml_storage_content_isset != 0) {FAIL("Multiple definition of attribute content in ");} surfxml_storage_content_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_storage_content); +if (simgrid_parse_storage_content_isset != 0) {FAIL("Multiple definition of attribute content in ");} simgrid_parse_storage_content_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_storage_content); YY_BREAK case 525: /* rule 525 can match eol */ YY_RULE_SETUP -if (surfxml_storage_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_storage_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_storage_id); +if (simgrid_parse_storage_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_storage_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_storage_id); YY_BREAK case 526: /* rule 526 can match eol */ YY_RULE_SETUP -if (surfxml_storage_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_storage_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_storage_id); +if (simgrid_parse_storage_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_storage_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_storage_id); YY_BREAK case 527: /* rule 527 can match eol */ YY_RULE_SETUP -if (surfxml_storage_typeId_isset != 0) {FAIL("Multiple definition of attribute typeId in ");} surfxml_storage_typeId_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_storage_typeId); +if (simgrid_parse_storage_typeId_isset != 0) {FAIL("Multiple definition of attribute typeId in ");} simgrid_parse_storage_typeId_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_storage_typeId); YY_BREAK case 528: /* rule 528 can match eol */ YY_RULE_SETUP -if (surfxml_storage_typeId_isset != 0) {FAIL("Multiple definition of attribute typeId in ");} surfxml_storage_typeId_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_storage_typeId); +if (simgrid_parse_storage_typeId_isset != 0) {FAIL("Multiple definition of attribute typeId in ");} simgrid_parse_storage_typeId_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_storage_typeId); YY_BREAK case 529: YY_RULE_SETUP { - if (!AX_surfxml_storage_attach) FAIL("Required attribute `attach' not set for `storage' element."); - if (!AX_surfxml_storage_id) FAIL("Required attribute `id' not set for `storage' element."); - if (!AX_surfxml_storage_typeId) FAIL("Required attribute `typeId' not set for `storage' element."); - LEAVE; STag_surfxml_storage();surfxml_pcdata_ix = 0; ENTER(S_surfxml_storage); + if (!AX_simgrid_parse_storage_attach) FAIL("Required attribute `attach' not set for `storage' element."); + if (!AX_simgrid_parse_storage_id) FAIL("Required attribute `id' not set for `storage' element."); + if (!AX_simgrid_parse_storage_typeId) FAIL("Required attribute `typeId' not set for `storage' element."); + LEAVE; STag_simgrid_parse_storage();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_storage); } YY_BREAK case 530: YY_RULE_SETUP { - if (!AX_surfxml_storage_attach) FAIL("Required attribute `attach' not set for `storage' element."); - if (!AX_surfxml_storage_id) FAIL("Required attribute `id' not set for `storage' element."); - if (!AX_surfxml_storage_typeId) FAIL("Required attribute `typeId' not set for `storage' element."); - LEAVE; STag_surfxml_storage(); surfxml_pcdata_ix = 0; ETag_surfxml_storage(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_storage_attach) FAIL("Required attribute `attach' not set for `storage' element."); + if (!AX_simgrid_parse_storage_id) FAIL("Required attribute `id' not set for `storage' element."); + if (!AX_simgrid_parse_storage_typeId) FAIL("Required attribute `typeId' not set for `storage' element."); + LEAVE; STag_simgrid_parse_storage(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_storage(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -10323,7 +10316,7 @@ case 532: YY_RULE_SETUP FAIL("Bad attribute `%s' in `storage' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_storage): +case YY_STATE_EOF(AL_simgrid_parse_storage): FAIL("EOF in attribute list of `storage' element."); YY_BREAK @@ -10332,11 +10325,11 @@ case 533: YY_RULE_SETUP { LEAVE; - ETag_surfxml_storage(); + ETag_simgrid_parse_storage(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -10349,9 +10342,9 @@ case 535: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_storage): -case YY_STATE_EOF(S_surfxml_storage): -case YY_STATE_EOF(S_surfxml_storage_2): +case YY_STATE_EOF(E_simgrid_parse_storage): +case YY_STATE_EOF(S_simgrid_parse_storage): +case YY_STATE_EOF(S_simgrid_parse_storage_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -10365,75 +10358,75 @@ case 537: /* rule 537 can match eol */ YY_RULE_SETUP { - AX_surfxml_storage___type_content = 0; - surfxml_storage___type_content_isset = 0; - AX_surfxml_storage___type_id = 0; - surfxml_storage___type_id_isset = 0; - AX_surfxml_storage___type_model = 16; - surfxml_storage___type_model_isset = 0; - AX_surfxml_storage___type_size = 0; - surfxml_storage___type_size_isset = 0; - ENTER(AL_surfxml_storage___type); pushbuffer(0); + AX_simgrid_parse_storage___type_content = 0; + simgrid_parse_storage___type_content_isset = 0; + AX_simgrid_parse_storage___type_id = 0; + simgrid_parse_storage___type_id_isset = 0; + AX_simgrid_parse_storage___type_model = 16; + simgrid_parse_storage___type_model_isset = 0; + AX_simgrid_parse_storage___type_size = 0; + simgrid_parse_storage___type_size_isset = 0; + ENTER(AL_simgrid_parse_storage___type); pushbuffer(0); } YY_BREAK case 538: /* rule 538 can match eol */ YY_RULE_SETUP -if (surfxml_storage___type_content_isset != 0) {FAIL("Multiple definition of attribute content in ");} surfxml_storage___type_content_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_storage___type_content); +if (simgrid_parse_storage___type_content_isset != 0) {FAIL("Multiple definition of attribute content in ");} simgrid_parse_storage___type_content_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_storage___type_content); YY_BREAK case 539: /* rule 539 can match eol */ YY_RULE_SETUP -if (surfxml_storage___type_content_isset != 0) {FAIL("Multiple definition of attribute content in ");} surfxml_storage___type_content_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_storage___type_content); +if (simgrid_parse_storage___type_content_isset != 0) {FAIL("Multiple definition of attribute content in ");} simgrid_parse_storage___type_content_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_storage___type_content); YY_BREAK case 540: /* rule 540 can match eol */ YY_RULE_SETUP -if (surfxml_storage___type_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_storage___type_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_storage___type_id); +if (simgrid_parse_storage___type_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_storage___type_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_storage___type_id); YY_BREAK case 541: /* rule 541 can match eol */ YY_RULE_SETUP -if (surfxml_storage___type_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_storage___type_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_storage___type_id); +if (simgrid_parse_storage___type_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_storage___type_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_storage___type_id); YY_BREAK case 542: /* rule 542 can match eol */ YY_RULE_SETUP -if (surfxml_storage___type_model_isset != 0) {FAIL("Multiple definition of attribute model in ");} surfxml_storage___type_model_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_storage___type_model); +if (simgrid_parse_storage___type_model_isset != 0) {FAIL("Multiple definition of attribute model in ");} simgrid_parse_storage___type_model_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_storage___type_model); YY_BREAK case 543: /* rule 543 can match eol */ YY_RULE_SETUP -if (surfxml_storage___type_model_isset != 0) {FAIL("Multiple definition of attribute model in ");} surfxml_storage___type_model_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_storage___type_model); +if (simgrid_parse_storage___type_model_isset != 0) {FAIL("Multiple definition of attribute model in ");} simgrid_parse_storage___type_model_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_storage___type_model); YY_BREAK case 544: /* rule 544 can match eol */ YY_RULE_SETUP -if (surfxml_storage___type_size_isset != 0) {FAIL("Multiple definition of attribute size in ");} surfxml_storage___type_size_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_storage___type_size); +if (simgrid_parse_storage___type_size_isset != 0) {FAIL("Multiple definition of attribute size in ");} simgrid_parse_storage___type_size_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_storage___type_size); YY_BREAK case 545: /* rule 545 can match eol */ YY_RULE_SETUP -if (surfxml_storage___type_size_isset != 0) {FAIL("Multiple definition of attribute size in ");} surfxml_storage___type_size_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_storage___type_size); +if (simgrid_parse_storage___type_size_isset != 0) {FAIL("Multiple definition of attribute size in ");} simgrid_parse_storage___type_size_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_storage___type_size); YY_BREAK case 546: YY_RULE_SETUP { - if (!AX_surfxml_storage___type_id) FAIL("Required attribute `id' not set for `storage_type' element."); - if (!AX_surfxml_storage___type_size) FAIL("Required attribute `size' not set for `storage_type' element."); - LEAVE; STag_surfxml_storage___type();surfxml_pcdata_ix = 0; ENTER(S_surfxml_storage___type); + if (!AX_simgrid_parse_storage___type_id) FAIL("Required attribute `id' not set for `storage_type' element."); + if (!AX_simgrid_parse_storage___type_size) FAIL("Required attribute `size' not set for `storage_type' element."); + LEAVE; STag_simgrid_parse_storage___type();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_storage___type); } YY_BREAK case 547: YY_RULE_SETUP { - if (!AX_surfxml_storage___type_id) FAIL("Required attribute `id' not set for `storage_type' element."); - if (!AX_surfxml_storage___type_size) FAIL("Required attribute `size' not set for `storage_type' element."); - LEAVE; STag_surfxml_storage___type(); surfxml_pcdata_ix = 0; ETag_surfxml_storage___type(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_storage___type_id) FAIL("Required attribute `id' not set for `storage_type' element."); + if (!AX_simgrid_parse_storage___type_size) FAIL("Required attribute `size' not set for `storage_type' element."); + LEAVE; STag_simgrid_parse_storage___type(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_storage___type(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -10445,7 +10438,7 @@ case 549: YY_RULE_SETUP FAIL("Bad attribute `%s' in `storage_type' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_storage___type): +case YY_STATE_EOF(AL_simgrid_parse_storage___type): FAIL("EOF in attribute list of `storage_type' element."); YY_BREAK @@ -10454,11 +10447,11 @@ case 550: YY_RULE_SETUP { LEAVE; - ETag_surfxml_storage___type(); + ETag_simgrid_parse_storage___type(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_13: case S_surfxml_AS_14: case S_surfxml_AS_1: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break; - case S_surfxml_zone: case S_surfxml_zone_13: case S_surfxml_zone_14: case S_surfxml_zone_1: case S_surfxml_zone_3: SET(S_surfxml_zone_14); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: SET(S_simgrid_parse_zone_14); break; } } YY_BREAK @@ -10471,9 +10464,9 @@ case 552: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_storage___type): -case YY_STATE_EOF(S_surfxml_storage___type): -case YY_STATE_EOF(S_surfxml_storage___type_2): +case YY_STATE_EOF(E_simgrid_parse_storage___type): +case YY_STATE_EOF(S_simgrid_parse_storage___type): +case YY_STATE_EOF(S_simgrid_parse_storage___type_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -10486,73 +10479,73 @@ case 554: /* rule 554 can match eol */ YY_RULE_SETUP { - AX_surfxml_trace_file = 0; - surfxml_trace_file_isset = 0; - AX_surfxml_trace_id = 0; - surfxml_trace_id_isset = 0; - AX_surfxml_trace_periodicity = 0; - surfxml_trace_periodicity_isset = 0; - ENTER(AL_surfxml_trace); pushbuffer(0); + AX_simgrid_parse_trace_file = 0; + simgrid_parse_trace_file_isset = 0; + AX_simgrid_parse_trace_id = 0; + simgrid_parse_trace_id_isset = 0; + AX_simgrid_parse_trace_periodicity = 0; + simgrid_parse_trace_periodicity_isset = 0; + ENTER(AL_simgrid_parse_trace); pushbuffer(0); } YY_BREAK case 555: /* rule 555 can match eol */ YY_RULE_SETUP -if (surfxml_trace_file_isset != 0) {FAIL("Multiple definition of attribute file in ");} surfxml_trace_file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_trace_file); +if (simgrid_parse_trace_file_isset != 0) {FAIL("Multiple definition of attribute file in ");} simgrid_parse_trace_file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_trace_file); YY_BREAK case 556: /* rule 556 can match eol */ YY_RULE_SETUP -if (surfxml_trace_file_isset != 0) {FAIL("Multiple definition of attribute file in ");} surfxml_trace_file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_trace_file); +if (simgrid_parse_trace_file_isset != 0) {FAIL("Multiple definition of attribute file in ");} simgrid_parse_trace_file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_trace_file); YY_BREAK case 557: /* rule 557 can match eol */ YY_RULE_SETUP -if (surfxml_trace_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_trace_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_trace_id); +if (simgrid_parse_trace_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_trace_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_trace_id); YY_BREAK case 558: /* rule 558 can match eol */ YY_RULE_SETUP -if (surfxml_trace_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_trace_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_trace_id); +if (simgrid_parse_trace_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_trace_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_trace_id); YY_BREAK case 559: /* rule 559 can match eol */ YY_RULE_SETUP -if (surfxml_trace_periodicity_isset != 0) {FAIL("Multiple definition of attribute periodicity in ");} surfxml_trace_periodicity_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_trace_periodicity); +if (simgrid_parse_trace_periodicity_isset != 0) {FAIL("Multiple definition of attribute periodicity in ");} simgrid_parse_trace_periodicity_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_trace_periodicity); YY_BREAK case 560: /* rule 560 can match eol */ YY_RULE_SETUP -if (surfxml_trace_periodicity_isset != 0) {FAIL("Multiple definition of attribute periodicity in ");} surfxml_trace_periodicity_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_trace_periodicity); +if (simgrid_parse_trace_periodicity_isset != 0) {FAIL("Multiple definition of attribute periodicity in ");} simgrid_parse_trace_periodicity_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_trace_periodicity); YY_BREAK case 561: YY_RULE_SETUP { - if (!AX_surfxml_trace_id) FAIL("Required attribute `id' not set for `trace' element."); - if (!AX_surfxml_trace_periodicity) FAIL("Required attribute `periodicity' not set for `trace' element."); - LEAVE; STag_surfxml_trace();pushbuffer(surfxml_pcdata_ix); BUFFERSET(surfxml_pcdata_ix);; ENTER(IN_trace); + if (!AX_simgrid_parse_trace_id) FAIL("Required attribute `id' not set for `trace' element."); + if (!AX_simgrid_parse_trace_periodicity) FAIL("Required attribute `periodicity' not set for `trace' element."); + LEAVE; STag_simgrid_parse_trace();pushbuffer(simgrid_parse_pcdata_ix); BUFFERSET(simgrid_parse_pcdata_ix);; ENTER(IN_trace); } YY_BREAK case 562: YY_RULE_SETUP { - if (!AX_surfxml_trace_id) FAIL("Required attribute `id' not set for `trace' element."); - if (!AX_surfxml_trace_periodicity) FAIL("Required attribute `periodicity' not set for `trace' element."); - LEAVE; STag_surfxml_trace(); surfxml_pcdata_ix = 0; ETag_surfxml_trace(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_trace_id) FAIL("Required attribute `id' not set for `trace' element."); + if (!AX_simgrid_parse_trace_periodicity) FAIL("Required attribute `periodicity' not set for `trace' element."); + LEAVE; STag_simgrid_parse_trace(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_trace(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS_10: case S_surfxml_AS_11: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_7: case S_surfxml_AS_9: SET(S_surfxml_AS_11); break; - case S_surfxml_AS: case S_surfxml_AS_13: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_12: case S_surfxml_AS_14: case S_surfxml_AS_15: case S_surfxml_AS_16: case S_surfxml_AS_1: SET(S_surfxml_AS_16); break; - case S_surfxml_AS_5: SET(S_surfxml_AS_6); break; - case S_surfxml_AS_6: case S_surfxml_AS_8: SET(S_surfxml_AS_9); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_10: case S_surfxml_zone_11: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_7: SET(S_surfxml_zone_11); break; - case S_surfxml_zone_13: case S_surfxml_zone_14: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_12: case S_surfxml_zone_15: case S_surfxml_zone_16: SET(S_surfxml_zone_16); break; - case S_surfxml_zone_5: SET(S_surfxml_zone_6); break; - case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS_10: case S_simgrid_parse_AS_11: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_7: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_11); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS_12: case S_simgrid_parse_AS_15: case S_simgrid_parse_AS_16: SET(S_simgrid_parse_AS_16); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_8: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone_10: case S_simgrid_parse_zone_11: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_7: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_11); break; + case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_12: case S_simgrid_parse_zone_15: case S_simgrid_parse_zone_16: SET(S_simgrid_parse_zone_16); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: SET(S_simgrid_parse_zone_6); break; + case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_8: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -10564,7 +10557,7 @@ case 564: YY_RULE_SETUP FAIL("Bad attribute `%s' in `trace' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_trace): +case YY_STATE_EOF(AL_simgrid_parse_trace): FAIL("EOF in attribute list of `trace' element."); YY_BREAK @@ -10574,22 +10567,22 @@ YY_RULE_SETUP { LEAVE; BUFFERDONE; - ETag_surfxml_trace(); - surfxml_pcdata_ix = popbuffer(); + ETag_simgrid_parse_trace(); + simgrid_parse_pcdata_ix = popbuffer(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS_10: case S_surfxml_AS_11: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_7: case S_surfxml_AS_9: SET(S_surfxml_AS_11); break; - case S_surfxml_AS: case S_surfxml_AS_13: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_12: case S_surfxml_AS_14: case S_surfxml_AS_15: case S_surfxml_AS_16: case S_surfxml_AS_1: SET(S_surfxml_AS_16); break; - case S_surfxml_AS_5: SET(S_surfxml_AS_6); break; - case S_surfxml_AS_6: case S_surfxml_AS_8: SET(S_surfxml_AS_9); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_10: case S_surfxml_zone_11: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_7: SET(S_surfxml_zone_11); break; - case S_surfxml_zone_13: case S_surfxml_zone_14: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_12: case S_surfxml_zone_15: case S_surfxml_zone_16: SET(S_surfxml_zone_16); break; - case S_surfxml_zone_5: SET(S_surfxml_zone_6); break; - case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS_10: case S_simgrid_parse_AS_11: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_7: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_11); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS_12: case S_simgrid_parse_AS_15: case S_simgrid_parse_AS_16: SET(S_simgrid_parse_AS_16); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_8: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone_10: case S_simgrid_parse_zone_11: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_7: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_11); break; + case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_12: case S_simgrid_parse_zone_15: case S_simgrid_parse_zone_16: SET(S_simgrid_parse_zone_16); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: SET(S_simgrid_parse_zone_6); break; + case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_8: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -10611,98 +10604,98 @@ case 568: /* rule 568 can match eol */ YY_RULE_SETUP { - AX_surfxml_trace___connect_element = 0; - surfxml_trace___connect_element_isset = 0; - AX_surfxml_trace___connect_kind = A_surfxml_trace___connect_kind_HOST___AVAIL; - surfxml_trace___connect_kind_isset = 0; - AX_surfxml_trace___connect_trace = 0; - surfxml_trace___connect_trace_isset = 0; - ENTER(AL_surfxml_trace___connect); pushbuffer(0); + AX_simgrid_parse_trace___connect_element = 0; + simgrid_parse_trace___connect_element_isset = 0; + AX_simgrid_parse_trace___connect_kind = A_simgrid_parse_trace___connect_kind_HOST___AVAIL; + simgrid_parse_trace___connect_kind_isset = 0; + AX_simgrid_parse_trace___connect_trace = 0; + simgrid_parse_trace___connect_trace_isset = 0; + ENTER(AL_simgrid_parse_trace___connect); pushbuffer(0); } YY_BREAK case 569: /* rule 569 can match eol */ YY_RULE_SETUP -if (surfxml_trace___connect_element_isset != 0) {FAIL("Multiple definition of attribute element in ");} surfxml_trace___connect_element_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_trace___connect_element); +if (simgrid_parse_trace___connect_element_isset != 0) {FAIL("Multiple definition of attribute element in ");} simgrid_parse_trace___connect_element_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_trace___connect_element); YY_BREAK case 570: /* rule 570 can match eol */ YY_RULE_SETUP -if (surfxml_trace___connect_element_isset != 0) {FAIL("Multiple definition of attribute element in ");} surfxml_trace___connect_element_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_trace___connect_element); +if (simgrid_parse_trace___connect_element_isset != 0) {FAIL("Multiple definition of attribute element in ");} simgrid_parse_trace___connect_element_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_trace___connect_element); YY_BREAK case 571: /* rule 571 can match eol */ case 572: /* rule 572 can match eol */ YY_RULE_SETUP -A_surfxml_trace___connect_kind = A_surfxml_trace___connect_kind_HOST___AVAIL; +A_simgrid_parse_trace___connect_kind = A_simgrid_parse_trace___connect_kind_HOST___AVAIL; YY_BREAK case 573: /* rule 573 can match eol */ case 574: /* rule 574 can match eol */ YY_RULE_SETUP -A_surfxml_trace___connect_kind = A_surfxml_trace___connect_kind_SPEED; +A_simgrid_parse_trace___connect_kind = A_simgrid_parse_trace___connect_kind_SPEED; YY_BREAK case 575: /* rule 575 can match eol */ case 576: /* rule 576 can match eol */ YY_RULE_SETUP -A_surfxml_trace___connect_kind = A_surfxml_trace___connect_kind_LINK___AVAIL; +A_simgrid_parse_trace___connect_kind = A_simgrid_parse_trace___connect_kind_LINK___AVAIL; YY_BREAK case 577: /* rule 577 can match eol */ case 578: /* rule 578 can match eol */ YY_RULE_SETUP -A_surfxml_trace___connect_kind = A_surfxml_trace___connect_kind_BANDWIDTH; +A_simgrid_parse_trace___connect_kind = A_simgrid_parse_trace___connect_kind_BANDWIDTH; YY_BREAK case 579: /* rule 579 can match eol */ case 580: /* rule 580 can match eol */ YY_RULE_SETUP -A_surfxml_trace___connect_kind = A_surfxml_trace___connect_kind_LATENCY; +A_simgrid_parse_trace___connect_kind = A_simgrid_parse_trace___connect_kind_LATENCY; YY_BREAK case 581: /* rule 581 can match eol */ YY_RULE_SETUP -if (surfxml_trace___connect_trace_isset != 0) {FAIL("Multiple definition of attribute trace in ");} surfxml_trace___connect_trace_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_trace___connect_trace); +if (simgrid_parse_trace___connect_trace_isset != 0) {FAIL("Multiple definition of attribute trace in ");} simgrid_parse_trace___connect_trace_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_trace___connect_trace); YY_BREAK case 582: /* rule 582 can match eol */ YY_RULE_SETUP -if (surfxml_trace___connect_trace_isset != 0) {FAIL("Multiple definition of attribute trace in ");} surfxml_trace___connect_trace_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_trace___connect_trace); +if (simgrid_parse_trace___connect_trace_isset != 0) {FAIL("Multiple definition of attribute trace in ");} simgrid_parse_trace___connect_trace_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_trace___connect_trace); YY_BREAK case 583: YY_RULE_SETUP { - if (!AX_surfxml_trace___connect_element) FAIL("Required attribute `element' not set for `trace_connect' element."); - if (!AX_surfxml_trace___connect_trace) FAIL("Required attribute `trace' not set for `trace_connect' element."); - LEAVE; STag_surfxml_trace___connect();surfxml_pcdata_ix = 0; ENTER(E_surfxml_trace___connect); + if (!AX_simgrid_parse_trace___connect_element) FAIL("Required attribute `element' not set for `trace_connect' element."); + if (!AX_simgrid_parse_trace___connect_trace) FAIL("Required attribute `trace' not set for `trace_connect' element."); + LEAVE; STag_simgrid_parse_trace___connect();simgrid_parse_pcdata_ix = 0; ENTER(E_simgrid_parse_trace___connect); } YY_BREAK case 584: YY_RULE_SETUP { - if (!AX_surfxml_trace___connect_element) FAIL("Required attribute `element' not set for `trace_connect' element."); - if (!AX_surfxml_trace___connect_trace) FAIL("Required attribute `trace' not set for `trace_connect' element."); - LEAVE; STag_surfxml_trace___connect(); surfxml_pcdata_ix = 0; ETag_surfxml_trace___connect(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_trace___connect_element) FAIL("Required attribute `element' not set for `trace_connect' element."); + if (!AX_simgrid_parse_trace___connect_trace) FAIL("Required attribute `trace' not set for `trace_connect' element."); + LEAVE; STag_simgrid_parse_trace___connect(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_trace___connect(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS_10: case S_surfxml_AS_11: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_7: case S_surfxml_AS_9: SET(S_surfxml_AS_11); break; - case S_surfxml_AS: case S_surfxml_AS_13: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_12: case S_surfxml_AS_14: case S_surfxml_AS_15: case S_surfxml_AS_16: case S_surfxml_AS_1: SET(S_surfxml_AS_16); break; - case S_surfxml_AS_5: SET(S_surfxml_AS_6); break; - case S_surfxml_AS_6: case S_surfxml_AS_8: SET(S_surfxml_AS_9); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_10: case S_surfxml_zone_11: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_7: SET(S_surfxml_zone_11); break; - case S_surfxml_zone_13: case S_surfxml_zone_14: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_12: case S_surfxml_zone_15: case S_surfxml_zone_16: SET(S_surfxml_zone_16); break; - case S_surfxml_zone_5: SET(S_surfxml_zone_6); break; - case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS_10: case S_simgrid_parse_AS_11: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_7: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_11); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS_12: case S_simgrid_parse_AS_15: case S_simgrid_parse_AS_16: SET(S_simgrid_parse_AS_16); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_8: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone_10: case S_simgrid_parse_zone_11: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_7: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_11); break; + case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_12: case S_simgrid_parse_zone_15: case S_simgrid_parse_zone_16: SET(S_simgrid_parse_zone_16); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: SET(S_simgrid_parse_zone_6); break; + case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_8: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -10714,7 +10707,7 @@ case 586: YY_RULE_SETUP FAIL("Bad attribute `%s' in `trace_connect' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_trace___connect): +case YY_STATE_EOF(AL_simgrid_parse_trace___connect): FAIL("EOF in attribute list of `trace_connect' element."); YY_BREAK @@ -10723,21 +10716,21 @@ case 587: YY_RULE_SETUP { LEAVE; - ETag_surfxml_trace___connect(); + ETag_simgrid_parse_trace___connect(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS_10: case S_surfxml_AS_11: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_7: case S_surfxml_AS_9: SET(S_surfxml_AS_11); break; - case S_surfxml_AS: case S_surfxml_AS_13: SET(S_surfxml_AS_14); break; - case S_surfxml_AS_12: case S_surfxml_AS_14: case S_surfxml_AS_15: case S_surfxml_AS_16: case S_surfxml_AS_1: SET(S_surfxml_AS_16); break; - case S_surfxml_AS_5: SET(S_surfxml_AS_6); break; - case S_surfxml_AS_6: case S_surfxml_AS_8: SET(S_surfxml_AS_9); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_10: case S_surfxml_zone_11: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_7: SET(S_surfxml_zone_11); break; - case S_surfxml_zone_13: case S_surfxml_zone_14: SET(S_surfxml_zone_14); break; - case S_surfxml_zone_12: case S_surfxml_zone_15: case S_surfxml_zone_16: SET(S_surfxml_zone_16); break; - case S_surfxml_zone_5: SET(S_surfxml_zone_6); break; - case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS_10: case S_simgrid_parse_AS_11: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_7: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_11); break; + case S_simgrid_parse_AS_13: case S_simgrid_parse_AS_14: case S_simgrid_parse_AS_1: SET(S_simgrid_parse_AS_14); break; + case S_simgrid_parse_AS_12: case S_simgrid_parse_AS_15: case S_simgrid_parse_AS_16: SET(S_simgrid_parse_AS_16); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_8: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone_10: case S_simgrid_parse_zone_11: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_7: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_11); break; + case S_simgrid_parse_zone_13: case S_simgrid_parse_zone_14: SET(S_simgrid_parse_zone_14); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_12: case S_simgrid_parse_zone_15: case S_simgrid_parse_zone_16: SET(S_simgrid_parse_zone_16); break; + case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_5: SET(S_simgrid_parse_zone_6); break; + case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_8: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -10750,7 +10743,7 @@ case 589: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_trace___connect): +case YY_STATE_EOF(E_simgrid_parse_trace___connect): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -10770,53 +10763,53 @@ case 591: /* rule 591 can match eol */ YY_RULE_SETUP { - AX_surfxml_zone_id = 0; - surfxml_zone_id_isset = 0; - AX_surfxml_zone_routing = 0; - surfxml_zone_routing_isset = 0; - ENTER(AL_surfxml_zone); pushbuffer(0); + AX_simgrid_parse_zone_id = 0; + simgrid_parse_zone_id_isset = 0; + AX_simgrid_parse_zone_routing = 0; + simgrid_parse_zone_routing_isset = 0; + ENTER(AL_simgrid_parse_zone); pushbuffer(0); } YY_BREAK case 592: /* rule 592 can match eol */ YY_RULE_SETUP -if (surfxml_zone_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_zone_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_zone_id); +if (simgrid_parse_zone_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_zone_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_zone_id); YY_BREAK case 593: /* rule 593 can match eol */ YY_RULE_SETUP -if (surfxml_zone_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} surfxml_zone_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_zone_id); +if (simgrid_parse_zone_id_isset != 0) {FAIL("Multiple definition of attribute id in ");} simgrid_parse_zone_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_zone_id); YY_BREAK case 594: /* rule 594 can match eol */ YY_RULE_SETUP -if (surfxml_zone_routing_isset != 0) {FAIL("Multiple definition of attribute routing in ");} surfxml_zone_routing_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_zone_routing); +if (simgrid_parse_zone_routing_isset != 0) {FAIL("Multiple definition of attribute routing in ");} simgrid_parse_zone_routing_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_zone_routing); YY_BREAK case 595: /* rule 595 can match eol */ YY_RULE_SETUP -if (surfxml_zone_routing_isset != 0) {FAIL("Multiple definition of attribute routing in ");} surfxml_zone_routing_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_zone_routing); +if (simgrid_parse_zone_routing_isset != 0) {FAIL("Multiple definition of attribute routing in ");} simgrid_parse_zone_routing_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_zone_routing); YY_BREAK case 596: YY_RULE_SETUP { - if (!AX_surfxml_zone_id) FAIL("Required attribute `id' not set for `zone' element."); - if (!AX_surfxml_zone_routing) FAIL("Required attribute `routing' not set for `zone' element."); - LEAVE; STag_surfxml_zone();surfxml_pcdata_ix = 0; ENTER(S_surfxml_zone); + if (!AX_simgrid_parse_zone_id) FAIL("Required attribute `id' not set for `zone' element."); + if (!AX_simgrid_parse_zone_routing) FAIL("Required attribute `routing' not set for `zone' element."); + LEAVE; STag_simgrid_parse_zone();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_zone); } YY_BREAK case 597: YY_RULE_SETUP { - if (!AX_surfxml_zone_id) FAIL("Required attribute `id' not set for `zone' element."); - if (!AX_surfxml_zone_routing) FAIL("Required attribute `routing' not set for `zone' element."); - LEAVE; STag_surfxml_zone(); surfxml_pcdata_ix = 0; ETag_surfxml_zone(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_zone_id) FAIL("Required attribute `id' not set for `zone' element."); + if (!AX_simgrid_parse_zone_routing) FAIL("Required attribute `routing' not set for `zone' element."); + LEAVE; STag_simgrid_parse_zone(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_zone(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -10828,7 +10821,7 @@ case 599: YY_RULE_SETUP FAIL("Bad attribute `%s' in `zone' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_zone): +case YY_STATE_EOF(AL_simgrid_parse_zone): FAIL("EOF in attribute list of `zone' element."); YY_BREAK @@ -10837,13 +10830,13 @@ case 600: YY_RULE_SETUP { LEAVE; - ETag_surfxml_zone(); + ETag_simgrid_parse_zone(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break; - case S_surfxml_include: case S_surfxml_include_1: case S_surfxml_include_2: SET(S_surfxml_include_2); break; - case S_surfxml_platform: case S_surfxml_platform_1: case S_surfxml_platform_3: case S_surfxml_platform_5: case S_surfxml_platform_6: SET(S_surfxml_platform_6); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_5: case S_surfxml_zone_6: SET(S_surfxml_zone_6); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_5: case S_simgrid_parse_AS_6: SET(S_simgrid_parse_AS_6); break; + case S_simgrid_parse_include: case S_simgrid_parse_include_1: case S_simgrid_parse_include_2: SET(S_simgrid_parse_include_2); break; + case S_simgrid_parse_platform: case S_simgrid_parse_platform_1: case S_simgrid_parse_platform_3: case S_simgrid_parse_platform_5: case S_simgrid_parse_platform_6: SET(S_simgrid_parse_platform_6); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_5: case S_simgrid_parse_zone_6: SET(S_simgrid_parse_zone_6); break; } } YY_BREAK @@ -10856,18 +10849,18 @@ case 602: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_zone): -case YY_STATE_EOF(S_surfxml_zone): -case YY_STATE_EOF(S_surfxml_zone_1): -case YY_STATE_EOF(S_surfxml_zone_11): -case YY_STATE_EOF(S_surfxml_zone_12): -case YY_STATE_EOF(S_surfxml_zone_14): -case YY_STATE_EOF(S_surfxml_zone_16): -case YY_STATE_EOF(S_surfxml_zone_3): -case YY_STATE_EOF(S_surfxml_zone_4): -case YY_STATE_EOF(S_surfxml_zone_6): -case YY_STATE_EOF(S_surfxml_zone_7): -case YY_STATE_EOF(S_surfxml_zone_9): +case YY_STATE_EOF(E_simgrid_parse_zone): +case YY_STATE_EOF(S_simgrid_parse_zone): +case YY_STATE_EOF(S_simgrid_parse_zone_1): +case YY_STATE_EOF(S_simgrid_parse_zone_11): +case YY_STATE_EOF(S_simgrid_parse_zone_12): +case YY_STATE_EOF(S_simgrid_parse_zone_14): +case YY_STATE_EOF(S_simgrid_parse_zone_16): +case YY_STATE_EOF(S_simgrid_parse_zone_3): +case YY_STATE_EOF(S_simgrid_parse_zone_4): +case YY_STATE_EOF(S_simgrid_parse_zone_6): +case YY_STATE_EOF(S_simgrid_parse_zone_7): +case YY_STATE_EOF(S_simgrid_parse_zone_9): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -10880,109 +10873,109 @@ case 604: /* rule 604 can match eol */ YY_RULE_SETUP { - AX_surfxml_zoneRoute_dst = 0; - surfxml_zoneRoute_dst_isset = 0; - AX_surfxml_zoneRoute_gw___dst = 0; - surfxml_zoneRoute_gw___dst_isset = 0; - AX_surfxml_zoneRoute_gw___src = 0; - surfxml_zoneRoute_gw___src_isset = 0; - AX_surfxml_zoneRoute_src = 0; - surfxml_zoneRoute_src_isset = 0; - AX_surfxml_zoneRoute_symmetrical = A_surfxml_zoneRoute_symmetrical_YES; - surfxml_zoneRoute_symmetrical_isset = 0; - ENTER(AL_surfxml_zoneRoute); pushbuffer(0); + AX_simgrid_parse_zoneRoute_dst = 0; + simgrid_parse_zoneRoute_dst_isset = 0; + AX_simgrid_parse_zoneRoute_gw___dst = 0; + simgrid_parse_zoneRoute_gw___dst_isset = 0; + AX_simgrid_parse_zoneRoute_gw___src = 0; + simgrid_parse_zoneRoute_gw___src_isset = 0; + AX_simgrid_parse_zoneRoute_src = 0; + simgrid_parse_zoneRoute_src_isset = 0; + AX_simgrid_parse_zoneRoute_symmetrical = A_simgrid_parse_zoneRoute_symmetrical_YES; + simgrid_parse_zoneRoute_symmetrical_isset = 0; + ENTER(AL_simgrid_parse_zoneRoute); pushbuffer(0); } YY_BREAK case 605: /* rule 605 can match eol */ YY_RULE_SETUP -if (surfxml_zoneRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_zoneRoute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_zoneRoute_dst); +if (simgrid_parse_zoneRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_zoneRoute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_zoneRoute_dst); YY_BREAK case 606: /* rule 606 can match eol */ YY_RULE_SETUP -if (surfxml_zoneRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} surfxml_zoneRoute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_zoneRoute_dst); +if (simgrid_parse_zoneRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in ");} simgrid_parse_zoneRoute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_zoneRoute_dst); YY_BREAK case 607: /* rule 607 can match eol */ YY_RULE_SETUP -if (surfxml_zoneRoute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} surfxml_zoneRoute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_zoneRoute_gw___dst); +if (simgrid_parse_zoneRoute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} simgrid_parse_zoneRoute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_zoneRoute_gw___dst); YY_BREAK case 608: /* rule 608 can match eol */ YY_RULE_SETUP -if (surfxml_zoneRoute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} surfxml_zoneRoute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_zoneRoute_gw___dst); +if (simgrid_parse_zoneRoute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in ");} simgrid_parse_zoneRoute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_zoneRoute_gw___dst); YY_BREAK case 609: /* rule 609 can match eol */ YY_RULE_SETUP -if (surfxml_zoneRoute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} surfxml_zoneRoute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_zoneRoute_gw___src); +if (simgrid_parse_zoneRoute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} simgrid_parse_zoneRoute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_zoneRoute_gw___src); YY_BREAK case 610: /* rule 610 can match eol */ YY_RULE_SETUP -if (surfxml_zoneRoute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} surfxml_zoneRoute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_zoneRoute_gw___src); +if (simgrid_parse_zoneRoute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in ");} simgrid_parse_zoneRoute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_zoneRoute_gw___src); YY_BREAK case 611: /* rule 611 can match eol */ YY_RULE_SETUP -if (surfxml_zoneRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_zoneRoute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_zoneRoute_src); +if (simgrid_parse_zoneRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_zoneRoute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_simgrid_parse_zoneRoute_src); YY_BREAK case 612: /* rule 612 can match eol */ YY_RULE_SETUP -if (surfxml_zoneRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} surfxml_zoneRoute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_zoneRoute_src); +if (simgrid_parse_zoneRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in ");} simgrid_parse_zoneRoute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_simgrid_parse_zoneRoute_src); YY_BREAK case 613: /* rule 613 can match eol */ case 614: /* rule 614 can match eol */ YY_RULE_SETUP -A_surfxml_zoneRoute_symmetrical = A_surfxml_zoneRoute_symmetrical_YES; +A_simgrid_parse_zoneRoute_symmetrical = A_simgrid_parse_zoneRoute_symmetrical_YES; YY_BREAK case 615: /* rule 615 can match eol */ case 616: /* rule 616 can match eol */ YY_RULE_SETUP -A_surfxml_zoneRoute_symmetrical = A_surfxml_zoneRoute_symmetrical_NO; +A_simgrid_parse_zoneRoute_symmetrical = A_simgrid_parse_zoneRoute_symmetrical_NO; YY_BREAK case 617: /* rule 617 can match eol */ case 618: /* rule 618 can match eol */ YY_RULE_SETUP -A_surfxml_zoneRoute_symmetrical = A_surfxml_zoneRoute_symmetrical_yes; +A_simgrid_parse_zoneRoute_symmetrical = A_simgrid_parse_zoneRoute_symmetrical_yes; YY_BREAK case 619: /* rule 619 can match eol */ case 620: /* rule 620 can match eol */ YY_RULE_SETUP -A_surfxml_zoneRoute_symmetrical = A_surfxml_zoneRoute_symmetrical_no; +A_simgrid_parse_zoneRoute_symmetrical = A_simgrid_parse_zoneRoute_symmetrical_no; YY_BREAK case 621: YY_RULE_SETUP { - if (!AX_surfxml_zoneRoute_dst) FAIL("Required attribute `dst' not set for `zoneRoute' element."); - if (!AX_surfxml_zoneRoute_gw___dst) FAIL("Required attribute `gw_dst' not set for `zoneRoute' element."); - if (!AX_surfxml_zoneRoute_gw___src) FAIL("Required attribute `gw_src' not set for `zoneRoute' element."); - if (!AX_surfxml_zoneRoute_src) FAIL("Required attribute `src' not set for `zoneRoute' element."); - LEAVE; STag_surfxml_zoneRoute();surfxml_pcdata_ix = 0; ENTER(S_surfxml_zoneRoute); + if (!AX_simgrid_parse_zoneRoute_dst) FAIL("Required attribute `dst' not set for `zoneRoute' element."); + if (!AX_simgrid_parse_zoneRoute_gw___dst) FAIL("Required attribute `gw_dst' not set for `zoneRoute' element."); + if (!AX_simgrid_parse_zoneRoute_gw___src) FAIL("Required attribute `gw_src' not set for `zoneRoute' element."); + if (!AX_simgrid_parse_zoneRoute_src) FAIL("Required attribute `src' not set for `zoneRoute' element."); + LEAVE; STag_simgrid_parse_zoneRoute();simgrid_parse_pcdata_ix = 0; ENTER(S_simgrid_parse_zoneRoute); } YY_BREAK case 622: YY_RULE_SETUP { - if (!AX_surfxml_zoneRoute_dst) FAIL("Required attribute `dst' not set for `zoneRoute' element."); - if (!AX_surfxml_zoneRoute_gw___dst) FAIL("Required attribute `gw_dst' not set for `zoneRoute' element."); - if (!AX_surfxml_zoneRoute_gw___src) FAIL("Required attribute `gw_src' not set for `zoneRoute' element."); - if (!AX_surfxml_zoneRoute_src) FAIL("Required attribute `src' not set for `zoneRoute' element."); - LEAVE; STag_surfxml_zoneRoute(); surfxml_pcdata_ix = 0; ETag_surfxml_zoneRoute(); popbuffer(); /* attribute */ + if (!AX_simgrid_parse_zoneRoute_dst) FAIL("Required attribute `dst' not set for `zoneRoute' element."); + if (!AX_simgrid_parse_zoneRoute_gw___dst) FAIL("Required attribute `gw_dst' not set for `zoneRoute' element."); + if (!AX_simgrid_parse_zoneRoute_gw___src) FAIL("Required attribute `gw_src' not set for `zoneRoute' element."); + if (!AX_simgrid_parse_zoneRoute_src) FAIL("Required attribute `src' not set for `zoneRoute' element."); + LEAVE; STag_simgrid_parse_zoneRoute(); simgrid_parse_pcdata_ix = 0; ETag_simgrid_parse_zoneRoute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_8: case S_surfxml_AS_9: SET(S_surfxml_AS_9); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_8: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_8: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -10994,7 +10987,7 @@ case 624: YY_RULE_SETUP FAIL("Bad attribute `%s' in `zoneRoute' element start tag.",yytext); YY_BREAK -case YY_STATE_EOF(AL_surfxml_zoneRoute): +case YY_STATE_EOF(AL_simgrid_parse_zoneRoute): FAIL("EOF in attribute list of `zoneRoute' element."); YY_BREAK @@ -11003,11 +10996,11 @@ case 625: YY_RULE_SETUP { LEAVE; - ETag_surfxml_zoneRoute(); + ETag_simgrid_parse_zoneRoute(); popbuffer(); /* attribute */ switch (YY_START) { - case S_surfxml_AS: case S_surfxml_AS_1: case S_surfxml_AS_3: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_8: case S_surfxml_AS_9: SET(S_surfxml_AS_9); break; - case S_surfxml_zone: case S_surfxml_zone_1: case S_surfxml_zone_3: case S_surfxml_zone_4: case S_surfxml_zone_6: case S_surfxml_zone_8: case S_surfxml_zone_9: SET(S_surfxml_zone_9); break; + case S_simgrid_parse_AS: case S_simgrid_parse_AS_1: case S_simgrid_parse_AS_3: case S_simgrid_parse_AS_4: case S_simgrid_parse_AS_6: case S_simgrid_parse_AS_8: case S_simgrid_parse_AS_9: SET(S_simgrid_parse_AS_9); break; + case S_simgrid_parse_zone: case S_simgrid_parse_zone_1: case S_simgrid_parse_zone_3: case S_simgrid_parse_zone_4: case S_simgrid_parse_zone_6: case S_simgrid_parse_zone_8: case S_simgrid_parse_zone_9: SET(S_simgrid_parse_zone_9); break; } } YY_BREAK @@ -11020,9 +11013,9 @@ case 627: YY_RULE_SETUP FAIL("Unexpected character `%c': `' expected.",yytext[0]); YY_BREAK -case YY_STATE_EOF(E_surfxml_zoneRoute): -case YY_STATE_EOF(S_surfxml_zoneRoute): -case YY_STATE_EOF(S_surfxml_zoneRoute_2): +case YY_STATE_EOF(E_simgrid_parse_zoneRoute): +case YY_STATE_EOF(S_simgrid_parse_zoneRoute): +case YY_STATE_EOF(S_simgrid_parse_zoneRoute_2): FAIL("Premature EOF: `' expected."); YY_BREAK @@ -11144,38 +11137,38 @@ YY_RULE_SETUP ECHO; YY_BREAK case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(S_surfxml_AS_2): -case YY_STATE_EOF(S_surfxml_AS_5): -case YY_STATE_EOF(S_surfxml_AS_8): -case YY_STATE_EOF(S_surfxml_AS_10): -case YY_STATE_EOF(S_surfxml_AS_13): -case YY_STATE_EOF(S_surfxml_AS_15): -case YY_STATE_EOF(S_surfxml_ASroute_1): -case YY_STATE_EOF(S_surfxml_actor_1): -case YY_STATE_EOF(S_surfxml_bypassASroute_1): -case YY_STATE_EOF(S_surfxml_bypassRoute_1): -case YY_STATE_EOF(S_surfxml_bypassZoneRoute_1): -case YY_STATE_EOF(S_surfxml_cluster_1): -case YY_STATE_EOF(S_surfxml_config_1): -case YY_STATE_EOF(S_surfxml_disk_1): -case YY_STATE_EOF(S_surfxml_host_1): -case YY_STATE_EOF(S_surfxml_include_1): -case YY_STATE_EOF(S_surfxml_link_1): -case YY_STATE_EOF(ROOT_surfxml_platform): -case YY_STATE_EOF(S_surfxml_platform_2): -case YY_STATE_EOF(S_surfxml_platform_5): -case YY_STATE_EOF(S_surfxml_platform_7): -case YY_STATE_EOF(S_surfxml_process_1): -case YY_STATE_EOF(S_surfxml_route_1): -case YY_STATE_EOF(S_surfxml_storage_1): -case YY_STATE_EOF(S_surfxml_storage___type_1): -case YY_STATE_EOF(S_surfxml_zone_2): -case YY_STATE_EOF(S_surfxml_zone_5): -case YY_STATE_EOF(S_surfxml_zone_8): -case YY_STATE_EOF(S_surfxml_zone_10): -case YY_STATE_EOF(S_surfxml_zone_13): -case YY_STATE_EOF(S_surfxml_zone_15): -case YY_STATE_EOF(S_surfxml_zoneRoute_1): +case YY_STATE_EOF(S_simgrid_parse_AS_2): +case YY_STATE_EOF(S_simgrid_parse_AS_5): +case YY_STATE_EOF(S_simgrid_parse_AS_8): +case YY_STATE_EOF(S_simgrid_parse_AS_10): +case YY_STATE_EOF(S_simgrid_parse_AS_13): +case YY_STATE_EOF(S_simgrid_parse_AS_15): +case YY_STATE_EOF(S_simgrid_parse_ASroute_1): +case YY_STATE_EOF(S_simgrid_parse_actor_1): +case YY_STATE_EOF(S_simgrid_parse_bypassASroute_1): +case YY_STATE_EOF(S_simgrid_parse_bypassRoute_1): +case YY_STATE_EOF(S_simgrid_parse_bypassZoneRoute_1): +case YY_STATE_EOF(S_simgrid_parse_cluster_1): +case YY_STATE_EOF(S_simgrid_parse_config_1): +case YY_STATE_EOF(S_simgrid_parse_disk_1): +case YY_STATE_EOF(S_simgrid_parse_host_1): +case YY_STATE_EOF(S_simgrid_parse_include_1): +case YY_STATE_EOF(S_simgrid_parse_link_1): +case YY_STATE_EOF(ROOT_simgrid_parse_platform): +case YY_STATE_EOF(S_simgrid_parse_platform_2): +case YY_STATE_EOF(S_simgrid_parse_platform_5): +case YY_STATE_EOF(S_simgrid_parse_platform_7): +case YY_STATE_EOF(S_simgrid_parse_process_1): +case YY_STATE_EOF(S_simgrid_parse_route_1): +case YY_STATE_EOF(S_simgrid_parse_storage_1): +case YY_STATE_EOF(S_simgrid_parse_storage___type_1): +case YY_STATE_EOF(S_simgrid_parse_zone_2): +case YY_STATE_EOF(S_simgrid_parse_zone_5): +case YY_STATE_EOF(S_simgrid_parse_zone_8): +case YY_STATE_EOF(S_simgrid_parse_zone_10): +case YY_STATE_EOF(S_simgrid_parse_zone_13): +case YY_STATE_EOF(S_simgrid_parse_zone_15): +case YY_STATE_EOF(S_simgrid_parse_zoneRoute_1): case YY_STATE_EOF(IMPOSSIBLE): yyterminate(); @@ -12193,7 +12186,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" /* Element context stack lookup. */ -int surfxml_element_context(int i) +int simgrid_parse_element_context(int i) { return (0 address, - ReadOptions options = ReadOptions::none()) const = 0; - - /** Read a given data structure from the address space */ - template inline void read(T* buffer, RemotePtr ptr) const { this->read_bytes(buffer, sizeof(T), ptr); } - - template inline void read(Remote& buffer, RemotePtr ptr) const - { - this->read_bytes(buffer.get_buffer(), sizeof(T), ptr); - } - - /** Read a given data structure from the address space - * - * This version returns by value. - */ - template inline Remote read(RemotePtr ptr) const - { - Remote res; - this->read_bytes(&res, sizeof(T), ptr); - return res; - } - - /** Read a string of known size */ - std::string read_string(RemotePtr address, std::size_t len) const - { - std::string res; - res.resize(len); - this->read_bytes(&res[0], len, address); - return res; - } -}; - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/ModelChecker.cpp b/src/mc/ModelChecker.cpp deleted file mode 100644 index 1e3c2be931..0000000000 --- a/src/mc/ModelChecker.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/ModelChecker.hpp" -#include "src/mc/explo/Exploration.hpp" -#include "src/mc/mc_config.hpp" -#include "src/mc/mc_exit.hpp" -#include "src/mc/mc_private.hpp" -#include "src/mc/remote/RemoteProcess.hpp" -#include "src/mc/transition/TransitionComm.hpp" -#include "xbt/automaton.hpp" -#include "xbt/system_error.hpp" - -#include -#include -#include -#include - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_ModelChecker, mc, "ModelChecker"); - -::simgrid::mc::ModelChecker* mc_model_checker = nullptr; - -#ifdef __linux__ -# define WAITPID_CHECKED_FLAGS __WALL -#else -# define WAITPID_CHECKED_FLAGS 0 -#endif - -namespace simgrid::mc { - -ModelChecker::ModelChecker(std::unique_ptr remote_simulation, int sockfd) - : checker_side_(sockfd), remote_process_(std::move(remote_simulation)) -{ -} - -void ModelChecker::start() -{ - checker_side_.start( - [](evutil_socket_t sig, short events, void* arg) { - auto mc = static_cast(arg); - if (events == EV_READ) { - std::array buffer; - ssize_t size = mc->checker_side_.get_channel().receive(buffer.data(), buffer.size(), false); - if (size == -1 && errno != EAGAIN) - throw simgrid::xbt::errno_error(); - - if (not mc->handle_message(buffer.data(), size)) - mc->checker_side_.break_loop(); - } else if (events == EV_SIGNAL) { - if (sig == SIGCHLD) - mc->handle_waitpid(); - } else { - xbt_die("Unexpected event"); - } - }, - this); - - XBT_DEBUG("Waiting for the model-checked process"); - int status; - - // The model-checked process SIGSTOP itself to signal it's ready: - const pid_t pid = remote_process_->pid(); - - xbt_assert(waitpid(pid, &status, WAITPID_CHECKED_FLAGS) == pid && WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP, - "Could not wait model-checked process"); - - if (not _sg_mc_dot_output_file.get().empty()) - MC_init_dot_output(); - - setup_ignore(); - - errno = 0; -#ifdef __linux__ - ptrace(PTRACE_SETOPTIONS, pid, nullptr, PTRACE_O_TRACEEXIT); - ptrace(PTRACE_CONT, pid, 0, 0); -#elif defined BSD - ptrace(PT_CONTINUE, pid, (caddr_t)1, 0); -#else -# error "no ptrace equivalent coded for this platform" -#endif - xbt_assert(errno == 0, - "Ptrace does not seem to be usable in your setup (errno: %d). " - "If you run from within a docker, adding `--cap-add SYS_PTRACE` to the docker line may help. " - "If it does not help, please report this bug.", - errno); -} - -static constexpr auto ignored_local_variables = { - std::make_pair("e", "*"), - std::make_pair("_log_ev", "*"), - - /* Ignore local variable about time used for tracing */ - std::make_pair("start_time", "*"), -}; - -void ModelChecker::setup_ignore() -{ - const RemoteProcess& process = this->get_remote_process(); - for (auto const& [var, frame] : ignored_local_variables) - process.ignore_local_variable(var, frame); - - /* Static variable used for tracing */ - process.ignore_global_variable("counter"); -} - -void ModelChecker::shutdown() -{ - XBT_DEBUG("Shutting down model-checker"); - - RemoteProcess& process = get_remote_process(); - if (process.running()) { - XBT_DEBUG("Killing process"); - finalize_app(true); - kill(process.pid(), SIGKILL); - process.terminate(); - } -} - -void ModelChecker::resume() -{ - if (checker_side_.get_channel().send(MessageType::CONTINUE) != 0) - throw xbt::errno_error(); - remote_process_->clear_cache(); -} - -static void MC_report_crash(int status) -{ - XBT_INFO("**************************"); - XBT_INFO("** CRASH IN THE PROGRAM **"); - XBT_INFO("**************************"); - if (WIFSIGNALED(status)) - XBT_INFO("From signal: %s", strsignal(WTERMSIG(status))); - else if (WIFEXITED(status)) - XBT_INFO("From exit: %i", WEXITSTATUS(status)); - if (not xbt_log_no_loc) - XBT_INFO("%s core dump was generated by the system.", WCOREDUMP(status) ? "A" : "No"); - if (mc_model_checker->get_exploration()) { - XBT_INFO("Counter-example execution trace:"); - for (auto const& s : mc_model_checker->get_exploration()->get_textual_trace()) - XBT_INFO(" %s", s.c_str()); - XBT_INFO("Path = %s", mc_model_checker->get_exploration()->get_record_trace().to_string().c_str()); - Api::get().get_session().log_state(); - if (xbt_log_no_loc) { - XBT_INFO("Stack trace not displayed because you passed --log=no_loc"); - } else { - XBT_INFO("Stack trace:"); - mc_model_checker->get_remote_process().dump_stack(); - } - } -} - -bool ModelChecker::handle_message(const char* buffer, ssize_t size) -{ - s_mc_message_t base_message; - xbt_assert(size >= (ssize_t)sizeof(base_message), "Broken message"); - memcpy(&base_message, buffer, sizeof(base_message)); - - switch(base_message.type) { - case MessageType::INITIAL_ADDRESSES: { - s_mc_message_initial_addresses_t message; - xbt_assert(size == sizeof(message), "Broken message. Got %d bytes instead of %d.", (int)size, (int)sizeof(message)); - memcpy(&message, buffer, sizeof(message)); - - get_remote_process().init(message.mmalloc_default_mdp, message.maxpid, message.actors); - break; - } - - case MessageType::IGNORE_HEAP: { - s_mc_message_ignore_heap_t message; - xbt_assert(size == sizeof(message), "Broken message"); - memcpy(&message, buffer, sizeof(message)); - - IgnoredHeapRegion region; - region.block = message.block; - region.fragment = message.fragment; - region.address = message.address; - region.size = message.size; - get_remote_process().ignore_heap(region); - break; - } - - case MessageType::UNIGNORE_HEAP: { - s_mc_message_ignore_memory_t message; - xbt_assert(size == sizeof(message), "Broken message"); - memcpy(&message, buffer, sizeof(message)); - get_remote_process().unignore_heap((void*)(std::uintptr_t)message.addr, message.size); - break; - } - - case MessageType::IGNORE_MEMORY: { - s_mc_message_ignore_memory_t message; - xbt_assert(size == sizeof(message), "Broken message"); - memcpy(&message, buffer, sizeof(message)); - this->get_remote_process().ignore_region(message.addr, message.size); - break; - } - - case MessageType::STACK_REGION: { - s_mc_message_stack_region_t message; - xbt_assert(size == sizeof(message), "Broken message"); - memcpy(&message, buffer, sizeof(message)); - this->get_remote_process().stack_areas().push_back(message.stack_region); - } break; - - case MessageType::REGISTER_SYMBOL: { - s_mc_message_register_symbol_t message; - xbt_assert(size == sizeof(message), "Broken message"); - memcpy(&message, buffer, sizeof(message)); - xbt_assert(not message.callback, "Support for client-side function proposition is not implemented."); - XBT_DEBUG("Received symbol: %s", message.name.data()); - - if (property_automaton == nullptr) - property_automaton = xbt_automaton_new(); - - const RemoteProcess* process = &this->get_remote_process(); - RemotePtr address = remote((int*)message.data); - xbt::add_proposition(property_automaton, message.name.data(), - [process, address]() { return process->read(address); }); - - break; - } - - case MessageType::WAITING: - return false; - - case MessageType::ASSERTION_FAILED: - XBT_INFO("**************************"); - XBT_INFO("*** PROPERTY NOT VALID ***"); - XBT_INFO("**************************"); - XBT_INFO("Counter-example execution trace:"); - for (auto const& s : get_exploration()->get_textual_trace()) - XBT_INFO(" %s", s.c_str()); - XBT_INFO("Path = %s", get_exploration()->get_record_trace().to_string().c_str()); - Api::get().get_session().log_state(); - - this->exit(SIMGRID_MC_EXIT_SAFETY); - - default: - xbt_die("Unexpected message from model-checked application"); - } - return true; -} - -/** Terminate the model-checker application */ -void ModelChecker::exit(int status) -{ - shutdown(); - ::exit(status); -} - -void ModelChecker::handle_waitpid() -{ - XBT_DEBUG("Check for wait event"); - int status; - pid_t pid; - while ((pid = waitpid(-1, &status, WNOHANG)) != 0) { - if (pid == -1) { - if (errno == ECHILD) { - // No more children: - xbt_assert(not this->get_remote_process().running(), "Inconsistent state"); - break; - } else { - XBT_ERROR("Could not wait for pid"); - throw simgrid::xbt::errno_error(); - } - } - - if (pid == this->get_remote_process().pid()) { - // From PTRACE_O_TRACEEXIT: -#ifdef __linux__ - if (status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))) { - xbt_assert(ptrace(PTRACE_GETEVENTMSG, remote_process_->pid(), 0, &status) != -1, "Could not get exit status"); - if (WIFSIGNALED(status)) { - MC_report_crash(status); - this->get_remote_process().terminate(); - this->exit(SIMGRID_MC_EXIT_PROGRAM_CRASH); - } - } -#endif - - // We don't care about signals, just reinject them: - if (WIFSTOPPED(status)) { - XBT_DEBUG("Stopped with signal %i", (int) WSTOPSIG(status)); - errno = 0; -#ifdef __linux__ - ptrace(PTRACE_CONT, remote_process_->pid(), 0, WSTOPSIG(status)); -#elif defined BSD - ptrace(PT_CONTINUE, remote_process_->pid(), (caddr_t)1, WSTOPSIG(status)); -#endif - xbt_assert(errno == 0, "Could not PTRACE_CONT"); - } - - else if (WIFSIGNALED(status)) { - MC_report_crash(status); - this->get_remote_process().terminate(); - this->exit(SIMGRID_MC_EXIT_PROGRAM_CRASH); - } else if (WIFEXITED(status)) { - XBT_DEBUG("Child process is over"); - this->get_remote_process().terminate(); - } - } - } -} - -void ModelChecker::wait_for_requests() -{ - this->resume(); - if (this->get_remote_process().running()) - checker_side_.dispatch(); -} - -Transition* ModelChecker::handle_simcall(aid_t aid, int times_considered, bool new_transition) -{ - s_mc_message_simcall_execute_t m; - memset(&m, 0, sizeof(m)); - m.type = MessageType::SIMCALL_EXECUTE; - m.aid_ = aid; - m.times_considered_ = times_considered; - checker_side_.get_channel().send(m); - - this->remote_process_->clear_cache(); - if (this->remote_process_->running()) - checker_side_.dispatch(); // The app may send messages while processing the transition - - s_mc_message_simcall_execute_answer_t answer; - ssize_t s = checker_side_.get_channel().receive(answer); - xbt_assert(s != -1, "Could not receive message"); - xbt_assert(s == sizeof(answer) && answer.type == MessageType::SIMCALL_EXECUTE_ANSWER, - "Received unexpected message %s (%i, size=%i) " - "expected MessageType::SIMCALL_EXECUTE_ANSWER (%i, size=%i)", - to_c_str(answer.type), (int)answer.type, (int)s, (int)MessageType::SIMCALL_EXECUTE_ANSWER, - (int)sizeof(answer)); - - if (new_transition) { - std::stringstream stream(answer.buffer.data()); - return deserialize_transition(aid, times_considered, stream); - } else - return nullptr; -} - -void ModelChecker::finalize_app(bool terminate_asap) -{ - s_mc_message_int_t m; - memset(&m, 0, sizeof m); - m.type = MessageType::FINALIZE; - m.value = terminate_asap; - xbt_assert(checker_side_.get_channel().send(m) == 0, "Could not ask the app to finalize on need"); - - s_mc_message_t answer; - xbt_assert(checker_side_.get_channel().receive(answer) != -1, "Could not receive answer to FINALIZE"); -} - -} // namespace simgrid::mc diff --git a/src/mc/ModelChecker.hpp b/src/mc/ModelChecker.hpp deleted file mode 100644 index c4b189435e..0000000000 --- a/src/mc/ModelChecker.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_MODEL_CHECKER_HPP -#define SIMGRID_MC_MODEL_CHECKER_HPP - -#include "src/mc/remote/CheckerSide.hpp" -#include "src/mc/remote/RemotePtr.hpp" -#include "src/mc/sosp/PageStore.hpp" -#include "xbt/base.h" -#include "xbt/string.hpp" - -#include -#include - -namespace simgrid::mc { - -/** State of the model-checker (global variables for the model checker) - */ -class ModelChecker { - CheckerSide checker_side_; - /** String pool for host names */ - std::set> hostnames_; - // This is the parent snapshot of the current state: - PageStore page_store_{500}; - std::unique_ptr remote_process_; - Exploration* exploration_ = nullptr; - - unsigned long visited_states_ = 0; - - // Expect MessageType::SIMCALL_TO_STRING or MessageType::SIMCALL_DOT_LABEL - std::string simcall_to_string(MessageType type, aid_t aid, int times_considered); - -public: - ModelChecker(ModelChecker const&) = delete; - ModelChecker& operator=(ModelChecker const&) = delete; - explicit ModelChecker(std::unique_ptr remote_simulation, int sockfd); - - RemoteProcess& get_remote_process() { return *remote_process_; } - Channel& channel() { return checker_side_.get_channel(); } - PageStore& page_store() { return page_store_; } - - xbt::string const& get_host_name(const char* hostname) - { - return *this->hostnames_.insert(xbt::string(hostname)).first; - } - - void start(); - void shutdown(); - void resume(); - void wait_for_requests(); - - /** Let the application take a transition. A new Transition is created iff the last parameter is true */ - Transition* handle_simcall(aid_t aid, int times_considered, bool new_transition); - - /* Interactions with the simcall observer */ - XBT_ATTRIB_NORETURN void exit(int status); - - void finalize_app(bool terminate_asap = false); - - Exploration* get_exploration() const { return exploration_; } - void set_exploration(Exploration* exploration) { exploration_ = exploration; } - - unsigned long get_visited_states() const { return visited_states_; } - void inc_visited_states() { visited_states_++; } - -private: - void setup_ignore(); - bool handle_message(const char* buffer, ssize_t size); - void handle_waitpid(); -}; - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/Session.cpp b/src/mc/Session.cpp deleted file mode 100644 index 7b4e357109..0000000000 --- a/src/mc/Session.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/Session.hpp" -#include "src/internal_config.h" // HAVE_SMPI -#include "src/mc/explo/Exploration.hpp" -#include "src/mc/mc_config.hpp" -#if HAVE_SMPI -#include "smpi/smpi.h" -#include "src/smpi/include/private.hpp" -#endif -#include "src/mc/api/State.hpp" -#include "src/mc/mc_exit.hpp" -#include "src/mc/mc_private.hpp" -#include "xbt/log.h" -#include "xbt/system_error.hpp" - -#include "signal.h" -#include -#include -#include - -#include -#ifdef __linux__ -#include -#endif - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_Session, mc, "Model-checker session"); -XBT_LOG_EXTERNAL_CATEGORY(mc_global); - -namespace simgrid::mc { - -template void run_child_process(int socket, Code code) -{ - /* On startup, simix_global_init() calls simgrid::mc::Client::initialize(), which checks whether the MC_ENV_SOCKET_FD - * env variable is set. If so, MC mode is assumed, and the client is setup from its side - */ - -#ifdef __linux__ - // Make sure we do not outlive our parent - sigset_t mask; - sigemptyset (&mask); - xbt_assert(sigprocmask(SIG_SETMASK, &mask, nullptr) >= 0, "Could not unblock signals"); - xbt_assert(prctl(PR_SET_PDEATHSIG, SIGHUP) == 0, "Could not PR_SET_PDEATHSIG"); -#endif - - // Remove CLOEXEC to pass the socket to the application - int fdflags = fcntl(socket, F_GETFD, 0); - xbt_assert(fdflags != -1 && fcntl(socket, F_SETFD, fdflags & ~FD_CLOEXEC) != -1, - "Could not remove CLOEXEC for socket"); - - // Disable lazy relocation in the model-checked process to prevent the application from - // modifying its .got.plt during snapshot. - setenv("LC_BIND_NOW", "1", 1); - - setenv(MC_ENV_SOCKET_FD, std::to_string(socket).c_str(), 1); - - code(); -} - -Session::Session(const std::function& code) -{ -#if HAVE_SMPI - smpi_init_options();//only performed once - xbt_assert(smpi_cfg_privatization() != SmpiPrivStrategies::MMAP, - "Please use the dlopen privatization schema when model-checking SMPI code"); -#endif - - // Create an AF_LOCAL socketpair used for exchanging messages - // between the model-checker process (ourselves) and the model-checked - // process: - int sockets[2]; - xbt_assert(socketpair(AF_LOCAL, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockets) != -1, "Could not create socketpair"); - - pid_t pid = fork(); - xbt_assert(pid >= 0, "Could not fork model-checked process"); - - if (pid == 0) { // Child - ::close(sockets[1]); - run_child_process(sockets[0], code); - DIE_IMPOSSIBLE; - } - - // Parent (model-checker): - ::close(sockets[0]); - - xbt_assert(mc_model_checker == nullptr, "Did you manage to start the MC twice in this process?"); - - auto process = std::make_unique(pid); - model_checker_ = std::make_unique(std::move(process), sockets[1]); - - mc_model_checker = model_checker_.get(); - model_checker_->start(); -} - -Session::~Session() -{ - this->close(); -} - -/** The application must be stopped. */ -void Session::take_initial_snapshot() -{ - xbt_assert(initial_snapshot_ == nullptr); - model_checker_->wait_for_requests(); - initial_snapshot_ = std::make_shared(0); -} - -void Session::restore_initial_state() const -{ - this->initial_snapshot_->restore(&model_checker_->get_remote_process()); -} - -void Session::log_state() const -{ - model_checker_->get_exploration()->log_state(); - - if (not _sg_mc_dot_output_file.get().empty()) { - fprintf(dot_output, "}\n"); - fclose(dot_output); - } - if (getenv("SIMGRID_MC_SYSTEM_STATISTICS")){ - int ret=system("free"); - if (ret != 0) - XBT_WARN("Call to system(free) did not return 0, but %d", ret); - } -} - -void Session::close() -{ - initial_snapshot_ = nullptr; - if (model_checker_) { - model_checker_->shutdown(); - model_checker_ = nullptr; - mc_model_checker = nullptr; - } -} - -bool Session::actor_is_enabled(aid_t pid) const -{ - s_mc_message_actor_enabled_t msg; - memset(&msg, 0, sizeof msg); - msg.type = simgrid::mc::MessageType::ACTOR_ENABLED; - msg.aid = pid; - model_checker_->channel().send(msg); - std::array buff; - ssize_t received = model_checker_->channel().receive(buff.data(), buff.size(), true); - xbt_assert(received == sizeof(s_mc_message_int_t), "Unexpected size in answer to ACTOR_ENABLED"); - return ((s_mc_message_int_t*)buff.data())->value; -} - -void Session::check_deadlock() const -{ - xbt_assert(model_checker_->channel().send(MessageType::DEADLOCK_CHECK) == 0, "Could not check deadlock state"); - s_mc_message_int_t message; - ssize_t s = model_checker_->channel().receive(message); - xbt_assert(s != -1, "Could not receive message"); - xbt_assert(s == sizeof(message) && message.type == MessageType::DEADLOCK_CHECK_REPLY, - "Received unexpected message %s (%i, size=%i) " - "expected MessageType::DEADLOCK_CHECK_REPLY (%i, size=%i)", - to_c_str(message.type), (int)message.type, (int)s, (int)MessageType::DEADLOCK_CHECK_REPLY, - (int)sizeof(message)); - - if (message.value != 0) { - XBT_CINFO(mc_global, "**************************"); - XBT_CINFO(mc_global, "*** DEADLOCK DETECTED ***"); - XBT_CINFO(mc_global, "**************************"); - XBT_CINFO(mc_global, "Counter-example execution trace:"); - for (auto const& frame : model_checker_->get_exploration()->get_textual_trace()) - XBT_CINFO(mc_global, " %s", frame.c_str()); - XBT_CINFO(mc_global, "Path = %s", model_checker_->get_exploration()->get_record_trace().to_string().c_str()); - log_state(); - throw DeadlockError(); - } -} -} // namespace simgrid::mc diff --git a/src/mc/Session.hpp b/src/mc/Session.hpp deleted file mode 100644 index b84e6fec73..0000000000 --- a/src/mc/Session.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_SESSION_HPP -#define SIMGRID_MC_SESSION_HPP - -#include "simgrid/forward.h" -#include "src/mc/ModelChecker.hpp" -#include "src/mc/remote/RemotePtr.hpp" - -#include - -namespace simgrid::mc { - -/** A model-checking session - * - * This is expected to become the interface used by model-checking - * algorithms to control the execution of the model-checked process - * and the exploration of the execution graph. Model-checking - * algorithms should be able to be written in high-level languages - * (e.g. Python) using bindings on this interface. - */ -class XBT_PUBLIC Session { -private: - std::unique_ptr model_checker_; - std::shared_ptr initial_snapshot_; - - // No copy: - Session(Session const&) = delete; - Session& operator=(Session const&) = delete; - -public: - /** Create a new session by executing the provided code in a fork() - * - * This sets up the environment for the model-checked process - * (environment variables, sockets, etc.). - * - * The code is expected to `exec` the model-checked application. - */ - explicit Session(const std::function& code); - - ~Session(); - void close(); - - void take_initial_snapshot(); - void restore_initial_state() const; - - /** Ask to the application to check for a deadlock. If so, do an error message and throw a DeadlockError. */ - void check_deadlock() const; - - void log_state() const; - - bool actor_is_enabled(aid_t pid) const; -}; -} // namespace simgrid::mc - -#endif diff --git a/src/mc/VisitedState.cpp b/src/mc/VisitedState.cpp deleted file mode 100644 index 6e46c3c3d0..0000000000 --- a/src/mc/VisitedState.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2011-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/VisitedState.hpp" -#include "src/mc/mc_private.hpp" - -#include -#include -#include -#include -#include "src/mc/api.hpp" - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_VisitedState, mc, "Logging specific to state equality detection mechanisms"); - -namespace simgrid::mc { - -/** @brief Save the current state */ -VisitedState::VisitedState(unsigned long state_number) : num(state_number) -{ - this->heap_bytes_used = Api::get().get_remote_heap_bytes(); - this->actors_count = Api::get().get_actors().size(); - this->system_state = std::make_shared(state_number); -} - -void VisitedStates::prune() -{ - while (states_.size() > (std::size_t)_sg_mc_max_visited_states) { - XBT_DEBUG("Try to remove visited state (maximum number of stored states reached)"); - auto min_element = boost::range::min_element( - states_, [](const std::unique_ptr& a, - const std::unique_ptr& b) { return a->num < b->num; }); - xbt_assert(min_element != states_.end()); - // and drop it: - states_.erase(min_element); - XBT_DEBUG("Remove visited state (maximum number of stored states reached)"); - } -} - -/** @brief Checks whether a given state has already been visited by the algorithm. */ -std::unique_ptr -VisitedStates::addVisitedState(unsigned long state_number, simgrid::mc::State* graph_state, bool compare_snapshots) -{ - auto new_state = std::make_unique(state_number); - graph_state->set_system_state(new_state->system_state); - XBT_DEBUG("Snapshot %p of visited state %ld (exploration stack state %ld)", new_state->system_state.get(), - new_state->num, graph_state->get_num()); - - auto [range_begin, range_end] = boost::range::equal_range(states_, new_state.get(), Api::get().compare_pair()); - - if (compare_snapshots) - for (auto i = range_begin; i != range_end; ++i) { - auto& visited_state = *i; - if (Api::get().snapshot_equal(visited_state->system_state.get(), new_state->system_state.get())) { - // The state has been visited: - - std::unique_ptr old_state = - std::move(visited_state); - - if (old_state->original_num == -1) // I'm the copy of an original process - new_state->original_num = old_state->num; - else // I'm the copy of a copy - new_state->original_num = old_state->original_num; - - if (dot_output == nullptr) - XBT_DEBUG("State %ld already visited ! (equal to state %ld)", new_state->num, old_state->num); - else - XBT_DEBUG("State %ld already visited ! (equal to state %ld (state %ld in dot_output))", new_state->num, - old_state->num, new_state->original_num); - - /* Replace the old state with the new one (with a bigger num) - (when the max number of visited states is reached, the oldest - one is removed according to its number (= with the min number) */ - XBT_DEBUG("Replace visited state %ld with the new visited state %ld", old_state->num, new_state->num); - - visited_state = std::move(new_state); - return old_state; - } - } - - XBT_DEBUG("Insert new visited state %ld (total : %lu)", new_state->num, (unsigned long)states_.size()); - states_.insert(range_begin, std::move(new_state)); - this->prune(); - return nullptr; -} - -} // namespace simgrid::mc diff --git a/src/mc/VisitedState.hpp b/src/mc/VisitedState.hpp deleted file mode 100644 index 33f3d1ae94..0000000000 --- a/src/mc/VisitedState.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_VISITED_STATE_HPP -#define SIMGRID_MC_VISITED_STATE_HPP - -#include "src/mc/api/State.hpp" -#include "src/mc/sosp/Snapshot.hpp" - -#include -#include - -namespace simgrid::mc { - -class XBT_PRIVATE VisitedState { -public: - std::shared_ptr system_state = nullptr; - std::size_t heap_bytes_used = 0; - int actors_count = 0; - long num = 0; // unique id of that state in the storage of all stored IDs - long original_num = -1; // num field of the VisitedState to which I was declared equal to (used for dot_output) - - explicit VisitedState(unsigned long state_number); -}; - -class XBT_PRIVATE VisitedStates { - std::vector> states_; -public: - void clear() { states_.clear(); } - std::unique_ptr addVisitedState(unsigned long state_number, - simgrid::mc::State* graph_state, bool compare_snapshots); - -private: - void prune(); -}; - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/api.cpp b/src/mc/api.cpp deleted file mode 100644 index 840ffef2c4..0000000000 --- a/src/mc/api.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* Copyright (c) 2020-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "api.hpp" - -#include "src/kernel/activity/MailboxImpl.hpp" -#include "src/kernel/activity/MutexImpl.hpp" -#include "src/kernel/actor/SimcallObserver.hpp" -#include "src/mc/Session.hpp" -#include "src/mc/explo/Exploration.hpp" -#include "src/mc/mc_base.hpp" -#include "src/mc/mc_exit.hpp" -#include "src/mc/mc_pattern.hpp" -#include "src/mc/mc_private.hpp" -#include "src/mc/remote/RemoteProcess.hpp" -#include "src/surf/HostImpl.hpp" - -#include -#include -#include "simgrid/s4u/Host.hpp" -#include "xbt/string.hpp" -#if HAVE_SMPI -#include "src/smpi/include/smpi_request.hpp" -#endif - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Api, mc, "Logging specific to MC Facade APIs "); -XBT_LOG_EXTERNAL_CATEGORY(mc_global); - -namespace simgrid::mc { - -simgrid::mc::Exploration* Api::initialize(char** argv, simgrid::mc::ExplorationAlgorithm algo) -{ - session_ = std::make_unique([argv] { - int i = 1; - while (argv[i] != nullptr && argv[i][0] == '-') - i++; - xbt_assert(argv[i] != nullptr, - "Unable to find a binary to exec on the command line. Did you only pass config flags?"); - execvp(argv[i], argv + i); - xbt_die("The model-checked process failed to exec(%s): %s", argv[i], strerror(errno)); - }); - - simgrid::mc::Exploration* explo; - switch (algo) { - case ExplorationAlgorithm::CommDeterminism: - explo = simgrid::mc::create_communication_determinism_checker(session_.get()); - break; - - case ExplorationAlgorithm::UDPOR: - explo = simgrid::mc::create_udpor_checker(session_.get()); - break; - - case ExplorationAlgorithm::Safety: - explo = simgrid::mc::create_dfs_exploration(session_.get()); - break; - - case ExplorationAlgorithm::Liveness: - explo = simgrid::mc::create_liveness_checker(session_.get()); - break; - - default: - THROW_IMPOSSIBLE; - } - - mc_model_checker->set_exploration(explo); - return explo; -} - -std::vector& Api::get_actors() const -{ - return mc_model_checker->get_remote_process().actors(); -} - -unsigned long Api::get_maxpid() const -{ - return mc_model_checker->get_remote_process().get_maxpid(); -} - -std::size_t Api::get_remote_heap_bytes() const -{ - RemoteProcess& process = mc_model_checker->get_remote_process(); - auto heap_bytes_used = mmalloc_get_bytes_used_remote(process.get_heap()->heaplimit, process.get_malloc_info()); - return heap_bytes_used; -} - -void Api::mc_inc_visited_states() const -{ - mc_model_checker->inc_visited_states(); -} - -unsigned long Api::mc_get_visited_states() const -{ - return mc_model_checker->get_visited_states(); -} - -void Api::mc_exit(int status) const -{ - mc_model_checker->exit(status); -} - -void Api::restore_state(const simgrid::mc::Snapshot* system_state) const -{ - system_state->restore(&mc_model_checker->get_remote_process()); -} - -bool Api::snapshot_equal(const Snapshot* s1, const Snapshot* s2) const -{ - return simgrid::mc::snapshot_equal(s1, s2); -} - -simgrid::mc::Snapshot* Api::take_snapshot(long num_state) const -{ - auto snapshot = new simgrid::mc::Snapshot(num_state); - return snapshot; -} - -void Api::s_close() -{ - session_.reset(); - if (simgrid::mc::property_automaton != nullptr) { - xbt_automaton_free(simgrid::mc::property_automaton); - simgrid::mc::property_automaton = nullptr; - } -} - -void Api::automaton_load(const char* file) const -{ - if (simgrid::mc::property_automaton == nullptr) - simgrid::mc::property_automaton = xbt_automaton_new(); - - xbt_automaton_load(simgrid::mc::property_automaton, file); -} - -std::vector Api::automaton_propositional_symbol_evaluate() const -{ - unsigned int cursor = 0; - std::vector values; - xbt_automaton_propositional_symbol_t ps = nullptr; - xbt_dynar_foreach (mc::property_automaton->propositional_symbols, cursor, ps) - values.push_back(xbt_automaton_propositional_symbol_evaluate(ps)); - return values; -} - -std::vector Api::get_automaton_state() const -{ - std::vector automaton_stack; - unsigned int cursor = 0; - xbt_automaton_state_t automaton_state; - xbt_dynar_foreach (mc::property_automaton->states, cursor, automaton_state) - if (automaton_state->type == -1) - automaton_stack.push_back(automaton_state); - return automaton_stack; -} - -int Api::compare_automaton_exp_label(const xbt_automaton_exp_label* l) const -{ - unsigned int cursor = 0; - xbt_automaton_propositional_symbol_t p = nullptr; - xbt_dynar_foreach (simgrid::mc::property_automaton->propositional_symbols, cursor, p) { - if (std::strcmp(xbt_automaton_propositional_symbol_get_name(p), l->u.predicat) == 0) - return cursor; - } - return -1; -} - -void Api::set_property_automaton(xbt_automaton_state_t const& automaton_state) const -{ - mc::property_automaton->current_state = automaton_state; -} - -xbt_automaton_exp_label_t Api::get_automaton_transition_label(xbt_dynar_t const& dynar, int index) const -{ - const xbt_automaton_transition* transition = xbt_dynar_get_as(dynar, index, xbt_automaton_transition_t); - return transition->label; -} - -xbt_automaton_state_t Api::get_automaton_transition_dst(xbt_dynar_t const& dynar, int index) const -{ - const xbt_automaton_transition* transition = xbt_dynar_get_as(dynar, index, xbt_automaton_transition_t); - return transition->dst; -} - -} // namespace simgrid::mc diff --git a/src/mc/api.hpp b/src/mc/api.hpp deleted file mode 100644 index 88b2e0c802..0000000000 --- a/src/mc/api.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (c) 2020-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_API_HPP -#define SIMGRID_MC_API_HPP - -#include -#include - -#include "simgrid/forward.h" -#include "src/mc/Session.hpp" -#include "src/mc/api/State.hpp" -#include "src/mc/mc_forward.hpp" -#include "src/mc/mc_record.hpp" -#include "xbt/automaton.hpp" -#include "xbt/base.h" - -namespace simgrid::mc { - -XBT_DECLARE_ENUM_CLASS(ExplorationAlgorithm, Safety, UDPOR, Liveness, CommDeterminism); - -/* -** This class aimes to implement FACADE APIs for simgrid. The FACADE layer sits between the CheckerSide -** (Unfolding_Checker, DPOR, ...) layer and the -** AppSide layer. The goal is to drill down into the entagled details in the CheckerSide layer and break down the -** detailes in a way that the CheckerSide eventually -** be capable to acquire the required information through the FACADE layer rather than the direct access to the AppSide. -*/ - -class Api { -private: - Api() = default; - - struct DerefAndCompareByActorsCountAndUsedHeap { - template bool operator()(X const& a, Y const& b) const - { - return std::make_pair(a->actors_count, a->heap_bytes_used) < std::make_pair(b->actors_count, b->heap_bytes_used); - } - }; - - std::unique_ptr session_; - -public: - // No copy: - Api(Api const&) = delete; - void operator=(Api const&) = delete; - - static Api& get() - { - static Api api; - return api; - } - - simgrid::mc::Exploration* initialize(char** argv, simgrid::mc::ExplorationAlgorithm algo); - - // ACTOR APIs - std::vector& get_actors() const; - unsigned long get_maxpid() const; - - // REMOTE APIs - std::size_t get_remote_heap_bytes() const; - - // MODEL CHECKER APIs - void mc_inc_visited_states() const; - unsigned long mc_get_visited_states() const; - XBT_ATTRIB_NORETURN void mc_exit(int status) const; - - // STATE APIs - void restore_state(const Snapshot* system_state) const; - - // SNAPSHOT APIs - bool snapshot_equal(const Snapshot* s1, const Snapshot* s2) const; - simgrid::mc::Snapshot* take_snapshot(long num_state) const; - - // SESSION APIs - simgrid::mc::Session const& get_session() const { return *session_; } - void s_close(); - - // AUTOMATION APIs - void automaton_load(const char* file) const; - std::vector automaton_propositional_symbol_evaluate() const; - std::vector get_automaton_state() const; - int compare_automaton_exp_label(const xbt_automaton_exp_label* l) const; - void set_property_automaton(xbt_automaton_state_t const& automaton_state) const; - inline DerefAndCompareByActorsCountAndUsedHeap compare_pair() const - { - return DerefAndCompareByActorsCountAndUsedHeap(); - } - xbt_automaton_exp_label_t get_automaton_transition_label(xbt_dynar_t const& dynar, int index) const; - xbt_automaton_state_t get_automaton_transition_dst(xbt_dynar_t const& dynar, int index) const; -}; - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/api/ActorState.hpp b/src/mc/api/ActorState.hpp new file mode 100644 index 0000000000..ed40454646 --- /dev/null +++ b/src/mc/api/ActorState.hpp @@ -0,0 +1,174 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_PATTERN_H +#define SIMGRID_MC_PATTERN_H + +#include "src/kernel/activity/CommImpl.hpp" +#include "src/mc/remote/RemotePtr.hpp" + +#include +#include +#include + +namespace simgrid::mc { + +/* On every state, each actor has an entry of the following type. + * This usually represents both the actor and its transition because + * most of the time an actor cannot have more than one enabled transition + * at a given time. However, certain transitions have multiple "paths" + * that can be followed, which means that a given actor may be able + * to do more than one thing at a time. + * + * Formally, at this state multiple transitions would exist all of + * which happened to be executed by the same actor. This distinction + * is important in cases + */ +class ActorState { + /** + * @brief The transitions that the actor is allowed to execute from this + * state, viz. those that are enabled for this actor + * + * Most actors can take only a single action from any given state. + * However, when an actor executes a transition with multiple + * possible variations (e.g. an MC_Random() [see class: RandomTransition] + * for more details]), multiple enabled actions are defined + * + * @invariant The transitions are arranged such that an actor + * with multiple possible paths of execution will contain all + * such transitions such that `pending_transitions_[i]` represents + * the variation of the transition with `times_considered = i`. + * + * @note: If only a subset of transitions of an actor that can + * take multiple transitions in some state are truly enabled, + * we would instead need to map `times_considered` to a transition, + * as the map is currently implicit in the ordering of the transitions + * in the vector + * + * TODO: If a single transition is taken at a time in a concurrent system, + * then nearly all of the transitions from in a state `s'` after taking + * an action `t` from state `s` (i.e. s -- t --> s') are the same + * sans for the new transition of the actor which just executed t. + * This means there may be a way to store the list once and apply differences + * rather than repeating elements frequently. + */ + std::vector> pending_transitions_; + + /* Possible exploration status of an actor transition in a state. + * Either the checker did not consider the transition, or it was considered and still to do, or considered and + * done. + */ + enum class InterleavingType { + /** This actor transition is not considered by the checker (yet?) */ + disabled = 0, + /** The checker algorithm decided that this actor transitions should be done at some point */ + todo, + /** The checker algorithm decided that this should be done, but it was done in the meanwhile */ + done, + }; + + /** Exploration control information */ + InterleavingType state_ = InterleavingType::disabled; + + /** The ID of that actor */ + const aid_t aid_; + + /** Number of times that the actor was considered to be executed in previous explorations of the state space */ + unsigned int times_considered_ = 0; + /** Maximal amount of times that the actor can be considered for execution in this state. + * If times_considered==max_consider, we fully explored that part of the state space */ + unsigned int max_consider_ = 0; + + /** Whether that actor is initially enabled in this state */ + bool enabled_; + +public: + ActorState(aid_t aid, bool enabled, unsigned int max_consider) : ActorState(aid, enabled, max_consider, {}) {} + + ActorState(aid_t aid, bool enabled, unsigned int max_consider, std::vector> transitions) + : pending_transitions_(std::move(transitions)), aid_(aid), max_consider_(max_consider), enabled_(enabled) + { + } + + unsigned int do_consider() + { + if (max_consider_ <= times_considered_ + 1) + mark_done(); + return times_considered_++; + } + unsigned int get_max_considered() const { return max_consider_; } + unsigned int get_times_considered() const { return times_considered_; } + unsigned int get_times_not_considered() const { return max_consider_ - times_considered_; } + bool has_more_to_consider() const { return get_times_not_considered() > 0; } + aid_t get_aid() const { return aid_; } + + /* returns whether the actor is marked as enabled in the application side */ + bool is_enabled() const { return enabled_; } + /* returns whether the actor is marked as disabled by the exploration algorithm */ + bool is_disabled() const { return this->state_ == InterleavingType::disabled; } + bool is_done() const { return this->state_ == InterleavingType::done; } + bool is_todo() const { return this->state_ == InterleavingType::todo; } + /** Mark that we should try executing this process at some point in the future of the checker algorithm */ + void mark_todo() + { + this->state_ = InterleavingType::todo; + this->times_considered_ = 0; + } + void mark_done() { this->state_ = InterleavingType::done; } + + /** + * @brief Retrieves the transition that we should consider for execution by + * this actor from the State instance with respect to which this ActorState object + * is considered + */ + std::shared_ptr get_transition() const + { + // The rationale for this selection is as follows: + // + // 1. For transitions with only one possibility of execution, + // we always wish to select action `0` even if we've + // marked the transition already as considered (which + // we'll do if we explore a trace following that transition). + // + // 2. For transitions that can be considered multiple + // times, we want to be sure to select the most up-to-date + // action. In general, this means selecting that which is + // now being considered at this state. If, however, we've + // executed the + // + // The formula satisfies both of the above conditions: + // + // > std::clamp(times_considered_, 0u, max_consider_ - 1) + return get_transition(std::clamp(times_considered_, 0u, max_consider_ - 1)); + } + + std::shared_ptr get_transition(unsigned times_considered) const + { + xbt_assert(times_considered < this->pending_transitions_.size(), + "Actor %ld does not have a state available transition with `times_considered = %u`,\n" + "yet one was asked for", + aid_, times_considered); + return this->pending_transitions_[times_considered]; + } + + void set_transition(std::shared_ptr t, unsigned times_considered) + { + xbt_assert(times_considered < this->pending_transitions_.size(), + "Actor %ld does not have a state available transition with `times_considered = %u`, " + "yet one was attempted to be set", + aid_, times_considered); + this->pending_transitions_[times_considered] = std::move(t); + } + + const std::vector>& get_enabled_transitions() const + { + static const auto no_enabled_transitions = std::vector>(); + return this->is_enabled() ? this->pending_transitions_ : no_enabled_transitions; + }; +}; + +} // namespace simgrid::mc + +#endif diff --git a/src/mc/api/ClockVector.cpp b/src/mc/api/ClockVector.cpp new file mode 100644 index 0000000000..b411bba06a --- /dev/null +++ b/src/mc/api/ClockVector.cpp @@ -0,0 +1,23 @@ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/api/ClockVector.hpp" + +namespace simgrid::mc { + +ClockVector ClockVector::max(const ClockVector& cv1, const ClockVector& cv2) +{ + auto max_vector = ClockVector(); + + for (const auto& [aid, value] : cv1.contents) + max_vector[aid] = std::max(value, cv2.get(aid).value_or(0)); + + for (const auto& [aid, value] : cv2.contents) + max_vector[aid] = std::max(value, cv1.get(aid).value_or(0)); + + return max_vector; +} + +} // namespace simgrid::mc \ No newline at end of file diff --git a/src/mc/api/ClockVector.hpp b/src/mc/api/ClockVector.hpp new file mode 100644 index 0000000000..32e395fa45 --- /dev/null +++ b/src/mc/api/ClockVector.hpp @@ -0,0 +1,130 @@ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_CLOCK_VECTOR_HPP +#define SIMGRID_MC_CLOCK_VECTOR_HPP + +#include "simgrid/forward.h" + +#include +#include +#include +#include + +namespace simgrid::mc { + +/** + * @brief A multi-dimensional vector used to keep track of + * happens-before relation between dependent events in an + * execution of DPOR, SDPOR, or ODPOR + * + * Clock vectors permit actors in a distributed system + * to determine whether two events occurred one after the other + * but they may not have); i.e. they permit actors to keep track of "time". + * A clever observation made in the original DPOR paper is that a + * transition-based "happens-before" relation can be computed for + * any particular trace `S` using clock vectors, effectively + * treating dependency like the passing of a message (the context + * in which vector clocks are typically used). + * + * Support, however, needs to be added to clock vectors since + * SimGrid permits the *creation* of new actors during execution. + * Since we don't know this size before-hand, we have to allow + * clock vectors to behave as if they were "infinitely" large. To + * do so, all newly mapped elements, if not assigned a value, are + * defaulted to `0`. This corresponds to the value this actor would + * have had regardless had its creation been known to have evnetually + * occurred: no actions taken by that actor had occurred prior, so + * there's no way the clock vector would have been updated. In other + * words, when comparing clock vectors of different sizes, it's equivalent + * to imagine both of the same size with elements absent in one or + * the other implicitly mapped to zero. + */ +struct ClockVector final { +private: + std::unordered_map contents; + +public: + ClockVector() = default; + ClockVector(const ClockVector&) = default; + ClockVector& operator=(ClockVector const&) = default; + ClockVector(ClockVector&&) = default; + ClockVector(std::initializer_list> init) : contents(std::move(init)) {} + + /** + * @brief The number of components in this + * clock vector + * + * A `ClockVector` implicitly maps the id of an actor + * it does not contain to a default value of `0`. + * Thus, a `ClockVector` is "lazy" in the sense + * that new actors are "automatically" mapped + * without needing to be explicitly added the clock + * vector when the actor is created. This means that + * comparison between clock vectors is possible + * even as actors become enabled and disabled + * + * @return uint32_t the number of elements in + * the clock vector + */ + size_t size() const { return this->contents.size(); } + + uint32_t& operator[](aid_t aid) + { + // NOTE: The `operator[]` overload of + // unordered_map will create a new key-value + // pair if `tid` does not exist and will use + // a _default_ value for the value (0 in this case) + // which is precisely what we want here + return this->contents[aid]; + } + + /** + * @brief Retrieves the value mapped to the given + * actor if it is contained in this clock vector + */ + std::optional get(aid_t aid) const + { + if (const auto iter = this->contents.find(aid); iter != this->contents.end()) + return std::optional{iter->second}; + return std::nullopt; + } + + /** + * @brief Computes a clock vector whose components + * are larger than the components of both of + * the given clock vectors + * + * The maximum of two clock vectors is definied to + * be the clock vector whose components are the maxmimum + * of the corresponding components of the arguments. + * Since the `ClockVector` class is "lazy", the two + * clock vectors given as arguments may not be of the same size. + * The resultant clock vector has components as follows: + * + * 1. For each actor that each clock vector maps, the + * resulting clock vector maps that thread to the maxmimum + * of the values mapped for the actor in each clock vector + * + * 2. For each actor that only a single clock vector maps, + * the resulting clock vector maps that thread to the + * value mapped by the lone clock vector + * + * The scheme is equivalent to assuming that an unmapped + * thread by any one clock vector is implicitly mapped to zero + * + * @param cv1 the first clock vector + * @param cv2 the second clock vector + * @return a clock vector whose components are at + * least as large as the corresponding components of each clock + * vector and whose size is large enough to contain the union + * of components of each clock vector + */ + static ClockVector max(const ClockVector& cv1, const ClockVector& cv2); +}; + +} // namespace simgrid::mc + +#endif diff --git a/src/mc/api/RemoteApp.cpp b/src/mc/api/RemoteApp.cpp new file mode 100644 index 0000000000..dc6c7d0d54 --- /dev/null +++ b/src/mc/api/RemoteApp.cpp @@ -0,0 +1,213 @@ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/api/RemoteApp.hpp" +#include "src/mc/explo/Exploration.hpp" +#include "src/mc/mc_config.hpp" +#include "xbt/asserts.h" +#include "src/mc/api/State.hpp" +#include "src/mc/mc_config.hpp" +#include "src/mc/mc_exit.hpp" +#include "src/mc/mc_private.hpp" +#include "xbt/log.h" +#include "xbt/system_error.hpp" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_Session, mc, "Model-checker session"); +XBT_LOG_EXTERNAL_CATEGORY(mc_global); + +namespace simgrid::mc { + +static std::string master_socket_name; + +RemoteApp::RemoteApp(const std::vector& args) : app_args_(args) +{ + master_socket_ = socket(AF_UNIX, +#ifdef __APPLE__ + SOCK_STREAM, /* Mac OSX does not have AF_UNIX + SOCK_SEQPACKET, even if that's faster */ +#else + SOCK_SEQPACKET, +#endif + 0); + xbt_assert(master_socket_ != -1, "Cannot create the master socket: %s", strerror(errno)); + + master_socket_name = "/tmp/simgrid-mc-" + std::to_string(getpid()); + master_socket_name.resize(MC_SOCKET_NAME_LEN); // truncate socket name if it's too long + master_socket_name.back() = '\0'; // ensure the data are null-terminated +#ifdef __linux__ + master_socket_name[0] = '\0'; // abstract socket, automatically removed after close +#else + unlink(master_socket_name.c_str()); // remove possible stale socket before bind + atexit([]() { + if (not master_socket_name.empty()) + unlink(master_socket_name.c_str()); + master_socket_name.clear(); + }); +#endif + + struct sockaddr_un serv_addr = {}; + serv_addr.sun_family = AF_UNIX; + master_socket_name.copy(serv_addr.sun_path, MC_SOCKET_NAME_LEN); + + xbt_assert(bind(master_socket_, (struct sockaddr*)&serv_addr, sizeof serv_addr) >= 0, + "Cannot bind the master socket to %c%s: %s.", (serv_addr.sun_path[0] ? serv_addr.sun_path[0] : '@'), + serv_addr.sun_path + 1, strerror(errno)); + + xbt_assert(listen(master_socket_, SOMAXCONN) >= 0, "Cannot listen to the master socket: %s.", strerror(errno)); + + application_factory_ = std::make_unique(app_args_); + checker_side_ = application_factory_->clone(master_socket_, master_socket_name); +} + +void RemoteApp::restore_initial_state() +{ + checker_side_ = application_factory_->clone(master_socket_, master_socket_name); +} + +unsigned long RemoteApp::get_maxpid() const +{ + // note: we could maybe cache it and count the actor creation on checker side too. + // But counting correctly accross state checkpoint/restore would be annoying. + + checker_side_->get_channel().send(MessageType::ACTORS_MAXPID); + s_mc_message_int_t answer; + ssize_t answer_size = checker_side_->get_channel().receive(answer); + xbt_assert(answer_size != -1, "Could not receive message"); + xbt_assert(answer_size == sizeof answer, "Broken message (size=%zd; expected %zu)", answer_size, sizeof answer); + xbt_assert(answer.type == MessageType::ACTORS_MAXPID_REPLY, + "Received unexpected message %s (%i); expected MessageType::ACTORS_MAXPID_REPLY (%i)", + to_c_str(answer.type), (int)answer.type, (int)MessageType::ACTORS_MAXPID_REPLY); + + return answer.value; +} + +void RemoteApp::get_actors_status(std::map& whereto) const +{ + // The messaging happens as follows: + // + // CheckerSide AppSide + // send ACTORS_STATUS ----> + // <----- send ACTORS_STATUS_REPLY_COUNT + // <----- send `N` ACTORS_STATUS_REPLY_TRANSITION (s_mc_message_actors_status_one_t) + // <----- send `M` ACTORS_STATUS_REPLY_SIMCALL (s_mc_message_simcall_probe_one_t) + // + // Note that we also receive disabled transitions, because the guiding strategies need them to decide what could + // unlock actors. + + checker_side_->get_channel().send(MessageType::ACTORS_STATUS); + + s_mc_message_actors_status_answer_t answer; + ssize_t answer_size = checker_side_->get_channel().receive(answer); + xbt_assert(answer_size != -1, "Could not receive message"); + xbt_assert(answer_size == sizeof answer, "Broken message (size=%zd; expected %zu)", answer_size, sizeof answer); + xbt_assert(answer.type == MessageType::ACTORS_STATUS_REPLY_COUNT, + "%d Received unexpected message %s (%i); expected MessageType::ACTORS_STATUS_REPLY_COUNT (%i)", getpid(), + to_c_str(answer.type), (int)answer.type, (int)MessageType::ACTORS_STATUS_REPLY_COUNT); + + // Message sanity checks + xbt_assert(answer.count >= 0, "Received an ACTORS_STATUS_REPLY_COUNT message with an actor count of '%d' < 0", + answer.count); + + std::vector status(answer.count); + if (answer.count > 0) { + size_t size = status.size() * sizeof(s_mc_message_actors_status_one_t); + ssize_t received = checker_side_->get_channel().receive(status.data(), size); + xbt_assert(static_cast(received) == size); + } + + whereto.clear(); + + for (const auto& actor : status) { + std::vector> actor_transitions; + int n_transitions = actor.max_considered; + for (int times_considered = 0; times_considered < n_transitions; times_considered++) { + s_mc_message_simcall_probe_one_t probe; + ssize_t received = checker_side_->get_channel().receive(probe); + xbt_assert(received >= 0, "Could not receive response to ACTORS_PROBE message (%s)", strerror(errno)); + xbt_assert(static_cast(received) == sizeof probe, + "Could not receive response to ACTORS_PROBE message (%zd bytes received != %zu bytes expected", + received, sizeof probe); + + std::stringstream stream(probe.buffer.data()); + actor_transitions.emplace_back(deserialize_transition(actor.aid, times_considered, stream)); + } + + XBT_DEBUG("Received %zu transitions for actor %ld. The first one is %s", actor_transitions.size(), actor.aid, + (actor_transitions.size() > 0 ? actor_transitions[0]->to_string().c_str() : "null")); + whereto.try_emplace(actor.aid, actor.aid, actor.enabled, actor.max_considered, std::move(actor_transitions)); + } +} + +void RemoteApp::check_deadlock() const +{ + xbt_assert(checker_side_->get_channel().send(MessageType::DEADLOCK_CHECK) == 0, "Could not check deadlock state"); + s_mc_message_int_t message; + ssize_t received = checker_side_->get_channel().receive(message); + xbt_assert(received != -1, "Could not receive message"); + xbt_assert(received == sizeof message, "Broken message (size=%zd; expected %zu)", received, sizeof message); + xbt_assert(message.type == MessageType::DEADLOCK_CHECK_REPLY, + "Received unexpected message %s (%i); expected MessageType::DEADLOCK_CHECK_REPLY (%i)", + to_c_str(message.type), (int)message.type, (int)MessageType::DEADLOCK_CHECK_REPLY); + + if (message.value != 0) { + auto* explo = Exploration::get_instance(); + XBT_CINFO(mc_global, "Counter-example execution trace:"); + for (auto const& frame : explo->get_textual_trace()) + XBT_CINFO(mc_global, " %s", frame.c_str()); + XBT_INFO("You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with " + "--cfg=model-check/replay:'%s'", + explo->get_record_trace().to_string().c_str()); + explo->log_state(); + throw McError(ExitStatus::DEADLOCK); + } +} + +void RemoteApp::wait_for_requests() +{ + checker_side_->wait_for_requests(); +} + +Transition* RemoteApp::handle_simcall(aid_t aid, int times_considered, bool new_transition) +{ + s_mc_message_simcall_execute_t m = {}; + m.type = MessageType::SIMCALL_EXECUTE; + m.aid_ = aid; + m.times_considered_ = times_considered; + checker_side_->get_channel().send(m); + + if (checker_side_->running()) + checker_side_->dispatch_events(); // The app may send messages while processing the transition + + s_mc_message_simcall_execute_answer_t answer; + ssize_t s = checker_side_->get_channel().receive(answer); + xbt_assert(s != -1, "Could not receive message"); + xbt_assert(s > 0 && answer.type == MessageType::SIMCALL_EXECUTE_REPLY, + "%d Received unexpected message %s (%i); expected MessageType::SIMCALL_EXECUTE_REPLY (%i)", getpid(), + to_c_str(answer.type), (int)answer.type, (int)MessageType::SIMCALL_EXECUTE_REPLY); + xbt_assert(s == sizeof answer, "Broken message (size=%zd; expected %zu)", s, sizeof answer); + + if (new_transition) { + std::stringstream stream(answer.buffer.data()); + return deserialize_transition(aid, times_considered, stream); + } else + return nullptr; +} + +void RemoteApp::finalize_app(bool terminate_asap) +{ + checker_side_->finalize(terminate_asap); +} + +} // namespace simgrid::mc diff --git a/src/mc/api/RemoteApp.hpp b/src/mc/api/RemoteApp.hpp new file mode 100644 index 0000000000..6954a985bf --- /dev/null +++ b/src/mc/api/RemoteApp.hpp @@ -0,0 +1,68 @@ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_REMOTE_APP_HPP +#define SIMGRID_MC_REMOTE_APP_HPP + +#include "simgrid/forward.h" +#include "src/mc/api/ActorState.hpp" +#include "src/mc/remote/CheckerSide.hpp" +#include "src/mc/remote/RemotePtr.hpp" + +#include + +namespace simgrid::mc { + +/** High-level view of the verified application, from the model-checker POV + * + * This is expected to become the interface used by model-checking algorithms to control the execution of + * the application process during the exploration of the execution graph. + * + * One day, this will allow parallel exploration, ie, the handling of several application processes (each encapsulated + * in a separate CheckerSide objects) that explore several parts of the exploration graph. + */ +class XBT_PUBLIC RemoteApp { +private: + std::unique_ptr checker_side_; + std::unique_ptr application_factory_; // when no meminfo, create checker_side_ by cloning this one + int master_socket_ = -1; + + const std::vector app_args_; + + // No copy: + RemoteApp(RemoteApp const&) = delete; + RemoteApp& operator=(RemoteApp const&) = delete; + +public: + /** Create a new session by executing the provided code in a fork() + * + * This sets up the environment for the model-checked process + * (environment variables, sockets, etc.). + * + * The code is expected to `exec` the model-checked application. + */ + explicit RemoteApp(const std::vector& args); + + void restore_initial_state(); + void wait_for_requests(); + + /** Ask to the application to check for a deadlock. If so, do an error message and throw a McError(DEADLOCK). */ + void check_deadlock() const; + + /** Ask the application to run post-mortem analysis, and maybe to stop ASAP */ + void finalize_app(bool terminate_asap = false); + + /** Retrieve the max PID of the running actors */ + unsigned long get_maxpid() const; + + /* Get the list of actors that are ready to run at that step. Usually shorter than maxpid */ + void get_actors_status(std::map& whereto) const; + + /** Take a transition. A new Transition is created iff the last parameter is true */ + Transition* handle_simcall(aid_t aid, int times_considered, bool new_transition); +}; +} // namespace simgrid::mc + +#endif diff --git a/src/mc/api/State.cpp b/src/mc/api/State.cpp index fac456f4af..f537a484b5 100644 --- a/src/mc/api/State.cpp +++ b/src/mc/api/State.cpp @@ -1,12 +1,18 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/api/State.hpp" -#include "src/mc/api.hpp" +#include "src/mc/api/strategy/BasicStrategy.hpp" +#include "src/mc/api/strategy/MaxMatchComm.hpp" +#include "src/mc/api/strategy/MinMatchComm.hpp" +#include "src/mc/api/strategy/UniformStrategy.hpp" +#include "src/mc/explo/Exploration.hpp" #include "src/mc/mc_config.hpp" +#include "xbt/random.hpp" +#include #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_state, mc, "Logging specific to MC states"); @@ -15,56 +21,279 @@ namespace simgrid::mc { long State::expended_states_ = 0; -State::State() : num_(++expended_states_) +State::State(RemoteApp& remote_app) : num_(++expended_states_) { - const unsigned long maxpid = Api::get().get_maxpid(); - actor_states_.resize(maxpid); - transition_.reset(new Transition()); - /* Stateful model checking */ - if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination) { - auto snapshot_ptr = Api::get().take_snapshot(num_); - system_state_ = std::shared_ptr(snapshot_ptr); + XBT_VERB("Creating a guide for the state"); + + if (_sg_mc_strategy == "none") + strategy_ = std::make_shared(); + else if (_sg_mc_strategy == "max_match_comm") + strategy_ = std::make_shared(); + else if (_sg_mc_strategy == "min_match_comm") + strategy_ = std::make_shared(); + else if (_sg_mc_strategy == "uniform") { + xbt::random::set_mersenne_seed(_sg_mc_random_seed); + strategy_ = std::make_shared(); + } else + THROW_IMPOSSIBLE; + + remote_app.get_actors_status(strategy_->actors_to_run_); +} + +State::State(RemoteApp& remote_app, std::shared_ptr parent_state) + : incoming_transition_(parent_state->get_transition_out()), num_(++expended_states_), parent_state_(parent_state) +{ + if (_sg_mc_strategy == "none") + strategy_ = std::make_shared(); + else if (_sg_mc_strategy == "max_match_comm") + strategy_ = std::make_shared(); + else if (_sg_mc_strategy == "min_match_comm") + strategy_ = std::make_shared(); + else if (_sg_mc_strategy == "uniform") + strategy_ = std::make_shared(); + else + THROW_IMPOSSIBLE; + strategy_->copy_from(parent_state_->strategy_.get()); + + remote_app.get_actors_status(strategy_->actors_to_run_); + + /* Copy the sleep set and eventually removes things from it: */ + /* For each actor in the previous sleep set, keep it if it is not dependent with current transition. + * And if we kept it and the actor is enabled in this state, mark the actor as already done, so that + * it is not explored*/ + for (const auto& [aid, transition] : parent_state_->get_sleep_set()) { + if (not incoming_transition_->depends(transition.get())) { + sleep_set_.try_emplace(aid, transition); + if (strategy_->actors_to_run_.count(aid) != 0) { + XBT_DEBUG("Actor %ld will not be explored, for it is in the sleep set", aid); + strategy_->actors_to_run_.at(aid).mark_done(); + } + } else + XBT_DEBUG("Transition >>%s<< removed from the sleep set because it was dependent with incoming >>%s<<", + transition->to_string().c_str(), incoming_transition_->to_string().c_str()); } } std::size_t State::count_todo() const { - return boost::range::count_if(this->actor_states_, [](simgrid::mc::ActorState const& a) { return a.is_todo(); }); + return boost::range::count_if(this->strategy_->actors_to_run_, [](auto& pair) { return pair.second.is_todo(); }); } -Transition* State::get_transition() const +std::size_t State::count_todo_multiples() const { - return transition_.get(); + size_t count = 0; + for (auto const& [_, actor] : strategy_->actors_to_run_) + if (actor.is_todo()) + count += actor.get_times_not_considered(); + + return count; } -int State::next_transition() const +aid_t State::next_transition() const { - std::vector& actors = mc_model_checker->get_remote_process().actors(); - XBT_DEBUG("Search for an actor to run. %zu actors to consider", actors.size()); - for (unsigned int i = 0; i < actors.size(); i++) { - /* Only consider actors (1) marked as interleaving by the checker and (2) currently enabled in the application*/ - if (aid_t aid = actors[i].copy.get_buffer()->get_pid(); - not actor_states_[aid].is_todo() || not Api::get().get_session().actor_is_enabled(aid)) + XBT_DEBUG("Search for an actor to run. %zu actors to consider", strategy_->actors_to_run_.size()); + for (auto const& [aid, actor] : strategy_->actors_to_run_) { + /* Only consider actors (1) marked as interleaving by the checker and (2) currently enabled in the application */ + if (not actor.is_todo() || not actor.is_enabled() || actor.is_done()) { + if (not actor.is_todo()) + XBT_DEBUG("Can't run actor %ld because it is not todo", aid); + + if (not actor.is_enabled()) + XBT_DEBUG("Can't run actor %ld because it is not enabled", aid); + + if (actor.is_done()) + XBT_DEBUG("Can't run actor %ld because it has already been done", aid); + continue; + } - return i; + return aid; } return -1; } -void State::execute_next(int next) + +std::pair State::next_transition_guided() const { - std::vector& actors = mc_model_checker->get_remote_process().actors(); - const kernel::actor::ActorImpl* actor = actors[next].copy.get_buffer(); - const aid_t aid = actor->get_pid(); + return strategy_->next_transition(); +} - /* This actor is ready to be executed. Prepare its execution when simcall_handle will be called on it */ - const unsigned times_considered = actor_states_[aid].do_consider(actor->simcall_.mc_max_consider_); +aid_t State::next_odpor_transition() const +{ + return wakeup_tree_.get_min_single_process_actor().value_or(-1); +} - XBT_DEBUG("Let's run actor %ld (times_considered = %u)", aid, times_considered); +// This should be done in GuidedState, or at least interact with it +std::shared_ptr State::execute_next(aid_t next, RemoteApp& app) +{ + // First, warn the guide, so it knows how to build a proper child state + strategy_->execute_next(next, app); + // This actor is ready to be executed. Execution involves three phases: + + // 1. Identify the appropriate ActorState to prepare for execution + // when simcall_handle will be called on it + auto& actor_state = strategy_->actors_to_run_.at(next); + const unsigned times_considered = actor_state.do_consider(); + const auto* expected_executed_transition = actor_state.get_transition(times_considered).get(); + xbt_assert(expected_executed_transition != nullptr, + "Expected a transition with %u times considered to be noted in actor %ld", times_considered, next); + + XBT_DEBUG("Let's run actor %ld (times_considered = %u)", next, times_considered); + + // 2. Execute the actor according to the preparation above Transition::executed_transitions_++; + auto* just_executed = app.handle_simcall(next, times_considered, true); + xbt_assert(just_executed->type_ == expected_executed_transition->type_, + "The transition that was just executed by actor %ld, viz:\n" + "%s\n" + "is not what was purportedly scheduled to execute, which was:\n" + "%s\n", + next, just_executed->to_string().c_str(), expected_executed_transition->to_string().c_str()); + + // 3. Update the state with the newest information. This means recording + // both + // 1. what action was last taken from this state (viz. `executed_transition`) + // 2. what action actor `next` was able to take given `times_considered` + // The latter update is important as *more* information is potentially available + // about a transition AFTER it has executed. + outgoing_transition_ = std::shared_ptr(just_executed); - transition_.reset(mc_model_checker->handle_simcall(aid, times_considered, true)); - mc_model_checker->wait_for_requests(); + actor_state.set_transition(outgoing_transition_, times_considered); + app.wait_for_requests(); + + return outgoing_transition_; } + +std::unordered_set State::get_backtrack_set() const +{ + std::unordered_set actors; + for (const auto& [aid, state] : get_actors_list()) { + if (state.is_todo() || state.is_done()) { + actors.insert(aid); + } + } + return actors; +} + +std::unordered_set State::get_sleeping_actors() const +{ + std::unordered_set actors; + for (const auto& [aid, _] : get_sleep_set()) { + actors.insert(aid); + } + return actors; +} + +std::unordered_set State::get_enabled_actors() const +{ + std::unordered_set actors; + for (const auto& [aid, state] : get_actors_list()) { + if (state.is_enabled()) { + actors.insert(aid); + } + } + return actors; +} + +void State::seed_wakeup_tree_if_needed(const odpor::Execution& prior) +{ + // TODO: It would be better not to have such a flag. + if (has_initialized_wakeup_tree) { + XBT_DEBUG("Reached a node with the following initialized WuT:"); + XBT_DEBUG("\n%s", wakeup_tree_.string_of_whole_tree().c_str()); + + return; + } + // TODO: Note that the next action taken by the actor may be updated + // after it executes. But we will have already inserted it into the + // tree and decided upon "happens-before" at that point for different + // executions :( + if (wakeup_tree_.empty()) { + // Find an enabled transition to pick + for (const auto& [_, actor] : get_actors_list()) { + if (actor.is_enabled()) { + // For each variant of the transition that is enabled, we want to insert the action into the tree. + // This ensures that all variants are searched + for (unsigned times = 0; times < actor.get_max_considered(); ++times) { + wakeup_tree_.insert(prior, odpor::PartialExecution{actor.get_transition(times)}); + } + break; // Only one actor gets inserted (see pseudocode) + } + } + } + has_initialized_wakeup_tree = true; +} + +void State::sprout_tree_from_parent_state() +{ + + XBT_DEBUG("Initializing Wut with parent one:"); + XBT_DEBUG("\n%s", parent_state_->wakeup_tree_.string_of_whole_tree().c_str()); + + xbt_assert(parent_state_ != nullptr, "Attempting to construct a wakeup tree for the root state " + "(or what appears to be, rather for state without a parent defined)"); + const auto min_process_node = parent_state_->wakeup_tree_.get_min_single_process_node(); + xbt_assert(min_process_node.has_value(), "Attempting to construct a subtree for a substate from a " + "parent with an empty wakeup tree. This indicates either that ODPOR " + "actor selection in State.cpp is incorrect, or that the code " + "deciding when to make subtrees in ODPOR is incorrect"); + if (not(get_transition_in()->aid_ == min_process_node.value()->get_actor() && + get_transition_in()->type_ == min_process_node.value()->get_action()->type_)) { + XBT_ERROR("We tried to make a subtree from a parent state who claimed to have executed `%s` on actor %ld " + "but whose wakeup tree indicates it should have executed `%s` on actor %ld. This indicates " + "that exploration is not following ODPOR. Are you sure you're choosing actors " + "to schedule from the wakeup tree? Trace so far:", + get_transition_in()->to_string(false).c_str(), get_transition_in()->aid_, + min_process_node.value()->get_action()->to_string(false).c_str(), min_process_node.value()->get_actor()); + for (auto const& elm : Exploration::get_instance()->get_textual_trace()) + XBT_ERROR("%s", elm.c_str()); + xbt_abort(); + } + this->wakeup_tree_ = odpor::WakeupTree::make_subtree_rooted_at(min_process_node.value()); +} + +void State::remove_subtree_using_current_out_transition() +{ + if (auto out_transition = get_transition_out(); out_transition != nullptr) { + if (const auto min_process_node = wakeup_tree_.get_min_single_process_node(); min_process_node.has_value()) { + xbt_assert((out_transition->aid_ == min_process_node.value()->get_actor()) && + (out_transition->type_ == min_process_node.value()->get_action()->type_), + "We tried to make a subtree from a parent state who claimed to have executed `%s` " + "but whose wakeup tree indicates it should have executed `%s`. This indicates " + "that exploration is not following ODPOR. Are you sure you're choosing actors " + "to schedule from the wakeup tree?", + out_transition->to_string(false).c_str(), + min_process_node.value()->get_action()->to_string(false).c_str()); + } + } + wakeup_tree_.remove_min_single_process_subtree(); +} + +void State::remove_subtree_at_aid(const aid_t proc) +{ + wakeup_tree_.remove_subtree_at_aid(proc); +} + +odpor::WakeupTree::InsertionResult State::insert_into_wakeup_tree(const odpor::PartialExecution& pe, + const odpor::Execution& E) +{ + return this->wakeup_tree_.insert(E, pe); +} + +void State::do_odpor_unwind() +{ + if (auto out_transition = get_transition_out(); out_transition != nullptr) { + remove_subtree_using_current_out_transition(); + + // Only when we've exhausted all variants of the transition which + // can be chosen from this state do we finally add the actor to the + // sleep set. This ensures that the current logic handling sleep sets + // works with ODPOR in the way we intend it to work. There is not a + // good way to perform transition equality in SimGrid; instead, we + // effectively simply check for the presence of an actor in the sleep set. + if (not get_actors_list().at(out_transition->aid_).has_more_to_consider()) + add_sleep_set(std::move(out_transition)); + } +} + } // namespace simgrid::mc diff --git a/src/mc/api/State.hpp b/src/mc/api/State.hpp index 84322067ad..6603ff0831 100644 --- a/src/mc/api/State.hpp +++ b/src/mc/api/State.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,8 +6,11 @@ #ifndef SIMGRID_MC_STATE_HPP #define SIMGRID_MC_STATE_HPP -#include "src/mc/mc_pattern.hpp" -#include "src/mc/sosp/Snapshot.hpp" +#include "src/mc/api/ActorState.hpp" +#include "src/mc/api/ClockVector.hpp" +#include "src/mc/api/RemoteApp.hpp" +#include "src/mc/api/strategy/Strategy.hpp" +#include "src/mc/explo/odpor/WakeupTree.hpp" #include "src/mc/transition/Transition.hpp" namespace simgrid::mc { @@ -16,36 +19,149 @@ namespace simgrid::mc { class XBT_PRIVATE State : public xbt::Extendable { static long expended_states_; /* Count total amount of states, for stats */ - /* Outgoing transition: what was the last transition that we took to leave this state? */ - std::unique_ptr transition_; + /** @brief The outgoing transition is the last transition that we took to leave this state. */ + std::shared_ptr outgoing_transition_ = nullptr; - /** Sequential state number (used for debugging) */ + /** @brief The incoming transition is what led to this state, coming from its parent */ + std::shared_ptr incoming_transition_ = nullptr; + + /** Sequential state ID (used for debugging) */ long num_ = 0; - /** State's exploration status by process */ - std::vector actor_states_; + /** Unique parent of this state. Required both for sleep set computation + and for guided model-checking */ + std::shared_ptr parent_state_ = nullptr; - /** Snapshot of system state (if needed) */ - std::shared_ptr system_state_; + std::shared_ptr strategy_; -public: - explicit State(); + /* Sleep sets are composed of the actor and the corresponding transition that made it being added to the sleep + * set. With this information, it is check whether it should be removed from it or not when exploring a new + * transition */ + std::map> sleep_set_; + /** + * The wakeup tree with respect to the execution represented + * by the totality of all states before and including this one + * and with respect to this state's sleep set + */ + odpor::WakeupTree wakeup_tree_; + bool has_initialized_wakeup_tree = false; + +public: + explicit State(RemoteApp& remote_app); + explicit State(RemoteApp& remote_app, std::shared_ptr parent_state); /* Returns a positive number if there is another transition to pick, or -1 if not */ - int next_transition() const; + aid_t next_transition() const; // this function should disapear as it is redundant with the next one - /* Explore a new path; the parameter must be the result of a previous call to next_transition() */ - void execute_next(int next); + /* Same as next_transition(), but choice is now guided, and an integer corresponding to the + internal cost of the transition is returned */ + std::pair next_transition_guided() const; + + /** + * Same as next_transition(), but the choice is not based off the ODPOR + * wakeup tree associated with this state + */ + aid_t next_odpor_transition() const; + + /** + * @brief Explore a new path on the remote app; the parameter 'next' must be the result of a previous call to + * next_transition() + */ + std::shared_ptr execute_next(aid_t next, RemoteApp& app); long get_num() const { return num_; } std::size_t count_todo() const; - void mark_todo(aid_t actor) { this->actor_states_[actor].mark_todo(); } - bool is_done(aid_t actor) const { return this->actor_states_[actor].is_done(); } - Transition* get_transition() const; - void set_transition(Transition* t) { transition_.reset(t); } - - Snapshot* get_system_state() const { return system_state_.get(); } - void set_system_state(std::shared_ptr state) { system_state_ = std::move(state); } + std::size_t count_todo_multiples() const; + + /* Marking as TODO some actor in this state: + * + consider_one mark aid actor (and assert it is possible) + * + consider_best ensure one actor is marked by eventually marking the best regarding its guiding method + * + consider_all mark all enabled actor that are not done yet */ + void consider_one(aid_t aid) const { strategy_->consider_one(aid); } + void consider_best() const { strategy_->consider_best(); } + unsigned long consider_all() const { return strategy_->consider_all(); } + + bool is_actor_done(aid_t actor) const { return strategy_->actors_to_run_.at(actor).is_done(); } + std::shared_ptr get_transition_out() const { return outgoing_transition_; } + std::shared_ptr get_transition_in() const { return incoming_transition_; } + std::shared_ptr get_parent_state() const { return parent_state_; } + + std::map const& get_actors_list() const { return strategy_->actors_to_run_; } + + unsigned long get_actor_count() const { return strategy_->actors_to_run_.size(); } + bool is_actor_enabled(aid_t actor) const { return strategy_->actors_to_run_.at(actor).is_enabled(); } + + /** + * @brief Computes the backtrack set for this state + * according to its definition in SimGrid. + * + * The backtrack set as it appears in DPOR, SDPOR, and ODPOR + * in SimGrid consists of those actors marked as `todo` + * (i.e. those that have yet to be explored) as well as those + * marked `done` (i.e. those that have already been explored) + * since the pseudocode in none of the above algorithms explicitly + * removes elements from the backtrack set. DPOR makes use + * explicitly of the `done` set, but we again note that the + * backtrack set still contains processes added to the done set. + */ + std::unordered_set get_backtrack_set() const; + std::unordered_set get_sleeping_actors() const; + std::unordered_set get_enabled_actors() const; + std::map> const& get_sleep_set() const { return sleep_set_; } + void add_sleep_set(std::shared_ptr t) { sleep_set_.insert_or_assign(t->aid_, std::move(t)); } + bool is_actor_sleeping(aid_t actor) const + { + return std::find_if(sleep_set_.begin(), sleep_set_.end(), [=](const auto& pair) { return pair.first == actor; }) != + sleep_set_.end(); + } + + /** + * @brief Inserts an arbitrary enabled actor into the wakeup tree + * associated with this state, if such an actor exists and if + * the wakeup tree is already not empty + * + * @param prior The sequence of steps leading up to this state + * with respec to which the tree associated with this state should be + * a wakeup tree (wakeup trees are defined relative to an execution) + * + * @invariant: You should not manipulate a wakeup tree with respect + * to more than one execution; doing so will almost certainly lead to + * unexpected results as wakeup trees are defined relative to a single + * execution + */ + void seed_wakeup_tree_if_needed(const odpor::Execution& prior); + + /** + * @brief Initializes the wakeup_tree_ instance by taking the subtree rooted at the + * single-process node `N` running actor `p := "actor taken by parent to form this state"` + * of the *parent's* wakeup tree + */ + void sprout_tree_from_parent_state(); + + /** + * @brief Removes the subtree rooted at the single-process node + * `N` running actor `p` of this state's wakeup tree + */ + void remove_subtree_using_current_out_transition(); + void remove_subtree_at_aid(aid_t proc); + bool has_empty_tree() const { return this->wakeup_tree_.empty(); } + std::string string_of_wut() const { return this->wakeup_tree_.string_of_whole_tree(); } + + /** + * @brief + */ + odpor::WakeupTree::InsertionResult insert_into_wakeup_tree(const odpor::PartialExecution&, const odpor::Execution&); + + /** @brief Prepares the state for re-exploration following + * another after having followed ODPOR from this state with + * the current out transition + * + * After ODPOR has completed searching a maximal trace, it + * finds the first point in the execution with a nonempty wakeup + * tree. This method corresponds to lines 20 and 21 in the ODPOR + * pseudocode + */ + void do_odpor_unwind(); /* Returns the total amount of states created so far (for statistics) */ static long get_expanded_states() { return expended_states_; } diff --git a/src/mc/api/strategy/BasicStrategy.hpp b/src/mc/api/strategy/BasicStrategy.hpp new file mode 100644 index 0000000000..ca44509880 --- /dev/null +++ b/src/mc/api/strategy/BasicStrategy.hpp @@ -0,0 +1,58 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_BASICSTRATEGY_HPP +#define SIMGRID_MC_BASICSTRATEGY_HPP + +#include "Strategy.hpp" +#include "src/mc/explo/Exploration.hpp" + +XBT_LOG_EXTERNAL_CATEGORY(mc_dfs); + +namespace simgrid::mc { + +/** Basic MC guiding class which corresponds to no guide. When asked for different states + * it will follow a depth first search politics to minize the number of opened states. */ +class BasicStrategy : public Strategy { + int depth_ = _sg_mc_max_depth; // Arbitrary starting point. next_transition must return a positive value to work with + // threshold in DFSExplorer + +public: + void copy_from(const Strategy* strategy) override + { + const auto* cast_strategy = dynamic_cast(strategy); + xbt_assert(cast_strategy != nullptr); + depth_ = cast_strategy->depth_ - 1; + if (depth_ <= 0) { + XBT_CERROR(mc_dfs, + "The exploration reached a depth greater than %d. Change the depth limit with " + "--cfg=model-check/max-depth. Here are the 100 first trace elements", + _sg_mc_max_depth.get()); + auto trace = Exploration::get_instance()->get_textual_trace(100); + for (auto const& elm : trace) + XBT_CERROR(mc_dfs, " %s", elm.c_str()); + xbt_die("Aborting now."); + } + } + BasicStrategy() = default; + ~BasicStrategy() override = default; + + std::pair best_transition(bool must_be_todo) const override { + for (auto const& [aid, actor] : actors_to_run_) { + /* Only consider actors (1) marked as interleaving by the checker and (2) currently enabled in the application */ + if ((not actor.is_todo() && must_be_todo) || not actor.is_enabled() || actor.is_done()) + continue; + + return std::make_pair(aid, depth_); + } + return std::make_pair(-1, depth_); + } + + void execute_next(aid_t aid, RemoteApp& app) override { return; } +}; + +} // namespace simgrid::mc + +#endif diff --git a/src/mc/api/strategy/MaxMatchComm.hpp b/src/mc/api/strategy/MaxMatchComm.hpp new file mode 100644 index 0000000000..77dadd154c --- /dev/null +++ b/src/mc/api/strategy/MaxMatchComm.hpp @@ -0,0 +1,90 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_WAITSTRATEGY_HPP +#define SIMGRID_MC_WAITSTRATEGY_HPP + +#include "src/mc/transition/TransitionComm.hpp" + +namespace simgrid::mc { + +/** Wait MC guiding class that aims at minimizing the number of in-fly communication. + * When possible, it will try to match corresponding in-fly communications. */ +class MaxMatchComm : public Strategy { + /** Stores for each mailbox what kind of transition is waiting on it. + * Negative number means that much recv are waiting on that mailbox, while + * a positiv number means that much send are waiting there. */ + std::map mailbox_; + int value_of_state_ = 0; // used to valuate the state. Corresponds to the number of in-fly communications + // The two next values are used to save the operation we execute so the next strategy can update its field accordingly + Transition::Type last_transition_; + unsigned last_mailbox_ = 0; + +public: + void copy_from(const Strategy* strategy) override + { + const auto* cast_strategy = dynamic_cast(strategy); + xbt_assert(cast_strategy != nullptr); + for (auto& [id, val] : cast_strategy->mailbox_) + mailbox_[id] = val; + if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_RECV) + mailbox_[cast_strategy->last_mailbox_]--; + if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_SEND) + mailbox_[cast_strategy->last_mailbox_]++; + + for (auto const& [_, val] : mailbox_) + value_of_state_ += std::abs(val); + } + MaxMatchComm() = default; + ~MaxMatchComm() override = default; + + std::pair best_transition(bool must_be_todo) const override + { + std::pair min_found = std::make_pair(-1, value_of_state_ + 2); + for (auto const& [aid, actor] : actors_to_run_) { + if ((not actor.is_todo() && must_be_todo) || not actor.is_enabled() || actor.is_done()) + continue; + + int aid_value = value_of_state_; + const Transition* transition = actor.get_transition(actor.get_times_considered()).get(); + + if (auto const* cast_recv = dynamic_cast(transition)) { + if (mailbox_.count(cast_recv->get_mailbox()) > 0 && mailbox_.at(cast_recv->get_mailbox()) > 0) { + aid_value--; // This means we have waiting recv corresponding to this recv + } else { + aid_value++; + } + } + + if (auto const* cast_send = dynamic_cast(transition)) { + if (mailbox_.count(cast_send->get_mailbox()) > 0 && mailbox_.at(cast_send->get_mailbox()) < 0) { + aid_value--; // This means we have waiting recv corresponding to this send + } else { + aid_value++; + } + } + + if (aid_value < min_found.second) + min_found = std::make_pair(aid, aid_value); + } + return min_found; + } + + void execute_next(aid_t aid, RemoteApp& app) override + { + const Transition* transition = actors_to_run_.at(aid).get_transition(actors_to_run_.at(aid).get_times_considered()).get(); + last_transition_ = transition->type_; + + if (auto const* cast_recv = dynamic_cast(transition)) + last_mailbox_ = cast_recv->get_mailbox(); + + if (auto const* cast_send = dynamic_cast(transition)) + last_mailbox_ = cast_send->get_mailbox(); + } +}; + +} // namespace simgrid::mc + +#endif diff --git a/src/mc/api/strategy/MinMatchComm.hpp b/src/mc/api/strategy/MinMatchComm.hpp new file mode 100644 index 0000000000..7d06c9dcf0 --- /dev/null +++ b/src/mc/api/strategy/MinMatchComm.hpp @@ -0,0 +1,94 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_MINWAITTAKEN_HPP +#define SIMGRID_MC_MINWAITTAKEN_HPP + +#include "src/mc/transition/TransitionComm.hpp" + +namespace simgrid::mc { + +/** Wait MC guiding class that aims at maximizing the number of in-fly communication. + * When possible, it will try not to match communications. */ +class MinMatchComm : public Strategy { + /** Stores for each mailbox what kind of transition is waiting on it. + * Negative number means that much recv are waiting on that mailbox, while + * a positiv number means that much send are waiting there. */ + std::map mailbox_; + /** Used to valuate the state. Corresponds to a maximum minus the number of in-fly communications. + * Maximum should be set in order not to reach 0.*/ + int value_of_state_ = _sg_mc_max_depth; + + // The two next values are used to save the operation we execute so the next strategy can update its field accordingly + Transition::Type last_transition_; + unsigned last_mailbox_ = 0; + +public: + void copy_from(const Strategy* strategy) override + { + const auto* cast_strategy = dynamic_cast(strategy); + xbt_assert(cast_strategy != nullptr); + for (auto& [id, val] : cast_strategy->mailbox_) + mailbox_[id] = val; + if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_RECV) + mailbox_[cast_strategy->last_mailbox_]--; + if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_SEND) + mailbox_[cast_strategy->last_mailbox_]++; + + for (auto const& [_, val] : mailbox_) + value_of_state_ -= std::abs(val); + xbt_assert(value_of_state_ > 0, "MinMatchComm value shouldn't reach 0"); + } + MinMatchComm() = default; + ~MinMatchComm() override = default; + + std::pair best_transition(bool must_be_todo) const override + { + std::pair min_found = std::make_pair(-1, value_of_state_ + 2); + for (auto const& [aid, actor] : actors_to_run_) { + if ((not actor.is_todo() && must_be_todo) || not actor.is_enabled() || actor.is_done()) + continue; + + int aid_value = value_of_state_; + const Transition* transition = actor.get_transition(actor.get_times_considered()).get(); + + if (auto const* cast_recv = dynamic_cast(transition)) { + if ((mailbox_.count(cast_recv->get_mailbox()) > 0 && mailbox_.at(cast_recv->get_mailbox()) <= 0) || + mailbox_.count(cast_recv->get_mailbox()) == 0) + aid_value--; // This means we don't have waiting recv corresponding to this recv + else + aid_value++; + } + if (auto const* cast_send = dynamic_cast(transition)) { + if ((mailbox_.count(cast_send->get_mailbox()) > 0 && mailbox_.at(cast_send->get_mailbox()) >= 0) || + mailbox_.count(cast_send->get_mailbox()) == 0) + aid_value--; + else + aid_value++; + } + + if (aid_value < min_found.second) + min_found = std::make_pair(aid, aid_value); + } + return min_found; + } + + + void execute_next(aid_t aid, RemoteApp& app) override + { + const Transition* transition = actors_to_run_.at(aid).get_transition(actors_to_run_.at(aid).get_times_considered()).get(); + last_transition_ = transition->type_; + + if (auto const* cast_recv = dynamic_cast(transition)) + last_mailbox_ = cast_recv->get_mailbox(); + + if (auto const* cast_send = dynamic_cast(transition)) + last_mailbox_ = cast_send->get_mailbox(); + } +}; + +} // namespace simgrid::mc + +#endif diff --git a/src/mc/api/strategy/Strategy.hpp b/src/mc/api/strategy/Strategy.hpp new file mode 100644 index 0000000000..60e21f53fa --- /dev/null +++ b/src/mc/api/strategy/Strategy.hpp @@ -0,0 +1,81 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_STRATEGY_HPP +#define SIMGRID_MC_STRATEGY_HPP + +#include "simgrid/forward.h" +#include "src/mc/api/RemoteApp.hpp" +#include "src/mc/mc_config.hpp" +#include "xbt/asserts.h" +#include +#include + +namespace simgrid::mc { + +class Strategy { +protected: + /** State's exploration status by actor. All actors should be present, eventually disabled for now. */ + std::map actors_to_run_; + +public: + /** Strategies can have values shared from parent to children state. + * This method should copy all value the strategy needs from its parent. */ + virtual void copy_from(const Strategy*) = 0; + + Strategy() = default; + virtual ~Strategy() = default; + + /** Returns the best transition among according to the strategy for this state. + * The strategy should consider only enabled transition not already done. + * Furthermore, if must_be_todo is set to true, only transitions marked as todo + * should be considered. */ + virtual std::pair best_transition(bool must_be_todo) const = 0; + + /** Returns the best transition among those that should be interleaved. */ + std::pair next_transition() const { return best_transition(true); } + + /** Allows for the strategy to update its fields knowing that the actor aid will + * be executed and a children strategy will then be created. */ + virtual void execute_next(aid_t aid, RemoteApp& app) = 0; + + /** Ensure at least one transition is marked as todo among the enabled ones not done. + * If required, it marks as todo the best transition according to the strategy. */ + void consider_best() { + if (std::any_of(begin(actors_to_run_), end(actors_to_run_), + [](const auto& actor) { return actor.second.is_todo(); })) + return; + aid_t best_aid = best_transition(false).first; + if (best_aid != -1) + actors_to_run_.at(best_aid).mark_todo(); + } + + // Mark aid as todo. If it makes no sense, ie. if it is already done or not enabled, + // else raise an error + void consider_one(aid_t aid) + { + xbt_assert(actors_to_run_.at(aid).is_enabled() && not actors_to_run_.at(aid).is_done(), + "Tried to mark as TODO actor %ld but it is either not enabled or already done", aid); + actors_to_run_.at(aid).mark_todo(); + } + // Mark as todo all actors enabled that are not done yet and return the number + // of marked actors + unsigned long consider_all() + { + unsigned long count = 0; + for (auto& [_, actor] : actors_to_run_) + if (actor.is_enabled() && not actor.is_done()) { + actor.mark_todo(); + count++; + } + return count; + } + + friend class State; +}; + +} // namespace simgrid::mc + +#endif diff --git a/src/mc/api/strategy/UniformStrategy.hpp b/src/mc/api/strategy/UniformStrategy.hpp new file mode 100644 index 0000000000..472c571d3a --- /dev/null +++ b/src/mc/api/strategy/UniformStrategy.hpp @@ -0,0 +1,67 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_UNIFORMSTRATEGY_HPP +#define SIMGRID_MC_UNIFORMSTRATEGY_HPP + +#include "src/mc/transition/Transition.hpp" +#include "xbt/random.hpp" + +namespace simgrid::mc { + +/** Guiding strategy that valuate states randomly */ +class UniformStrategy : public Strategy { + static constexpr int MAX_RAND = 100000; + + std::map valuation; + +public: + UniformStrategy() + { + for (long aid = 0; aid < 10; aid++) + valuation[aid] = xbt::random::uniform_int(0, MAX_RAND); + } + void copy_from(const Strategy* strategy) override + { + for (auto const& [aid, _] : actors_to_run_) + valuation[aid] = xbt::random::uniform_int(0, MAX_RAND); + } + + std::pair best_transition(bool must_be_todo) const override + { + int possibilities = 0; + + // Consider only valid actors + for (auto const& [aid, actor] : actors_to_run_) { + if ((actor.is_todo() || not must_be_todo) && (not actor.is_done()) && actor.is_enabled()) + possibilities++; + } + + int chosen; + if (possibilities == 0) + return std::make_pair(-1, 0); + if (possibilities == 1) + chosen = 0; + else + chosen = xbt::random::uniform_int(0, possibilities-1); + + for (auto const& [aid, actor] : actors_to_run_) { + if (((not actor.is_todo()) && must_be_todo) || actor.is_done() || (not actor.is_enabled())) + continue; + if (chosen == 0) { + return std::make_pair(aid, valuation.at(aid)); + } + chosen--; + } + + return std::make_pair(-1, 0); + } + + void execute_next(aid_t aid, RemoteApp& app) override {} +}; + +} // namespace simgrid::mc + +#endif diff --git a/src/mc/compare.cpp b/src/mc/compare.cpp deleted file mode 100644 index 6b7ffe1f45..0000000000 --- a/src/mc/compare.cpp +++ /dev/null @@ -1,1263 +0,0 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/** \file compare.cpp Memory snapshotting and comparison */ - -#include "src/mc/mc_config.hpp" -#include "src/mc/mc_private.hpp" -#include "src/mc/sosp/Snapshot.hpp" - -#include - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_compare, mc, "Logging specific to mc_compare in mc"); - -namespace simgrid::mc { - -/*********************************** Heap comparison ***********************************/ -/***************************************************************************************/ - -class HeapLocation { -public: - int block_ = 0; - int fragment_ = 0; - - HeapLocation() = default; - explicit HeapLocation(int block, int fragment = 0) : block_(block), fragment_(fragment) {} - - bool operator==(HeapLocation const& that) const - { - return block_ == that.block_ && fragment_ == that.fragment_; - } - bool operator<(HeapLocation const& that) const - { - return std::make_pair(block_, fragment_) < std::make_pair(that.block_, that.fragment_); - } -}; - -using HeapLocationPair = std::array; -using HeapLocationPairs = std::set; - -class HeapArea : public HeapLocation { -public: - bool valid_ = false; - HeapArea() = default; - explicit HeapArea(int block) : valid_(true) { block_ = block; } - HeapArea(int block, int fragment) : valid_(true) - { - block_ = block; - fragment_ = fragment; - } -}; - -class ProcessComparisonState { -public: - const std::vector* to_ignore = nullptr; - std::vector equals_to; - std::vector types; - std::size_t heapsize = 0; - - void initHeapInformation(const s_xbt_mheap_t* heap, const std::vector& i); -}; - -class StateComparator { -public: - s_xbt_mheap_t std_heap_copy; - std::size_t heaplimit; - std::array processStates; - - std::unordered_set, simgrid::xbt::hash>> - compared_pointers; - - void clear() - { - compared_pointers.clear(); - } - - int initHeapInformation(const s_xbt_mheap_t* heap1, const s_xbt_mheap_t* heap2, - const std::vector& i1, const std::vector& i2); - - template HeapArea& equals_to_(std::size_t i, std::size_t j) - { - return processStates[rank - 1].equals_to[MAX_FRAGMENT_PER_BLOCK * i + j]; - } - template Type*& types_(std::size_t i, std::size_t j) - { - return processStates[rank - 1].types[MAX_FRAGMENT_PER_BLOCK * i + j]; - } - - template HeapArea const& equals_to_(std::size_t i, std::size_t j) const - { - return processStates[rank - 1].equals_to[MAX_FRAGMENT_PER_BLOCK * i + j]; - } - template Type* const& types_(std::size_t i, std::size_t j) const - { - return processStates[rank - 1].types[MAX_FRAGMENT_PER_BLOCK * i + j]; - } - - /** Check whether two blocks are known to be matching - * - * @param b1 Block of state 1 - * @param b2 Block of state 2 - * @return if the blocks are known to be matching - */ - bool blocksEqual(int b1, int b2) const - { - return this->equals_to_<1>(b1, 0).block_ == b2 && this->equals_to_<2>(b2, 0).block_ == b1; - } - - /** Check whether two fragments are known to be matching - * - * @param b1 Block of state 1 - * @param f1 Fragment of state 1 - * @param b2 Block of state 2 - * @param f2 Fragment of state 2 - * @return if the fragments are known to be matching - */ - int fragmentsEqual(int b1, int f1, int b2, int f2) const - { - return this->equals_to_<1>(b1, f1).block_ == b2 && this->equals_to_<1>(b1, f1).fragment_ == f2 && - this->equals_to_<2>(b2, f2).block_ == b1 && this->equals_to_<2>(b2, f2).fragment_ == f1; - } - - void match_equals(const HeapLocationPairs* list); -}; - -} // namespace simgrid::mc - -/************************************************************************************/ - -static ssize_t heap_comparison_ignore_size(const std::vector* ignore_list, - const void* address) -{ - auto pos = std::lower_bound(ignore_list->begin(), ignore_list->end(), address, - [](auto const& reg, auto const* addr) { return reg.address < addr; }); - return (pos != ignore_list->end() && pos->address == address) ? pos->size : -1; -} - -static bool is_stack(const simgrid::mc::RemoteProcess& process, const void* address) -{ - auto const& stack_areas = process.stack_areas(); - return std::any_of(stack_areas.begin(), stack_areas.end(), - [address](auto const& stack) { return stack.address == address; }); -} - -// TODO, this should depend on the snapshot? -static bool is_block_stack(const simgrid::mc::RemoteProcess& process, int block) -{ - auto const& stack_areas = process.stack_areas(); - return std::any_of(stack_areas.begin(), stack_areas.end(), - [block](auto const& stack) { return stack.block == block; }); -} - -namespace simgrid::mc { - -void StateComparator::match_equals(const HeapLocationPairs* list) -{ - for (auto const& pair : *list) { - if (pair[0].fragment_ != -1) { - this->equals_to_<1>(pair[0].block_, pair[0].fragment_) = HeapArea(pair[1].block_, pair[1].fragment_); - this->equals_to_<2>(pair[1].block_, pair[1].fragment_) = HeapArea(pair[0].block_, pair[0].fragment_); - } else { - this->equals_to_<1>(pair[0].block_, 0) = HeapArea(pair[1].block_, pair[1].fragment_); - this->equals_to_<2>(pair[1].block_, 0) = HeapArea(pair[0].block_, pair[0].fragment_); - } - } -} - -void ProcessComparisonState::initHeapInformation(const s_xbt_mheap_t* heap, const std::vector& i) -{ - auto heaplimit = heap->heaplimit; - this->heapsize = heap->heapsize; - this->to_ignore = &i; - this->equals_to.assign(heaplimit * MAX_FRAGMENT_PER_BLOCK, HeapArea()); - this->types.assign(heaplimit * MAX_FRAGMENT_PER_BLOCK, nullptr); -} - -int StateComparator::initHeapInformation(const s_xbt_mheap_t* heap1, const s_xbt_mheap_t* heap2, - const std::vector& i1, - const std::vector& i2) -{ - if ((heap1->heaplimit != heap2->heaplimit) || (heap1->heapsize != heap2->heapsize)) - return -1; - this->heaplimit = heap1->heaplimit; - this->std_heap_copy = *mc_model_checker->get_remote_process().get_heap(); - this->processStates[0].initHeapInformation(heap1, i1); - this->processStates[1].initHeapInformation(heap2, i2); - return 0; -} - -// TODO, have a robust way to find it in O(1) -static inline Region* MC_get_heap_region(const Snapshot& snapshot) -{ - for (auto const& region : snapshot.snapshot_regions_) - if (region->region_type() == RegionType::Heap) - return region.get(); - xbt_die("No heap region"); -} - -static bool heap_area_differ(const RemoteProcess& process, StateComparator& state, const void* area1, const void* area2, - const Snapshot& snapshot1, const Snapshot& snapshot2, HeapLocationPairs* previous, - Type* type, int pointer_level); - -static bool mmalloc_heap_differ(const RemoteProcess& process, StateComparator& state, const Snapshot& snapshot1, - const Snapshot& snapshot2) -{ - /* Check busy blocks */ - size_t i1 = 1; - - malloc_info heapinfo_temp1; - malloc_info heapinfo_temp2; - malloc_info heapinfo_temp2b; - - const Region* heap_region1 = MC_get_heap_region(snapshot1); - const Region* heap_region2 = MC_get_heap_region(snapshot2); - - // This is the address of std_heap->heapinfo in the application process: - uint64_t heapinfo_address = process.heap_address.address() + offsetof(s_xbt_mheap_t, heapinfo); - - // This is in snapshot do not use them directly: - const malloc_info* heapinfos1 = snapshot1.read(remote(heapinfo_address)); - const malloc_info* heapinfos2 = snapshot2.read(remote(heapinfo_address)); - - while (i1 < state.heaplimit) { - const auto* heapinfo1 = - static_cast(heap_region1->read(&heapinfo_temp1, &heapinfos1[i1], sizeof(malloc_info))); - const auto* heapinfo2 = - static_cast(heap_region2->read(&heapinfo_temp2, &heapinfos2[i1], sizeof(malloc_info))); - - if (heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type == MMALLOC_TYPE_HEAPINFO) { /* Free block */ - i1 ++; - continue; - } - - xbt_assert(heapinfo1->type >= 0, "Unknown mmalloc block type: %d", heapinfo1->type); - - void* addr_block1 = (ADDR2UINT(i1) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase; - - if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED) { /* Large block */ - if (is_stack(process, addr_block1)) { - for (size_t k = 0; k < heapinfo1->busy_block.size; k++) - state.equals_to_<1>(i1 + k, 0) = HeapArea(i1, -1); - for (size_t k = 0; k < heapinfo2->busy_block.size; k++) - state.equals_to_<2>(i1 + k, 0) = HeapArea(i1, -1); - i1 += heapinfo1->busy_block.size; - continue; - } - - if (state.equals_to_<1>(i1, 0).valid_) { - i1++; - continue; - } - - size_t i2 = 1; - bool equal = false; - - /* Try first to associate to same block in the other heap */ - if (heapinfo2->type == heapinfo1->type && state.equals_to_<2>(i1, 0).valid_ == 0) { - const void* addr_block2 = (ADDR2UINT(i1) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase; - if (not heap_area_differ(process, state, addr_block1, addr_block2, snapshot1, snapshot2, nullptr, nullptr, 0)) { - for (size_t k = 1; k < heapinfo2->busy_block.size; k++) - state.equals_to_<2>(i1 + k, 0) = HeapArea(i1, -1); - for (size_t k = 1; k < heapinfo1->busy_block.size; k++) - state.equals_to_<1>(i1 + k, 0) = HeapArea(i1, -1); - equal = true; - i1 += heapinfo1->busy_block.size; - } - } - - while (i2 < state.heaplimit && not equal) { - const void* addr_block2 = (ADDR2UINT(i2) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase; - - if (i2 == i1) { - i2++; - continue; - } - - const auto* heapinfo2b = - static_cast(heap_region2->read(&heapinfo_temp2b, &heapinfos2[i2], sizeof(malloc_info))); - - if (heapinfo2b->type != MMALLOC_TYPE_UNFRAGMENTED) { - i2++; - continue; - } - - if (state.equals_to_<2>(i2, 0).valid_) { - i2++; - continue; - } - - if (not heap_area_differ(process, state, addr_block1, addr_block2, snapshot1, snapshot2, nullptr, nullptr, 0)) { - for (size_t k = 1; k < heapinfo2b->busy_block.size; k++) - state.equals_to_<2>(i2 + k, 0) = HeapArea(i1, -1); - for (size_t k = 1; k < heapinfo1->busy_block.size; k++) - state.equals_to_<1>(i1 + k, 0) = HeapArea(i2, -1); - equal = true; - i1 += heapinfo1->busy_block.size; - } - i2++; - } - - if (not equal) { - XBT_DEBUG("Block %zu not found (size_used = %zu, addr = %p)", i1, heapinfo1->busy_block.busy_size, addr_block1); - return true; - } - } else { /* Fragmented block */ - for (size_t j1 = 0; j1 < (size_t)(BLOCKSIZE >> heapinfo1->type); j1++) { - if (heapinfo1->busy_frag.frag_size[j1] == -1) /* Free fragment_ */ - continue; - - if (state.equals_to_<1>(i1, j1).valid_) - continue; - - void* addr_frag1 = (char*)addr_block1 + (j1 << heapinfo1->type); - - size_t i2 = 1; - bool equal = false; - - /* Try first to associate to same fragment_ in the other heap */ - if (heapinfo2->type == heapinfo1->type && not state.equals_to_<2>(i1, j1).valid_) { - const void* addr_block2 = (ADDR2UINT(i1) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase; - const void* addr_frag2 = (const char*)addr_block2 + (j1 << heapinfo2->type); - if (not heap_area_differ(process, state, addr_frag1, addr_frag2, snapshot1, snapshot2, nullptr, nullptr, 0)) - equal = true; - } - - while (i2 < state.heaplimit && not equal) { - const auto* heapinfo2b = - static_cast(heap_region2->read(&heapinfo_temp2b, &heapinfos2[i2], sizeof(malloc_info))); - - if (heapinfo2b->type == MMALLOC_TYPE_FREE || heapinfo2b->type == MMALLOC_TYPE_HEAPINFO) { - i2 ++; - continue; - } - - // We currently do not match fragments with unfragmented blocks (maybe we should). - if (heapinfo2b->type == MMALLOC_TYPE_UNFRAGMENTED) { - i2++; - continue; - } - - xbt_assert(heapinfo2b->type >= 0, "Unknown mmalloc block type: %d", heapinfo2b->type); - - for (size_t j2 = 0; j2 < (size_t)(BLOCKSIZE >> heapinfo2b->type); j2++) { - if (i2 == i1 && j2 == j1) - continue; - - if (state.equals_to_<2>(i2, j2).valid_) - continue; - - const void* addr_block2 = (ADDR2UINT(i2) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase; - const void* addr_frag2 = (const char*)addr_block2 + (j2 << heapinfo2b->type); - - if (not heap_area_differ(process, state, addr_frag1, addr_frag2, snapshot1, snapshot2, nullptr, nullptr, - 0)) { - equal = true; - break; - } - } - i2++; - } - - if (not equal) { - XBT_DEBUG("Block %zu, fragment_ %zu not found (size_used = %zd, address = %p)\n", i1, j1, - heapinfo1->busy_frag.frag_size[j1], addr_frag1); - return true; - } - } - i1++; - } - } - - /* All blocks/fragments are equal to another block/fragment_ ? */ - for (size_t i = 1; i < state.heaplimit; i++) { - const auto* heapinfo1 = - static_cast(heap_region1->read(&heapinfo_temp1, &heapinfos1[i], sizeof(malloc_info))); - - if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED && i1 == state.heaplimit && heapinfo1->busy_block.busy_size > 0 && - not state.equals_to_<1>(i, 0).valid_) { - XBT_DEBUG("Block %zu not found (size used = %zu)", i, heapinfo1->busy_block.busy_size); - return true; - } - - if (heapinfo1->type <= 0) - continue; - for (size_t j = 0; j < (size_t)(BLOCKSIZE >> heapinfo1->type); j++) - if (i1 == state.heaplimit && heapinfo1->busy_frag.frag_size[j] > 0 && not state.equals_to_<1>(i, j).valid_) { - XBT_DEBUG("Block %zu, Fragment %zu not found (size used = %zd)", i, j, heapinfo1->busy_frag.frag_size[j]); - return true; - } - } - - for (size_t i = 1; i < state.heaplimit; i++) { - const auto* heapinfo2 = - static_cast(heap_region2->read(&heapinfo_temp2, &heapinfos2[i], sizeof(malloc_info))); - if (heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED && i1 == state.heaplimit && heapinfo2->busy_block.busy_size > 0 && - not state.equals_to_<2>(i, 0).valid_) { - XBT_DEBUG("Block %zu not found (size used = %zu)", i, - heapinfo2->busy_block.busy_size); - return true; - } - - if (heapinfo2->type <= 0) - continue; - - for (size_t j = 0; j < (size_t)(BLOCKSIZE >> heapinfo2->type); j++) - if (i1 == state.heaplimit && heapinfo2->busy_frag.frag_size[j] > 0 && not state.equals_to_<2>(i, j).valid_) { - XBT_DEBUG("Block %zu, Fragment %zu not found (size used = %zd)", - i, j, heapinfo2->busy_frag.frag_size[j]); - return true; - } - } - return false; -} - -/** - * - * @param state - * @param real_area1 Process address for state 1 - * @param real_area2 Process address for state 2 - * @param snapshot1 Snapshot of state 1 - * @param snapshot2 Snapshot of state 2 - * @param previous - * @param size - * @param check_ignore - * @return true when different, false otherwise (same or unknown) - */ -static bool heap_area_differ_without_type(const RemoteProcess& process, StateComparator& state, const void* real_area1, - const void* real_area2, const Snapshot& snapshot1, const Snapshot& snapshot2, - HeapLocationPairs* previous, int size, int check_ignore) -{ - const Region* heap_region1 = MC_get_heap_region(snapshot1); - const Region* heap_region2 = MC_get_heap_region(snapshot2); - - for (int i = 0; i < size; ) { - if (check_ignore > 0) { - ssize_t ignore1 = heap_comparison_ignore_size(state.processStates[0].to_ignore, (const char*)real_area1 + i); - if (ignore1 != -1) { - ssize_t ignore2 = heap_comparison_ignore_size(state.processStates[1].to_ignore, (const char*)real_area2 + i); - if (ignore2 == ignore1) { - if (ignore1 == 0) { - return false; - } else { - i = i + ignore2; - check_ignore--; - continue; - } - } - } - } - - if (MC_snapshot_region_memcmp((const char*)real_area1 + i, heap_region1, (const char*)real_area2 + i, heap_region2, - 1) != 0) { - int pointer_align = (i / sizeof(void *)) * sizeof(void *); - const void* addr_pointed1 = snapshot1.read(remote((void* const*)((const char*)real_area1 + pointer_align))); - const void* addr_pointed2 = snapshot2.read(remote((void* const*)((const char*)real_area2 + pointer_align))); - - if (process.in_maestro_stack(remote(addr_pointed1)) && process.in_maestro_stack(remote(addr_pointed2))) { - i = pointer_align + sizeof(void *); - continue; - } - - if (snapshot1.on_heap(addr_pointed1) && snapshot2.on_heap(addr_pointed2)) { - // Both addresses are in the heap: - if (heap_area_differ(process, state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, nullptr, 0)) - return true; - i = pointer_align + sizeof(void *); - continue; - } - return true; - } - i++; - } - return false; -} - -/** - * - * @param state - * @param real_area1 Process address for state 1 - * @param real_area2 Process address for state 2 - * @param snapshot1 Snapshot of state 1 - * @param snapshot2 Snapshot of state 2 - * @param previous - * @param type - * @param area_size either a byte_size or an elements_count (?) - * @param check_ignore - * @param pointer_level - * @return true when different, false otherwise (same or unknown) - */ -static bool heap_area_differ_with_type(const simgrid::mc::RemoteProcess& process, StateComparator& state, - const void* real_area1, const void* real_area2, const Snapshot& snapshot1, - const Snapshot& snapshot2, HeapLocationPairs* previous, const Type* type, - int area_size, int check_ignore, int pointer_level) -{ - // HACK: This should not happen but in practice, there are some - // DW_TAG_typedef without an associated DW_AT_type: - //<1><538832>: Abbrev Number: 111 (DW_TAG_typedef) - // <538833> DW_AT_name : (indirect string, offset: 0x2292f3): gregset_t - // <538837> DW_AT_decl_file : 98 - // <538838> DW_AT_decl_line : 37 - if (type == nullptr) - return false; - - if (is_stack(process, real_area1) && is_stack(process, real_area2)) - return false; - - if (check_ignore > 0) { - ssize_t ignore1 = heap_comparison_ignore_size(state.processStates[0].to_ignore, real_area1); - if (ignore1 > 0 && heap_comparison_ignore_size(state.processStates[1].to_ignore, real_area2) == ignore1) - return false; - } - - const Type* subtype; - const Type* subsubtype; - int elm_size; - const void* addr_pointed1; - const void* addr_pointed2; - - const Region* heap_region1 = MC_get_heap_region(snapshot1); - const Region* heap_region2 = MC_get_heap_region(snapshot2); - - switch (type->type) { - case DW_TAG_unspecified_type: - return true; - - case DW_TAG_base_type: - if (not type->name.empty() && type->name == "char") { /* String, hence random (arbitrary ?) size */ - if (real_area1 == real_area2) - return false; - else - return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, area_size) != 0; - } else { - if (area_size != -1 && type->byte_size != area_size) - return false; - else - return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0; - } - - case DW_TAG_enumeration_type: - if (area_size != -1 && type->byte_size != area_size) - return false; - return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0; - - case DW_TAG_typedef: - case DW_TAG_const_type: - case DW_TAG_volatile_type: - return heap_area_differ_with_type(process, state, real_area1, real_area2, snapshot1, snapshot2, previous, - type->subtype, area_size, check_ignore, pointer_level); - - case DW_TAG_array_type: - subtype = type->subtype; - switch (subtype->type) { - case DW_TAG_unspecified_type: - return true; - - case DW_TAG_base_type: - case DW_TAG_enumeration_type: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_rvalue_reference_type: - case DW_TAG_structure_type: - case DW_TAG_class_type: - case DW_TAG_union_type: - if (subtype->full_type) - subtype = subtype->full_type; - elm_size = subtype->byte_size; - break; - // TODO, just remove the type indirection? - case DW_TAG_const_type: - case DW_TAG_typedef: - case DW_TAG_volatile_type: - subsubtype = subtype->subtype; - if (subsubtype->full_type) - subsubtype = subsubtype->full_type; - elm_size = subsubtype->byte_size; - break; - default: - return false; - } - for (int i = 0; i < type->element_count; i++) { - // TODO, add support for variable stride (DW_AT_byte_stride) - if (heap_area_differ_with_type(process, state, (const char*)real_area1 + (i * elm_size), - (const char*)real_area2 + (i * elm_size), snapshot1, snapshot2, previous, - type->subtype, subtype->byte_size, check_ignore, pointer_level)) - return true; - } - return false; - - case DW_TAG_reference_type: - case DW_TAG_rvalue_reference_type: - case DW_TAG_pointer_type: - if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) { - addr_pointed1 = snapshot1.read(remote((void* const*)real_area1)); - addr_pointed2 = snapshot2.read(remote((void* const*)real_area2)); - return (addr_pointed1 != addr_pointed2); - } - pointer_level++; - if (pointer_level <= 1) { - addr_pointed1 = snapshot1.read(remote((void* const*)real_area1)); - addr_pointed2 = snapshot2.read(remote((void* const*)real_area2)); - if (snapshot1.on_heap(addr_pointed1) && snapshot2.on_heap(addr_pointed2)) - return heap_area_differ(process, state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, - type->subtype, pointer_level); - else - return (addr_pointed1 != addr_pointed2); - } - for (size_t i = 0; i < (area_size / sizeof(void*)); i++) { - addr_pointed1 = snapshot1.read(remote((void* const*)((const char*)real_area1 + i * sizeof(void*)))); - addr_pointed2 = snapshot2.read(remote((void* const*)((const char*)real_area2 + i * sizeof(void*)))); - bool differ = snapshot1.on_heap(addr_pointed1) && snapshot2.on_heap(addr_pointed2) - ? heap_area_differ(process, state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, - previous, type->subtype, pointer_level) - : addr_pointed1 != addr_pointed2; - if (differ) - return true; - } - return false; - - case DW_TAG_structure_type: - case DW_TAG_class_type: - if (type->full_type) - type = type->full_type; - if (type->byte_size == 0) - return false; - if (area_size != -1 && type->byte_size != area_size) { - if (area_size <= type->byte_size || area_size % type->byte_size != 0) - return false; - for (size_t i = 0; i < (size_t)(area_size / type->byte_size); i++) { - if (heap_area_differ_with_type(process, state, (const char*)real_area1 + i * type->byte_size, - (const char*)real_area2 + i * type->byte_size, snapshot1, snapshot2, previous, - type, -1, check_ignore, 0)) - return true; - } - } else { - for (const simgrid::mc::Member& member : type->members) { - // TODO, optimize this? (for the offset case) - const void* real_member1 = dwarf::resolve_member(real_area1, type, &member, &snapshot1); - const void* real_member2 = dwarf::resolve_member(real_area2, type, &member, &snapshot2); - if (heap_area_differ_with_type(process, state, real_member1, real_member2, snapshot1, snapshot2, previous, - member.type, -1, check_ignore, 0)) - return true; - } - } - return false; - - case DW_TAG_union_type: - return heap_area_differ_without_type(process, state, real_area1, real_area2, snapshot1, snapshot2, previous, - type->byte_size, check_ignore); - - default: - THROW_IMPOSSIBLE; - } -} - -/** Infer the type of a part of the block from the type of the block - * - * TODO, handle DW_TAG_array_type as well as arrays of the object ((*p)[5], p[5]) - * - * TODO, handle subfields ((*p).bar.foo, (*p)[5].bar…) - * - * @param type DWARF type ID of the root address - * @param area_size - * @return DWARF type ID for given offset - */ -static Type* get_offset_type(void* real_base_address, Type* type, int offset, int area_size, const Snapshot& snapshot) -{ - // Beginning of the block, the inferred variable type if the type of the block: - if (offset == 0) - return type; - - switch (type->type) { - case DW_TAG_structure_type: - case DW_TAG_class_type: - if (type->full_type) - type = type->full_type; - if (area_size != -1 && type->byte_size != area_size) { - if (area_size > type->byte_size && area_size % type->byte_size == 0) - return type; - else - return nullptr; - } - - for (const simgrid::mc::Member& member : type->members) { - if (member.has_offset_location()) { - // We have the offset, use it directly (shortcut): - if (member.offset() == offset) - return member.type; - } else { - void* real_member = dwarf::resolve_member(real_base_address, type, &member, &snapshot); - if ((char*)real_member - (char*)real_base_address == offset) - return member.type; - } - } - return nullptr; - - default: - /* FIXME: other cases ? */ - return nullptr; - } -} - -/** - * - * @param area1 Process address for state 1 - * @param area2 Process address for state 2 - * @param snapshot1 Snapshot of state 1 - * @param snapshot2 Snapshot of state 2 - * @param previous Pairs of blocks already compared on the current path (or nullptr) - * @param type_id Type of variable - * @param pointer_level - * @return true when different, false otherwise (same or unknown) - */ -static bool heap_area_differ(const RemoteProcess& process, StateComparator& state, const void* area1, const void* area2, - const Snapshot& snapshot1, const Snapshot& snapshot2, HeapLocationPairs* previous, - Type* type, int pointer_level) -{ - ssize_t block1; - ssize_t block2; - ssize_t size; - int check_ignore = 0; - - int type_size = -1; - int offset1 = 0; - int offset2 = 0; - int new_size1 = -1; - int new_size2 = -1; - - Type* new_type1 = nullptr; - - bool match_pairs = false; - - // This is the address of std_heap->heapinfo in the application process: - uint64_t heapinfo_address = process.heap_address.address() + offsetof(s_xbt_mheap_t, heapinfo); - - const malloc_info* heapinfos1 = snapshot1.read(remote(heapinfo_address)); - const malloc_info* heapinfos2 = snapshot2.read(remote(heapinfo_address)); - - malloc_info heapinfo_temp1; - malloc_info heapinfo_temp2; - - simgrid::mc::HeapLocationPairs current; - if (previous == nullptr) { - previous = ¤t; - match_pairs = true; - } - - // Get block number: - block1 = ((const char*)area1 - (const char*)state.std_heap_copy.heapbase) / BLOCKSIZE + 1; - block2 = ((const char*)area2 - (const char*)state.std_heap_copy.heapbase) / BLOCKSIZE + 1; - - // If either block is a stack block: - if (is_block_stack(process, (int)block1) && is_block_stack(process, (int)block2)) { - previous->insert(HeapLocationPair{{HeapLocation(block1, -1), HeapLocation(block2, -1)}}); - if (match_pairs) - state.match_equals(previous); - return false; - } - - // If either block is not in the expected area of memory: - if (((const char*)area1 < (const char*)state.std_heap_copy.heapbase) || - (block1 > (ssize_t)state.processStates[0].heapsize) || (block1 < 1) || - ((const char*)area2 < (const char*)state.std_heap_copy.heapbase) || - (block2 > (ssize_t)state.processStates[1].heapsize) || (block2 < 1)) { - return true; - } - - // Process address of the block: - void* real_addr_block1 = (ADDR2UINT(block1) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase; - void* real_addr_block2 = (ADDR2UINT(block2) - 1) * BLOCKSIZE + (char*)state.std_heap_copy.heapbase; - - if (type) { - if (type->full_type) - type = type->full_type; - - // This assume that for "boring" types (volatile ...) byte_size is absent: - while (type->byte_size == 0 && type->subtype != nullptr) - type = type->subtype; - - // Find type_size: - if (type->type == DW_TAG_pointer_type || - (type->type == DW_TAG_base_type && not type->name.empty() && type->name == "char")) - type_size = -1; - else - type_size = type->byte_size; - } - - const Region* heap_region1 = MC_get_heap_region(snapshot1); - const Region* heap_region2 = MC_get_heap_region(snapshot2); - - const auto* heapinfo1 = - static_cast(heap_region1->read(&heapinfo_temp1, &heapinfos1[block1], sizeof(malloc_info))); - const auto* heapinfo2 = - static_cast(heap_region2->read(&heapinfo_temp2, &heapinfos2[block2], sizeof(malloc_info))); - - if ((heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type==MMALLOC_TYPE_HEAPINFO) - && (heapinfo2->type == MMALLOC_TYPE_FREE || heapinfo2->type ==MMALLOC_TYPE_HEAPINFO)) { - /* Free block */ - if (match_pairs) - state.match_equals(previous); - return false; - } - - if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED && heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED) { - /* Complete block */ - - // TODO, lookup variable type from block type as done for fragmented blocks - - if (state.equals_to_<1>(block1, 0).valid_ && state.equals_to_<2>(block2, 0).valid_ && - state.blocksEqual(block1, block2)) { - if (match_pairs) - state.match_equals(previous); - return false; - } - - if (type_size != -1 && type_size != (ssize_t)heapinfo1->busy_block.busy_size && - type_size != (ssize_t)heapinfo2->busy_block.busy_size && - (type->name.empty() || - type->name == "struct s_smx_context")) { // FIXME: there is no struct s_smx_context anymore - if (match_pairs) - state.match_equals(previous); - return false; - } - - if (heapinfo1->busy_block.size != heapinfo2->busy_block.size || - heapinfo1->busy_block.busy_size != heapinfo2->busy_block.busy_size) - return true; - - if (not previous->insert(HeapLocationPair{{HeapLocation(block1, -1), HeapLocation(block2, -1)}}).second) { - if (match_pairs) - state.match_equals(previous); - return false; - } - - size = heapinfo1->busy_block.busy_size; - - // Remember (basic) type inference. - // The current data structure only allows us to do this for the whole block. - if (type != nullptr && area1 == real_addr_block1) - state.types_<1>(block1, 0) = type; - if (type != nullptr && area2 == real_addr_block2) - state.types_<2>(block2, 0) = type; - - if (size <= 0) { - if (match_pairs) - state.match_equals(previous); - return false; - } - - if (heapinfo1->busy_block.ignore > 0 && heapinfo2->busy_block.ignore == heapinfo1->busy_block.ignore) - check_ignore = heapinfo1->busy_block.ignore; - - } else if ((heapinfo1->type > 0) && (heapinfo2->type > 0)) { /* Fragmented block */ - // Fragment number: - ssize_t frag1 = (ADDR2UINT(area1) % BLOCKSIZE) >> heapinfo1->type; - ssize_t frag2 = (ADDR2UINT(area2) % BLOCKSIZE) >> heapinfo2->type; - - // Process address of the fragment_: - void* real_addr_frag1 = (char*)real_addr_block1 + (frag1 << heapinfo1->type); - void* real_addr_frag2 = (char*)real_addr_block2 + (frag2 << heapinfo2->type); - - // Check the size of the fragments against the size of the type: - if (type_size != -1) { - if (heapinfo1->busy_frag.frag_size[frag1] == -1 || heapinfo2->busy_frag.frag_size[frag2] == -1) { - if (match_pairs) - state.match_equals(previous); - return false; - } - // ? - if (type_size != heapinfo1->busy_frag.frag_size[frag1] - || type_size != heapinfo2->busy_frag.frag_size[frag2]) { - if (match_pairs) - state.match_equals(previous); - return false; - } - } - - // Check if the blocks are already matched together: - if (state.equals_to_<1>(block1, frag1).valid_ && state.equals_to_<2>(block2, frag2).valid_ && - state.fragmentsEqual(block1, frag1, block2, frag2)) { - if (match_pairs) - state.match_equals(previous); - return false; - } - // Compare the size of both fragments: - if (heapinfo1->busy_frag.frag_size[frag1] != heapinfo2->busy_frag.frag_size[frag2]) { - if (type_size == -1) { - if (match_pairs) - state.match_equals(previous); - return false; - } else - return true; - } - - // Size of the fragment_: - size = heapinfo1->busy_frag.frag_size[frag1]; - - // Remember (basic) type inference. - // The current data structure only allows us to do this for the whole fragment_. - if (type != nullptr && area1 == real_addr_frag1) - state.types_<1>(block1, frag1) = type; - if (type != nullptr && area2 == real_addr_frag2) - state.types_<2>(block2, frag2) = type; - - // The type of the variable is already known: - if (type) { - new_type1 = type; - } - // Type inference from the block type. - else if (state.types_<1>(block1, frag1) != nullptr || state.types_<2>(block2, frag2) != nullptr) { - Type* new_type2 = nullptr; - - offset1 = (const char*)area1 - (const char*)real_addr_frag1; - offset2 = (const char*)area2 - (const char*)real_addr_frag2; - - if (state.types_<1>(block1, frag1) != nullptr && state.types_<2>(block2, frag2) != nullptr) { - new_type1 = get_offset_type(real_addr_frag1, state.types_<1>(block1, frag1), offset1, size, snapshot1); - new_type2 = get_offset_type(real_addr_frag2, state.types_<2>(block2, frag2), offset1, size, snapshot2); - } else if (state.types_<1>(block1, frag1) != nullptr) { - new_type1 = get_offset_type(real_addr_frag1, state.types_<1>(block1, frag1), offset1, size, snapshot1); - new_type2 = get_offset_type(real_addr_frag2, state.types_<1>(block1, frag1), offset2, size, snapshot2); - } else if (state.types_<2>(block2, frag2) != nullptr) { - new_type1 = get_offset_type(real_addr_frag1, state.types_<2>(block2, frag2), offset1, size, snapshot1); - new_type2 = get_offset_type(real_addr_frag2, state.types_<2>(block2, frag2), offset2, size, snapshot2); - } else { - if (match_pairs) - state.match_equals(previous); - return false; - } - - if (new_type1 != nullptr && new_type2 != nullptr && new_type1 != new_type2) { - type = new_type1; - while (type->byte_size == 0 && type->subtype != nullptr) - type = type->subtype; - new_size1 = type->byte_size; - - type = new_type2; - while (type->byte_size == 0 && type->subtype != nullptr) - type = type->subtype; - new_size2 = type->byte_size; - - } else { - if (match_pairs) - state.match_equals(previous); - return false; - } - } - - if (new_size1 > 0 && new_size1 == new_size2) { - type = new_type1; - size = new_size1; - } - - if (offset1 == 0 && offset2 == 0 && - not previous->insert(HeapLocationPair{{HeapLocation(block1, frag1), HeapLocation(block2, frag2)}}).second) { - if (match_pairs) - state.match_equals(previous); - return false; - } - - if (size <= 0) { - if (match_pairs) - state.match_equals(previous); - return false; - } - - if ((heapinfo1->busy_frag.ignore[frag1] > 0) && - (heapinfo2->busy_frag.ignore[frag2] == heapinfo1->busy_frag.ignore[frag1])) - check_ignore = heapinfo1->busy_frag.ignore[frag1]; - } else - return true; - - /* Start comparison */ - if (type ? heap_area_differ_with_type(process, state, area1, area2, snapshot1, snapshot2, previous, type, size, - check_ignore, pointer_level) - : heap_area_differ_without_type(process, state, area1, area2, snapshot1, snapshot2, previous, size, - check_ignore)) - return true; - - if (match_pairs) - state.match_equals(previous); - return false; -} -} // namespace simgrid::mc - -/************************** Snapshot comparison *******************************/ -/******************************************************************************/ - -static bool areas_differ_with_type(const simgrid::mc::RemoteProcess& process, simgrid::mc::StateComparator& state, - const void* real_area1, const simgrid::mc::Snapshot& snapshot1, - simgrid::mc::Region* region1, const void* real_area2, - const simgrid::mc::Snapshot& snapshot2, simgrid::mc::Region* region2, - const simgrid::mc::Type* type, int pointer_level) -{ - const simgrid::mc::Type* subtype; - const simgrid::mc::Type* subsubtype; - int elm_size; - - xbt_assert(type != nullptr); - switch (type->type) { - case DW_TAG_unspecified_type: - return true; - - case DW_TAG_base_type: - case DW_TAG_enumeration_type: - case DW_TAG_union_type: - return MC_snapshot_region_memcmp(real_area1, region1, real_area2, region2, type->byte_size) != 0; - case DW_TAG_typedef: - case DW_TAG_volatile_type: - case DW_TAG_const_type: - return areas_differ_with_type(process, state, real_area1, snapshot1, region1, real_area2, snapshot2, region2, - type->subtype, pointer_level); - case DW_TAG_array_type: - subtype = type->subtype; - switch (subtype->type) { - case DW_TAG_unspecified_type: - return true; - - case DW_TAG_base_type: - case DW_TAG_enumeration_type: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_rvalue_reference_type: - case DW_TAG_structure_type: - case DW_TAG_class_type: - case DW_TAG_union_type: - if (subtype->full_type) - subtype = subtype->full_type; - elm_size = subtype->byte_size; - break; - case DW_TAG_const_type: - case DW_TAG_typedef: - case DW_TAG_volatile_type: - subsubtype = subtype->subtype; - if (subsubtype->full_type) - subsubtype = subsubtype->full_type; - elm_size = subsubtype->byte_size; - break; - default: - return false; - } - for (int i = 0; i < type->element_count; i++) { - size_t off = i * elm_size; - if (areas_differ_with_type(process, state, (const char*)real_area1 + off, snapshot1, region1, - (const char*)real_area2 + off, snapshot2, region2, type->subtype, pointer_level)) - return true; - } - break; - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_rvalue_reference_type: { - const void* addr_pointed1 = MC_region_read_pointer(region1, real_area1); - const void* addr_pointed2 = MC_region_read_pointer(region2, real_area2); - - if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) - return (addr_pointed1 != addr_pointed2); - if (addr_pointed1 == nullptr && addr_pointed2 == nullptr) - return false; - if (addr_pointed1 == nullptr || addr_pointed2 == nullptr) - return true; - if (not state.compared_pointers.insert(std::make_pair(addr_pointed1, addr_pointed2)).second) - return false; - - pointer_level++; - - // Some cases are not handled here: - // * the pointers lead to different areas (one to the heap, the other to the RW segment ...) - // * a pointer leads to the read-only segment of the current object - // * a pointer lead to a different ELF object - - if (snapshot1.on_heap(addr_pointed1)) { - if (not snapshot2.on_heap(addr_pointed2)) - return true; - // The pointers are both in the heap: - return simgrid::mc::heap_area_differ(process, state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, - nullptr, type->subtype, pointer_level); - - } else if (region1->contain(simgrid::mc::remote(addr_pointed1))) { - // The pointers are both in the current object R/W segment: - if (not region2->contain(simgrid::mc::remote(addr_pointed2))) - return true; - if (not type->type_id) - return (addr_pointed1 != addr_pointed2); - else - return areas_differ_with_type(process, state, addr_pointed1, snapshot1, region1, addr_pointed2, snapshot2, - region2, type->subtype, pointer_level); - } else { - // TODO, We do not handle very well the case where - // it belongs to a different (non-heap) region from the current one. - - return (addr_pointed1 != addr_pointed2); - } - } - case DW_TAG_structure_type: - case DW_TAG_class_type: - for (const simgrid::mc::Member& member : type->members) { - const void* member1 = simgrid::dwarf::resolve_member(real_area1, type, &member, &snapshot1); - const void* member2 = simgrid::dwarf::resolve_member(real_area2, type, &member, &snapshot2); - simgrid::mc::Region* subregion1 = snapshot1.get_region(member1, region1); // region1 is hinted - simgrid::mc::Region* subregion2 = snapshot2.get_region(member2, region2); // region2 is hinted - if (areas_differ_with_type(process, state, member1, snapshot1, subregion1, member2, snapshot2, subregion2, - member.type, pointer_level)) - return true; - } - break; - case DW_TAG_subroutine_type: - return false; - default: - XBT_VERB("Unknown case: %d", type->type); - break; - } - - return false; -} - -static bool global_variables_differ(const simgrid::mc::RemoteProcess& process, simgrid::mc::StateComparator& state, - const simgrid::mc::ObjectInformation* object_info, simgrid::mc::Region* r1, - simgrid::mc::Region* r2, const simgrid::mc::Snapshot& snapshot1, - const simgrid::mc::Snapshot& snapshot2) -{ - xbt_assert(r1 && r2, "Missing region."); - - const std::vector& variables = object_info->global_variables; - - for (simgrid::mc::Variable const& current_var : variables) { - // If the variable is not in this object, skip it: - // We do not expect to find a pointer to something which is not reachable - // by the global variables. - if ((char*)current_var.address < object_info->start_rw || (char*)current_var.address > object_info->end_rw) - continue; - - const simgrid::mc::Type* bvariable_type = current_var.type; - if (areas_differ_with_type(process, state, current_var.address, snapshot1, r1, current_var.address, snapshot2, r2, - bvariable_type, 0)) { - XBT_VERB("Global variable %s (%p) is different between snapshots", current_var.name.c_str(), current_var.address); - return true; - } - } - - return false; -} - -static bool local_variables_differ(const simgrid::mc::RemoteProcess& process, simgrid::mc::StateComparator& state, - const simgrid::mc::Snapshot& snapshot1, const simgrid::mc::Snapshot& snapshot2, - const_mc_snapshot_stack_t stack1, const_mc_snapshot_stack_t stack2) -{ - if (stack1->local_variables.size() != stack2->local_variables.size()) { - XBT_VERB("Different number of local variables"); - return true; - } - - for (unsigned int cursor = 0; cursor < stack1->local_variables.size(); cursor++) { - const_local_variable_t current_var1 = &stack1->local_variables[cursor]; - const_local_variable_t current_var2 = &stack2->local_variables[cursor]; - if (current_var1->name != current_var2->name || current_var1->subprogram != current_var2->subprogram || - current_var1->ip != current_var2->ip) { - // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram - XBT_VERB("Different name of variable (%s - %s) or frame (%s - %s) or ip (%lu - %lu)", current_var1->name.c_str(), - current_var2->name.c_str(), current_var1->subprogram->name.c_str(), - current_var2->subprogram->name.c_str(), current_var1->ip, current_var2->ip); - return true; - } - - if (areas_differ_with_type(process, state, current_var1->address, snapshot1, - snapshot1.get_region(current_var1->address), current_var2->address, snapshot2, - snapshot2.get_region(current_var2->address), current_var1->type, 0)) { - XBT_VERB("Local variable %s (%p - %p) in frame %s is different between snapshots", current_var1->name.c_str(), - current_var1->address, current_var2->address, current_var1->subprogram->name.c_str()); - return true; - } - } - return false; -} - -namespace simgrid::mc { - -bool snapshot_equal(const Snapshot* s1, const Snapshot* s2) -{ - // TODO, make this a field of ModelChecker or something similar - static StateComparator state_comparator; - - const RemoteProcess& process = mc_model_checker->get_remote_process(); - - if (s1->hash_ != s2->hash_) { - XBT_VERB("(%ld - %ld) Different hash: 0x%" PRIx64 "--0x%" PRIx64, s1->num_state_, s2->num_state_, s1->hash_, - s2->hash_); - return false; - } - XBT_VERB("(%ld - %ld) Same hash: 0x%" PRIx64, s1->num_state_, s2->num_state_, s1->hash_); - - /* Compare enabled processes */ - if (s1->enabled_processes_ != s2->enabled_processes_) { - XBT_VERB("(%ld - %ld) Different amount of enabled processes", s1->num_state_, s2->num_state_); - return false; - } - - /* Compare size of stacks */ - for (unsigned long i = 0; i < s1->stacks_.size(); i++) { - size_t size_used1 = s1->stack_sizes_[i]; - size_t size_used2 = s2->stack_sizes_[i]; - if (size_used1 != size_used2) { - XBT_VERB("(%ld - %ld) Different size used in stacks: %zu - %zu", s1->num_state_, s2->num_state_, size_used1, - size_used2); - return false; - } - } - - /* Init heap information used in heap comparison algorithm */ - const s_xbt_mheap_t* heap1 = static_cast( - s1->read_bytes(alloca(sizeof(s_xbt_mheap_t)), sizeof(s_xbt_mheap_t), process.heap_address, ReadOptions::lazy())); - const s_xbt_mheap_t* heap2 = static_cast( - s2->read_bytes(alloca(sizeof(s_xbt_mheap_t)), sizeof(s_xbt_mheap_t), process.heap_address, ReadOptions::lazy())); - if (state_comparator.initHeapInformation(heap1, heap2, s1->to_ignore_, s2->to_ignore_) == -1) { - XBT_VERB("(%ld - %ld) Different heap information", s1->num_state_, s2->num_state_); - return false; - } - - /* Stacks comparison */ - for (unsigned int cursor = 0; cursor < s1->stacks_.size(); cursor++) { - const_mc_snapshot_stack_t stack1 = &s1->stacks_[cursor]; - const_mc_snapshot_stack_t stack2 = &s2->stacks_[cursor]; - - if (local_variables_differ(process, state_comparator, *s1, *s2, stack1, stack2)) { - XBT_VERB("(%ld - %ld) Different local variables between stacks %u", s1->num_state_, s2->num_state_, cursor + 1); - return false; - } - } - - size_t regions_count = s1->snapshot_regions_.size(); - if (regions_count != s2->snapshot_regions_.size()) - return false; - - for (size_t k = 0; k != regions_count; ++k) { - Region* region1 = s1->snapshot_regions_[k].get(); - Region* region2 = s2->snapshot_regions_[k].get(); - - // Preconditions: - if (region1->region_type() != RegionType::Data) - continue; - - xbt_assert(region1->region_type() == region2->region_type()); - xbt_assert(region1->object_info() == region2->object_info()); - xbt_assert(region1->object_info()); - - /* Compare global variables */ - if (global_variables_differ(process, state_comparator, region1->object_info(), region1, region2, *s1, *s2)) { - std::string const& name = region1->object_info()->file_name; - XBT_VERB("(%ld - %ld) Different global variables in %s", s1->num_state_, s2->num_state_, name.c_str()); - return false; - } - } - - /* Compare heap */ - if (mmalloc_heap_differ(process, state_comparator, *s1, *s2)) { - XBT_VERB("(%ld - %ld) Different heap (mmalloc_compare)", s1->num_state_, s2->num_state_); - return false; - } - - XBT_VERB("(%ld - %ld) No difference found", s1->num_state_, s2->num_state_); - - return true; -} -} // namespace simgrid::mc diff --git a/src/include/mc/datatypes.h b/src/mc/datatypes.h similarity index 74% rename from src/include/mc/datatypes.h rename to src/mc/datatypes.h index 36a7d4da32..faf354b37f 100644 --- a/src/include/mc/datatypes.h +++ b/src/mc/datatypes.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,15 +15,15 @@ SG_BEGIN_DECL -struct s_stack_region{ - void *address; +struct s_stack_region { + void* address; #if HAVE_UCONTEXT_H ucontext_t* context; #endif size_t size; int block; }; -typedef struct s_stack_region s_stack_region_t; +typedef struct s_stack_region s_stack_region_t; SG_END_DECL diff --git a/src/mc/explo/CommunicationDeterminismChecker.cpp b/src/mc/explo/CommunicationDeterminismChecker.cpp index 4464631415..639b28c1f4 100644 --- a/src/mc/explo/CommunicationDeterminismChecker.cpp +++ b/src/mc/explo/CommunicationDeterminismChecker.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,8 +11,10 @@ #include "src/mc/mc_private.hpp" #include "src/mc/transition/TransitionAny.hpp" #include "src/mc/transition/TransitionComm.hpp" +#include "xbt/string.hpp" #include +#include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_comm_determinism, mc, "Logging specific to MC communication determinism detection"); @@ -60,9 +62,14 @@ struct PatternCommunicationList { /********** Checker extension **********/ -struct CommDetExtension { +class CommDetExtension { + Exploration& exploration_; + +public: static simgrid::xbt::Extension EXTENSION_ID; + explicit CommDetExtension(Exploration& explo) : exploration_(explo) {} + std::vector initial_communications_pattern; std::vector> incomplete_communications_pattern; @@ -74,12 +81,12 @@ struct CommDetExtension { void exploration_start() { - const unsigned long maxpid = Api::get().get_maxpid(); + const unsigned long maxpid = exploration_.get_remote_app().get_maxpid(); initial_communications_pattern.resize(maxpid); incomplete_communications_pattern.resize(maxpid); } - void restore_communications_pattern(const simgrid::mc::State* state); + void restore_communications_pattern(const simgrid::mc::State* state, RemoteApp const& remote_app); void enforce_deterministic_pattern(aid_t process, const PatternCommunication* comm); void get_comm_pattern(const Transition* transition); void complete_comm_pattern(const CommWaitTransition* transition); @@ -94,17 +101,17 @@ public: std::vector communication_indices_; static simgrid::xbt::Extension EXTENSION_ID; - explicit StateCommDet(CommDetExtension* checker) + explicit StateCommDet(CommDetExtension const& checker, RemoteApp const& remote_app) { - const unsigned long maxpid = Api::get().get_maxpid(); + const unsigned long maxpid = remote_app.get_maxpid(); for (unsigned long i = 0; i < maxpid; i++) { std::vector res; - for (auto const& comm : checker->incomplete_communications_pattern[i]) + for (auto const& comm : checker.incomplete_communications_pattern[i]) res.push_back(comm->dup()); incomplete_comm_pattern_.push_back(std::move(res)); } - for (auto const& list_process_comm : checker->initial_communications_pattern) + for (auto const& list_process_comm : checker.initial_communications_pattern) this->communication_indices_.push_back(list_process_comm.index_comm); } }; @@ -129,13 +136,13 @@ static simgrid::mc::CommPatternDifference compare_comm_pattern(const simgrid::mc return CommPatternDifference::NONE; } -void CommDetExtension::restore_communications_pattern(const simgrid::mc::State* state) +void CommDetExtension::restore_communications_pattern(const simgrid::mc::State* state, RemoteApp const& remote_app) { for (size_t i = 0; i < initial_communications_pattern.size(); i++) initial_communications_pattern[i].index_comm = state->extension()->communication_indices_[i]; - const unsigned long maxpid = Api::get().get_maxpid(); + const unsigned long maxpid = remote_app.get_maxpid(); for (unsigned long i = 0; i < maxpid; i++) { incomplete_communications_pattern[i].clear(); for (simgrid::mc::PatternCommunication const& comm : @@ -202,8 +209,8 @@ void CommDetExtension::enforce_deterministic_pattern(aid_t actor, const PatternC XBT_INFO("***** Non-send-deterministic communications pattern *****"); XBT_INFO("*********************************************************"); XBT_INFO("%s", send_diff.c_str()); - Api::get().get_session().log_state(); - Api::get().mc_exit(SIMGRID_MC_EXIT_NON_DETERMINISM); + exploration_.log_state(); + throw McError(ExitStatus::NON_DETERMINISM); } else if (_sg_mc_comms_determinism && (not send_deterministic && not recv_deterministic)) { XBT_INFO("****************************************************"); XBT_INFO("***** Non-deterministic communications pattern *****"); @@ -212,8 +219,8 @@ void CommDetExtension::enforce_deterministic_pattern(aid_t actor, const PatternC XBT_INFO("%s", send_diff.c_str()); if (not recv_diff.empty()) XBT_INFO("%s", recv_diff.c_str()); - Api::get().get_session().log_state(); - Api::get().mc_exit(SIMGRID_MC_EXIT_NON_DETERMINISM); + exploration_.log_state(); + throw McError(ExitStatus::NON_DETERMINISM); } } } @@ -228,8 +235,8 @@ void CommDetExtension::get_comm_pattern(const Transition* transition) auto pattern = std::make_unique(); pattern->index = initial_pattern.index_comm + incomplete_pattern.size(); - if (transition->type_ == Transition::Type::COMM_SEND) { - auto* send = static_cast(transition); + if (transition->type_ == Transition::Type::COMM_ASYNC_SEND) { + const auto* send = static_cast(transition); pattern->type = PatternCommunicationType::send; pattern->comm_addr = send->get_comm(); @@ -237,8 +244,8 @@ void CommDetExtension::get_comm_pattern(const Transition* transition) // FIXME: Detached sends should be enforced when the receive is waited - } else if (transition->type_ == Transition::Type::COMM_RECV) { - auto* recv = static_cast(transition); + } else if (transition->type_ == Transition::Type::COMM_ASYNC_RECV) { + const auto* recv = static_cast(transition); pattern->type = PatternCommunicationType::receive; pattern->comm_addr = recv->get_comm(); @@ -285,8 +292,8 @@ void CommDetExtension::handle_comm_pattern(const Transition* transition) return; switch (transition->type_) { - case Transition::Type::COMM_SEND: - case Transition::Type::COMM_RECV: + case Transition::Type::COMM_ASYNC_SEND: + case Transition::Type::COMM_ASYNC_RECV: get_comm_pattern(transition); break; case Transition::Type::COMM_WAIT: @@ -314,26 +321,32 @@ void CommDetExtension::handle_comm_pattern(const Transition* transition) } */ -Exploration* create_communication_determinism_checker(Session* session) +Exploration* create_communication_determinism_checker(const std::vector& args, ReductionMode mode) { CommDetExtension::EXTENSION_ID = simgrid::mc::Exploration::extension_create(); StateCommDet::EXTENSION_ID = simgrid::mc::State::extension_create(); XBT_DEBUG("********* Start communication determinism verification *********"); - auto extension = new CommDetExtension(); + auto* base = new DFSExplorer(args, mode); + auto* extension = new CommDetExtension(*base); - DFSExplorer::on_exploration_start([extension]() { + DFSExplorer::on_exploration_start([extension](RemoteApp const&) { XBT_INFO("Check communication determinism"); extension->exploration_start(); }); - DFSExplorer::on_backtracking([extension]() { extension->initial_communications_pattern_done = true; }); - DFSExplorer::on_state_creation([extension](State* state) { state->extension_set(new StateCommDet(extension)); }); + DFSExplorer::on_backtracking( + [extension](RemoteApp const&) { extension->initial_communications_pattern_done = true; }); + DFSExplorer::on_state_creation([extension](State* state, RemoteApp const& remote_app) { + state->extension_set(new StateCommDet(*extension, remote_app)); + }); - DFSExplorer::on_restore_system_state([extension](State* state) { extension->restore_communications_pattern(state); }); + DFSExplorer::on_restore_system_state([extension](State const* state, RemoteApp const& remote_app) { + extension->restore_communications_pattern(state, remote_app); + }); - DFSExplorer::on_restore_initial_state([extension]() { - const unsigned long maxpid = Api::get().get_maxpid(); + DFSExplorer::on_restore_initial_state([extension](RemoteApp const& remote_app) { + const unsigned long maxpid = remote_app.get_maxpid(); assert(maxpid == extension->incomplete_communications_pattern.size()); assert(maxpid == extension->initial_communications_pattern.size()); for (unsigned long j = 0; j < maxpid; j++) { @@ -342,10 +355,12 @@ Exploration* create_communication_determinism_checker(Session* session) } }); - DFSExplorer::on_transition_replay([extension](Transition* t) { extension->handle_comm_pattern(t); }); - DFSExplorer::on_transition_execute([extension](Transition* t) { extension->handle_comm_pattern(t); }); + DFSExplorer::on_transition_replay( + [extension](Transition const* t, RemoteApp const&) { extension->handle_comm_pattern(t); }); + DFSExplorer::on_transition_execute( + [extension](Transition const* t, RemoteApp const&) { extension->handle_comm_pattern(t); }); - DFSExplorer::on_log_state([extension]() { + DFSExplorer::on_log_state([extension](RemoteApp const&) { if (_sg_mc_comms_determinism) { if (extension->send_deterministic && not extension->recv_deterministic) { XBT_INFO("*******************************************************"); @@ -366,7 +381,7 @@ Exploration* create_communication_determinism_checker(Session* session) delete extension; }); - return new DFSExplorer(session); + return base; } } // namespace simgrid::mc diff --git a/src/mc/explo/DFSExplorer.cpp b/src/mc/explo/DFSExplorer.cpp index b39b7fbe62..b328d15773 100644 --- a/src/mc/explo/DFSExplorer.cpp +++ b/src/mc/explo/DFSExplorer.cpp @@ -1,321 +1,481 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/explo/DFSExplorer.hpp" -#include "src/mc/VisitedState.hpp" #include "src/mc/mc_config.hpp" #include "src/mc/mc_exit.hpp" #include "src/mc/mc_private.hpp" #include "src/mc/mc_record.hpp" +#include "src/mc/remote/mc_protocol.h" #include "src/mc/transition/Transition.hpp" -#include "src/xbt/mmalloc/mmprivate.h" +#include "xbt/asserts.h" #include "xbt/log.h" +#include "xbt/string.hpp" #include "xbt/sysdep.h" #include #include +#include #include #include +#include #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dfs, mc, "DFS exploration algorithm of the model-checker"); namespace simgrid::mc { -xbt::signal DFSExplorer::on_exploration_start_signal; -xbt::signal DFSExplorer::on_backtracking_signal; +xbt::signal DFSExplorer::on_exploration_start_signal; +xbt::signal DFSExplorer::on_backtracking_signal; -xbt::signal DFSExplorer::on_state_creation_signal; +xbt::signal DFSExplorer::on_state_creation_signal; -xbt::signal DFSExplorer::on_restore_system_state_signal; -xbt::signal DFSExplorer::on_restore_initial_state_signal; -xbt::signal DFSExplorer::on_transition_replay_signal; -xbt::signal DFSExplorer::on_transition_execute_signal; +xbt::signal DFSExplorer::on_restore_system_state_signal; +xbt::signal DFSExplorer::on_restore_initial_state_signal; +xbt::signal DFSExplorer::on_transition_replay_signal; +xbt::signal DFSExplorer::on_transition_execute_signal; -xbt::signal DFSExplorer::on_log_state_signal; - -void DFSExplorer::check_non_termination(const State* current_state) -{ - for (auto state = stack_.rbegin(); state != stack_.rend(); ++state) - if (Api::get().snapshot_equal((*state)->get_system_state(), current_state->get_system_state())) { - XBT_INFO("Non-progressive cycle: state %ld -> state %ld", (*state)->get_num(), current_state->get_num()); - XBT_INFO("******************************************"); - XBT_INFO("*** NON-PROGRESSIVE CYCLE DETECTED ***"); - XBT_INFO("******************************************"); - XBT_INFO("Counter-example execution trace:"); - for (auto const& s : get_textual_trace()) - XBT_INFO(" %s", s.c_str()); - XBT_INFO("Path = %s", get_record_trace().to_string().c_str()); - log_state(); - - throw TerminationError(); - } -} +xbt::signal DFSExplorer::on_log_state_signal; RecordTrace DFSExplorer::get_record_trace() // override { RecordTrace res; - for (auto const& state : stack_) - res.push_back(state->get_transition()); + + if (const auto trans = stack_.back()->get_transition_out(); trans != nullptr) + res.push_back(trans.get()); + for (const auto* state = stack_.back().get(); state != nullptr; state = state->get_parent_state().get()) + if (state->get_transition_in() != nullptr) + res.push_front(state->get_transition_in().get()); + return res; } -std::vector DFSExplorer::get_textual_trace() // override +void DFSExplorer::restore_stack(std::shared_ptr state) { - std::vector trace; - for (auto const& state : stack_) { - const auto* t = state->get_transition(); - trace.push_back(xbt::string_printf("%ld: %s", t->aid_, t->to_string().c_str())); + stack_.clear(); + execution_seq_ = odpor::Execution(); + auto current_state = state; + stack_.emplace_front(current_state); + // condition corresponds to reaching initial state + while (current_state->get_parent_state() != nullptr) { + current_state = current_state->get_parent_state(); + stack_.emplace_front(current_state); + } + XBT_DEBUG("Replaced stack by %s", get_record_trace().to_string().c_str()); + if (reduction_mode_ == ReductionMode::sdpor || reduction_mode_ == ReductionMode::odpor) { + // NOTE: The outgoing transition for the top-most state of the stack refers to that which was taken + // as part of the last trace explored by the algorithm. Thus, only the sequence of transitions leading up to, + // but not including, the last state must be included when reconstructing the Exploration for SDPOR. + for (auto iter = std::next(stack_.begin()); iter != stack_.end(); ++iter) { + execution_seq_.push_transition((*iter)->get_transition_in()); + } + XBT_DEBUG("Replaced SDPOR/ODPOR execution to reflect the new stack"); } - return trace; } void DFSExplorer::log_state() // override { - on_log_state_signal(); - XBT_INFO("DFS exploration ended. %ld unique states visited; %ld backtracks (%lu transition replays, %lu states " + on_log_state_signal(get_remote_app()); + XBT_INFO("DFS exploration ended. %ld unique states visited; %lu backtracks (%lu transition replays, %lu states " "visited overall)", - State::get_expanded_states(), backtrack_count_, Api::get().mc_get_visited_states(), - Transition::get_replayed_transitions()); + State::get_expanded_states(), backtrack_count_, Transition::get_replayed_transitions(), + visited_states_count_); + Exploration::log_state(); } void DFSExplorer::run() { - on_exploration_start_signal(); + on_exploration_start_signal(get_remote_app()); /* This function runs the DFS algorithm the state space. * We do so iteratively instead of recursively, dealing with the call stack manually. * This allows one to explore the call stack at will. */ while (not stack_.empty()) { /* Get current state */ - State* state = stack_.back().get(); + auto state = stack_.back(); XBT_DEBUG("**************************************************"); - XBT_DEBUG("Exploration depth=%zu (state:%ld; %zu interleaves)", stack_.size(), state->get_num(), + XBT_DEBUG("Exploration depth=%zu (state:#%ld; %zu interleaves todo)", stack_.size(), state->get_num(), state->count_todo()); - Api::get().mc_inc_visited_states(); + visited_states_count_++; // Backtrack if we reached the maximum depth if (stack_.size() > (std::size_t)_sg_mc_max_depth) { - if (reductionMode_ == ReductionMode::dpor) { + if (reduction_mode_ == ReductionMode::dpor) { XBT_ERROR("/!\\ Max depth of %d reached! THIS WILL PROBABLY BREAK the dpor reduction /!\\", _sg_mc_max_depth.get()); XBT_ERROR("/!\\ If bad things happen, disable dpor with --cfg=model-check/reduction:none /!\\"); - } else + } else if (reduction_mode_ == ReductionMode::sdpor || reduction_mode_ == ReductionMode::odpor) { + XBT_ERROR("/!\\ Max depth of %d reached! THIS **WILL** BREAK the reduction, which is not sound " + "when stopping at a fixed depth /!\\", + _sg_mc_max_depth.get()); + XBT_ERROR("/!\\ If bad things happen, disable the reduction with --cfg=model-check/reduction:none /!\\"); + } else { XBT_WARN("/!\\ Max depth reached ! /!\\ "); + } this->backtrack(); continue; } - // Backtrack if we are revisiting a state we saw previously - if (visited_state_ != nullptr) { - XBT_DEBUG("State already visited (equal to state %ld), exploration stopped on this path.", - visited_state_->original_num == -1 ? visited_state_->num : visited_state_->original_num); - - visited_state_ = nullptr; - this->backtrack(); - continue; + if (reduction_mode_ == ReductionMode::odpor) { + // In the case of ODPOR, the wakeup tree for this state may be empty if we're exploring new territory + // (rather than following the partial execution of a wakeup tree). This corresponds to lines 9 to 13 of + // the ODPOR pseudocode + // + // INVARIANT: The execution sequence should be consistent with the state when seeding the tree. If the sequence + // gets out of sync with the state, selection will not work as we intend + state->seed_wakeup_tree_if_needed(execution_seq_); } // Search for the next transition - int next = state->next_transition(); - - if (next < 0) { // If there is no more transition in the current state, backtrack. - XBT_DEBUG("There remains %zu actors, but none to interleave (depth %zu).", - mc_model_checker->get_remote_process().actors().size(), stack_.size() + 1); + // next_transition returns a pair + // in case we want to consider multiple states (eg. during backtrack) + const aid_t next = reduction_mode_ == ReductionMode::odpor ? state->next_odpor_transition() + : std::get<0>(state->next_transition_guided()); + + if (next < 0 || not state->is_actor_enabled(next)) { + if (next >= 0) { // Actor is not enabled, then + XBT_DEBUG( + "Reduction %s wants to execute a disabled transition %s. If it's ODPOR, ReversibleRace is suboptimal.", + to_c_str(reduction_mode_), state->get_actors_list().at(next).get_transition()->to_string(true).c_str()); + if (reduction_mode_ == ReductionMode::odpor) { + // Remove the disabled transition from the wakeup tree so that ODPOR doesn't try it again + state->remove_subtree_at_aid(next); + state->add_sleep_set(state->get_actors_list().at(next).get_transition()); + } else { + xbt_assert(false, "Only ODPOR should be confident enought in itself to try executing a disabled transition"); + } + } + // If there is no more transition in the current state (or if ODPOR picked an actor that is not enabled -- + // ReversibleRace is an overapproximation), backtrace + XBT_VERB("%lu actors remain, but none of them need to be interleaved (depth %zu).", state->get_actor_count(), + stack_.size() + 1); - if (mc_model_checker->get_remote_process().actors().empty()) { - mc_model_checker->finalize_app(); + if (state->get_actor_count() == 0) { + get_remote_app().finalize_app(); XBT_VERB("Execution came to an end at %s (state: %ld, depth: %zu)", get_record_trace().to_string().c_str(), state->get_num(), stack_.size()); } + this->backtrack(); continue; } + if (XBT_LOG_ISENABLED(mc_dfs, xbt_log_priority_verbose)) { + XBT_VERB("Sleep set actually containing:"); + for (const auto& [aid, transition] : state->get_sleep_set()) + XBT_VERB(" <%ld,%s>", aid, transition->to_string().c_str()); + } + + auto todo = state->get_actors_list().at(next).get_transition(); + XBT_DEBUG("wanna execute %ld: %.60s", next, todo->to_string().c_str()); + /* Actually answer the request: let's execute the selected request (MCed does one step) */ - state->execute_next(next); - on_transition_execute_signal(state->get_transition()); + auto executed_transition = state->execute_next(next, get_remote_app()); + on_transition_execute_signal(state->get_transition_out().get(), get_remote_app()); // If there are processes to interleave and the maximum depth has not been // reached then perform one step of the exploration algorithm. - XBT_VERB("Execute %ld: %.60s (stack depth: %zu, state: %ld, %zu interleaves)", state->get_transition()->aid_, - state->get_transition()->to_string().c_str(), stack_.size(), state->get_num(), state->count_todo()); - - std::string req_str; - if (dot_output != nullptr) - req_str = state->get_transition()->dot_string(); + XBT_VERB("Executed %ld: %.60s (stack depth: %zu, state: %ld, %zu interleaves)", state->get_transition_out()->aid_, + state->get_transition_out()->to_string().c_str(), stack_.size(), state->get_num(), state->count_todo()); /* Create the new expanded state (copy the state of MCed into our MCer data) */ - auto next_state = std::make_unique(); - on_state_creation_signal(next_state.get()); - - if (_sg_mc_termination) - this->check_non_termination(next_state.get()); - - /* Check whether we already explored next_state in the past (but only if interested in state-equality reduction) */ - if (_sg_mc_max_visited_states > 0) - visited_state_ = visited_states_.addVisitedState(next_state->get_num(), next_state.get(), true); + auto next_state = std::make_shared(get_remote_app(), state); + on_state_creation_signal(next_state.get(), get_remote_app()); + + if (reduction_mode_ == ReductionMode::odpor) { + // With ODPOR, after taking a step forward, we must assign a copy of that subtree to the next state. + // + // NOTE: We only add actions to the sleep set AFTER we've regenerated states. We must perform the search + // fully down a single path before we consider adding any elements to the sleep set according to the pseudocode + next_state->sprout_tree_from_parent_state(); + } else { + /* Sleep set procedure: + * adding the taken transition to the sleep set of the original state. + * Since the parent sleep set is used to compute the child sleep set, this need to be + * done after next_state creation */ + XBT_DEBUG("Marking Transition >>%s<< of process %ld done and adding it to the sleep set", + state->get_transition_out()->to_string().c_str(), state->get_transition_out()->aid_); + state->add_sleep_set( + state->get_transition_out()); // Actors are marked done when they are considered in ActorState + } - /* If this is a new state (or if we don't care about state-equality reduction) */ - if (visited_state_ == nullptr) { - /* Get an enabled process and insert it in the interleave set of the next state */ - auto actors = Api::get().get_actors(); - for (auto& remoteActor : actors) { - auto actor = remoteActor.copy.get_buffer(); - if (get_session().actor_is_enabled(actor->get_pid())) { - next_state->mark_todo(actor->get_pid()); - if (reductionMode_ == ReductionMode::dpor) - break; // With DPOR, we take the first enabled transition + /* DPOR persistent set procedure: + * for each new transition considered, check if it depends on any other previous transition executed before it + * on another process. If there exists one, find the more recent, and add its process to the interleave set. + * If the process is not enabled at this point, then add every enabled process to the interleave */ + if (reduction_mode_ == ReductionMode::dpor) { + aid_t issuer_id = state->get_transition_out()->aid_; + stack_t tmp_stack = stack_; + while (not tmp_stack.empty()) { + if (const State* prev_state = tmp_stack.back().get(); + state->get_transition_out()->aid_ == prev_state->get_transition_out()->aid_) { + XBT_DEBUG("Simcall >>%s<< and >>%s<< with same issuer %ld", state->get_transition_out()->to_string().c_str(), + prev_state->get_transition_out()->to_string().c_str(), issuer_id); + tmp_stack.pop_back(); + continue; + } else if (prev_state->get_transition_out()->depends(state->get_transition_out().get())) { + XBT_VERB("Dependent Transitions:"); + XBT_VERB(" #%ld %s (state=%ld)", prev_state->get_transition_out()->aid_, + prev_state->get_transition_out()->to_string().c_str(), prev_state->get_num()); + XBT_VERB(" #%ld %s (state=%ld)", state->get_transition_out()->aid_, + state->get_transition_out()->to_string().c_str(), state->get_num()); + + if (prev_state->is_actor_enabled(issuer_id)) { + if (not prev_state->is_actor_done(issuer_id)) { + prev_state->consider_one(issuer_id); + opened_states_.emplace_back(tmp_stack.back()); + } else + XBT_DEBUG("Actor %ld is already in done set: no need to explore it again", issuer_id); + } else { + XBT_DEBUG("Actor %ld is not enabled: DPOR may be failing. To stay sound, we are marking every enabled " + "transition as todo", + issuer_id); + // If we ended up marking at least a transition, explore it at some point + if (prev_state->consider_all() > 0) + opened_states_.emplace_back(tmp_stack.back()); + } + break; + } else { + XBT_VERB("INDEPENDENT Transitions:"); + XBT_VERB(" #%ld %s (state=%ld)", prev_state->get_transition_out()->aid_, + prev_state->get_transition_out()->to_string().c_str(), prev_state->get_num()); + XBT_VERB(" #%ld %s (state=%ld)", state->get_transition_out()->aid_, + state->get_transition_out()->to_string().c_str(), state->get_num()); + } + tmp_stack.pop_back(); + } + } else if (reduction_mode_ == ReductionMode::sdpor) { + /** + * SDPOR Source Set Procedure: + * + * Find "reversible races" in the current execution `E` with respect to the latest action `p`. For each such race, + * determine one thread not contained in the backtrack set at the "race point" `r` which "represents" the trace + * formed by first executing everything after `r` that doesn't depend on it (`v := notdep(r, E)`) and then `p` to + * flip the race. + * + * The intuition is that some subsequence of `v` may enable `p`, so we want to be sure that search "in that + * direction" + */ + execution_seq_.push_transition(std::move(executed_transition)); + xbt_assert(execution_seq_.get_latest_event_handle().has_value(), "No events are contained in the SDPOR execution " + "even though one was just added"); + + const auto next_E_p = execution_seq_.get_latest_event_handle().value(); + for (const auto e_race : execution_seq_.get_reversible_races_of(next_E_p)) { + State* prev_state = stack_[e_race].get(); + const auto choices = execution_seq_.get_missing_source_set_actors_from(e_race, prev_state->get_backtrack_set()); + if (not choices.empty()) { + // NOTE: To incorporate the idea of attempting to select the "best" backtrack point into SDPOR, instead of + // selecting the `first` initial, we should instead compute all choices and decide which is best + // + // Here, we choose the actor with the lowest ID to ensure we get deterministic results + const auto q = + std::min_element(choices.begin(), choices.end(), [](const aid_t a1, const aid_t a2) { return a1 < a2; }); + prev_state->consider_one(*q); + opened_states_.emplace_back(std::move(prev_state)); } } + } else if (reduction_mode_ == ReductionMode::odpor) { + // In the case of ODPOR, we simply observe the transition that was executed until we've reached a maximal trace + execution_seq_.push_transition(std::move(executed_transition)); + } - if (dot_output != nullptr) - std::fprintf(dot_output, "\"%ld\" -> \"%ld\" [%s];\n", state->get_num(), next_state->get_num(), - req_str.c_str()); + // Before leaving that state, if the transition we just took can be taken multiple times, we + // need to give it to the opened states + if (stack_.back()->count_todo_multiples() > 0) + opened_states_.emplace_back(stack_.back()); - } else if (dot_output != nullptr) - std::fprintf(dot_output, "\"%ld\" -> \"%ld\" [%s];\n", state->get_num(), - visited_state_->original_num == -1 ? visited_state_->num : visited_state_->original_num, - req_str.c_str()); + stack_.emplace_back(std::move(next_state)); - stack_.push_back(std::move(next_state)); - } + /* If this is a new state (or if we don't care about state-equality reduction) */ + /* Get an enabled process and insert it in the interleave set of the next state */ + if (reduction_mode_ == ReductionMode::dpor) + stack_.back()->consider_best(); // Take only one transition if DPOR: others may be considered later if required + else { + stack_.back()->consider_all(); + } + dot_output("\"%ld\" -> \"%ld\" [%s];\n", state->get_num(), stack_.back()->get_num(), + state->get_transition_out()->dot_string().c_str()); + } log_state(); } -void DFSExplorer::backtrack() +std::shared_ptr DFSExplorer::best_opened_state() { - backtrack_count_++; - XBT_VERB("Backtracking from %s", get_record_trace().to_string().c_str()); - on_backtracking_signal(); - stack_.pop_back(); + int best_prio = 0; // cache the value for the best priority found so far (initialized to silence gcc) + auto best = end(opened_states_); // iterator to the state to explore having the best priority + auto valid = begin(opened_states_); // iterator marking the limit between states still to explore, and already + // explored ones + + // Keep only still non-explored states (aid != -1), and record the one with the best (greater) priority. + for (auto current = begin(opened_states_); current != end(opened_states_); ++current) { + auto [aid, prio] = (*current)->next_transition_guided(); + if (aid == -1) + continue; + if (valid != current) + *valid = std::move(*current); + if (best == end(opened_states_) || prio < best_prio) { + best_prio = prio; + best = valid; + } + ++valid; + } - get_session().check_deadlock(); + std::shared_ptr best_state; + if (best < valid) { + // There are non-explored states, and one of them has the best priority. Remove it from opened_states_ before + // returning. + best_state = std::move(*best); + --valid; + if (best != valid) + *best = std::move(*valid); + } + opened_states_.erase(valid, end(opened_states_)); - /* Traverse the stack backwards until a state with a non empty interleave set is found, deleting all the states that - * have it empty in the way. For each deleted state, check if the request that has generated it (from its - * predecessor state), depends on any other previous request executed before it. If it does then add it to the - * interleave set of the state that executed that previous request. */ + return best_state; +} - while (not stack_.empty()) { - std::unique_ptr state = std::move(stack_.back()); - stack_.pop_back(); - if (reductionMode_ == ReductionMode::dpor) { - aid_t issuer_id = state->get_transition()->aid_; - for (auto i = stack_.rbegin(); i != stack_.rend(); ++i) { - State* prev_state = i->get(); - if (state->get_transition()->aid_ == prev_state->get_transition()->aid_) { - XBT_DEBUG("Simcall >>%s<< and >>%s<< with same issuer %ld", state->get_transition()->to_string().c_str(), - prev_state->get_transition()->to_string().c_str(), issuer_id); - break; - } else if (prev_state->get_transition()->depends(state->get_transition())) { - XBT_VERB("Dependent Transitions:"); - XBT_VERB(" %s (state=%ld)", prev_state->get_transition()->to_string().c_str(), prev_state->get_num()); - XBT_VERB(" %s (state=%ld)", state->get_transition()->to_string().c_str(), state->get_num()); +std::shared_ptr DFSExplorer::next_odpor_state() +{ + for (auto iter = stack_.rbegin(); iter != stack_.rend(); ++iter) { + const auto& state = *iter; + state->do_odpor_unwind(); + XBT_DEBUG("\tPerformed ODPOR 'clean-up'. Sleep set has:"); + for (const auto& [aid, transition] : state->get_sleep_set()) + XBT_DEBUG("\t <%ld,%s>", aid, transition->to_string().c_str()); + if (not state->has_empty_tree()) { + return state; + } + } + return nullptr; +} - if (not prev_state->is_done(issuer_id)) - prev_state->mark_todo(issuer_id); - else - XBT_DEBUG("Actor %ld is in done set", issuer_id); - break; +void DFSExplorer::backtrack() +{ + if (const auto last_event = execution_seq_.get_latest_event_handle(); + reduction_mode_ == ReductionMode::odpor and last_event.has_value()) { + /** + * ODPOR Race Detection Procedure: + * + * For each reversible race in the current execution, we note if there are any continuations `C` equivalent to that + * which would reverse the race that have already either a) been searched by ODPOR or b) been *noted* to be searched + * by the wakeup tree at the appropriate reversal point, either as `C` directly or an as equivalent to `C` + * ("eventually looks like C", viz. the `~_E` relation) + */ + for (auto e_prime = static_cast(0); e_prime <= last_event.value(); ++e_prime) { + XBT_DEBUG("ODPOR: Now considering all possible race with `%u`", e_prime); + for (const auto e : execution_seq_.get_reversible_races_of(e_prime)) { + XBT_DEBUG("ODPOR: Reversible race detected between events `%u` and `%u`", e, e_prime); + State& prev_state = *stack_[e]; + if (const auto v = execution_seq_.get_odpor_extension_from(e, e_prime, prev_state); v.has_value()) { + switch (prev_state.insert_into_wakeup_tree(v.value(), execution_seq_.get_prefix_before(e))) { + case odpor::WakeupTree::InsertionResult::root: { + XBT_DEBUG("ODPOR: Reversible race with `%u`(%ld: %.20s) unaccounted for in the wakeup tree for " + "the execution prior to event `%u`(%ld: %.20s):", + e_prime, stack_[e_prime]->get_transition_out()->aid_, + stack_[e_prime]->get_transition_out()->to_string(true).c_str(), e, + prev_state.get_transition_out()->aid_, + prev_state.get_transition_out()->to_string(true).c_str()); + break; + } + case odpor::WakeupTree::InsertionResult::interior_node: { + XBT_DEBUG("ODPOR: Reversible race with `%u` partially accounted for in the wakeup tree for " + "the execution prior to event `%u`:", + e_prime, e); + break; + } + case odpor::WakeupTree::InsertionResult::leaf: { + XBT_DEBUG("ODPOR: Reversible race with `%u` accounted for in the wakeup tree for " + "the execution prior to event `%u`:", + e_prime, e); + break; + } + } + for (const auto& seq : simgrid::mc::odpor::get_textual_trace(v.value())) { + XBT_DEBUG(" %s", seq.c_str()); + } } else { - XBT_VERB("INDEPENDENT Transitions:"); - XBT_VERB(" %s (state=%ld)", prev_state->get_transition()->to_string().c_str(), prev_state->get_num()); - XBT_VERB(" %s (state=%ld)", state->get_transition()->to_string().c_str(), state->get_num()); + XBT_DEBUG("ODPOR: Ignoring race: `sleep(E')` intersects `WI_[E'](v := notdep(%u, E))`", e); + XBT_DEBUG("Sleep set contains:"); + for (const auto& [aid, transition] : prev_state.get_sleep_set()) + XBT_DEBUG(" <%ld,%s>", aid, transition->to_string().c_str()); } } } - - if (state->count_todo() && stack_.size() < (std::size_t)_sg_mc_max_depth) { - /* We found a back-tracking point, let's loop */ - XBT_DEBUG("Back-tracking to state %ld at depth %zu", state->get_num(), stack_.size() + 1); - stack_.push_back( - std::move(state)); // Put it back on the stack from which it was removed earlier in this while loop - this->restore_state(); - XBT_DEBUG("Back-tracking to state %ld at depth %zu done", stack_.back()->get_num(), stack_.size()); - break; - } else { - XBT_DEBUG("Delete state %ld at depth %zu", state->get_num(), stack_.size() + 1); - } } -} -void DFSExplorer::restore_state() -{ - /* If asked to rollback on a state that has a snapshot, restore it */ - State* last_state = stack_.back().get(); - if (const auto* system_state = last_state->get_system_state()) { - Api::get().restore_state(system_state); - on_restore_system_state_signal(last_state); + XBT_VERB("Backtracking from %s", get_record_trace().to_string().c_str()); + XBT_DEBUG("%lu alternatives are yet to be explored:", opened_states_.size()); + + on_backtracking_signal(get_remote_app()); + get_remote_app().check_deadlock(); + + // Take the point with smallest distance + auto backtracking_point = reduction_mode_ == ReductionMode::odpor ? next_odpor_state() : best_opened_state(); + + // if no backtracking point, then set the stack_ to empty so we can end the exploration + if (not backtracking_point) { + XBT_DEBUG("No more opened point of exploration, the search will end"); + stack_.clear(); return; } - /* if no snapshot, we need to restore the initial state and replay the transitions */ - get_session().restore_initial_state(); - on_restore_initial_state_signal(); + // We found a backtracking point, let's go to it + backtrack_count_++; + XBT_DEBUG("Backtracking to state#%ld", backtracking_point->get_num()); + + // Search how to restore the backtracking point + std::deque replay_recipe; + for (const auto* s = backtracking_point.get(); s != nullptr; s = s->get_parent_state().get()) { + if (s->get_transition_in() != nullptr) // The root has no transition_in + replay_recipe.push_front(s->get_transition_in().get()); + } + // Restore the initial state if no intermediate state was found + get_remote_app().restore_initial_state(); + on_restore_initial_state_signal(get_remote_app()); + + /* if no snapshot, we need to restore the initial state and replay the transitions */ /* Traverse the stack from the state at position start and re-execute the transitions */ - for (std::unique_ptr const& state : stack_) { - if (state == stack_.back()) /* If we are arrived on the target state, don't replay the outgoing transition */ - break; - state->get_transition()->replay(); - on_transition_replay_signal(state->get_transition()); - /* Update statistics */ - Api::get().mc_inc_visited_states(); + for (auto& transition : replay_recipe) { + transition->replay(get_remote_app()); + on_transition_replay_signal(transition, get_remote_app()); + visited_states_count_++; } + this->restore_stack(backtracking_point); } -DFSExplorer::DFSExplorer(Session* session) : Exploration(session) +DFSExplorer::DFSExplorer(const std::vector& args, ReductionMode mode) : Exploration(args), reduction_mode_(mode) { - reductionMode_ = reduction_mode; - if (_sg_mc_termination) - reductionMode_ = ReductionMode::none; - else if (reductionMode_ == ReductionMode::unset) - reductionMode_ = ReductionMode::dpor; - - if (_sg_mc_termination) - XBT_INFO("Check non progressive cycles"); - else - XBT_INFO("Start a DFS exploration. Reduction is: %s.", - (reductionMode_ == ReductionMode::none ? "none" - : (reductionMode_ == ReductionMode::dpor ? "dpor" : "unknown"))); - - get_session().take_initial_snapshot(); - - XBT_DEBUG("Starting the DFS exploration"); + XBT_INFO("Start a DFS exploration. Reduction is: %s.", to_c_str(reduction_mode_)); - auto initial_state = std::make_unique(); + auto initial_state = std::make_shared(get_remote_app()); XBT_DEBUG("**************************************************"); + stack_.emplace_back(std::move(initial_state)); + /* Get an enabled actor and insert it in the interleave set of the initial state */ - auto actors = Api::get().get_actors(); - XBT_DEBUG("Initial state. %zu actors to consider", actors.size()); - for (auto& actor : actors) { - aid_t aid = actor.copy.get_buffer()->get_pid(); - if (get_session().actor_is_enabled(aid)) { - initial_state->mark_todo(aid); - if (reductionMode_ == ReductionMode::dpor) { - XBT_DEBUG("Actor %ld is TODO, DPOR is ON so let's go for this one.", aid); - break; - } - XBT_DEBUG("Actor %ld is TODO", aid); - } + XBT_DEBUG("Initial state. %lu actors to consider", stack_.back()->get_actor_count()); + if (reduction_mode_ == ReductionMode::dpor) + stack_.back()->consider_best(); + else { + stack_.back()->consider_all(); } - - stack_.push_back(std::move(initial_state)); + if (stack_.back()->count_todo_multiples() > 1) + opened_states_.emplace_back(stack_.back()); } -Exploration* create_dfs_exploration(Session* session) +Exploration* create_dfs_exploration(const std::vector& args, ReductionMode mode) { - return new DFSExplorer(session); + return new DFSExplorer(args, mode); } } // namespace simgrid::mc diff --git a/src/mc/explo/DFSExplorer.hpp b/src/mc/explo/DFSExplorer.hpp index 8c59356b9b..bb80b08f98 100644 --- a/src/mc/explo/DFSExplorer.hpp +++ b/src/mc/explo/DFSExplorer.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,76 +6,118 @@ #ifndef SIMGRID_MC_SAFETY_CHECKER_HPP #define SIMGRID_MC_SAFETY_CHECKER_HPP -#include "src/mc/VisitedState.hpp" +#include "src/mc/api/ClockVector.hpp" +#include "src/mc/api/State.hpp" #include "src/mc/explo/Exploration.hpp" -#include "src/mc/mc_safety.hpp" +#include "src/mc/explo/odpor/Execution.hpp" +#include "src/mc/mc_config.hpp" +#include #include #include +#include #include +#include #include namespace simgrid::mc { +using stack_t = std::deque>; + class XBT_PRIVATE DFSExplorer : public Exploration { - ReductionMode reductionMode_ = ReductionMode::unset; - long backtrack_count_ = 0; +private: + ReductionMode reduction_mode_; + unsigned long backtrack_count_ = 0; // for statistics + unsigned long visited_states_count_ = 0; // for statistics - static xbt::signal on_exploration_start_signal; - static xbt::signal on_backtracking_signal; + static xbt::signal on_exploration_start_signal; + static xbt::signal on_backtracking_signal; - static xbt::signal on_state_creation_signal; + static xbt::signal on_state_creation_signal; - static xbt::signal on_restore_system_state_signal; - static xbt::signal on_restore_initial_state_signal; - static xbt::signal on_transition_replay_signal; - static xbt::signal on_transition_execute_signal; + static xbt::signal on_restore_system_state_signal; + static xbt::signal on_restore_initial_state_signal; + static xbt::signal on_transition_replay_signal; + static xbt::signal on_transition_execute_signal; - static xbt::signal on_log_state_signal; + static xbt::signal on_log_state_signal; public: - explicit DFSExplorer(Session* session); + explicit DFSExplorer(const std::vector& args, ReductionMode mode); void run() override; RecordTrace get_record_trace() override; - std::vector get_textual_trace() override; void log_state() override; /** Called once when the exploration starts */ - static void on_exploration_start(std::function const& f) { on_exploration_start_signal.connect(f); } + static void on_exploration_start(std::function const& f) + { + on_exploration_start_signal.connect(f); + } /** Called each time that the exploration backtracks from a exploration end */ - static void on_backtracking(std::function const& f) { on_backtracking_signal.connect(f); } + static void on_backtracking(std::function const& f) + { + on_backtracking_signal.connect(f); + } /** Called each time that a new state is create */ - static void on_state_creation(std::function const& f) { on_state_creation_signal.connect(f); } + static void on_state_creation(std::function const& f) + { + on_state_creation_signal.connect(f); + } /** Called when rollbacking directly onto a previously checkpointed state */ - static void on_restore_system_state(std::function const& f) + static void on_restore_system_state(std::function const& f) { on_restore_system_state_signal.connect(f); } /** Called when the state to which we backtrack was not checkpointed state, forcing us to restore the initial state * before replaying some transitions */ - static void on_restore_initial_state(std::function const& f) { on_restore_initial_state_signal.connect(f); } + static void on_restore_initial_state(std::function const& f) + { + on_restore_initial_state_signal.connect(f); + } /** Called when replaying a transition that was previously executed, to reach a backtracked state */ - static void on_transition_replay(std::function const& f) + static void on_transition_replay(std::function const& f) { on_transition_replay_signal.connect(f); } /** Called when executing a new transition */ - static void on_transition_execute(std::function const& f) + static void on_transition_execute(std::function const& f) { on_transition_execute_signal.connect(f); } /** Called when displaying the statistics at the end of the exploration */ - static void on_log_state(std::function const& f) { on_log_state_signal.connect(f); } + static void on_log_state(std::function const& f) { on_log_state_signal.connect(f); } private: - void check_non_termination(const State* current_state); void backtrack(); - void restore_state(); /** Stack representing the position in the exploration graph */ - std::list> stack_; - VisitedStates visited_states_; - std::unique_ptr visited_state_; + stack_t stack_; + + /** + * Provides additional metadata about the position in the exploration graph + * which is used by SDPOR and ODPOR + */ + odpor::Execution execution_seq_; + + /** Per-actor clock vectors used to compute the "happens-before" relation */ + std::unordered_map per_actor_clocks_; + + /** Opened states are states that still contains todo actors. + * When backtracking, we pick a state from it*/ + std::vector> opened_states_; + std::shared_ptr best_opened_state(); + + /** If we're running ODPOR, picks the corresponding state in the stack + * (opened_states_ are ignored) + */ + std::shared_ptr next_odpor_state(); + + /** Change current stack_ value to correspond to the one we would have + * had if we executed transition to get to state. This is required when + * backtracking, and achieved thanks to the fact states save their parent.*/ + void restore_stack(std::shared_ptr state); + + RecordTrace get_record_trace_of_stack(stack_t stack); }; } // namespace simgrid::mc diff --git a/src/mc/explo/Exploration.cpp b/src/mc/explo/Exploration.cpp new file mode 100644 index 0000000000..58bc34d610 --- /dev/null +++ b/src/mc/explo/Exploration.cpp @@ -0,0 +1,135 @@ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/Exploration.hpp" +#include "src/mc/mc_config.hpp" +#include "src/mc/mc_environ.h" +#include "src/mc/mc_exit.hpp" +#include "src/mc/mc_private.hpp" +#include "xbt/string.hpp" + +#include + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_explo, mc, "Generic exploration algorithm of the model-checker"); + +namespace simgrid::mc { + +static simgrid::config::Flag cfg_dot_output_file{ + "model-check/dot-output", "Name of dot output file corresponding to graph state", ""}; + +Exploration* Exploration::instance_ = nullptr; // singleton instance + +Exploration::Exploration(const std::vector& args) : remote_app_(std::make_unique(args)) +{ + xbt_assert(instance_ == nullptr, "Cannot have more than one exploration instance"); + instance_ = this; + + if (not cfg_dot_output_file.get().empty()) { + dot_output_ = fopen(cfg_dot_output_file.get().c_str(), "w"); + xbt_assert(dot_output_ != nullptr, "Error open dot output file: %s", strerror(errno)); + + fprintf(dot_output_, "digraph graphname{\n fixedsize=true; rankdir=TB; ranksep=.25; edge [fontsize=12]; node " + "[fontsize=10, shape=circle,width=.5 ]; graph [resolution=20, fontsize=10];\n"); + } +} + +Exploration::~Exploration() +{ + if (dot_output_ != nullptr) + fclose(dot_output_); + instance_ = nullptr; +} + +void Exploration::dot_output(const char* fmt, ...) +{ + if (dot_output_ != nullptr) { + va_list ap; + va_start(ap, fmt); + vfprintf(dot_output_, fmt, ap); + va_end(ap); + fflush(dot_output_); + } +} + +void Exploration::log_state() +{ + if (not cfg_dot_output_file.get().empty()) { + dot_output("}\n"); + fclose(dot_output_); + } + if (getenv(MC_ENV_SYSTEM_STATISTICS)) { + int ret = system("free"); + if (ret != 0) + XBT_WARN("Call to system(free) did not return 0, but %d", ret); + } +} +// Make our tests fully reproducible despite the subtle differences of strsignal() across archs +static const char* signal_name(int status) +{ + switch (WTERMSIG(status)) { + case SIGABRT: // FreeBSD uses "Abort trap" as a strsignal for SIGABRT + return "Aborted"; + case SIGSEGV: // MacOSX uses "Segmentation fault: 11" for SIGKILL + return "Segmentation fault"; + default: + return strsignal(WTERMSIG(status)); + } +} + +std::vector Exploration::get_textual_trace(int max_elements) +{ + std::vector trace; + for (auto const& transition : get_record_trace()) { + auto const& call_location = transition->get_call_location(); + if (not call_location.empty()) + trace.push_back(xbt::string_printf("Actor %ld in %s ==> simcall: %s", transition->aid_, call_location.c_str(), + transition->to_string().c_str())); + else + trace.push_back(xbt::string_printf("Actor %ld in simcall %s", transition->aid_, transition->to_string().c_str())); + max_elements--; + if (max_elements == 0) + break; + } + return trace; +} + +XBT_ATTRIB_NORETURN void Exploration::report_crash(int status) +{ + XBT_INFO("**************************"); + XBT_INFO("** CRASH IN THE PROGRAM **"); + XBT_INFO("**************************"); + if (WIFSIGNALED(status)) + XBT_INFO("From signal: %s", signal_name(status)); + else if (WIFEXITED(status)) + XBT_INFO("From exit: %i", WEXITSTATUS(status)); + if (not xbt_log_no_loc) + XBT_INFO("%s core dump was generated by the system.", WCOREDUMP(status) ? "A" : "No"); + + XBT_INFO("Counter-example execution trace:"); + for (auto const& s : get_textual_trace()) + XBT_INFO(" %s", s.c_str()); + XBT_INFO("You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with " + "--cfg=model-check/replay:'%s'", + get_record_trace().to_string().c_str()); + log_state(); + + throw McError(ExitStatus::PROGRAM_CRASH); +} +XBT_ATTRIB_NORETURN void Exploration::report_assertion_failure() +{ + XBT_INFO("**************************"); + XBT_INFO("*** PROPERTY NOT VALID ***"); + XBT_INFO("**************************"); + XBT_INFO("Counter-example execution trace:"); + for (auto const& s : get_textual_trace()) + XBT_INFO(" %s", s.c_str()); + XBT_INFO("You can debug the problem (and see the whole details) by rerunning out of simgrid-mc with " + "--cfg=model-check/replay:'%s'", + get_record_trace().to_string().c_str()); + log_state(); + throw McError(ExitStatus::SAFETY); +} + +}; // namespace simgrid::mc diff --git a/src/mc/explo/Exploration.hpp b/src/mc/explo/Exploration.hpp index 5b995f7ded..8ef417c627 100644 --- a/src/mc/explo/Exploration.hpp +++ b/src/mc/explo/Exploration.hpp @@ -1,5 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,7 +6,14 @@ #ifndef SIMGRID_MC_CHECKER_HPP #define SIMGRID_MC_CHECKER_HPP -#include "src/mc/api.hpp" +#include "simgrid/forward.h" +#include "src/mc/api/RemoteApp.hpp" +#include "src/mc/mc_config.hpp" +#include "src/mc/mc_exit.hpp" +#include "src/mc/mc_record.hpp" +#include + +#include namespace simgrid::mc { @@ -20,48 +26,55 @@ namespace simgrid::mc { * you might be able to write your model-checking algorithm as plain * imperative code instead. * - * It is expected to interact with the model-checking core through the - * `Session` interface (but currently the `Session` interface does not - * have all the necessary features). */ + * It is expected to interact with the model-checked application through the + * `RemoteApp` interface (that is currently not perfectly sufficient to that extend). */ // abstract class Exploration : public xbt::Extendable { - Session* session_; + std::unique_ptr remote_app_; + static Exploration* instance_; + + FILE* dot_output_ = nullptr; public: - explicit Exploration(Session* session) : session_(session) {} + explicit Exploration(const std::vector& args); + virtual ~Exploration(); + static Exploration* get_instance() { return instance_; } // No copy: - Exploration(Exploration const&) = delete; + Exploration(Exploration const&) = delete; Exploration& operator=(Exploration const&) = delete; - virtual ~Exploration() = default; - /** Main function of this algorithm */ virtual void run() = 0; + /** Produce an error message indicating that the application crashed (status was produced by waitpid) */ + XBT_ATTRIB_NORETURN void report_crash(int status); + /** Produce an error message indicating that a property was violated */ + XBT_ATTRIB_NORETURN void report_assertion_failure(); + /* These methods are callbacks called by the model-checking engine * to get and display information about the current state of the * model-checking algorithm: */ - /** Show the current trace/stack - * - * Could this be handled in the Session/ModelChecker instead? */ + /** Retrieve the current stack to build an execution trace */ virtual RecordTrace get_record_trace() = 0; /** Generate a textual execution trace of the simulated application */ - virtual std::vector get_textual_trace() = 0; + std::vector get_textual_trace(int max_elements = -1); /** Log additional information about the state of the model-checker */ - virtual void log_state() = 0; + virtual void log_state(); + + RemoteApp& get_remote_app() { return *remote_app_.get(); } - Session& get_session() { return *session_; } + /** Print something to the dot output file*/ + void dot_output(const char* fmt, ...) XBT_ATTRIB_PRINTF(2, 3); }; // External constructors so that the types (and the types of their content) remain hidden -XBT_PUBLIC Exploration* create_liveness_checker(Session* session); -XBT_PUBLIC Exploration* create_dfs_exploration(Session* session); -XBT_PUBLIC Exploration* create_communication_determinism_checker(Session* session); -XBT_PUBLIC Exploration* create_udpor_checker(Session* session); +XBT_PUBLIC Exploration* create_dfs_exploration(const std::vector& args, ReductionMode mode); +XBT_PUBLIC Exploration* create_communication_determinism_checker(const std::vector& args, ReductionMode mode); +XBT_PUBLIC Exploration* create_udpor_checker(const std::vector& args); } // namespace simgrid::mc diff --git a/src/mc/explo/LivenessChecker.cpp b/src/mc/explo/LivenessChecker.cpp deleted file mode 100644 index c467eee9f1..0000000000 --- a/src/mc/explo/LivenessChecker.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/* Copyright (c) 2011-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/explo/LivenessChecker.hpp" -#include "src/mc/Session.hpp" -#include "src/mc/mc_config.hpp" -#include "src/mc/mc_exit.hpp" -#include "src/mc/mc_private.hpp" - -#include -#include - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_liveness, mc, "Logging specific to algorithms for liveness properties verification"); - -/********* Static functions *********/ - -namespace simgrid::mc { - -VisitedPair::VisitedPair(int pair_num, xbt_automaton_state_t automaton_state, - std::shared_ptr> atomic_propositions, - std::shared_ptr graph_state) - : num(pair_num), automaton_state(automaton_state) -{ - this->graph_state = std::move(graph_state); - if (not this->graph_state->get_system_state()) - this->graph_state->set_system_state(std::make_shared(pair_num)); - this->heap_bytes_used = Api::get().get_remote_heap_bytes(); - this->actors_count = Api::get().get_actors().size(); - this->other_num = -1; - this->atomic_propositions = std::move(atomic_propositions); -} - -static bool evaluate_label(const xbt_automaton_exp_label* l, std::vector const& values) -{ - switch (l->type) { - case xbt_automaton_exp_label::AUT_OR: - return evaluate_label(l->u.or_and.left_exp, values) || evaluate_label(l->u.or_and.right_exp, values); - case xbt_automaton_exp_label::AUT_AND: - return evaluate_label(l->u.or_and.left_exp, values) && evaluate_label(l->u.or_and.right_exp, values); - case xbt_automaton_exp_label::AUT_NOT: - return not evaluate_label(l->u.exp_not, values); - case xbt_automaton_exp_label::AUT_PREDICAT: - return values.at(Api::get().compare_automaton_exp_label(l)) != 0; - case xbt_automaton_exp_label::AUT_ONE: - return true; - default: - xbt_die("Unexpected value for automaton"); - } -} - -Pair::Pair(unsigned long expanded_pairs) : num(expanded_pairs) {} - -std::shared_ptr> LivenessChecker::get_proposition_values() const -{ - auto values = Api::get().automaton_propositional_symbol_evaluate(); - return std::make_shared>(std::move(values)); -} - -std::shared_ptr LivenessChecker::insert_acceptance_pair(simgrid::mc::Pair* pair) -{ - auto new_pair = - std::make_shared(pair->num, pair->automaton_state, pair->atomic_propositions, pair->graph_state); - - auto [res_begin, res_end] = boost::range::equal_range(acceptance_pairs_, new_pair.get(), Api::get().compare_pair()); - - if (pair->search_cycle) - for (auto i = res_begin; i != res_end; ++i) { - std::shared_ptr const& pair_test = *i; - if (xbt_automaton_state_compare(pair_test->automaton_state, new_pair->automaton_state) != 0 || - *(pair_test->atomic_propositions) != *(new_pair->atomic_propositions) || - not Api::get().snapshot_equal(pair_test->graph_state->get_system_state(), - new_pair->graph_state->get_system_state())) - continue; - XBT_INFO("Pair %d already reached (equal to pair %d) !", new_pair->num, pair_test->num); - exploration_stack_.pop_back(); - if (dot_output != nullptr) - fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", this->previous_pair_, pair_test->num, - this->previous_request_.c_str()); - return nullptr; - } - - acceptance_pairs_.insert(res_begin, new_pair); - return new_pair; -} - -void LivenessChecker::remove_acceptance_pair(int pair_num) -{ - for (auto i = acceptance_pairs_.begin(); i != acceptance_pairs_.end(); ++i) - if ((*i)->num == pair_num) { - acceptance_pairs_.erase(i); - break; - } -} - -void LivenessChecker::replay() -{ - XBT_DEBUG("**** Begin Replay ****"); - - /* Intermediate backtracking */ - if (_sg_mc_checkpoint > 0) { - const Pair* pair = exploration_stack_.back().get(); - if (const auto* system_state = pair->graph_state->get_system_state()) { - Api::get().restore_state(system_state); - return; - } - } - - get_session().restore_initial_state(); - - /* Traverse the stack from the initial state and re-execute the transitions */ - int depth = 1; - for (std::shared_ptr const& pair : exploration_stack_) { - if (pair == exploration_stack_.back()) - break; - - std::shared_ptr state = pair->graph_state; - - if (pair->exploration_started) { - state->get_transition()->replay(); - XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth, state->get_transition()->to_string().c_str(), state.get()); - } - - /* Update statistics */ - visited_pairs_count_++; - depth++; - } - XBT_DEBUG("**** End Replay ****"); -} - -/** - * @brief Checks whether a given pair has already been visited by the algorithm. - */ -int LivenessChecker::insert_visited_pair(std::shared_ptr visited_pair, simgrid::mc::Pair* pair) -{ - if (_sg_mc_max_visited_states == 0) - return -1; - - if (visited_pair == nullptr) - visited_pair = - std::make_shared(pair->num, pair->automaton_state, pair->atomic_propositions, pair->graph_state); - - auto [range_begin, range_end] = - boost::range::equal_range(visited_pairs_, visited_pair.get(), Api::get().compare_pair()); - - for (auto i = range_begin; i != range_end; ++i) { - const VisitedPair* pair_test = i->get(); - if (xbt_automaton_state_compare(pair_test->automaton_state, visited_pair->automaton_state) != 0 || - *(pair_test->atomic_propositions) != *(visited_pair->atomic_propositions) || - not Api::get().snapshot_equal(pair_test->graph_state->get_system_state(), - visited_pair->graph_state->get_system_state())) - continue; - if (pair_test->other_num == -1) - visited_pair->other_num = pair_test->num; - else - visited_pair->other_num = pair_test->other_num; - if (dot_output == nullptr) - XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", visited_pair->num, pair_test->num); - else - XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", visited_pair->num, - pair_test->num, visited_pair->other_num); - (*i) = std::move(visited_pair); - return (*i)->other_num; - } - - visited_pairs_.insert(range_begin, std::move(visited_pair)); - this->purge_visited_pairs(); - return -1; -} - -void LivenessChecker::purge_visited_pairs() -{ - if (_sg_mc_max_visited_states != 0 && visited_pairs_.size() > (std::size_t)_sg_mc_max_visited_states) { - // Remove the oldest entry with a linear search: - visited_pairs_.erase( - boost::min_element(visited_pairs_, [](std::shared_ptr const a, - std::shared_ptr const& b) { return a->num < b->num; })); - } -} - -LivenessChecker::LivenessChecker(Session* session) : Exploration(session) {} - -RecordTrace LivenessChecker::get_record_trace() // override -{ - RecordTrace res; - for (std::shared_ptr const& pair : exploration_stack_) - res.push_back(pair->graph_state->get_transition()); - return res; -} - -void LivenessChecker::log_state() // override -{ - XBT_INFO("Expanded pairs = %lu", expanded_pairs_count_); - XBT_INFO("Visited pairs = %lu", visited_pairs_count_); - XBT_INFO("Executed transitions = %lu", Transition::get_executed_transitions()); -} - -void LivenessChecker::show_acceptance_cycle(std::size_t depth) -{ - XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); - XBT_INFO("| ACCEPTANCE CYCLE |"); - XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); - XBT_INFO("Counter-example that violates formula:"); - for (auto const& s : this->get_textual_trace()) - XBT_INFO(" %s", s.c_str()); - XBT_INFO("Path = %s", get_record_trace().to_string().c_str()); - log_state(); - XBT_INFO("Counter-example depth: %zu", depth); -} - -std::vector LivenessChecker::get_textual_trace() // override -{ - std::vector trace; - for (std::shared_ptr const& pair : exploration_stack_) - trace.push_back(pair->graph_state->get_transition()->to_string()); - - return trace; -} - -std::shared_ptr LivenessChecker::create_pair(const Pair* current_pair, xbt_automaton_state_t state, - std::shared_ptr> propositions) -{ - ++expanded_pairs_count_; - auto next_pair = std::make_shared(expanded_pairs_count_); - next_pair->automaton_state = state; - next_pair->graph_state = std::make_shared(); - next_pair->atomic_propositions = std::move(propositions); - if (current_pair) - next_pair->depth = current_pair->depth + 1; - else - next_pair->depth = 1; - /* Add all enabled actors to the interleave set of the initial state */ - for (auto& act : Api::get().get_actors()) { - auto actor = act.copy.get_buffer(); - if (get_session().actor_is_enabled(actor->get_pid())) - next_pair->graph_state->mark_todo(actor->get_pid()); - } - - next_pair->requests = next_pair->graph_state->count_todo(); - /* FIXME : get search_cycle value for each accepting state */ - if (next_pair->automaton_state->type == 1 || (current_pair && current_pair->search_cycle)) - next_pair->search_cycle = true; - else - next_pair->search_cycle = false; - return next_pair; -} - -void LivenessChecker::backtrack() -{ - /* Traverse the stack backwards until a pair with a non empty interleave - set is found, deleting all the pairs that have it empty in the way. */ - while (not exploration_stack_.empty()) { - std::shared_ptr current_pair = exploration_stack_.back(); - exploration_stack_.pop_back(); - if (current_pair->requests > 0) { - /* We found a backtracking point */ - XBT_DEBUG("Backtracking to depth %d", current_pair->depth); - exploration_stack_.push_back(std::move(current_pair)); - this->replay(); - XBT_DEBUG("Backtracking done"); - break; - } else { - XBT_DEBUG("Delete pair %d at depth %d", current_pair->num, current_pair->depth); - if (current_pair->automaton_state->type == 1) - this->remove_acceptance_pair(current_pair->num); - } - } -} - -void LivenessChecker::run() -{ - XBT_INFO("Check the liveness property %s", _sg_mc_property_file.get().c_str()); - Api::get().automaton_load(_sg_mc_property_file.get().c_str()); - - XBT_DEBUG("Starting the liveness algorithm"); - get_session().take_initial_snapshot(); - - /* Initialize */ - this->previous_pair_ = 0; - - std::shared_ptr> propos = this->get_proposition_values(); - - // For each initial state of the property automaton, push a - // (application_state, automaton_state) pair to the exploration stack: - auto automaton_stack = Api::get().get_automaton_state(); - for (auto* automaton_state : automaton_stack) { - if (automaton_state->type == -1) - exploration_stack_.push_back(this->create_pair(nullptr, automaton_state, propos)); - } - - /* Actually run the double DFS search for counter-examples */ - while (not exploration_stack_.empty()) { - std::shared_ptr current_pair = exploration_stack_.back(); - - /* Update current state in buchi automaton */ - Api::get().set_property_automaton(current_pair->automaton_state); - - XBT_DEBUG( - "********************* ( Depth = %d, search_cycle = %d, interleave size = %zu, pair_num = %d, requests = %d)", - current_pair->depth, current_pair->search_cycle, current_pair->graph_state->count_todo(), current_pair->num, - current_pair->requests); - - if (current_pair->requests == 0) { - this->backtrack(); - continue; - } - - std::shared_ptr reached_pair; - if (current_pair->automaton_state->type == 1 && not current_pair->exploration_started) { - reached_pair = this->insert_acceptance_pair(current_pair.get()); - if (reached_pair == nullptr) { - this->show_acceptance_cycle(current_pair->depth); - throw LivenessError(); - } - } - - /* Pair already visited ? stop the exploration on the current path */ - if (not current_pair->exploration_started) { - int visited_num = this->insert_visited_pair(reached_pair, current_pair.get()); - if (visited_num != -1) { - if (dot_output != nullptr) { - fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", this->previous_pair_, visited_num, - this->previous_request_.c_str()); - fflush(dot_output); - } - XBT_DEBUG("Pair already visited (equal to pair %d), exploration on the current path stopped.", visited_num); - current_pair->requests = 0; - this->backtrack(); - continue; - } - } - - current_pair->graph_state->execute_next(current_pair->graph_state->next_transition()); - XBT_DEBUG("Execute: %s", current_pair->graph_state->get_transition()->to_string().c_str()); - - if (dot_output != nullptr) { - if (this->previous_pair_ != 0 && this->previous_pair_ != current_pair->num) { - fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", this->previous_pair_, current_pair->num, - this->previous_request_.c_str()); - this->previous_request_.clear(); - } - this->previous_pair_ = current_pair->num; - this->previous_request_ = current_pair->graph_state->get_transition()->dot_string(); - if (current_pair->search_cycle) - fprintf(dot_output, "%d [shape=doublecircle];\n", current_pair->num); - fflush(dot_output); - } - - if (not current_pair->exploration_started) - visited_pairs_count_++; - - current_pair->requests--; - current_pair->exploration_started = true; - - /* Get values of atomic propositions (variables used in the property formula) */ - std::shared_ptr> prop_values = this->get_proposition_values(); - - // For each enabled transition in the property automaton, push a - // (application_state, automaton_state) pair to the exploration stack: - for (int i = xbt_dynar_length(current_pair->automaton_state->out) - 1; i >= 0; i--) { - const auto* transition_succ_label = - Api::get().get_automaton_transition_label(current_pair->automaton_state->out, i); - auto* transition_succ_dst = Api::get().get_automaton_transition_dst(current_pair->automaton_state->out, i); - if (evaluate_label(transition_succ_label, *prop_values)) - exploration_stack_.push_back(this->create_pair(current_pair.get(), transition_succ_dst, prop_values)); - } - } - - XBT_INFO("No property violation found."); - log_state(); -} - -Exploration* create_liveness_checker(Session* session) -{ - return new LivenessChecker(session); -} - -} // namespace simgrid::mc diff --git a/src/mc/explo/LivenessChecker.hpp b/src/mc/explo/LivenessChecker.hpp deleted file mode 100644 index 31aa65cca1..0000000000 --- a/src/mc/explo/LivenessChecker.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_LIVENESS_CHECKER_HPP -#define SIMGRID_MC_LIVENESS_CHECKER_HPP - -#include "src/mc/api/State.hpp" -#include "src/mc/explo/Exploration.hpp" -#include "xbt/automaton.hpp" - -#include -#include -#include - -namespace simgrid::mc { - -class XBT_PRIVATE Pair { -public: - int num = 0; - bool search_cycle = false; - std::shared_ptr graph_state = nullptr; /* System state included */ - xbt_automaton_state_t automaton_state = nullptr; - std::shared_ptr> atomic_propositions; - int requests = 0; - int depth = 0; - bool exploration_started = false; - - explicit Pair(unsigned long expanded_pairs); - - Pair(Pair const&) = delete; - Pair& operator=(Pair const&) = delete; -}; - -class XBT_PRIVATE VisitedPair { -public: - int num; - int other_num = 0; /* Dot output for */ - std::shared_ptr graph_state = nullptr; /* System state included */ - xbt_automaton_state_t automaton_state; - std::shared_ptr> atomic_propositions; - std::size_t heap_bytes_used = 0; - int actors_count = 0; - - VisitedPair(int pair_num, xbt_automaton_state_t automaton_state, - std::shared_ptr> atomic_propositions, std::shared_ptr graph_state); -}; - -class XBT_PRIVATE LivenessChecker : public Exploration { -public: - explicit LivenessChecker(Session* session); - void run() override; - RecordTrace get_record_trace() override; - std::vector get_textual_trace() override; - void log_state() override; - -private: - std::shared_ptr> get_proposition_values() const; - std::shared_ptr insert_acceptance_pair(Pair* pair); - int insert_visited_pair(std::shared_ptr visited_pair, Pair* pair); - void show_acceptance_cycle(std::size_t depth); - void replay(); - void remove_acceptance_pair(int pair_num); - void purge_visited_pairs(); - void backtrack(); - std::shared_ptr create_pair(const Pair* pair, xbt_automaton_state_t state, - std::shared_ptr> propositions); - - // A stack of (application_state, automaton_state) pairs for DFS exploration: - std::list> exploration_stack_; - std::list> acceptance_pairs_; - std::list> visited_pairs_; - unsigned long visited_pairs_count_ = 0; - unsigned long expanded_pairs_count_ = 0; - int previous_pair_ = 0; - std::string previous_request_; -}; - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/explo/UdporChecker.cpp b/src/mc/explo/UdporChecker.cpp index 7f43c4e678..f5c512f480 100644 --- a/src/mc/explo/UdporChecker.cpp +++ b/src/mc/explo/UdporChecker.cpp @@ -1,36 +1,360 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/explo/UdporChecker.hpp" +#include "src/mc/api/State.hpp" +#include "src/mc/explo/udpor/Comb.hpp" +#include "src/mc/explo/udpor/ExtensionSetCalculator.hpp" +#include "src/mc/explo/udpor/History.hpp" +#include "src/mc/explo/udpor/maximal_subsets_iterator.hpp" + +#include +#include #include +#include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_udpor, mc, "Logging specific to MC safety verification "); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_udpor, mc, "Logging specific to verification using UDPOR"); -namespace simgrid::mc { +namespace simgrid::mc::udpor { + +UdporChecker::UdporChecker(const std::vector& args) : Exploration(args) {} + +void UdporChecker::run() +{ + XBT_INFO("Starting a UDPOR exploration"); + state_stack.clear(); + state_stack.push_back(get_current_state()); + explore(Configuration(), EventSet(), EventSet(), EventSet()); + XBT_INFO("UDPOR exploration terminated -- model checking completed"); +} + +void UdporChecker::explore(const Configuration& C, EventSet D, EventSet A, EventSet prev_exC) +{ + auto& stateC = *state_stack.back(); + auto exC = compute_exC(C, stateC, prev_exC); + const auto enC = compute_enC(C, exC); + XBT_DEBUG("explore(C, D, A) with:\n" + "C\t := %s \n" + "D\t := %s \n" + "A\t := %s \n" + "ex(C)\t := %s \n" + "en(C)\t := %s \n", + C.to_string().c_str(), D.to_string().c_str(), A.to_string().c_str(), exC.to_string().c_str(), + enC.to_string().c_str()); + XBT_DEBUG("ex(C) has %zu elements, of which %zu are in en(C)", exC.size(), enC.size()); + + // If enC is a subset of D, intuitively + // there aren't any enabled transitions + // which are "worth" exploring since their + // exploration would lead to a so-called + // "sleep-set blocked" trace. + if (enC.is_subset_of(D)) { + XBT_DEBUG("en(C) is a subset of the sleep set D (size %zu); if we " + "kept exploring, we'd hit a sleep-set blocked trace", + D.size()); + XBT_DEBUG("The current configuration has %zu elements", C.get_events().size()); + + // When `en(C)` is empty, intuitively this means that there + // are no enabled transitions that can be executed from the + // state reached by `C` (denoted `state(C)`), i.e. by some + // execution of the transitions in C obeying the causality + // relation. Here, then, we may be in a deadlock (the other + // possibility is that we've finished running everything, and + // we wouldn't be in deadlock then) + if (enC.empty()) { + XBT_VERB("**************************"); + XBT_VERB("*** TRACE INVESTIGATED ***"); + XBT_VERB("**************************"); + XBT_VERB("Execution sequence:"); + for (auto const& s : get_textual_trace()) + XBT_VERB(" %s", s.c_str()); + get_remote_app().check_deadlock(); + } + + return; + } + UnfoldingEvent* e = select_next_unfolding_event(A, enC); + xbt_assert(e != nullptr, "\n\n****** INVARIANT VIOLATION ******\n" + "UDPOR guarantees that an event will be chosen at each point in\n" + "the search, yet no events were actually chosen\n" + "*********************************\n\n"); + XBT_DEBUG("Selected event `%s` (%zu dependencies) to extend the configuration", e->to_string().c_str(), + e->get_immediate_causes().size()); + + // Ce := C + {e} + Configuration Ce = C; + Ce.add_event(e); + + A.remove(e); + exC.remove(e); + + // Explore(C + {e}, D, A \ {e}) + + // Move the application into stateCe (i.e. `state(C + {e})`) and make note of that state + move_to_stateCe(&stateC, e); + state_stack.push_back(record_current_state()); + + explore(Ce, D, std::move(A), std::move(exC)); -UdporChecker::UdporChecker(Session* session) : Exploration(session) {} + // Prepare to move the application back one state. + // We need only remove the state from the stack here: if we perform + // another `Explore()` after computing an alternative, at that + // point we'll actually create a fresh RemoteProcess + state_stack.pop_back(); -void UdporChecker::run() {} + // D <-- D + {e} + D.insert(e); + + XBT_DEBUG("Checking for the existence of an alternative..."); + if (auto J = C.compute_alternative_to(D, this->unfolding); J.has_value()) { + // Before searching the "right half", we need to make + // sure the program actually reflects the fact + // that we are searching again from `state(C)`. While the + // stack of states is properly adjusted to represent + // `state(C)` all together, the RemoteApp is currently sitting + // at some *future* state with respect to `state(C)` since the + // recursive calls had moved it there. + restore_program_state_with_current_stack(); + + // Explore(C, D + {e}, J \ C) + auto J_minus_C = J.value().get_events().subtracting(C.get_events()); + + XBT_DEBUG("Alternative detected! The alternative is:\n" + "J\t := %s \n" + "J / C := %s\n" + "UDPOR is going to explore it...", + J.value().to_string().c_str(), J_minus_C.to_string().c_str()); + explore(C, D, std::move(J_minus_C), std::move(prev_exC)); + } else { + XBT_DEBUG("No alternative detected with:\n" + "C\t := %s \n" + "D\t := %s \n" + "A\t := %s \n", + C.to_string().c_str(), D.to_string().c_str(), A.to_string().c_str()); + } + + // D <-- D - {e} + D.remove(e); + + // Remove(e, C, D) + clean_up_explore(e, C, D); +} + +EventSet UdporChecker::compute_exC(const Configuration& C, const State& stateC, const EventSet& prev_exC) +{ + // See eqs. 5.7 of section 5.2 of [3] + // C = C' + {e_cur}, i.e. C' = C - {e_cur} + // + // Then + // + // ex(C) = ex(C' + {e_cur}) = ex(C') / {e_cur} + + // U{ : K is maximal, `a` depends on all of K, `a` enabled at config(K) } + const UnfoldingEvent* e_cur = C.get_latest_event(); + EventSet exC = prev_exC; + exC.remove(e_cur); + + // IMPORTANT NOTE: In order to have deterministic results, we need to process + // the actors in a deterministic manner so that events are discovered by + // UDPOR in a deterministic order. The processing done here always processes + // actors in a consistent order since `std::map` is by-default ordered using + // `std::less` (see the return type of `State::get_actors_list()`) + for (const auto& [aid, actor_state] : stateC.get_actors_list()) { + const auto& enabled_transitions = actor_state.get_enabled_transitions(); + if (enabled_transitions.empty()) { + XBT_DEBUG("\t Actor `%ld` is disabled: no partial extensions need to be considered", aid); + } else { + XBT_DEBUG("\t Actor `%ld` is enabled", aid); + for (const auto& transition : enabled_transitions) { + XBT_DEBUG("\t Considering partial extension for %s", transition->to_string().c_str()); + EventSet extension = ExtensionSetCalculator::partially_extend(C, &unfolding, transition); + exC.form_union(extension); + } + } + } + return exC; +} + +EventSet UdporChecker::compute_enC(const Configuration& C, const EventSet& exC) const +{ + EventSet enC; + for (const auto* e : exC) { + if (C.is_compatible_with(e)) { + enC.insert(e); + } + } + return enC; +} + +void UdporChecker::move_to_stateCe(State* state, UnfoldingEvent* e) +{ + const aid_t next_actor = e->get_transition()->aid_; + + // TODO: Add the trace if possible for reporting a bug + xbt_assert(next_actor >= 0, "\n\n****** INVARIANT VIOLATION ******\n" + "In reaching this execution path, UDPOR ensures that at least one\n" + "one transition of the state of an visited event is enabled, yet no\n" + "state was actually enabled. Please report this as a bug.\n" + "*********************************\n\n"); + auto latest_transition_by_next_actor = state->execute_next(next_actor, get_remote_app()); + + // The transition that is associated with the event was just + // executed, so it's possible that the new version of the transition + // (i.e. the one after execution) has *more* information than + // that which existed *prior* to execution. + // + // + // ------- !!!!! UDPOR INVARIANT !!!!! ------- + // + // At this point, we are leveraging the fact that + // UDPOR will not contain more than one copy of any + // transition executed by any actor for any + // particular step taken by that actor. That is, + // if transition `i` of the `j`th actor is contained in the + // configuration `C` currently under consideration + // by UDPOR, then only one and only one copy exists in `C` + // + // This means that we can referesh the transitions associated + // with each event lazily, i.e. only after we have chosen the + // event to continue our execution. + e->set_transition(std::move(latest_transition_by_next_actor)); +} + +void UdporChecker::restore_program_state_with_current_stack() +{ + XBT_DEBUG("Restoring state using the current stack"); + get_remote_app().restore_initial_state(); + + /* Traverse the stack from the state at position start and re-execute the transitions */ + for (const std::unique_ptr& state : state_stack) { + if (state == state_stack.back()) /* If we are arrived on the target state, don't replay the outgoing transition */ + break; + state->get_transition_out()->replay(get_remote_app()); + } +} + +std::unique_ptr UdporChecker::record_current_state() +{ + auto next_state = this->get_current_state(); + + // In UDPOR, we care about all enabled transitions in a given state + next_state->consider_all(); + + return next_state; +} + +UnfoldingEvent* UdporChecker::select_next_unfolding_event(const EventSet& A, const EventSet& enC) +{ + if (enC.empty()) { + throw std::invalid_argument("There are no unfolding events to select. " + "Are you sure that you checked that en(C) was not " + "empty before attempting to select an event from it?"); + } + + // UDPOR's exploration is non-deterministic (as is DPOR's) + // in the sense that at any given point there may + // be multiple paths that can be followed. The correctness and optimality + // of the algorithm remains unaffected by the route taken by UDPOR when + // given multiple choices; but to ensure that SimGrid itself has deterministic + // behavior on all platforms, we always pick events with lower id's + // to ensure we explore the unfolding deterministically. + if (A.empty()) { + const auto min_event = std::min_element(enC.begin(), enC.end(), + [](const auto e1, const auto e2) { return e1->get_id() < e2->get_id(); }); + return const_cast(*min_event); + } else { + const auto intersection = A.make_intersection(enC); + const auto min_event = std::min_element(intersection.begin(), intersection.end(), + [](const auto e1, const auto e2) { return e1->get_id() < e2->get_id(); }); + return const_cast(*min_event); + } +} + +void UdporChecker::clean_up_explore(const UnfoldingEvent* e, const Configuration& C, const EventSet& D) +{ + // The "clean-up set" conceptually represents + // those events which will no longer be considered + // by UDPOR during its exploration. The concept is + // introduced to avoid modification during iteration + // over the current unfolding to determine who needs to + // be removed. Since sets are unordered, it's quite possible + // that e.g. two events `e` and `e'` such that `e < e'` + // which are determined eligible for removal are removed + // in the order `e` and then `e'`. Determining that `e'` + // needs to be removed requires that its history be in + // tact to e.g. compute the conflicts with the event. + // + // Thus, we compute the set and remove all of the events + // at once in lieu of removing events while iterating over them. + // We can hypothesize that processing the events in reverse + // topological order would prevent any issues concerning + // the order in which are processed + EventSet clean_up_set; + + // Q_(C, D, U) = C u D u U (complicated expression) + // See page 9 of "Unfolding-based Partial Order Reduction" + + // "C u D" portion + const EventSet C_union_D = C.get_events().make_union(D); + + // "U (complicated expression)" portion + const EventSet conflict_union = std::accumulate( + C_union_D.begin(), C_union_D.end(), EventSet(), [&](const EventSet& acc, const UnfoldingEvent* e_prime) { + return acc.make_union(unfolding.get_immediate_conflicts_of(e_prime)); + }); + + const EventSet Q_CDU = C_union_D.make_union(conflict_union.get_local_config()); + + XBT_DEBUG("Computed Q_CDU as '%s'", Q_CDU.to_string().c_str()); + + // Move {e} \ Q_CDU from U to G + if (not Q_CDU.contains(e)) { + XBT_DEBUG("Moving %s from U to G...", e->to_string().c_str()); + clean_up_set.insert(e); + } + + // foreach ê in #ⁱ_U(e) + for (const auto* e_hat : this->unfolding.get_immediate_conflicts_of(e)) { + // Move [ê] \ Q_CDU from U to G + const EventSet to_remove = e_hat->get_local_config().subtracting(Q_CDU); + XBT_DEBUG("Moving {%s} from U to G...", to_remove.to_string().c_str()); + clean_up_set.form_union(to_remove); + } + + // TODO: We still perhaps need to + // figure out how to deal with the fact that the previous + // extension sets computed for past configurations + // contain events that may be removed from `U`. Perhaps + // it would be best to keep them around forever (they + // are moved to `G` after all and can be discarded at will, + // which means they may never have to be removed at all). + // + // Of course, the benefit of moving them into the set `G` + // is that the computation for immediate conflicts becomes + // more efficient (we have to search all of `U` for such conflicts, + // and there would be no reason to search those events + // that UDPOR has marked as no longer being important) + // For now, there appear to be no "obvious" issues (although + // UDPOR's behavior is often far from obvious...) + this->unfolding.mark_finished(clean_up_set); +} RecordTrace UdporChecker::get_record_trace() { RecordTrace res; + for (auto const& state : state_stack) + res.push_back(state->get_transition_out().get()); return res; } -std::vector UdporChecker::get_textual_trace() -{ - std::vector trace; - return trace; -} +} // namespace simgrid::mc::udpor -void UdporChecker::log_state() {} +namespace simgrid::mc { -Exploration* create_udpor_checker(Session* session) +Exploration* create_udpor_checker(const std::vector& args) { - return new UdporChecker(session); + return new simgrid::mc::udpor::UdporChecker(args); } } // namespace simgrid::mc diff --git a/src/mc/explo/UdporChecker.hpp b/src/mc/explo/UdporChecker.hpp index 168a14a58c..02f2a8e1d1 100644 --- a/src/mc/explo/UdporChecker.hpp +++ b/src/mc/explo/UdporChecker.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -7,20 +7,147 @@ #ifndef SIMGRID_MC_UDPOR_CHECKER_HPP #define SIMGRID_MC_UDPOR_CHECKER_HPP +#include "src/mc/api/State.hpp" #include "src/mc/explo/Exploration.hpp" +#include "src/mc/explo/udpor/Configuration.hpp" +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/Unfolding.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" #include "src/mc/mc_record.hpp" -namespace simgrid::mc { +#include +#include +#include +namespace simgrid::mc::udpor { + +/** + * @brief Performs exploration of a concurrent system via the + * UDPOR algorithm + * + * The `UdporChecker` implementation is based primarily off three papers, + * herein referred to as [1], [2], and [3] respectively, as well as the + * current implementation of `tiny_simgrid`: + * + * 1. "Unfolding-based Partial Order Reduction" by Rodriguez et al. + * 2. "Quasi-Optimal Partial Order Reduction" by Nguyen et al. + * 3. The Anh Pham's Thesis "Exploration efficace de l'espace ..." + */ class XBT_PRIVATE UdporChecker : public Exploration { public: - explicit UdporChecker(Session* session); + explicit UdporChecker(const std::vector& args); + void run() override; RecordTrace get_record_trace() override; - std::vector get_textual_trace() override; - void log_state() override; -}; + std::unique_ptr get_current_state() { return std::make_unique(get_remote_app()); } + +private: + Unfolding unfolding = Unfolding(); + + // The current sequence of states that the checker has + // visited in order to reach the current configuration + std::list> state_stack; + + /** + * @brief Explores the unfolding of the concurrent system + * represented by the ModelChecker instance "mcmodel_checker" + * + * This function performs the actual search following the + * UDPOR algorithm according to [1]. + * + * @param C the current configuration from which UDPOR will be used + * to explore expansions of the concurrent system being modeled + * @param D the set of events that should not be considered by UDPOR + * while performing its searches, in order to avoid sleep-set blocked + * executions. See [1] for more details + * @param A the set of events to "guide" UDPOR in the correct direction + * when it returns back to a node in the unfolding and must decide among + * events to select from `ex(C)`. See [1] for more details + * + * TODO: Add the optimization where we can check if e == e_prior + * to prevent repeated work when computing ex(C) + */ + void explore(const Configuration& C, EventSet D, EventSet A, EventSet prev_exC); -} // namespace simgrid::mc + /** + * @brief Identifies the next event from the unfolding of the concurrent system + * that should next be explored as an extension of a configuration with + * enabled events `enC` + * + * @param A The set of events `A` maintained by the UDPOR algorithm to help + * determine how events should be selected. See the original paper [1] for more details + * + * @param enC The set `enC` of enabled events from the extension set `exC` used + * by the UDPOR algorithm to select new events to search. See the original + * paper [1] for more details + */ + UnfoldingEvent* select_next_unfolding_event(const EventSet& A, const EventSet& enC); + + /** + * @brief Computes the sets `ex(C)` and `en(C)` of the given configuration + * `C` as an incremental computation from the the previous computation of `ex(C)` + * + * A central component to UDPOR is the computation of the set `ex(C)`. The + * extension set `ex(C)` of a configuration `C` is defined as the set of events + * outside of `C` whose full dependency chain is contained in `C` (see [1] + * for more details). + * + * In general, computing `ex(C)` is very expensive. In paper [3], The Anh Pham + * shows a method of incremental computation of the set `ex(C)` under the + * conclusions afforded under the computation model in consideration, of which + * SimGrid is apart, which allow for `ex(C)` to be computed much more efficiently. + * Intuitively, the idea is to take advantage of the fact that you can avoid a lot + * of repeated computation by exploiting the aforementioned properties (in [3]) in + * what is akin to a dynamic programming optimization. See [3] for more details + * + * @param C the configuration based on which the two sets `ex(C)` and `en(C)` are + * computed + * @param stateC the state of the program after having executed C (viz. `state(C)`) + * @param prev_exC the previous value of `ex(C)`, viz. that which was computed for + * the configuration `C' := C - {e}` + * @returns the extension set `ex(C)` of `C` + */ + EventSet compute_exC(const Configuration& C, const State& stateC, const EventSet& prev_exC); + EventSet compute_enC(const Configuration& C, const EventSet& exC) const; + + /** + * + */ + void move_to_stateCe(State* stateC, UnfoldingEvent* e); + + /** + * @brief Creates a new snapshot of the state of the application + * as it currently looks + */ + std::unique_ptr record_current_state(); + + /** + * @brief Move the application side into the state at the top of the + * state stack provided + * + * As UDPOR performs its search, it moves the application-side along with + * it so that the application is always providing the checker with + * the correct information about what each actor is running (and whether + * those actors are enabled) at the state reached by the configuration it + * decides to search. + * + * When UDPOR decides to "backtrack" (e.g. after reaching a configuration + * whose en(C) is empty), before it attempts to continue the search by taking + * a different path from a configuration it visited in the past, it must ensure + * that the application-side has moved back into `state(C)`. + * + * The search may have moved the application arbitrarily deep into its execution, + * and the search may backtrack arbitrarily closer to the beginning of the execution. + * The UDPOR implementation in SimGrid ensures that the stack is updated appropriately, + * but the process must still be regenerated. + */ + void restore_program_state_with_current_stack(); + + /** + * @brief Perform the functionality of the `Remove(e, C, D)` function in [1] + */ + void clean_up_explore(const UnfoldingEvent* e, const Configuration& C, const EventSet& D); +}; +} // namespace simgrid::mc::udpor #endif diff --git a/src/mc/explo/odpor/ClockVector_test.cpp b/src/mc/explo/odpor/ClockVector_test.cpp new file mode 100644 index 0000000000..9d49c60309 --- /dev/null +++ b/src/mc/explo/odpor/ClockVector_test.cpp @@ -0,0 +1,366 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/api/ClockVector.hpp" + +using namespace simgrid::mc; + +TEST_CASE("simgrid::mc::ClockVector: Constructing Vectors") +{ + SECTION("Without values") + { + ClockVector cv; + REQUIRE(cv.size() == 0); + + // Verify `cv` doesn't map any values + REQUIRE_FALSE(cv.get(0).has_value()); + REQUIRE_FALSE(cv.get(1).has_value()); + REQUIRE_FALSE(cv.get(2).has_value()); + REQUIRE_FALSE(cv.get(3).has_value()); + } + + SECTION("With initial values") + { + ClockVector cv{ + {1, 5}, {3, 1}, {7, 10}, {6, 5}, {8, 1}, {10, 10}, + }; + REQUIRE(cv.size() == 6); + + // Verify `cv` maps each value + REQUIRE(cv.get(1).has_value()); + REQUIRE(cv.get(1).value() == 5); + REQUIRE(cv[1] == 5); + REQUIRE(cv.get(3).has_value()); + REQUIRE(cv.get(3).value() == 1); + REQUIRE(cv[3] == 1); + REQUIRE(cv.get(7).has_value()); + REQUIRE(cv.get(7).value() == 10); + REQUIRE(cv[7] == 10); + REQUIRE(cv.get(6).has_value()); + REQUIRE(cv.get(6).value() == 5); + REQUIRE(cv[6] == 5); + REQUIRE(cv.get(8).has_value()); + REQUIRE(cv.get(8).value() == 1); + REQUIRE(cv[8] == 1); + REQUIRE(cv.get(10).has_value()); + REQUIRE(cv.get(10).value() == 10); + REQUIRE(cv[10] == 10); + } +} + +TEST_CASE("simgrid::mc::ClockVector: Testing operator[]") +{ + ClockVector cv; + cv[0] = 1; + REQUIRE(cv.size() == 1); + + REQUIRE(cv.get(0).has_value()); + REQUIRE(cv.get(0).value() == 1); + + // Verify `cv` doesn't map other values + REQUIRE_FALSE(cv.get(2).has_value()); + REQUIRE_FALSE(cv.get(3).has_value()); + + cv[10] = 31; + REQUIRE(cv.size() == 2); + + // Old values are still mapped + REQUIRE(cv.get(0).has_value()); + REQUIRE(cv.get(0).value() == 1); + REQUIRE(cv[0] == 1); + REQUIRE(cv.get(10).has_value()); + REQUIRE(cv.get(10).value() == 31); + REQUIRE(cv[10] == 31); + + // Verify `cv` doesn't map other values + REQUIRE_FALSE(cv.get(2).has_value()); + REQUIRE_FALSE(cv.get(3).has_value()); +} + +TEST_CASE("simgrid::mc::ClockVector: Testing Maximal Clock Vectors") +{ + SECTION("Max with zero clock vector yields self") + { + ClockVector cv1{ + {1, 2}, + {2, 10}, + {3, 5}, + }; + ClockVector cv2; + ClockVector maxCV = ClockVector::max(cv1, cv2); + + REQUIRE(maxCV.size() == 3); + REQUIRE(maxCV.get(1).has_value()); + REQUIRE(maxCV.get(1).value() == 2); + REQUIRE(maxCV[1] == 2); + + REQUIRE(maxCV.get(2).has_value()); + REQUIRE(maxCV.get(2).value() == 10); + REQUIRE(maxCV[2] == 10); + + REQUIRE(maxCV.get(3).has_value()); + REQUIRE(maxCV.get(3).value() == 5); + REQUIRE(maxCV[3] == 5); + } + + SECTION("Max with self clock vector yields self") + { + ClockVector cv1{ + {1, 2}, + {2, 10}, + {3, 5}, + }; + ClockVector maxCV = ClockVector::max(cv1, cv1); + + REQUIRE(maxCV.size() == 3); + REQUIRE(maxCV.get(1).has_value()); + REQUIRE(maxCV.get(1).value() == 2); + REQUIRE(maxCV[1] == 2); + + REQUIRE(maxCV.get(2).has_value()); + REQUIRE(maxCV.get(2).value() == 10); + REQUIRE(maxCV[2] == 10); + + REQUIRE(maxCV.get(3).has_value()); + REQUIRE(maxCV.get(3).value() == 5); + REQUIRE(maxCV[3] == 5); + } + + SECTION("Testing with partial overlaps") + { + SECTION("Example 1") + { + ClockVector cv1{ + {1, 2}, + {2, 10}, + {3, 5}, + }; + ClockVector cv2{ + {1, 5}, + {3, 1}, + {7, 10}, + }; + ClockVector maxCV = ClockVector::max(cv1, cv2); + + REQUIRE(maxCV.size() == 4); + REQUIRE(maxCV.get(1).has_value()); + REQUIRE(maxCV.get(1).value() == 5); + REQUIRE(maxCV[1] == 5); + + REQUIRE(maxCV.get(2).has_value()); + REQUIRE(maxCV.get(2).value() == 10); + REQUIRE(maxCV[2] == 10); + + REQUIRE(maxCV.get(3).has_value()); + REQUIRE(maxCV.get(3).value() == 5); + REQUIRE(maxCV[3] == 5); + + REQUIRE(maxCV.get(7).has_value()); + REQUIRE(maxCV.get(7).value() == 10); + REQUIRE(maxCV[7] == 10); + } + + SECTION("Example 2") + { + ClockVector cv1{ + {1, 2}, {2, 10}, {3, 5}, {4, 40}, {11, 3}, {12, 8}, + }; + ClockVector cv2{ + {1, 18}, {2, 4}, {4, 41}, {10, 3}, {12, 8}, + }; + ClockVector maxCV = ClockVector::max(cv1, cv2); + + REQUIRE(maxCV.size() == 7); + REQUIRE(maxCV.get(1).has_value()); + REQUIRE(maxCV.get(1).value() == 18); + REQUIRE(maxCV[1] == 18); + + REQUIRE(maxCV.get(2).has_value()); + REQUIRE(maxCV.get(2).value() == 10); + REQUIRE(maxCV[2] == 10); + + REQUIRE(maxCV.get(3).has_value()); + REQUIRE(maxCV.get(3).value() == 5); + REQUIRE(maxCV[3] == 5); + + REQUIRE(maxCV.get(4).has_value()); + REQUIRE(maxCV.get(4).value() == 41); + REQUIRE(maxCV[4] == 41); + + REQUIRE(maxCV.get(10).has_value()); + REQUIRE(maxCV.get(10).value() == 3); + REQUIRE(maxCV[10] == 3); + + REQUIRE(maxCV.get(11).has_value()); + REQUIRE(maxCV.get(11).value() == 3); + REQUIRE(maxCV[11] == 3); + + REQUIRE(maxCV.get(12).has_value()); + REQUIRE(maxCV.get(12).value() == 8); + REQUIRE(maxCV[12] == 8); + } + + SECTION("Example 3") + { + ClockVector cv1{{1, 2}, {4, 41}, {12, 0}, {100, 5}}; + ClockVector cv2{{2, 4}, {4, 10}, {10, 3}, {12, 8}, {19, 0}, {21, 6}, {22, 0}}; + ClockVector cv3{{21, 60}, {22, 6}, {100, 3}}; + ClockVector maxCV = ClockVector::max(cv1, cv2); + maxCV = ClockVector::max(maxCV, cv3); + + REQUIRE(maxCV.size() == 9); + REQUIRE(maxCV.get(1).has_value()); + REQUIRE(maxCV.get(1).value() == 2); + REQUIRE(maxCV[1] == 2); + + REQUIRE(maxCV.get(2).has_value()); + REQUIRE(maxCV.get(2).value() == 4); + REQUIRE(maxCV[2] == 4); + + REQUIRE(maxCV.get(4).has_value()); + REQUIRE(maxCV.get(4).value() == 41); + REQUIRE(maxCV[4] == 41); + + REQUIRE(maxCV.get(10).has_value()); + REQUIRE(maxCV.get(10).value() == 3); + REQUIRE(maxCV[10] == 3); + + REQUIRE(maxCV.get(12).has_value()); + REQUIRE(maxCV.get(12).value() == 8); + REQUIRE(maxCV[12] == 8); + + REQUIRE(maxCV.get(19).has_value()); + REQUIRE(maxCV.get(19).value() == 0); + REQUIRE(maxCV[19] == 0); + + REQUIRE(maxCV.get(21).has_value()); + REQUIRE(maxCV.get(21).value() == 60); + REQUIRE(maxCV[21] == 60); + + REQUIRE(maxCV.get(22).has_value()); + REQUIRE(maxCV.get(22).value() == 6); + REQUIRE(maxCV[22] == 6); + + REQUIRE(maxCV.get(100).has_value()); + REQUIRE(maxCV.get(100).value() == 5); + REQUIRE(maxCV[100] == 5); + } + } + + SECTION("Testing without overlaps") + { + SECTION("Example 1") + { + ClockVector cv1{{1, 2}}; + ClockVector cv2{ + {2, 4}, + {4, 41}, + {10, 3}, + {12, 8}, + }; + ClockVector maxCV = ClockVector::max(cv1, cv2); + + REQUIRE(maxCV.size() == 5); + REQUIRE(maxCV.get(1).has_value()); + REQUIRE(maxCV.get(1).value() == 2); + REQUIRE(maxCV[1] == 2); + + REQUIRE(maxCV.get(2).has_value()); + REQUIRE(maxCV.get(2).value() == 4); + REQUIRE(maxCV[2] == 4); + + REQUIRE(maxCV.get(4).has_value()); + REQUIRE(maxCV.get(4).value() == 41); + REQUIRE(maxCV[4] == 41); + + REQUIRE(maxCV.get(10).has_value()); + REQUIRE(maxCV.get(10).value() == 3); + REQUIRE(maxCV[10] == 3); + + REQUIRE(maxCV.get(12).has_value()); + REQUIRE(maxCV.get(12).value() == 8); + REQUIRE(maxCV[12] == 8); + } + + SECTION("Example 2") + { + ClockVector cv1{{1, 2}, {4, 41}}; + ClockVector cv2{ + {2, 4}, + {10, 3}, + {12, 8}, + }; + ClockVector maxCV = ClockVector::max(cv1, cv2); + + REQUIRE(maxCV.size() == 5); + REQUIRE(maxCV.get(1).has_value()); + REQUIRE(maxCV.get(1).value() == 2); + REQUIRE(maxCV[1] == 2); + + REQUIRE(maxCV.get(2).has_value()); + REQUIRE(maxCV.get(2).value() == 4); + REQUIRE(maxCV[2] == 4); + + REQUIRE(maxCV.get(4).has_value()); + REQUIRE(maxCV.get(4).value() == 41); + REQUIRE(maxCV[4] == 41); + + REQUIRE(maxCV.get(10).has_value()); + REQUIRE(maxCV.get(10).value() == 3); + REQUIRE(maxCV[10] == 3); + + REQUIRE(maxCV.get(12).has_value()); + REQUIRE(maxCV.get(12).value() == 8); + REQUIRE(maxCV[12] == 8); + } + + SECTION("Example 3") + { + ClockVector cv1{{1, 2}, {4, 41}}; + ClockVector cv2{{2, 4}, {10, 3}, {12, 8}, {19, 0}, {21, 6}}; + ClockVector cv3{{22, 6}, {100, 3}}; + ClockVector maxCV = ClockVector::max(cv1, cv2); + maxCV = ClockVector::max(maxCV, cv3); + + REQUIRE(maxCV.size() == 9); + REQUIRE(maxCV.get(1).has_value()); + REQUIRE(maxCV.get(1).value() == 2); + REQUIRE(maxCV[1] == 2); + + REQUIRE(maxCV.get(2).has_value()); + REQUIRE(maxCV.get(2).value() == 4); + REQUIRE(maxCV[2] == 4); + + REQUIRE(maxCV.get(4).has_value()); + REQUIRE(maxCV.get(4).value() == 41); + REQUIRE(maxCV[4] == 41); + + REQUIRE(maxCV.get(10).has_value()); + REQUIRE(maxCV.get(10).value() == 3); + REQUIRE(maxCV[10] == 3); + + REQUIRE(maxCV.get(12).has_value()); + REQUIRE(maxCV.get(12).value() == 8); + REQUIRE(maxCV[12] == 8); + + REQUIRE(maxCV.get(19).has_value()); + REQUIRE(maxCV.get(19).value() == 0); + REQUIRE(maxCV[19] == 0); + + REQUIRE(maxCV.get(21).has_value()); + REQUIRE(maxCV.get(21).value() == 6); + REQUIRE(maxCV[21] == 6); + + REQUIRE(maxCV.get(22).has_value()); + REQUIRE(maxCV.get(22).value() == 6); + REQUIRE(maxCV[22] == 6); + + REQUIRE(maxCV.get(100).has_value()); + REQUIRE(maxCV.get(100).value() == 3); + REQUIRE(maxCV[100] == 3); + } + } +} \ No newline at end of file diff --git a/src/mc/explo/odpor/Execution.cpp b/src/mc/explo/odpor/Execution.cpp new file mode 100644 index 0000000000..0694161cd2 --- /dev/null +++ b/src/mc/explo/odpor/Execution.cpp @@ -0,0 +1,501 @@ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/odpor/Execution.hpp" +#include "src/mc/api/State.hpp" +#include "xbt/asserts.h" +#include "xbt/string.hpp" +#include +#include +#include + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_odpor_execution, mc_dfs, "ODPOR exploration algorithm of the model-checker"); + +namespace simgrid::mc::odpor { + +std::vector get_textual_trace(const PartialExecution& w) +{ + std::vector trace; + for (const auto& t : w) { + auto a = xbt::string_printf("Actor %ld: %s", t->aid_, t->to_string(true).c_str()); + trace.emplace_back(std::move(a)); + } + return trace; +} + +Execution::Execution(const PartialExecution& w) +{ + push_partial_execution(w); +} + +void Execution::push_transition(std::shared_ptr t) +{ + if (t == nullptr) { + throw std::invalid_argument("Unexpectedly received `nullptr`"); + } + ClockVector max_clock_vector; + for (const Event& e : this->contents_) { + if (e.get_transition()->depends(t.get())) { + max_clock_vector = ClockVector::max(max_clock_vector, e.get_clock_vector()); + } + } + max_clock_vector[t->aid_] = this->size(); + contents_.push_back(Event({std::move(t), max_clock_vector})); +} + +void Execution::push_partial_execution(const PartialExecution& w) +{ + for (const auto& t : w) { + push_transition(t); + } +} + +std::vector Execution::get_textual_trace() const +{ + std::vector trace; + for (const auto& t : this->contents_) { + auto a = xbt::string_printf("Actor %ld: %s", t.get_transition()->aid_, t.get_transition()->to_string(true).c_str()); + trace.emplace_back(std::move(a)); + } + return trace; +} + +std::unordered_set Execution::get_racing_events_of(Execution::EventHandle target) const +{ + std::unordered_set racing_events; + // This keep tracks of events that happens-before the target + std::unordered_set disqualified_events; + + // For each event of the execution + for (auto e_i = target; e_i != std::numeric_limits::max(); e_i--) { + // We need `e_i -->_E target` as a necessary condition + if (not happens_before(e_i, target)) { + XBT_DEBUG("ODPOR_RACING_EVENTS with `%u` : `%u` discarded because `%u` --\\-->_E `%u`", target, e_i, e_i, target); + continue; + } + + // Further, `proc(e_i) != proc(target)` + if (get_actor_with_handle(e_i) == get_actor_with_handle(target)) { + disqualified_events.insert(e_i); + XBT_DEBUG("ODPOR_RACING_EVENTS with `%u` : `%u` disqualified because proc(`%u`)=proc(`%u`)", target, e_i, e_i, + target); + continue; + } + + // There could an event that "happens-between" the two events which would discount `e_i` as a race + for (auto e_j = e_i; e_j < target; e_j++) { + // If both: + // 1. e_i --->_E e_j; and + // 2. disqualified_events.count(e_j) > 0 + // then e_i --->_E target indirectly (either through + // e_j directly, or transitively through e_j) + if (disqualified_events.count(e_j) > 0 && happens_before(e_i, e_j)) { + XBT_DEBUG("ODPOR_RACING_EVENTS with `%u` : `%u` disqualified because `%u` happens-between `%u`-->`%u`-->`%u`)", + target, e_i, e_j, e_i, e_j, target); + disqualified_events.insert(e_i); + break; + } + } + + // If `e_i` wasn't disqualified in the last round, + // it's in a race with `target`. After marking it + // as such, we ensure no other event `e` can happen-before + // it (since this would transitively make it the event + // which "happens-between" `target` and `e`) + if (disqualified_events.count(e_i) == 0) { + XBT_DEBUG("ODPOR_RACING_EVENTS with `%u` : `%u` is a valid racing event", target, e_i); + racing_events.insert(e_i); + disqualified_events.insert(e_i); + } + } + + return racing_events; +} + +std::unordered_set Execution::get_reversible_races_of(EventHandle handle) const +{ + std::unordered_set reversible_races; + const auto* this_transition = get_transition_for_handle(handle); + for (EventHandle race : get_racing_events_of(handle)) { + const auto* other_transition = get_transition_for_handle(race); + + if (this_transition->reversible_race(other_transition)) { + reversible_races.insert(race); + } + } + return reversible_races; +} + +Execution Execution::get_prefix_before(Execution::EventHandle handle) const +{ + return Execution(std::vector{contents_.begin(), contents_.begin() + handle}); +} + +std::unordered_set +Execution::get_missing_source_set_actors_from(EventHandle e, const std::unordered_set& backtrack_set) const +{ + // If this execution is empty, there are no initials + // relative to the last transition added to the execution + // since such a transition does not exist + if (empty()) { + return std::unordered_set{}; + } + + // To actually compute `I_[E'](v) ∩ backtrack(E')`, we must + // first compute `E'` and "move" in the direction of `v`. + // We perform a scan over `E` (this execution) and make + // note of any events which occur after `e` but don't + // "happen-after" `e` by pushing them onto `E'`. Note that + // correctness is still preserved in computing `v` "on-the-fly" + // to determine if an event `e` by actor `q` is an initial for `E'` + // after `v`: only those events that "occur-before" `e` in `v` could + // "happen-before" `ve for any valid "happens-before" relation + // (see property 1 in the ODPOR paper, viz. "is included in <_E") + + // First, grab `E' := pre(e, E)` and determine what actor `p` is + const auto next_E_p = get_latest_event_handle().value(); + xbt_assert(e != next_E_p, + "This method assumes that the event `e` (%u) and `next_[E](p)` (%u)" + "are in a reversible race, yet we claim to have such a race between the" + "same event. This indicates the the SDPOR pseudocode implementation is broken " + "as it supplies these values.", + e, next_E_p); + Execution E_prime_v = get_prefix_before(e); + std::vector v; + std::unordered_set I_E_prime_v; + std::unordered_set disqualified_actors; + + // Note `e + 1` here: `notdep(e, E)` is defined as the + // set of events that *occur-after* but don't *happen-after* `e` + for (auto e_prime = e + 1; e_prime <= next_E_p; ++e_prime) { + // Any event `e*` which occurs after `e` but which does not + // happen after `e` is a member of `v`. In addition to marking + // the event in `v`, we also "simulate" running the action `v` + // from E' + if (not happens_before(e, e_prime) || e_prime == next_E_p) { + // First, push the transition onto the hypothetical execution + E_prime_v.push_transition(get_event_with_handle(e_prime).get_transition()); + const EventHandle e_prime_in_E_prime_v = E_prime_v.get_latest_event_handle().value(); + + // When checking whether any event in `dom_[E'](v)` happens before + // `next_[E'](q)` below for thread `q`, we must consider that the + // events relative to `E` (this execution) are different than those + // relative to `E'.v`. Thus e.g. event `7` in `E` may be event `4` + // in `E'.v`. Since we are asking about "happens-before" + // `-->_[E'.v]` about `E'.v`, we must build `v` relative to `E'`. + // + // Note that we add `q` to v regardless of whether `q` itself has been + // disqualified since we've determined that `e_prime` "occurs-after" but + // does not "happen-after" `e` + v.push_back(e_prime_in_E_prime_v); + + const aid_t q = E_prime_v.get_actor_with_handle(e_prime_in_E_prime_v); + if (disqualified_actors.count(q) > 0) { // Did we already note that `q` is not an initial? + continue; + } + const bool is_initial = std::none_of(v.begin(), v.end(), [&](const auto& e_star) { + return E_prime_v.happens_before(e_star, e_prime_in_E_prime_v); + }); + if (is_initial) { + // If the backtrack set already contains `q`, we're done: + // they've made note to search for (or have already searched for) + // this initial + if (backtrack_set.count(q) > 0) { + return std::unordered_set{}; + } else { + I_E_prime_v.insert(q); + } + } else { + // If `q` is disqualified as a candidate, clearly + // no event occurring after `e_prime` in `E` executed + // by actor `q` will qualify since any (valid) happens-before + // relation orders actions taken by each actor + disqualified_actors.insert(q); + } + } + } + xbt_assert(not I_E_prime_v.empty(), + "For any non-empty execution, we know that " + "at minimum one actor is an initial since " + "some execution is possible with respect to a " + "prefix before event `%u`, yet we didn't find anyone. " + "This implies the implementation of this function is broken.", + e); + return I_E_prime_v; +} + +std::optional Execution::get_odpor_extension_from(EventHandle e, EventHandle e_prime, + const State& state_at_e) const +{ + // `e` is assumed to be in a reversible race with `e_prime`. + // If `e > e_prime`, then `e` occurs-after `e_prime` which means + // `e` could not race with if + if (e > e_prime) { + throw std::invalid_argument("ODPOR extensions can only be computed for " + "events in a reversible race, which is claimed, " + "yet the racing event 'occurs-after' the target"); + } + + if (empty()) { + return std::nullopt; + } + + PartialExecution v; + std::vector v_handles; + std::unordered_set WI_E_prime_v; + std::unordered_set disqualified_actors; + Execution E_prime_v = get_prefix_before(e); + const std::unordered_set sleep_E_prime = state_at_e.get_sleeping_actors(); + + // Note `e + 1` here: `notdep(e, E)` is defined as the + // set of events that *occur-after* but don't *happen-after* `e` + // + // SUBTLE NOTE: ODPOR requires us to compute `notdep(e, E)` EVEN THOUGH + // the race is between `e` and `e'`; that is, events occurring in `E` + // that "occur-after" `e'` may end up in the partial execution `v`. + // + // Observe that `notdep(e, E).proc(e')` will contain all transitions + // that don't happen-after `e` in the order they appear FOLLOWED BY + // THE **TRANSITION** ASSOCIATED WITH **`e'`**!! + // + // SUBTLE NOTE: Observe that any event that "happens-after" `e'` + // must necessarily "happen-after" `e` as well, since `e` and + // `e'` are presumed to be in a reversible race. Hence, we know that + // all events `e_star` such that `e` "happens-before" `e_star` cannot affect + // the enabledness of `e'`; furthermore, `e'` cannot affect the enabledness + // of any event independent with `e` that "occurs-after" `e'` + for (auto e_star = e + 1; e_star <= get_latest_event_handle().value(); ++e_star) { + // Any event `e*` which occurs after `e` but which does not + // happen after `e` is a member of `v`. In addition to marking + // the event in `v`, we also "simulate" running the action `v` from E' + // to be able to compute `--->[E'.v]` + if (not happens_before(e, e_star)) { + xbt_assert(e_star != e_prime, + "Invariant Violation: We claimed events %u and %u were in a reversible race, yet we also " + "claim that they do not happen-before one another. This is impossible: " + "are you sure that the two events are in a reversible race?", + e, e_prime); + E_prime_v.push_transition(get_event_with_handle(e_star).get_transition()); + v.push_back(get_event_with_handle(e_star).get_transition()); + + XBT_DEBUG("Added Event `%u` (%ld:%s) to the construction of v", e_star, get_actor_with_handle(e_star), + get_event_with_handle(e_star).get_transition()->to_string().c_str()); + + const EventHandle e_star_in_E_prime_v = E_prime_v.get_latest_event_handle().value(); + + // When checking whether any event in `dom_[E'](v)` happens before + // `next_[E'](q)` below for thread `q`, we must consider that the + // events relative to `E` (this execution) are different than those + // relative to `E'.v`. Thus e.g. event `7` in `E` may be event `4` + // in `E'.v`. Since we are asking about "happens-before" + // `-->_[E'.v]` about `E'.v`, we must build `v` relative to `E'` + v_handles.push_back(e_star_in_E_prime_v); + + // Note that we add `q` to v regardless of whether `q` itself has been + // disqualified since `q` may itself disqualify other actors + // (i.e. even if `q` is disqualified from being an initial, it + // is still contained in the sequence `v`) + const aid_t q = E_prime_v.get_actor_with_handle(e_star_in_E_prime_v); + if (disqualified_actors.count(q) > 0) { // Did we already note that `q` is not an initial? + continue; + } + const bool is_initial = std::none_of(v_handles.begin(), v_handles.end(), [&](const auto& handle) { + return E_prime_v.happens_before(handle, e_star_in_E_prime_v); + }); + if (is_initial) { + // If the sleep set already contains `q`, we're done: + // we've found an initial contained in the sleep set and + // so the intersection is non-empty + if (sleep_E_prime.count(q) > 0) { + return std::nullopt; + } else { + WI_E_prime_v.insert(q); + } + } else { + // If `q` is disqualified as a candidate, clearly + // no event occurring after `e_prime` in `E` executed + // by actor `q` will qualify since any (valid) happens-before + // relation orders actions taken by each actor + disqualified_actors.insert(q); + } + } else { + XBT_DEBUG("Event `%u` (%ld:%s) dismissed from the construction of v", e_star, get_actor_with_handle(e_star), + get_event_with_handle(e_star).get_transition()->to_string().c_str()); + } + } + + // Now we add `e_prime := ` to `E'.v` and repeat the same work + // It's possible `proc(e_prime)` is an initial + // + // Note the form of `v` in the pseudocode: + // `v := notdep(e, E).e'^ + E_prime_v.push_transition(get_event_with_handle(e_prime).get_transition()); + v.push_back(get_event_with_handle(e_prime).get_transition()); + + const EventHandle e_prime_in_E_prime_v = E_prime_v.get_latest_event_handle().value(); + v_handles.push_back(e_prime_in_E_prime_v); + + const bool is_initial = std::none_of(v_handles.begin(), v_handles.end(), [&](const auto& handle) { + return E_prime_v.happens_before(handle, e_prime_in_E_prime_v); + }); + if (is_initial) { + if (const aid_t q = E_prime_v.get_actor_with_handle(e_prime_in_E_prime_v); sleep_E_prime.count(q) > 0) { + return std::nullopt; + } else { + WI_E_prime_v.insert(q); + } + } + + const Execution pre_E_e = get_prefix_before(e); + const auto sleeping_actors = state_at_e.get_sleeping_actors(); + + // Check if any enabled actor that is independent with + // this execution after `v` is contained in the sleep set + for (const auto& [aid, astate] : state_at_e.get_actors_list()) { + const bool is_in_WI_E = + astate.is_enabled() and pre_E_e.is_independent_with_execution_of(v, astate.get_transition()); + const bool is_in_sleep_set = sleeping_actors.count(aid) > 0; + + // `action(aid)` is in `WI_[E](v)` but also is contained in the sleep set. + // This implies that the intersection between the two is non-empty + if (is_in_WI_E && is_in_sleep_set) + return std::nullopt; + } + + return v; +} + +bool Execution::is_initial_after_execution_of(const PartialExecution& w, aid_t p) const +{ + auto E_w = *this; + std::vector w_handles; + for (const auto& w_i : w) { + // Take one step in the direction of `w` + E_w.push_transition(w_i); + + // If that step happened to be executed by `p`, + // great: we know that `p` is contained in `w`. + // We now need to verify that it doens't "happen-after" + // any events which occur before it + if (w_i->aid_ == p) { + const auto p_handle = E_w.get_latest_event_handle().value(); + return std::none_of(w_handles.begin(), w_handles.end(), + [&](const auto handle) { return E_w.happens_before(handle, p_handle); }); + } else { + w_handles.push_back(E_w.get_latest_event_handle().value()); + } + } + return false; +} + +bool Execution::is_independent_with_execution_of(const PartialExecution& w, std::shared_ptr next_E_p) const +{ + // INVARIANT: Here, we assume that for any process `p_i` of `w`, + // the events of this execution followed by the execution of all + // actors occurring before `p_i` in `v` (`p_j`, `0 <= j < i`) + // are sufficient to enable `p_i`. This is fortunately the case + // with what ODPOR requires of us, viz. to ask the question about + // `v := notdep(e, E)` for some execution `E` and event `e` of + // that execution. + auto E_p_w = *this; + E_p_w.push_transition(std::move(next_E_p)); + const auto p_handle = E_p_w.get_latest_event_handle().value(); + + // As we add events to `w`, verify that none + // of them "happen-after" the event associated with + // the step `next_E_p` (viz. p_handle) + for (const auto& w_i : w) { + E_p_w.push_transition(w_i); + const auto w_i_handle = E_p_w.get_latest_event_handle().value(); + if (E_p_w.happens_before(p_handle, w_i_handle)) { + return false; + } + } + return true; +} + +std::optional Execution::get_shortest_odpor_sq_subset_insertion(const PartialExecution& v, + const PartialExecution& w) const +{ + // See section 4 of Abdulla. et al.'s 2017 ODPOR paper for details (specifically + // where the [iterative] computation of `v ~_[E] w` is described) + auto E_v = *this; + auto w_now = w; + + for (const auto& next_E_p : v) { + // Is `p in `I_[E](w)`? + if (const aid_t p = next_E_p->aid_; E_v.is_initial_after_execution_of(w_now, p)) { + // Remove `p` from w and continue + + // INVARIANT: If `p` occurs in `w`, it had better refer to the same + // transition referenced by `v`. Unfortunately, we have two + // sources of truth here which can be manipulated at the same + // time as arguments to the function. If ODPOR works correctly, + // they should always refer to the same value; but as a sanity check, + // we have an assert that tests that at least the types are the same. + const auto action_by_p_in_w = + std::find_if(w_now.begin(), w_now.end(), [=](const auto& action) { return action->aid_ == p; }); + xbt_assert(action_by_p_in_w != w_now.end(), "Invariant violated: actor `p` " + "is claimed to be an initial after `w` but is " + "not actually contained in `w`. This indicates that there " + "is a bug computing initials"); + const auto& w_action = *action_by_p_in_w; + xbt_assert(w_action->type_ == next_E_p->type_, + "Invariant violated: `v` claims that actor `%ld` executes '%s' while " + "`w` claims that it executes '%s'. These two partial executions both " + "refer to `next_[E](p)`, which should be the same", + p, next_E_p->to_string(false).c_str(), w_action->to_string(false).c_str()); + w_now.erase(action_by_p_in_w); + } + // Is `E ⊢ p ◇ w`? + else if (E_v.is_independent_with_execution_of(w_now, next_E_p)) { + // INVARIANT: Note that it is impossible for `p` to be + // excluded from the set `I_[E](w)` BUT ALSO be contained in + // `w` itself if `E ⊢ p ◇ w` (intuitively, the fact that `E ⊢ p ◇ w` + // means that are able to move `p` anywhere in `w` IF it occurred, so + // if it really does occur we know it must then be an initial). + // We assert this is the case here + const auto action_by_p_in_w = + std::find_if(w_now.begin(), w_now.end(), [=](const auto& action) { return action->aid_ == p; }); + xbt_assert(action_by_p_in_w == w_now.end(), + "Invariant violated: We claimed that actor `%ld` is not an initial " + "after `w`, yet it's independent with all actions of `w` AND occurs in `w`." + "This indicates that there is a bug computing initials", + p); + } else { + // Neither of the two above conditions hold, so the relation fails + return std::nullopt; + } + + // Move one step forward in the direction of `v` and repeat + E_v.push_transition(next_E_p); + } + return std::optional{std::move(w_now)}; +} + +bool Execution::happens_before(Execution::EventHandle e1_handle, Execution::EventHandle e2_handle) const +{ + // 1. "happens-before" (-->_E) is a subset of "occurs before" (<_E) + // and is an irreflexive relation + if (e1_handle >= e2_handle) { + return false; + } + + // Each execution maintains a stack of clock vectors which are updated + // according to the procedure outlined in section 4 of the original DPOR paper + const Event& e2 = get_event_with_handle(e2_handle); + const aid_t proc_e1 = get_actor_with_handle(e1_handle); + + if (const auto e1_in_e2_clock = e2.get_clock_vector().get(proc_e1); e1_in_e2_clock.has_value()) { + return e1_handle <= e1_in_e2_clock.value(); + } + // If `e1` does not appear in e2's clock vector, this implies + // not only that the transitions associated with `e1` and `e2 + // are independent, but further that there are no transitive + // dependencies between e1 and e2 + return false; +} + +} // namespace simgrid::mc::odpor diff --git a/src/mc/explo/odpor/Execution.hpp b/src/mc/explo/odpor/Execution.hpp new file mode 100644 index 0000000000..6d8ca425ac --- /dev/null +++ b/src/mc/explo/odpor/Execution.hpp @@ -0,0 +1,365 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_ODPOR_EXECUTION_HPP +#define SIMGRID_MC_ODPOR_EXECUTION_HPP + +#include "src/mc/api/ClockVector.hpp" +#include "src/mc/explo/odpor/odpor_forward.hpp" +#include "src/mc/mc_forward.hpp" +#include "src/mc/mc_record.hpp" +#include "src/mc/transition/Transition.hpp" + +#include +#include +#include +#include + +namespace simgrid::mc::odpor { + +std::vector get_textual_trace(const PartialExecution& w); + +/** + * @brief The occurrence of a transition in an execution + * + * An execution is set of *events*, where each element represents + * the occurrence or execution of the `i`th step of a particular + * actor `j` + */ +class Event { + std::pair, ClockVector> contents_; + +public: + Event() = default; + Event(Event&&) = default; + Event(const Event&) = default; + Event& operator=(const Event&) = default; + explicit Event(std::pair, ClockVector> pair) : contents_(std::move(pair)) {} + + std::shared_ptr get_transition() const { return std::get<0>(contents_); } + const ClockVector& get_clock_vector() const { return std::get<1>(contents_); } +}; + +/** + * @brief An ordered sequence of transitions which describe + * the evolution of a process undergoing model checking + * + * An execution conceptually is just a string of actors + * ids (e.g. "1.2.3.1.2.2.1.1"), where the `i`th occurrence + * of actor id `j` corresponds to the `i`th action executed + * by the actor with id `j` (viz. the `i`th step of actor `j`). + * Executions can stand alone on their own or can extend + * the execution of other sequences + * + * Executions are conceived based on the following papers: + * 1. "Source Sets: A Foundation for Optimal Dynamic Partial Order Reduction" + * by Abdulla et al. + * + * In addition to representing an actual steps taken, + * an execution keeps track of the "happens-before" + * relation among the transitions in the execution + * by following the procedure outlined in section 4 of the + * original DPOR paper with clock vectors. + * As new transitions are added to the execution, clock vectors are + * computed as appropriate and associated with the corresponding position + * in the execution. This allows us to determine “happens-before” in + * constant-time between points in the execution (called events + * [which is unfortunately the same name used in UDPOR for a slightly + * different concept]), albeit for an up-front cost of traversing the + * execution stack. The happens-before relation is important in many + * places in SDPOR and ODPOR. + * + * @note: For more nuanced happens-before relations, clock + * vectors may not always suffice. Clock vectors work + * well with transition-based dependencies like that used in + * SimGrid; but to have a more refined independence relation, + * an event-based dependency approach is needed. See the section 2 + * in the ODPOR paper [1] concerning event-based dependencies and + * how the happens-before relation can be refined in a + * computation model much like that of SimGrid. In fact, the same issue + * arrises with UDPOR with context-sensitive dependencies: + * the two concepts are analogous if not identical + */ +class Execution { +private: + std::vector contents_; + Execution(std::vector&& contents) : contents_(std::move(contents)) {} + +public: + using EventHandle = uint32_t; + + Execution() = default; + Execution(const Execution&) = default; + Execution& operator=(Execution const&) = default; + Execution(Execution&&) = default; + Execution(const PartialExecution&); + + std::vector get_textual_trace() const; + + size_t size() const { return this->contents_.size(); } + bool empty() const { return this->contents_.empty(); } + auto begin() const { return this->contents_.begin(); } + auto end() const { return this->contents_.end(); } + + /** + * @brief Computes the "core" portion the SDPOR algorithm, + * viz. the intersection of the backtracking set and the + * set of initials with respect to the *last* event added + * to the execution + * + * The "core" portion of the SDPOR algorithm is found on + * lines 6-9 of the pseudocode: + * + * 6 | let E' := pre(E, e) + * 7 | let v := notdep(e, E).p + * 8 | if I_[E'](v) ∩ backtrack(E') = empty then + * 9 | --> add some q in I_[E'](v) to backtrack(E') + * + * This method computes all of the lines simultaneously, + * returning the set `I_[E'](v)` if condition on line 8 holds. + * The event `e` and the set `backtrack(E')` are the provided + * arguments to the method. + * + * @param e the event with respect to which to determine + * whether a backtrack point needs to be added for the + * prefix corresponding to the execution prior to `e` + * + * @param backtrack_set The set of actors which should + * not be considered for selection as an SDPOR initial. + * While this set need not necessarily correspond to the + * backtrack set `backtrack(E')`, doing so provides what + * is expected for SDPOR + * + * See the SDPOR algorithm pseudocode in [1] for more + * details for the context of the function. + * + * @precondition: This method assumes that events `e` and + * `e' := get_latest_event_handle()` are in a *reversible* race, + * as is explicitly the case in SDPOR + * + * @returns a set of actors not already contained in `backtrack_set` + * which serve as an initials to reverse the race between `e` + * and `e' := get_latest_event_handle()`; that is, an initial that is + * not already contained in the set `backtrack_set`. + */ + std::unordered_set get_missing_source_set_actors_from(EventHandle e, + const std::unordered_set& backtrack_set) const; + + /** + * @brief Computes the analogous lines from the SDPOR algorithm + * in the ODPOR algorithm, viz. the intersection of the sleep set + * and the set of weak initials with respect to the given pair + * of racing events + * + * This method computes lines 4-6 of the ODPOR pseudocode, viz.: + * + * 4 | let E' := pre(E, e) + * 5 | let v := notdep(e, E).e'^ + * 6 | if sleep(E') ∩ WI_[E'](v) = empty then + * 7 | --> wut(E') := insert_[E'](v, wut(E')) + * + * The sequence `v` is computed and returned as needed, based on whether + * the check on line 6 passes. + * + * @precondition: This method assumes that events `e` and + * `e_prime` are in a *reversible* race, as is the case + * in ODPOR. + * + * @returns a partial execution `v := notdep(e, E)` (where `E` refers + * to this execution) that should be inserted into a wakeup tree with + * respect to this execution if `sleep(E') ∩ WI_[E'](v) = empty`, and + * `std::nullopt` otherwise + */ + std::optional get_odpor_extension_from(EventHandle e, EventHandle e_prime, + const State& state_at_e) const; + + /** + * @brief For a given sequence of actors `v` and a sequence of transitions `w`, + * computes the sequence, if any, that should be inserted as a child in wakeup tree for + * this execution + * + * Recall that the procedure for implementing the insertion + * is outlined in section 6.2 of Abdulla et al. 2017 as follows: + * + * | Let `v` be the smallest (w.r.t to "<") sequence in [the tree] B + * | such that `v ~_[E] w`. If `v` is a leaf node, the tree can be left + * | unmodified. + * | + * | Otherwise let `w'` be the shortest sequence such that `w [=_[E] v.w'` + * | and add `v.w'` as a new leaf, ordered after all already existing nodes + * | of the form `v.w''` + * + * The procedure for determining whether `v ~_[E] w` is given as Lemma 4.6 of + * Abdulla et al. 2017: + * + * | The relation `v ~_[E] w` holds if either + * | (1) v = <>, or + * | (2) v := p.v' and either + * | (a) p in I_[E](w) and `v' ~_[E.p] (w \ p)` + * | (b) E ⊢ p ◊ w and `v' ~_[E.p] w` + * + * This method computes the result `v.w'` as needed (viz. only if `v ~_[E] w` + * with respect to this execution `E`). The implementation takes advantage + * of the fact that determining whether `v ~_[E] w` yields "for free" the + * the shortest such `w'` we are looking for; if we ultimately determine + * that `v ~_[E] w`, the work we did to do so leaves us precisely with `w'`, + * so we can simply prepend `v` to it and call it a day + * + * @precondition: This method assumes that `E.v` is a valid execution, viz. + * that the events of `E` are sufficient to enabled `v_0` and that + * `v_0, ..., v_{i - 1}` are sufficient to enable `v_i`. This is the + * case when e.g. `v := notdep(e, E).p` for example in ODPOR + * + * @returns a partial execution `v.w'` that should be inserted + * as a child of a wakeup tree node representing the sequence `v` + * if `v ~_[E] w`, or `std::nullopt` if that relation does not hold + * between the two sequences `v` and `w` + */ + std::optional get_shortest_odpor_sq_subset_insertion(const PartialExecution& v, + const PartialExecution& w) const; + + /** + * @brief For a given sequence `w`, determines whether p in I_[E](w) + * + * @note: You may notice that some of the other methods compute this + * value as well. What we notice, though, in those cases is that + * we are repeatedly asking about initials with respect to an execution. + * It is better, then, to bunch the work together in those cases to + * get asymptotically better results (e.g. instead of calling with all + * `N` actors, we can process them "in-parallel" as is done with the + * computation of SDPOR initials) + */ + bool is_initial_after_execution_of(const PartialExecution& w, aid_t p) const; + + /** + * @brief Determines whether `E ⊢ p ◊ w` given the next action taken by `p` + */ + bool is_independent_with_execution_of(const PartialExecution& w, std::shared_ptr next_E_p) const; + + /** + * @brief Determines the event associated with the given handle `handle` + */ + const Event& get_event_with_handle(EventHandle handle) const { return contents_[handle]; } + + /** + * @brief Determines the actor associated with the given event handle `handle` + */ + aid_t get_actor_with_handle(EventHandle handle) const { return get_event_with_handle(handle).get_transition()->aid_; } + + /** + * @brief Determines the transition associated with the given handle `handle` + */ + const Transition* get_transition_for_handle(EventHandle handle) const + { + return get_event_with_handle(handle).get_transition().get(); + } + + /** + * @brief Returns a handle to the newest event of the execution, if such an event exists + * + * @returns the handle to the last event of the execution. + * If the sequence is empty, no such handle exists and the + * method returns `std::nullopt` + */ + std::optional get_latest_event_handle() const + { + return contents_.empty() ? std::nullopt : std::optional{static_cast(size() - 1)}; + } + + /** + * @brief Returns a set of events which are in + * "immediate conflict" (according to the definition given + * in the ODPOR paper) with the given event + * + * Two events `e` and `e'` in an execution `E` are said to + * *race* iff + * + * 1. `proc(e) != proc(e')`; that is, the events correspond to + * the execution of different actors + * 2. `e -->_E e'` and there is no `e''` in `E` such that + * `e -->_E e''` and `e'' -->_E e'`; that is, the two events + * "happen-before" one another in `E` and no other event in + * `E` "happens-between" `e` and `e'` + * + * @param handle the event with respect to which races are + * computed + * @returns a set of event handles, each element of which is an + * event in this execution which is in a *race* with event `handle` + */ + std::unordered_set get_racing_events_of(EventHandle handle) const; + + /** + * @brief Returns a set of events which are in a reversible + * race with the given event handle `handle` + * + * Two events `e` and `e'` in an execution `E` are said to + * be in a *reversible race* iff + * + * 1. `e` and `e'` race + * 2. In any equivalent execution sequence `E'` to `E` + * where `e` occurs immediately before `e'`, the actor + * running `e'` was enabled in the state prior to `e` + * + * @param handle the event with respect to which + * reversible races are computed + * @returns a set of event handles, each element of which is an event + * in this execution which is in a *reversible race* with event `handle` + */ + std::unordered_set get_reversible_races_of(EventHandle handle) const; + + /** + * @brief Computes `pre(e, E)` as described in ODPOR [1] + * + * The execution `pre(e, E)` for an event `e` in an + * execution `E` is the contiguous prefix of events + * `E' <= E` up to but excluding the event `e` itself. + * Roughly speaking, the prefix intuitively represents + * the "history" of causes which permitted event `e` + * to exist + */ + Execution get_prefix_before(EventHandle) const; + + /** + * @brief Whether the event represented by `e1` + * "happens-before" the event represented by + * `e2` in the context of this execution + * + * In the terminology of the ODPOR paper, + * this function computes + * + * `e1 --->_E e2` + * + * where `E` is this execution + * + * @note: The happens-before relation computed by this + * execution is "coarse" in the sense that context-sensitive + * independence is not exploited. To include such context-sensitive + * dependencies requires a new method of keeping track of + * the happens-before procedure, which is nontrivial... + */ + bool happens_before(EventHandle e1, EventHandle e2) const; + + /** + * @brief Extends the execution by one more step + * + * Intutively, pushing a transition `t` onto execution `E` + * is equivalent to making the execution become (using the + * notation of [1]) `E.proc(t)` where `proc(t)` is the + * actor which executed transition `t`. + */ + void push_transition(std::shared_ptr); + + /** + * @brief Extends the execution by a sequence of steps + * + * This method has the equivalent effect of pushing the + * transitions of the partial execution one-by-one onto + * the execution + */ + void push_partial_execution(const PartialExecution&); +}; + +} // namespace simgrid::mc::odpor +#endif diff --git a/src/mc/explo/odpor/Execution_test.cpp b/src/mc/explo/odpor/Execution_test.cpp new file mode 100644 index 0000000000..302ccea031 --- /dev/null +++ b/src/mc/explo/odpor/Execution_test.cpp @@ -0,0 +1,732 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/odpor/Execution.hpp" +#include "src/mc/explo/odpor/odpor_tests_private.hpp" +#include "src/mc/transition/TransitionComm.hpp" + +using namespace simgrid::mc; +using namespace simgrid::mc::odpor; +using namespace simgrid::mc::udpor; + +TEST_CASE("simgrid::mc::odpor::Execution: Constructing Executions") +{ + Execution execution; + REQUIRE(execution.empty()); + REQUIRE(execution.size() == 0); + REQUIRE_FALSE(execution.get_latest_event_handle().has_value()); +} + +TEST_CASE("simgrid::mc::odpor::Execution: Testing Happens-Before") +{ + SECTION("Example 1") + { + // We check each permutation for happens before + // among the given actions added to the execution + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 4); + + Execution execution; + execution.push_transition(a1); + execution.push_transition(a2); + execution.push_transition(a3); + execution.push_transition(a4); + + SECTION("Happens-before is irreflexive") + { + REQUIRE_FALSE(execution.happens_before(0, 0)); + REQUIRE_FALSE(execution.happens_before(1, 1)); + REQUIRE_FALSE(execution.happens_before(2, 2)); + REQUIRE_FALSE(execution.happens_before(3, 3)); + } + + SECTION("Happens-before values for each pair of events") + { + REQUIRE_FALSE(execution.happens_before(0, 1)); + REQUIRE_FALSE(execution.happens_before(0, 2)); + REQUIRE(execution.happens_before(0, 3)); + REQUIRE_FALSE(execution.happens_before(1, 2)); + REQUIRE_FALSE(execution.happens_before(1, 3)); + REQUIRE_FALSE(execution.happens_before(2, 3)); + } + + SECTION("Happens-before is a subset of 'occurs-before' ") + { + REQUIRE_FALSE(execution.happens_before(1, 0)); + REQUIRE_FALSE(execution.happens_before(2, 0)); + REQUIRE_FALSE(execution.happens_before(3, 0)); + REQUIRE_FALSE(execution.happens_before(2, 1)); + REQUIRE_FALSE(execution.happens_before(3, 1)); + REQUIRE_FALSE(execution.happens_before(3, 2)); + } + } + + SECTION("Example 2") + { + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 3); + + // Notice that `a5` and `a6` are executed by the same actor; thus, although + // the actor is executing independent actions, each still "happen-before" + // the another + + Execution execution; + execution.push_transition(a1); + execution.push_transition(a2); + execution.push_transition(a3); + execution.push_transition(a4); + + SECTION("Happens-before is irreflexive") + { + REQUIRE_FALSE(execution.happens_before(0, 0)); + REQUIRE_FALSE(execution.happens_before(1, 1)); + REQUIRE_FALSE(execution.happens_before(2, 2)); + REQUIRE_FALSE(execution.happens_before(3, 3)); + } + + SECTION("Happens-before values for each pair of events") + { + REQUIRE_FALSE(execution.happens_before(0, 1)); + REQUIRE_FALSE(execution.happens_before(0, 2)); + REQUIRE_FALSE(execution.happens_before(0, 3)); + REQUIRE(execution.happens_before(1, 2)); + REQUIRE(execution.happens_before(1, 3)); + REQUIRE(execution.happens_before(2, 3)); + } + + SECTION("Happens-before is a subset of 'occurs-before'") + { + REQUIRE_FALSE(execution.happens_before(1, 0)); + REQUIRE_FALSE(execution.happens_before(2, 0)); + REQUIRE_FALSE(execution.happens_before(3, 0)); + REQUIRE_FALSE(execution.happens_before(2, 1)); + REQUIRE_FALSE(execution.happens_before(3, 1)); + REQUIRE_FALSE(execution.happens_before(3, 2)); + } + } + + SECTION("Happens-before is transitively-closed") + { + SECTION("Example 1") + { + // Given a reversible race between events `e1` and `e3` in a simulation, + // we assert that `e5` would be eliminated from being contained in + // the sequence `notdep(e1, E)` + const auto e0 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto e3 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e4 = std::make_shared(Transition::Type::UNKNOWN, 3); + + Execution execution; + execution.push_partial_execution(PartialExecution{e0, e1, e2, e3, e4}); + REQUIRE(execution.happens_before(0, 2)); + REQUIRE(execution.happens_before(2, 4)); + REQUIRE(execution.happens_before(0, 4)); + } + + SECTION("Stress testing transitivity of the happens-before relation") + { + // This test verifies that for each triple of events + // in the execution, for a modestly intersting one, + // that transitivity holds + const auto e0 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e2 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e3 = std::make_shared(Transition::Type::UNKNOWN, 2, -10); + const auto e4 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto e5 = std::make_shared(Transition::Type::UNKNOWN, 0); + const auto e6 = std::make_shared(Transition::Type::UNKNOWN, 2, -5); + const auto e7 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e8 = std::make_shared(Transition::Type::UNKNOWN, 0); + const auto e9 = std::make_shared(Transition::Type::UNKNOWN, 2, -10); + const auto e10 = std::make_shared(Transition::Type::UNKNOWN, 3); + + Execution execution; + execution.push_partial_execution(PartialExecution{e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10}); + + const auto max_handle = execution.get_latest_event_handle(); + for (Execution::EventHandle e_i = 0; e_i < max_handle; ++e_i) { + for (Execution::EventHandle e_j = 0; e_j < max_handle; ++e_j) { + for (Execution::EventHandle e_k = 0; e_k < max_handle; ++e_k) { + const bool e_i_before_e_j = execution.happens_before(e_i, e_j); + const bool e_j_before_e_k = execution.happens_before(e_j, e_k); + const bool e_i_before_e_k = execution.happens_before(e_i, e_k); + // Logical equivalent of `e_i_before_e_j ^ e_j_before_e_k --> e_i_before_e_k` + REQUIRE((not(e_i_before_e_j && e_j_before_e_k) || e_i_before_e_k)); + } + } + } + } + } +} + +TEST_CASE("simgrid::mc::odpor::Execution: Testing Racing Events and Initials") +{ + SECTION("Example 1") + { + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a5 = std::make_shared(Transition::Type::UNKNOWN, 2); + + Execution execution; + execution.push_transition(a1); + execution.push_transition(a2); + execution.push_transition(a3); + execution.push_transition(a4); + execution.push_transition(a5); + + // Nothing comes before event 0 + REQUIRE(execution.get_racing_events_of(0) == std::unordered_set{}); + + // Events 0 and 1 are independent + REQUIRE(execution.get_racing_events_of(1) == std::unordered_set{}); + + // 2 and 1 are executed by different actors and happen right after each other + REQUIRE(execution.get_racing_events_of(2) == std::unordered_set{1}); + + // Although a3 and a4 are dependent, they are executed by the same actor + REQUIRE(execution.get_racing_events_of(3) == std::unordered_set{}); + + // Event 4 is in a race with neither event 0 nor event 2 since those events + // "happen-before" event 3 with which event 4 races + // + // Furthermore, event 1 is run by the same actor and thus also is not in a race. + // Hence, only event 3 races with event 4 + REQUIRE(execution.get_racing_events_of(4) == std::unordered_set{3}); + } + + SECTION("Example 2: Events with multiple races") + { + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 3); + + Execution execution; + execution.push_transition(a1); + execution.push_transition(a2); + execution.push_transition(a3); + execution.push_transition(a4); + + // Nothing comes before event 0 + REQUIRE(execution.get_racing_events_of(0) == std::unordered_set{}); + + // Events 0 and 1 are independent + REQUIRE(execution.get_racing_events_of(1) == std::unordered_set{}); + + // Event 2 is independent with event 1 and run by the same actor as event 0 + REQUIRE(execution.get_racing_events_of(2) == std::unordered_set{}); + + // All events are dependent with event 3, but event 0 "happens-before" event 2 + REQUIRE(execution.get_racing_events_of(3) == std::unordered_set{1, 2}); + + SECTION("Check initials with respect to event 1") + { + // First, note that v := notdep(1, execution).p == {e2}.{e3} == {e2, e3} + // Since e2 -->_E e3, actor 3 is not an initial for E' := pre(1, execution) + // with respect to `v`. e2, however, has nothing happening before it in dom_E(v), + // so it is an initial of E' wrt. `v` + const auto initial_wrt_event1 = execution.get_missing_source_set_actors_from(1, std::unordered_set{}); + REQUIRE(initial_wrt_event1 == std::unordered_set{1}); + } + + SECTION("Check initials with respect to event 2") + { + // First, note that v := notdep(1, execution).p == {}.{e3} == {e3} + // e3 has nothing happening before it in dom_E(v), so it is an initial + // of E' wrt. `v` + const auto initial_wrt_event2 = execution.get_missing_source_set_actors_from(2, std::unordered_set{}); + REQUIRE(initial_wrt_event2 == std::unordered_set{3}); + } + } + + SECTION("Example 3: Testing 'Lock' Example") + { + // In this example, `e0` and `e1` are lock actions that + // are in a race. We assert that + const auto e0 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e1 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e2 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e3 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e4 = std::make_shared(Transition::Type::UNKNOWN, 3); + + Execution execution; + execution.push_transition(e0); + execution.push_transition(e1); + execution.push_transition(e2); + execution.push_transition(e3); + execution.push_transition(e4); + REQUIRE(execution.get_racing_events_of(4) == std::unordered_set{0}); + } + + SECTION("Example 4: Indirect Races") + { + const auto e0 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e1 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e2 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e3 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e4 = std::make_shared(Transition::Type::UNKNOWN, 6); + const auto e5 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e6 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto e7 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto e8 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto e9 = std::make_shared(Transition::Type::UNKNOWN, 2); + + Execution execution(PartialExecution{e0, e1, e2, e3, e4, e5, e6, e7, e8, e9}); + + // Nothing comes before event 0 + REQUIRE(execution.get_racing_events_of(0) == std::unordered_set{}); + + // Events 0 and 1 are independent + REQUIRE(execution.get_racing_events_of(1) == std::unordered_set{}); + + // Events 1 and 2 are independent + REQUIRE(execution.get_racing_events_of(2) == std::unordered_set{}); + + // Events 1 and 3 are independent; the rest are executed by the same actor + REQUIRE(execution.get_racing_events_of(3) == std::unordered_set{}); + + // 1. Events 3 and 4 race + // 2. Events 2 and 4 do NOT race since 2 --> 3 --> 4 + // 3. Events 1 and 4 do NOT race since 1 is independent of 4 + // 4. Events 0 and 4 do NOT race since 0 --> 2 --> 4 + REQUIRE(execution.get_racing_events_of(4) == std::unordered_set{3}); + + // Events 4 and 5 race; and because everyone before 4 (including 3) either + // a) happens-before, b) races, or c) does not race with 4, 4 is the race + REQUIRE(execution.get_racing_events_of(5) == std::unordered_set{4}); + + // The same logic that applied to event 5 applies to event 6 + REQUIRE(execution.get_racing_events_of(6) == std::unordered_set{5}); + + // The same logic applies, except that this time since events 6 and 7 are run + // by the same actor, they don'tt actually race with one another + REQUIRE(execution.get_racing_events_of(7) == std::unordered_set{}); + + // Event 8 is independent with everything + REQUIRE(execution.get_racing_events_of(8) == std::unordered_set{}); + + // Event 9 is independent with events 7 and 8; event 6, however, is in race with 9. + // The same logic above eliminates events before 6 + REQUIRE(execution.get_racing_events_of(9) == std::unordered_set{6}); + } + + SECTION("Example 5: Stress testing race detection") + { + const auto e0 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e2 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e3 = std::make_shared(Transition::Type::UNKNOWN, 2, -10); + const auto e4 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto e5 = std::make_shared(Transition::Type::UNKNOWN, 0); + const auto e6 = std::make_shared(Transition::Type::UNKNOWN, 2, -5); + const auto e7 = std::make_shared(Transition::Type::UNKNOWN, 1, -5); + const auto e8 = std::make_shared(Transition::Type::UNKNOWN, 0, 4); + const auto e9 = std::make_shared(Transition::Type::UNKNOWN, 2, -10); + const auto e10 = std::make_shared(Transition::Type::UNKNOWN, 3); + + Execution execution(PartialExecution{e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10}); + + // Nothing comes before event 0 + CHECK(execution.get_racing_events_of(0) == std::unordered_set{}); + + // Events 0 and 1 are independent + CHECK(execution.get_racing_events_of(1) == std::unordered_set{}); + + // Events 1 and 2 are executed by the same actor, even though they are dependent + CHECK(execution.get_racing_events_of(2) == std::unordered_set{}); + + // Events 2 and 3 are independent while events 1 and 2 are dependent + CHECK(execution.get_racing_events_of(3) == std::unordered_set{1}); + + // Event 4 is independent with everything so it can never be in a race + CHECK(execution.get_racing_events_of(4) == std::unordered_set{}); + + // Event 5 is independent with event 4. Since events 2 and 3 are dependent with event 5, + // but are independent of each other, both events are in a race with event 5 + CHECK(execution.get_racing_events_of(5) == std::unordered_set{2, 3}); + + // Events 5 and 6 are dependent. Everyone before 5 who's dependent with 5 + // cannot be in a race with 6; everyone before 5 who's independent with 5 + // could not race with 6 + CHECK(execution.get_racing_events_of(6) == std::unordered_set{5}); + + // Same goes for event 7 as for 6 + CHECK(execution.get_racing_events_of(7) == std::unordered_set{6}); + + // Events 5 and 8 are both run by the same actor; events in-between are independent + CHECK(execution.get_racing_events_of(8) == std::unordered_set{}); + + // Event 6 blocks event 9 from racing with event 6 + CHECK(execution.get_racing_events_of(9) == std::unordered_set{}); + + // Event 10 is independent with everything so it can never be in a race + CHECK(execution.get_racing_events_of(10) == std::unordered_set{}); + } + + SECTION("Example with many races for one event") + { + const auto e0 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e1 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto e3 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto e4 = std::make_shared(Transition::Type::UNKNOWN, 5); + const auto e5 = std::make_shared(Transition::Type::UNKNOWN, 6); + const auto e6 = std::make_shared(Transition::Type::UNKNOWN, 7); + + Execution execution(PartialExecution{e0, e1, e2, e3, e4, e5, e6}); + REQUIRE(execution.get_racing_events_of(6) == std::unordered_set{0, 1, 2, 3, 4, 5}); + } +} + +TEST_CASE("simgrid::mc::odpor::Execution: Independence Tests") +{ + SECTION("Complete independence") + { + // Every transition is independent with every other and run by different actors. Hopefully + // we say that the events are independent with each other... + const auto a0 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 5); + const auto a5 = std::make_shared(Transition::Type::UNKNOWN, 6); + const auto a6 = std::make_shared(Transition::Type::UNKNOWN, 7); + const auto a7 = std::make_shared(Transition::Type::UNKNOWN, 7); + Execution execution(PartialExecution{a0, a1, a2, a3}); + + REQUIRE(execution.is_independent_with_execution_of(PartialExecution{a4, a5}, a6)); + REQUIRE(execution.is_independent_with_execution_of(PartialExecution{a6, a5}, a1)); + REQUIRE(execution.is_independent_with_execution_of(PartialExecution{a6, a1}, a0)); + REQUIRE(Execution().is_independent_with_execution_of(PartialExecution{a7, a7, a1}, a3)); + REQUIRE(Execution().is_independent_with_execution_of(PartialExecution{a4, a0, a1}, a3)); + REQUIRE(Execution().is_independent_with_execution_of(PartialExecution{a0, a7, a1}, a2)); + + // In this case, we notice that `a6` and `a7` are executed by the same actor. + // Hence, a6 cannot be independent with extending the execution with a4.a5.a7. + // Notice that we are treating *a6* as the next step of actor 7 (that is what we + // supplied as an argument) + REQUIRE_FALSE(execution.is_independent_with_execution_of(PartialExecution{a4, a5, a7}, a6)); + } + + SECTION("Independence is trivial with an empty extension") + { + REQUIRE(Execution().is_independent_with_execution_of( + PartialExecution{}, std::make_shared(Transition::Type::UNKNOWN, 1))); + } + + SECTION("Dependencies stopping independence from being possible") + { + const auto a0 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a5 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a6 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a7 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a8 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto indep = std::make_shared(Transition::Type::UNKNOWN, 2); + Execution execution(PartialExecution{a0, a1, a2, a3}); + + // We see that although `a4` comes after `a1` with which it is dependent, it + // would come before "a6" in the partial execution `w`, so it would not be independent + REQUIRE_FALSE(execution.is_independent_with_execution_of(PartialExecution{a5, a6, a7}, a4)); + + // Removing `a6` from the picture, though, gives us the independence we're looking for. + REQUIRE(execution.is_independent_with_execution_of(PartialExecution{a5, a7}, a4)); + + // BUT, we we ask about a transition which is run by the same actor, even if they would be + // independent otherwise, we again lose independence + REQUIRE_FALSE(execution.is_independent_with_execution_of(PartialExecution{a5, a7, a8}, a4)); + + // This is a more interesting case: + // `indep` clearly is independent with the rest of the series, even though + // there are dependencies among the other events in the partial execution + REQUIRE(Execution().is_independent_with_execution_of(PartialExecution{a1, a6, a7}, indep)); + + // This ensures that independence is trivial with an empty partial execution + REQUIRE(execution.is_independent_with_execution_of(PartialExecution{}, a1)); + } + + SECTION("More interesting dependencies stopping independence") + { + const auto e0 = std::make_shared(Transition::Type::UNKNOWN, 1, 5); + const auto e1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e2 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e3 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e4 = std::make_shared(Transition::Type::UNKNOWN, 3, 5); + const auto e5 = std::make_shared(Transition::Type::UNKNOWN, 4, 4); + Execution execution(PartialExecution{e0, e1, e2, e3, e4, e5}); + + SECTION("Action run by same actor disqualifies independence") + { + const auto w_1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto w_2 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto w_3 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto w_4 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto w = PartialExecution{w_1, w_2, w_3}; + + const auto actor4_action = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto actor4_action2 = std::make_shared(Transition::Type::UNKNOWN, 4); + + // Action `actor4_action` is independent with everything EXCEPT the last transition + // which is executed by the same actor + execution.is_independent_with_execution_of(w, actor4_action); + + // Action `actor4_action2` is independent with everything + // EXCEPT the last transition which is executed by the same actor + execution.is_independent_with_execution_of(w, actor4_action); + } + } +} + +TEST_CASE("simgrid::mc::odpor::Execution: Initials Test") +{ + const auto a0 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a5 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a6 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a7 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a8 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto indep = std::make_shared(Transition::Type::UNKNOWN, 2); + Execution execution(PartialExecution{a0, a1, a2, a3}); + + SECTION("Initials trivial with empty executions") + { + // There are no initials for an empty extension since + // a requirement is that the actor be contained in the + // extension itself + REQUIRE_FALSE(execution.is_initial_after_execution_of(PartialExecution{}, 0)); + REQUIRE_FALSE(execution.is_initial_after_execution_of(PartialExecution{}, 1)); + REQUIRE_FALSE(execution.is_initial_after_execution_of(PartialExecution{}, 2)); + REQUIRE_FALSE(Execution().is_initial_after_execution_of(PartialExecution{}, 0)); + REQUIRE_FALSE(Execution().is_initial_after_execution_of(PartialExecution{}, 1)); + REQUIRE_FALSE(Execution().is_initial_after_execution_of(PartialExecution{}, 2)); + } + + SECTION("The first actor is always an initial") + { + // Even in the case that the action is dependent with every + // other, if it is the first action to occur as part of the + // extension of the execution sequence, by definition it is + // an initial (recall that initials intuitively tell you which + // actions can be run starting from an execution `E`; if we claim + // to witness `E.w`, then clearly at least the first step of `w` is an initial) + REQUIRE(execution.is_initial_after_execution_of(PartialExecution{a3}, a3->aid_)); + REQUIRE(execution.is_initial_after_execution_of(PartialExecution{a2, a3, a6}, a2->aid_)); + REQUIRE(execution.is_initial_after_execution_of(PartialExecution{a6, a1, a0}, a6->aid_)); + REQUIRE(Execution().is_initial_after_execution_of(PartialExecution{a0, a1, a2, a3}, a0->aid_)); + REQUIRE(Execution().is_initial_after_execution_of(PartialExecution{a5, a2, a8, a7, a6, a0}, a5->aid_)); + REQUIRE(Execution().is_initial_after_execution_of(PartialExecution{a8, a7, a1}, a8->aid_)); + } + + SECTION("Example: Disqualified and re-qualified after switching ordering") + { + // Even though actor `2` executes an independent + // transition later on, it is blocked since its first transition + // is dependent with actor 1's transition + REQUIRE_FALSE(Execution().is_initial_after_execution_of(PartialExecution{a1, a5, indep}, 2)); + + // However, if actor 2 executes its independent action first, it DOES become an initial + REQUIRE(Execution().is_initial_after_execution_of(PartialExecution{a1, indep, a5}, 2)); + } + + SECTION("Example: Large partial executions") + { + // The record trace is `1 3 4 4 3 1 4 2` + + // Actor 1 starts the execution + REQUIRE(Execution().is_initial_after_execution_of(PartialExecution{a1, a2, a3, a4, a6, a7, a8, indep}, 1)); + + // Actor 2 all the way at the end is independent with everybody: despite + // the tangle that comes before it, we can more it to the front with no issue + REQUIRE(Execution().is_initial_after_execution_of(PartialExecution{a1, a2, a3, a4, a6, a7, a8, indep}, 2)); + + // Actor 3 is eliminated since `a1` is dependent with `a2` + REQUIRE_FALSE(Execution().is_initial_after_execution_of(PartialExecution{a1, a2, a3, a4, a6, a7, a8, indep}, 3)); + + // Likewise with actor 4 + REQUIRE_FALSE(Execution().is_initial_after_execution_of(PartialExecution{a1, a2, a3, a4, a6, a7, a8, indep}, 4)); + } + + SECTION("Example: Stress tests for initials computation") + { + const auto v_1 = std::make_shared(Transition::Type::UNKNOWN, 1, 3); + const auto v_2 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto v_3 = std::make_shared(Transition::Type::UNKNOWN, 2, 3); + const auto v_4 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto v_5 = std::make_shared(Transition::Type::UNKNOWN, 3, 8); + const auto v_6 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto v_7 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto v_8 = std::make_shared(Transition::Type::UNKNOWN, 4, 3); + const auto v = PartialExecution{v_1, v_2, v_3, v_4}; + + // Actor 1 being the first actor in the expansion, it is clearly an initial + REQUIRE(Execution().is_initial_after_execution_of(v, 1)); + + // Actor 2 can't be switched before actor 1 without creating an trace + // that leads to a different state than that of `E.v := ().v := v` + REQUIRE_FALSE(Execution().is_initial_after_execution_of(v, 2)); + + // The first action of Actor 3 is independent with what comes before it, so it can + // be moved forward. Note that this is the case even though it later executes and action + // that's dependent with most everyone else + REQUIRE(Execution().is_initial_after_execution_of(v, 3)); + + // Actor 4 is blocked actor 3's second action `v_7` + REQUIRE_FALSE(Execution().is_initial_after_execution_of(v, 4)); + } +} + +TEST_CASE("simgrid::mc::odpor::Execution: SDPOR Backtracking Simulation") +{ + // This test case assumes that each detected race is detected to also + // be reversible. For each reversible + const auto e0 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto e2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto e3 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto e4 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto e5 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto e6 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto e7 = std::make_shared(Transition::Type::UNKNOWN, 1); + + Execution execution; + + execution.push_transition(e0); + REQUIRE(execution.get_racing_events_of(0) == std::unordered_set{}); + + execution.push_transition(e1); + REQUIRE(execution.get_racing_events_of(1) == std::unordered_set{}); + + // Actor 3, since it starts the extension from event 1, clearly is an initial from there + execution.push_transition(e2); + REQUIRE(execution.get_racing_events_of(2) == std::unordered_set{1}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{}) == std::unordered_set{3}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{4, 5}) == + std::unordered_set{3}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{3}) == std::unordered_set{}); + + // e1 and e3 are in an reversible race. Actor 4 is not hindered from being moved to + // the front since e2 is independent with e3; hence, it is an initial + execution.push_transition(e3); + REQUIRE(execution.get_racing_events_of(3) == std::unordered_set{1}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{}) == std::unordered_set{4}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{3, 5}) == + std::unordered_set{4}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{4}) == std::unordered_set{}); + + // e4 is not in a race since e3 is run by the same actor and occurs before e4 + execution.push_transition(e4); + REQUIRE(execution.get_racing_events_of(4) == std::unordered_set{}); + + // e5 is independent with everything between e1 and e5, and `proc(e5) == 2` + execution.push_transition(e5); + REQUIRE(execution.get_racing_events_of(5) == std::unordered_set{1}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{}) == std::unordered_set{2}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{4, 5}) == + std::unordered_set{2}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{2}) == std::unordered_set{}); + + // Event 6 has two races: one with event 4 and one with event 5. In the latter race, actor 3 follows + // immediately after and so is evidently a source set actor; in the former race, only actor 2 can + // be brought to the front of the queue + execution.push_transition(e6); + REQUIRE(execution.get_racing_events_of(6) == std::unordered_set{4, 5}); + CHECK(execution.get_missing_source_set_actors_from(4, std::unordered_set{}) == std::unordered_set{2}); + CHECK(execution.get_missing_source_set_actors_from(4, std::unordered_set{6, 7}) == + std::unordered_set{2}); + CHECK(execution.get_missing_source_set_actors_from(4, std::unordered_set{2}) == std::unordered_set{}); + CHECK(execution.get_missing_source_set_actors_from(5, std::unordered_set{}) == std::unordered_set{3}); + CHECK(execution.get_missing_source_set_actors_from(5, std::unordered_set{6, 7}) == + std::unordered_set{3}); + CHECK(execution.get_missing_source_set_actors_from(5, std::unordered_set{3}) == std::unordered_set{}); + + // Finally, event e7 races with e6 and `proc(e7) = 1` is brought forward + execution.push_transition(e7); + REQUIRE(execution.get_racing_events_of(7) == std::unordered_set{6}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{}) == std::unordered_set{1}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{4, 5}) == + std::unordered_set{1}); + CHECK(execution.get_missing_source_set_actors_from(1, std::unordered_set{1}) == std::unordered_set{}); +} + +TEST_CASE("simgrid::mc::odpor::Execution: ODPOR Smallest Sequence Tests") +{ + const auto a0 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a5 = std::make_shared(Transition::Type::UNKNOWN, 4); + + Execution execution; + execution.push_transition(a0); + execution.push_transition(a1); + execution.push_transition(a2); + execution.push_transition(a3); + execution.push_transition(a4); + execution.push_transition(a5); + + SECTION("Equivalent insertions") + { + SECTION("Example: Eliminated through independence") + { + // TODO: Is this even a sensible question to ask if the two sequences + // don't agree upon what each actor executed after `E`? + const auto insertion = + Execution().get_shortest_odpor_sq_subset_insertion(PartialExecution{a1, a2}, PartialExecution{a2, a5}); + REQUIRE(insertion.has_value()); + REQUIRE(insertion.value() == PartialExecution{}); + } + + SECTION("Exact match yields empty set") + { + const auto insertion = + Execution().get_shortest_odpor_sq_subset_insertion(PartialExecution{a1, a2}, PartialExecution{a1, a2}); + REQUIRE(insertion.has_value()); + REQUIRE(insertion.value() == PartialExecution{}); + } + } + + SECTION("Match against empty executions") + { + SECTION("Empty `v` trivially yields `w`") + { + auto insertion = + Execution().get_shortest_odpor_sq_subset_insertion(PartialExecution{}, PartialExecution{a1, a5, a2}); + REQUIRE(insertion.has_value()); + REQUIRE(insertion.value() == PartialExecution{a1, a5, a2}); + + insertion = execution.get_shortest_odpor_sq_subset_insertion(PartialExecution{}, PartialExecution{a1, a5, a2}); + REQUIRE(insertion.has_value()); + REQUIRE(insertion.value() == PartialExecution{a1, a5, a2}); + } + + SECTION("Empty `w` yields empty execution") + { + auto insertion = + Execution().get_shortest_odpor_sq_subset_insertion(PartialExecution{a1, a4, a5}, PartialExecution{}); + REQUIRE(insertion.has_value()); + REQUIRE(insertion.value() == PartialExecution{}); + + insertion = execution.get_shortest_odpor_sq_subset_insertion(PartialExecution{a1, a5, a2}, PartialExecution{}); + REQUIRE(insertion.has_value()); + REQUIRE(insertion.value() == PartialExecution{}); + } + } +} diff --git a/src/mc/explo/odpor/WakeupTree.cpp b/src/mc/explo/odpor/WakeupTree.cpp new file mode 100644 index 0000000000..73b2171894 --- /dev/null +++ b/src/mc/explo/odpor/WakeupTree.cpp @@ -0,0 +1,249 @@ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/odpor/WakeupTree.hpp" +#include "src/mc/explo/odpor/Execution.hpp" +#include "xbt/asserts.h" +#include "xbt/string.hpp" + +#include +#include +#include +#include + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_wut, mc, "Logging specific to ODPOR WakeupTrees"); + +namespace simgrid::mc::odpor { + +void WakeupTreeNode::add_child(WakeupTreeNode* node) +{ + this->children_.push_back(node); + node->parent_ = this; +} + +std::string WakeupTreeNode::string_of_whole_tree(int indentation_level) const +{ + std::string tabulations = ""; + for (int i = 0; i < indentation_level; i++) + tabulations += " "; + std::string final_string = action_ == nullptr ? "<>\n" + : tabulations + "Actor " + std::to_string(action_->aid_) + ": " + + action_->to_string(true) + "\n"; + for (auto node : children_) + final_string += node->string_of_whole_tree(indentation_level + 1); + return final_string; +} + +PartialExecution WakeupTreeNode::get_sequence() const +{ + // TODO: Prevent having to compute this at the node level + // and instead track this with the iterator + PartialExecution seq_; + const WakeupTreeNode* cur_node = this; + while (cur_node != nullptr && not cur_node->is_root()) { + seq_.push_front(cur_node->action_); + cur_node = cur_node->parent_; + } + return seq_; +} + +void WakeupTreeNode::detatch_from_parent() +{ + if (parent_ != nullptr) { + // TODO: There may be a better method + // of keeping track of a node's reference to + // its parent, perhaps keeping track + // of a std::list<>::iterator instead. + // This would allow us to detach a node + // in O(1) instead of O(|children|) time + parent_->children_.remove(this); + } +} + +WakeupTree::WakeupTree() : WakeupTree(std::make_unique()) {} +WakeupTree::WakeupTree(std::unique_ptr root) : root_(root.get()) +{ + this->insert_node(std::move(root)); +} + +std::vector WakeupTree::get_single_process_texts() const +{ + std::vector trace; + for (const auto* child : root_->children_) { + const auto t = child->get_action(); + auto message = xbt::string_printf("Actor %ld: %s", t->aid_, t->to_string(true).c_str()); + trace.emplace_back(std::move(message)); + } + return trace; +} + +std::optional WakeupTree::get_min_single_process_actor() const +{ + if (const auto node = get_min_single_process_node(); node.has_value()) { + return node.value()->get_actor(); + } + return std::nullopt; +} + +std::optional WakeupTree::get_min_single_process_node() const +{ + if (empty()) { + return std::nullopt; + } + // INVARIANT: The induced post-order relation always places children + // in order before the parent. The list of children maintained by + // each node represents that ordering, and the first child of + // the root is by definition the smallest of the single-process nodes + xbt_assert(not this->root_->children_.empty(), "What the"); + return this->root_->children_.front(); +} + +std::string WakeupTree::string_of_whole_tree() const +{ + return root_->string_of_whole_tree(0); +} + +WakeupTree WakeupTree::make_subtree_rooted_at(WakeupTreeNode* root) +{ + // Perform a BFS search to perform a deep copy of the portion + // of the tree underneath and including `root`. Note that `root` + // is contained within the context of a *different* wakeup tree; + // hence, we have to be careful to update each node's children + // appropriately + auto subtree = WakeupTree(); + + std::list> frontier{std::make_pair(root, subtree.root_)}; + while (not frontier.empty()) { + auto [node_in_other_tree, subtree_equivalent] = frontier.front(); + frontier.pop_front(); + + // For each child of the node corresponding to that in `subtree`, + // make clones of each of its children and add them to `frontier` + // to that their children are added, and so on. + for (WakeupTreeNode* child_in_other_tree : node_in_other_tree->get_ordered_children()) { + WakeupTreeNode* child_equivalent = subtree.make_node(child_in_other_tree->get_action()); + subtree_equivalent->add_child(child_equivalent); + frontier.push_back(std::make_pair(child_in_other_tree, child_equivalent)); + } + } + return subtree; +} + +void WakeupTree::remove_subtree_rooted_at(WakeupTreeNode* root) +{ + if (not contains(root)) { + throw std::invalid_argument("Attempting to remove a subtree pivoted from a node " + "that is not contained in this wakeup tree"); + } + + std::list subtree_contents{root}; + std::list frontier{root}; + while (not frontier.empty()) { + const auto* node = frontier.front(); + frontier.pop_front(); + for (const auto& child : node->get_ordered_children()) { + frontier.push_back(child); + subtree_contents.push_back(child); + } + } + + // After having found each node with BFS, now we can + // remove them. This prevents the "joys" of iteration during mutation. + // We also remove the `root` from being referenced by its own parent (since + // it will soon be destroyed) + root->detatch_from_parent(); + for (WakeupTreeNode* node_to_remove : subtree_contents) { + this->remove_node(node_to_remove); + } +} + +void WakeupTree::remove_subtree_at_aid(aid_t proc) +{ + for (const auto& child : root_->get_ordered_children()) + if (child->get_actor() == proc) { + this->remove_subtree_rooted_at(child); + break; + } +} + +void WakeupTree::remove_min_single_process_subtree() +{ + if (const auto node = get_min_single_process_node(); node.has_value()) { + remove_subtree_rooted_at(node.value()); + } +} + +bool WakeupTree::contains(const WakeupTreeNode* node) const +{ + return std::find_if(this->nodes_.begin(), this->nodes_.end(), [=](const auto& pair) { return pair.first == node; }) != + this->nodes_.end(); +} + +WakeupTreeNode* WakeupTree::make_node(std::shared_ptr u) +{ + auto node = std::make_unique(std::move(u)); + auto* node_handle = node.get(); + this->nodes_[node_handle] = std::move(node); + return node_handle; +} + +void WakeupTree::insert_node(std::unique_ptr node) +{ + auto* node_handle = node.get(); + this->nodes_[node_handle] = std::move(node); +} + +void WakeupTree::remove_node(WakeupTreeNode* node) +{ + this->nodes_.erase(node); +} + +WakeupTree::InsertionResult WakeupTree::insert(const Execution& E, const PartialExecution& w) +{ + // See section 6.2 of Abdulla. et al.'s 2017 ODPOR paper for details + + // Find the first node `v` in the tree such that + // `v ~_[E] w` and `v` is not a leaf node + for (WakeupTreeNode* node : *this) { + if (const auto shortest_sequence = E.get_shortest_odpor_sq_subset_insertion(node->get_sequence(), w); + shortest_sequence.has_value()) { + // Insert the sequence as a child of `node`, but only + // if the node is not already a leaf + if (not node->is_leaf() || node == this->root_) { + // NOTE: It's entirely possible that the shortest + // sequence we are inserting is empty. Consider the + // following two cases: + // + // 1. `w` is itself empty. Evidently, insertion succeeds but nothing needs + // to happen + // + // 2. a leaf node in the tree already contains `w` exactly. + // In this case, the empty `w'` returned (viz. `shortest_seq`) + // such that `w [=_[E] v.w'` would be empty + this->insert_sequence_after(node, shortest_sequence.value()); + return node == this->root_ ? InsertionResult::root : InsertionResult::interior_node; + } + // Since we're following the post-order traversal of the tree, + // the first such node we see is the smallest w.r.t "<" + return InsertionResult::leaf; + } + } + xbt_die("Insertion should always succeed with the root node (which contains no " + "prior execution). If we've reached this point, this implies either that " + "the wakeup tree traversal is broken or that computation of the shortest " + "sequence to insert into the tree is broken"); +} + +void WakeupTree::insert_sequence_after(WakeupTreeNode* node, const PartialExecution& w) +{ + WakeupTreeNode* cur_node = node; + for (const auto& w_i : w) { + WakeupTreeNode* new_node = this->make_node(w_i); + cur_node->add_child(new_node); + cur_node = new_node; + } +} + +} // namespace simgrid::mc::odpor diff --git a/src/mc/explo/odpor/WakeupTree.hpp b/src/mc/explo/odpor/WakeupTree.hpp new file mode 100644 index 0000000000..def2840e0f --- /dev/null +++ b/src/mc/explo/odpor/WakeupTree.hpp @@ -0,0 +1,245 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_ODPOR_WAKEUP_TREE_HPP +#define SIMGRID_MC_ODPOR_WAKEUP_TREE_HPP + +#include "src/mc/explo/odpor/WakeupTreeIterator.hpp" +#include "src/mc/explo/odpor/odpor_forward.hpp" +#include "src/mc/transition/Transition.hpp" + +#include +#include +#include +#include +#include + +namespace simgrid::mc::odpor { + +/** + * @brief A single node in a wakeup tree + * + * Each node in a wakeup tree represents a single step + * taken in an extension of the execution represented + * by the tree within which the node is contained. That is, + * a node in the tree is one step on a "pre-defined" + * path forward for some execution sequence. The partial + * execution that is implicitly represented by the node + * is that formed by taking each step on the (unique) + * path in the tree from the root node to this node. + * Thus, the tree itself contains all of the paths + * that "should be" searched, while each node is + * simply a step on each path. + */ +class WakeupTreeNode { +private: + WakeupTreeNode* parent_ = nullptr; + + /** An ordered list of children of for this node in the tree */ + std::list children_; + + /** @brief The contents of the node */ + std::shared_ptr action_; + + /** @brief Removes the node as a child from the parent */ + void detatch_from_parent(); + + /** Allows the owning tree to insert directly into the child */ + friend WakeupTree; + friend WakeupTreeIterator; + +public: + explicit WakeupTreeNode(std::shared_ptr u) : action_(u) {} + + WakeupTreeNode() = default; + ~WakeupTreeNode() = default; + WakeupTreeNode(const WakeupTreeNode&) = delete; + WakeupTreeNode(WakeupTreeNode&&) = default; + WakeupTreeNode& operator=(const WakeupTreeNode&) = delete; + WakeupTreeNode& operator=(WakeupTreeNode&&) = default; + + auto begin() const { return this->children_.begin(); } + auto end() const { return this->children_.end(); } + auto rbegin() const { return this->children_.rbegin(); } + auto rend() const { return this->children_.rend(); } + + bool is_leaf() const { return children_.empty(); } + bool is_root() const { return parent_ == nullptr; } + aid_t get_actor() const { return action_->aid_; } + PartialExecution get_sequence() const; + std::shared_ptr get_action() const { return action_; } + const std::list& get_ordered_children() const { return children_; } + + std::string string_of_whole_tree(int indentation_level) const; + + /** Insert a node `node` as a new child of this node */ + void add_child(WakeupTreeNode* node); +}; + +/** + * @brief The structure used by ODPOR to maintains paths of execution + * that should be followed in the future + * + * The wakeup tree data structure is formally defined in the Abdulla et al. + * 2017 ODPOR paper. Conceptually, the tree consists of nodes which are + * mapped to actions. Each node represents a partial extension of an execution, + * the complete extension being the transitions taken in sequence from + * the root of the tree to the node itself. Leaf nodes in the tree conceptually, + * then, represent paths that are guaranteed to explore different parts + * of the search space. + * + * Iteration over a wakeup tree occurs as a post-order traversal of its nodes + * + * @note A wakeup tree is defined relative to some execution `E`. The + * structure itself does not hold onto a reference of the execution with + * respect to which it is a wakeup tree. + * + * @todo: If the idea of execution "views" is ever added -- viz. being able + * to share the contents of a single execution -- then a wakeup tree could + * contain a reference to such a view which would then be maintained by the + * manipulator of the tree + */ +class WakeupTree { +private: + WakeupTreeNode* root_; + + /** + * @brief All of the nodes that are currently are a part of the tree + * + * @invariant Each node event maps itself to the owner of that node, + * i.e. the unique pointer that manages the data at the address. The tree owns all + * of the addresses that are referenced by the nodes WakeupTreeNode. + * ODPOR guarantees that nodes are persisted as long as needed. + */ + std::unordered_map> nodes_; + + void insert_node(std::unique_ptr node); + void insert_sequence_after(WakeupTreeNode* node, const PartialExecution& w); + void remove_node(WakeupTreeNode* node); + bool contains(const WakeupTreeNode* node) const; + + /** + * @brief Removes the node `root` and all of its descendants from + * this wakeup tree + * + * @throws: If the node `root` is not contained in this tree, an + * exception is raised + */ + void remove_subtree_rooted_at(WakeupTreeNode* root); + + /** + * @brief Adds a new node to the tree, disconnected from + * any other, which represents the partial execution + * "fragment" `u` + */ + WakeupTreeNode* make_node(std::shared_ptr u); + + /* Allow the iterator to access the contents of the tree */ + friend WakeupTreeIterator; + +public: + WakeupTree(); + explicit WakeupTree(std::unique_ptr root); + + /** + * @brief Creates a copy of the subtree whose root is the node + * `root` in this tree + */ + static WakeupTree make_subtree_rooted_at(WakeupTreeNode* root); + + auto begin() const { return WakeupTreeIterator(*this); } + auto end() const { return WakeupTreeIterator(); } + + std::vector get_single_process_texts() const; + + std::string string_of_whole_tree() const; + + /** + * @brief Remove the subtree of the smallest (with respect + * to the tree's "<" relation) single-process node. + * + * A "single-process" node is one whose execution represents + * taking a single action (i.e. those of the root node). The + * smallest under "<" is that which is continuously selected and + * removed by ODPOR. + * + * If the tree is empty, this method has no effect. + */ + void remove_min_single_process_subtree(); + + void remove_subtree_at_aid(aid_t proc); + + /** + * @brief Whether or not this tree is considered empty + * + * @note Unlike other collection types, a wakeup tree is + * considered "empty" if it only contains the root node; + * that is, if it is "uninteresting". In such a case, + */ + bool empty() const { return nodes_.size() == static_cast(1); } + + /** + * @brief Returns the number of *non-empty* entries in the tree, viz. the + * number of nodes in the tree that have an action mapped to them + */ + size_t get_num_entries() const { return not empty() ? (nodes_.size() - 1) : static_cast(0); } + + /** + * @brief Returns the number of nodes in the tree, including the root node + */ + size_t get_num_nodes() const { return nodes_.size(); } + + /** + * @brief Gets the actor of the node that is the "smallest" (with respect + * to the tree's "<" relation) single-process node. + * + * If the tree is empty, returns std::nullopt + */ + std::optional get_min_single_process_actor() const; + + /** + * @brief Gets the node itself that is the "smallest" (with respect + * to the tree's "<" relation) single-process node. + * + * If the tree is empty, returns std::nullopt + */ + std::optional get_min_single_process_node() const; + + /** @brief Describes how a tree insertion was carried out */ + enum class InsertionResult { leaf, interior_node, root }; + + /** + * @brief Inserts an sequence `seq` of processes into the tree + * such that that this tree is a wakeup tree relative to the + * given execution + * + * A key component of managing wakeup trees in ODPOR is + * determining what should be inserted into a wakeup tree. + * The procedure for implementing the insertion is outlined in section 6.2 + * of Abdulla et al. 2017 as follows: + * + * | Let `v` be the smallest (w.r.t to "<") sequence in [the tree] B + * | such that `v ~_[E] w`. If `v` is a leaf node, the tree can be left + * | unmodified. + * | + * | Otherwise let `w'` be the shortest sequence such that `w [=_[E] v.w'` + * | and add `v.w'` as a new leaf, ordered after all already existing nodes + * | of the form `v.w''` + * + * This method performs the post-order search of part one and the insertion of + * `v.w'` of part two of the above procedure. Note that the execution will + * provide `v.w'` (see `Execution::get_shortest_odpor_sq_subset_insertion()`). + * + * @invariant: It is assumed that this tree is a wakeup tree + * with respect to the given execution `E` + * + * @return Whether a sequence equivalent to `seq` is already contained + * as a leaf node in the tree + */ + InsertionResult insert(const Execution& E, const PartialExecution& seq); +}; + +} // namespace simgrid::mc::odpor +#endif diff --git a/src/mc/explo/odpor/WakeupTreeIterator.cpp b/src/mc/explo/odpor/WakeupTreeIterator.cpp new file mode 100644 index 0000000000..9017fd8223 --- /dev/null +++ b/src/mc/explo/odpor/WakeupTreeIterator.cpp @@ -0,0 +1,86 @@ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/odpor/WakeupTreeIterator.hpp" +#include "src/mc/explo/odpor/WakeupTree.hpp" +#include "xbt/asserts.h" + +namespace simgrid::mc::odpor { + +WakeupTreeIterator::WakeupTreeIterator(const WakeupTree& tree) : root_list{tree.root_} +{ + post_order_iteration.push(root_list.begin()); + push_until_left_most_found(); +} + +void WakeupTreeIterator::push_until_left_most_found() +{ + // INVARIANT: Since we are traversing over a tree, + // there are no cycles. This means that at least + // one node in the tree won't have any children, + // so the loop will eventually terminate + WakeupTreeNode* cur_top_node = *post_order_iteration.top(); + while (not cur_top_node->is_leaf()) { + // INVARIANT: Since we push children in + // reverse order (right-most to left-most), + // we ensure that we'll always process left-most + // children first + auto& children = cur_top_node->children_; + for (auto iter = children.rbegin(); iter != children.rend(); ++iter) { + // iter.base() points one element past where we seek; that is, + // we want the value one position forward + post_order_iteration.push(std::prev(iter.base())); + } + has_added_children.push(cur_top_node); + cur_top_node = *post_order_iteration.top(); + } +} + +void WakeupTreeIterator::increment() +{ + // If there are no nodes in the stack, we've + // completed the traversal: there's nothing left + // to do + if (post_order_iteration.empty()) { + return; + } + + post_order_iteration.pop(); + + // If there are now no longer any nodes left, + // we know that `prev_top` must be the original + // root; that is, we were *just* pointing at the + // original root, so we're done + if (post_order_iteration.empty()) { + return; + } + + xbt_assert(not has_added_children.empty(), "Invariant violated: There are more " + "nodes in the iteration that we must search " + "yet nobody has claimed to have added these nodes. " + "This implies that the algorithm is not iterating over " + "the wakeup tree is not following the post-fix order " + "correctly"); + + // Otherwise, look at what is the new, current top node. + // We're traversing the tree in + // + // If we've already added our children, we want + // to be sure not to add them again; but we ALSO + // want to be sure that we now start checking against + // the the node that's next in line as "finished" + // + // INVARIANT: Since we're searching in post-fix order, + // it always suffices to compare the current node + // with the top of the stack of nodes which have added their + // children + if (*post_order_iteration.top() == has_added_children.top()) { + has_added_children.pop(); + } else { + push_until_left_most_found(); + } +} + +} // namespace simgrid::mc::odpor \ No newline at end of file diff --git a/src/mc/explo/odpor/WakeupTreeIterator.hpp b/src/mc/explo/odpor/WakeupTreeIterator.hpp new file mode 100644 index 0000000000..c33d483dfa --- /dev/null +++ b/src/mc/explo/odpor/WakeupTreeIterator.hpp @@ -0,0 +1,88 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_ODPOR_WAKEUP_TREE_ITERATOR_HPP +#define SIMGRID_MC_ODPOR_WAKEUP_TREE_ITERATOR_HPP + +#include "src/mc/explo/odpor/odpor_forward.hpp" + +#include +#include +#include + +namespace simgrid::mc::odpor { + +/** + * @brief A forward-iterator that performs a postorder traversal + * of the nodes of a WakeupTree + * + * Inserting a sequence `w` into a wakeup tree `B` with respect to + * some execution `E` requires determining the "<-minimal" node `N` + * with sequence `v` in the tree such that `v ~_[E] w`. The "<" relation + * over a wakeup tree orders its nodes by first recursively ordering all + * children of a node `N` followed by the node `N` itself, viz. a postorder. + * This iterator provides such a postorder traversal over the nodes in the + * wakeup tree. + */ +class WakeupTreeIterator + : public boost::iterator_facade { +public: + // Use rule-of-three, and implicitely disable the move constructor which cannot be 'noexcept' (as required by C++ Core + // Guidelines), due to the std::list and std:stack members. + WakeupTreeIterator() = default; + WakeupTreeIterator(const WakeupTreeIterator&) = default; + ~WakeupTreeIterator() = default; + + explicit WakeupTreeIterator(const WakeupTree& tree); + +private: + using node_handle = std::list::iterator; + + /** + * @brief A list which is used to "store" the root node of the traversed + * wakeup tree + * + * The root node is, by definition, not the child of any other node. This + * means that the root node also is contained in any list into which the + * iterator can generate a pointer (iterator). This list takes the role + * of allowing the iterator to treat the root node like any other. + */ + std::list root_list; + + /** + * @brief The current "view" of the iteration in post-order traversal + */ + std::stack post_order_iteration; + + /** + * @brief The nodes in the current ordering that have already + * added their own children + * + * We need to be able to determine whether to add the children + * of a given node. Eventually, we want to search that node itself, + * but we have to first search its children. Later, when we + * reach each node in this stack again, we'll remember not to add + * its children and will search the node in the stack instead. + */ + std::stack has_added_children; + + /** + * @brief Search the wakeup tree until a leaf node appears at the front + * of the iteration, pushing all children towards the top of the stack + * as the search progresses + */ + void push_until_left_most_found(); + + // boost::iterator_facade<...> interface to implement + void increment(); + bool equal(const WakeupTreeIterator& other) const { return post_order_iteration == other.post_order_iteration; } + WakeupTreeNode*& dereference() const { return *post_order_iteration.top(); } + + // Allows boost::iterator_facade<...> to function properly + friend class boost::iterator_core_access; +}; + +} // namespace simgrid::mc::odpor +#endif diff --git a/src/mc/explo/odpor/WakeupTree_test.cpp b/src/mc/explo/odpor/WakeupTree_test.cpp new file mode 100644 index 0000000000..e0ef032bb9 --- /dev/null +++ b/src/mc/explo/odpor/WakeupTree_test.cpp @@ -0,0 +1,469 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/odpor/Execution.hpp" +#include "src/mc/explo/odpor/WakeupTree.hpp" +#include "src/mc/explo/udpor/udpor_tests_private.hpp" +#include "src/xbt/utils/iter/LazyPowerset.hpp" + +using namespace simgrid::mc; +using namespace simgrid::mc::odpor; +using namespace simgrid::mc::udpor; + +static void test_tree_iterator(const WakeupTree& tree, const std::vector& expected) +{ + uint64_t num_nodes_traversed = 0; + auto tree_iter = tree.begin(); + for (auto expected_iter = expected.begin(); expected_iter != expected.end(); + ++expected_iter, ++tree_iter, ++num_nodes_traversed) { + REQUIRE(tree_iter != tree.end()); + REQUIRE((*tree_iter)->get_sequence() == *expected_iter); + } + REQUIRE(num_nodes_traversed == tree.get_num_nodes()); +} + +static void test_tree_empty(const WakeupTree& tree) +{ + REQUIRE(tree.empty()); + REQUIRE(tree.get_num_entries() == 0); + REQUIRE(tree.get_num_nodes() == 1); + REQUIRE_FALSE(tree.get_min_single_process_node().has_value()); + REQUIRE_FALSE(tree.get_min_single_process_actor().has_value()); + test_tree_iterator(tree, std::vector{PartialExecution{}}); +} + +TEST_CASE("simgrid::mc::odpor::WakeupTree: Constructing Trees") +{ + SECTION("Constructing empty trees") + { + test_tree_empty(WakeupTree()); + } + + SECTION("Testing subtree creation and manipulation") + { + // Here, we make everything dependent. This will ensure that each unique sequence + // inserted into the tree never "eventually looks like" + const auto a0 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 5); + const auto a5 = std::make_shared(Transition::Type::UNKNOWN, 6); + + Execution execution; + execution.push_transition(a0); + execution.push_transition(a1); + execution.push_transition(a2); + execution.push_transition(a3); + execution.push_transition(a4); + execution.push_transition(a5); + + // The tree is as follows: + // {} + // / / + // a1 a4 + // / / / + // a2 a3 a1 + // / / / / + // a3 a2 a5 a2 + // / / / + // a4 a4 a3 + // + // Recall that new nodes (in this case the one with + // action `a2`) are added such that they are "greater than" (under + // the tree's `<` relation) all those that exist under the given parent + WakeupTree tree; + tree.insert(Execution(), {a1, a2, a3, a4}); + tree.insert(Execution(), {a1, a3, a2, a4}); + tree.insert(Execution(), {a1, a3, a2, a4, a5}); + tree.insert(Execution(), {a1, a3, a5}); + tree.insert(Execution(), {a4, a2, a1, a3}); + REQUIRE(tree.get_num_nodes() == 13); + test_tree_iterator(tree, std::vector{ + PartialExecution{a1, a2, a3, a4}, PartialExecution{a1, a2, a3}, + PartialExecution{a1, a2}, PartialExecution{a1, a3, a2, a4}, + PartialExecution{a1, a3, a2}, PartialExecution{a1, a3, a5}, PartialExecution{a1, a3}, + PartialExecution{a1}, PartialExecution{a4, a2, a1, a3}, PartialExecution{a4, a2, a1}, + PartialExecution{a4, a2}, PartialExecution{a4}, PartialExecution{}}); + + SECTION("Cloning a tree from the root produces the same tree") + { + // The root node is the last node + auto tree_root = tree.begin(); + std::advance(tree_root, tree.get_num_nodes() - 1); + + WakeupTree clone = WakeupTree::make_subtree_rooted_at(*tree_root); + REQUIRE(clone.empty() == tree.empty()); + REQUIRE(clone.get_num_entries() == tree.get_num_entries()); + REQUIRE(clone.get_num_nodes() == tree.get_num_nodes()); + + auto tree_iter = tree.begin(); + for (auto clone_iter = clone.begin(); clone_iter != clone.end(); ++clone_iter, ++tree_iter) { + REQUIRE(tree_iter != tree.end()); + REQUIRE((*tree_iter)->get_sequence() == (*clone_iter)->get_sequence()); + } + } + + SECTION("Cloning a subtree from a leaf gives an empty tree") + { + // Let's pick the first leaf + WakeupTree clone = WakeupTree::make_subtree_rooted_at(*tree.begin()); + REQUIRE(clone.empty()); + REQUIRE(clone.get_num_entries() == 0); + REQUIRE(clone.get_num_nodes() == 1); + } + + SECTION("Cloning a subtree from an interior node gives the subtree underneath") + { + // Here, we pick the second-to-last node in the + // series, which is the right-most child of the root + auto right_most = tree.begin(); + std::advance(right_most, tree.get_num_nodes() - 2); + + WakeupTree clone = WakeupTree::make_subtree_rooted_at(*right_most); + REQUIRE_FALSE(clone.empty()); + REQUIRE(clone.get_num_entries() == 3); + REQUIRE(clone.get_num_nodes() == 4); + // Importantly, note that action `a4` is not included in + // any of the executions; for in the subtree `clone` `a4` + // is now the root. + test_tree_iterator(clone, std::vector{PartialExecution{a2, a1, a3}, PartialExecution{a2, a1}, + PartialExecution{a2}, PartialExecution{}}); + } + + SECTION("Removing the first single-process subtree") + { + // Prior to removal, the first `a1` was the first single-process node + REQUIRE(tree.get_min_single_process_node().has_value()); + REQUIRE(tree.get_min_single_process_actor().has_value()); + REQUIRE(tree.get_min_single_process_actor().value() == a1->aid_); + + tree.remove_min_single_process_subtree(); + + // Now the first `a4` is + REQUIRE(tree.get_min_single_process_node().has_value()); + REQUIRE(tree.get_min_single_process_actor().has_value()); + REQUIRE(tree.get_min_single_process_actor().value() == a4->aid_); + + REQUIRE(tree.get_num_nodes() == 5); + test_tree_iterator(tree, std::vector{PartialExecution{a4, a2, a1, a3}, + PartialExecution{a4, a2, a1}, PartialExecution{a4, a2}, + PartialExecution{a4}, PartialExecution{}}); + tree.remove_min_single_process_subtree(); + + // At this point, we've removed each single-process subtree, so + // the tree should be empty + REQUIRE(tree.empty()); + } + + SECTION("Removing the first single-process subtree from an empty tree has no effect") + { + WakeupTree empty_tree; + test_tree_empty(empty_tree); + + empty_tree.remove_min_single_process_subtree(); + + // There should be no effect: the tree should still be empty + // and the function should have no effect + test_tree_empty(empty_tree); + } + } +} + +TEST_CASE("simgrid::mc::odpor::WakeupTree: Testing Insertion for Empty Executions") +{ + SECTION("Following an execution") + { + // We imagine the following completed execution `E` + // consisting of executing actions a0-a3. Execution + // `E` is the first such maximal execution explored + // by ODPOR, which implies that a) all sleep sets are + // empty and b) all wakeup trees (i.e. for each prefix) consist of the root + // node with a single leaf containing the action + // taken, save for the wakeup tree of the execution itself + // which is empty. + + // We first notice that there's a reversible race between + // events 0 and 3. + + const auto a0 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 2); + + Execution execution; + execution.push_transition(a0); + execution.push_transition(a1); + execution.push_transition(a2); + execution.push_transition(a3); + execution.push_transition(a4); + + REQUIRE(execution.get_racing_events_of(2) == std::unordered_set{0}); + REQUIRE(execution.get_racing_events_of(3) == std::unordered_set{0}); + + WakeupTree tree; + + SECTION("Attempting to insert the empty sequence into an empty tree should have no effect") + { + tree.insert(Execution(), {}); + test_tree_iterator(tree, std::vector{PartialExecution{}}); + } + + // First, we initialize the tree to how it looked prior + // to the insertion of the race. + tree.insert(Execution(), {a0}); + + // Then, after insertion, we ensure that the node was + // indeed added to the tree. + tree.insert(Execution(), {a1, a3}); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{a1, a3}, + PartialExecution{a1}, PartialExecution{}}); + + SECTION("Attempting to re-insert the same EXACT sequence should have no effect") + { + tree.insert(Execution(), {a1, a3}); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{a1, a3}, + PartialExecution{a1}, PartialExecution{}}); + } + + SECTION("Attempting to re-insert an equivalent sequence should have no effect") + { + // a3 and a1 are interchangeable since `a1` is independent with everything. + // Since we found an equivalent sequence that is a leaf, nothing should result.. + tree.insert(Execution(), {a3, a1}); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{a1, a3}, + PartialExecution{a1}, PartialExecution{}}); + } + + SECTION("Attempting to insert the empty sequence should have no effect") + { + tree.insert(Execution(), {}); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{a1, a3}, + PartialExecution{a1}, PartialExecution{}}); + } + + SECTION("Inserting an extension should create a branch point") + { + // `a1.a2` shares the same `a1` prefix as `a1.a3`. Thus, the tree + // should now look as follows: + // + // {} + // / / + // a0 a1 + // / / + // a3 a4 + // + // Recall that new nodes (in this case the one with + // action `a2`) are added such that they are "greater than" (under + // the tree's `<` relation) all those that exist under the given parent. + tree.insert(Execution(), {a1, a4}); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{a1, a3}, + PartialExecution{a1, a4}, PartialExecution{a1}, + PartialExecution{}}); + } + + SECTION("Inserting an equivalent sequence to a leaf should preserve the tree as-is") + { + // `a1.a2` is equivalent to `a1.a3` since `a2` and `a3` are independent + // (`E ⊢ p ◊ w` where `p := proc(a2)` and `w := a3`). Thus, the tree + // should now STILL look as follows: + // + // {} + // / / + // a0 a1 + // / + // a3 + // + // Recall that new nodes (in this case the one with + // action `a2`) are added such that they are "greater than" (under + // the tree's `<` relation) all those that exist under the given parent. + tree.insert(Execution(), {a1, a3}); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{a1, a3}, + PartialExecution{a1}, PartialExecution{}}); + } + } + + SECTION("Performing Arbitrary Insertions") + { + const auto a0 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a1 = std::make_shared(Transition::Type::UNKNOWN, 4); + const auto a2 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto a3 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto a4 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto a5 = std::make_shared(Transition::Type::UNKNOWN, 4); + WakeupTree tree; + + SECTION("Attempting to insert the empty sequence into an empty tree should have no effect") + { + tree.insert(Execution(), {}); + test_tree_iterator(tree, std::vector{PartialExecution{}}); + } + + SECTION("Attempting to re-insert the same sequence multiple times should have no extra effect") + { + tree.insert(Execution(), {a4}); + tree.insert(Execution(), {a4}); + tree.insert(Execution(), {a4}); + REQUIRE(tree.get_num_nodes() == 2); + test_tree_iterator(tree, std::vector{PartialExecution{a4}, PartialExecution{}}); + } + + SECTION("Attempting to insert an independent sequence same should have no extra effect") + { + // a4 and a1 are independent actions. Intuitively, then, we need only + // search one ordering of the two actions. The wakeup tree handles + // this by computing the `~` relation. The relation itself determines + // whether the `a1` is an initial of `a3`, which it is not. It then + // checks whether `a1` is independent with everything in the sequence + // (in this case, consisting only of `a1`) which IS true. Since `a4` + // is already a leaf node of the tree, it suffices to only have `a4` + // in this tree to guide ODPOR. + tree.insert(Execution(), {a4}); + tree.insert(Execution(), {a1}); + REQUIRE(tree.get_num_nodes() == 2); + test_tree_iterator(tree, std::vector{PartialExecution{a4}, PartialExecution{}}); + } + + SECTION( + "Attempting to insert a progression of executions should have no extra effect when the first process is a leaf") + { + // All progressions starting with `a0` are effectively already accounted + // for by inserting `a0` since we `a0` "can always be made to look like" + // (viz. the `~` relation) `a0.*` where `*` is some sequence of actions + tree.insert(Execution(), {a0}); + tree.insert(Execution(), {a0, a3}); + tree.insert(Execution(), {a0, a3, a2}); + tree.insert(Execution(), {a0, a3, a2, a4}); + tree.insert(Execution(), {a0, a3, a2, a4}); + REQUIRE(tree.get_num_nodes() == 2); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{}}); + } + + SECTION("Stress test with multiple branch points: `~_E` with different looking sequences") + { + // After the insertions below, the tree looks like the following: + // {} + // / / + // a0 a2 + // / | / + // a0 a3 a5 + tree.insert(Execution(), {a0}); + tree.insert(Execution(), {a2, a0}); + tree.insert(Execution(), {a2, a3}); + tree.insert(Execution(), {a2, a5}); + REQUIRE(tree.get_num_nodes() == 6); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{a2, a0}, + PartialExecution{a2, a3}, PartialExecution{a2, a5}, + PartialExecution{a2}, PartialExecution{}}); + SECTION("Adding more stress") + { + // In this case, `a2` and `a1` can be interchanged with each other. + // Thus `a2.a1 == a1.a2`. Since there is already an interior node + // containing `a2`, we attempt to add the what remains (viz. `a1`) to the + // series. HOWEVER: we notice that `a2.a5` is "eventually equivalent to" + // (that is `~` with) `a1.a2` since `a2` is an initial of the latter and + // `a1` and `a5` are independent of each other. + tree.insert(Execution(), {a1, a2}); + REQUIRE(tree.get_num_nodes() == 6); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{a2, a0}, + PartialExecution{a2, a3}, PartialExecution{a2, a5}, + PartialExecution{a2}, PartialExecution{}}); + + // With a3.a0, we notice that starting a sequence with `a3` is + // always different than starting one with either `a0` or + // + // After the insertion, the tree looks like the following: + // {} + // / / / + // a0 a2 a3 + // / | / | + // a0 a3 a5 a0 + tree.insert(Execution(), {a3, a0}); + REQUIRE(tree.get_num_nodes() == 8); + test_tree_iterator(tree, std::vector{PartialExecution{a0}, PartialExecution{a2, a0}, + PartialExecution{a2, a3}, PartialExecution{a2, a5}, + PartialExecution{a2}, PartialExecution{a3, a0}, + PartialExecution{a3}, PartialExecution{}}); + } + } + } + + SECTION("Insertion with more subtle equivalents") + { + const auto cd_1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto i_2 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto i_3 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto d_1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto d_2 = std::make_shared(Transition::Type::UNKNOWN, 2); + WakeupTree complex_tree; + // After the insertions below, the tree looks like the following: + // {} + // / / + // cd_1 i_2 + // / / + // i_2 d_2 + // / / + // d_1 cd_1 + // / / / + // i_3 d_1 i_3 + // / / / + // d_2 i_3 d_2 + // / / / + // d_2 d_2 d_1 + // + // d_1.i_3.d_2 is equivalent to i_3.d_2.d_1 + complex_tree.insert(Execution(), {cd_1, i_2, d_1, i_3, d_2, d_2}); + complex_tree.insert(Execution(), {i_2, d_2, cd_1, d_1, i_3, d_2}); + complex_tree.insert(Execution(), {i_2, d_2, cd_1, i_3, d_2, d_1}); + REQUIRE(complex_tree.get_num_nodes() == 16); + test_tree_iterator(complex_tree, std::vector{{cd_1, i_2, d_1, i_3, d_2, d_2}, + {cd_1, i_2, d_1, i_3, d_2}, + {cd_1, i_2, d_1, i_3}, + {cd_1, i_2, d_1}, + {cd_1, i_2}, + {cd_1}, + {i_2, d_2, cd_1, d_1, i_3, d_2}, + {i_2, d_2, cd_1, d_1, i_3}, + {i_2, d_2, cd_1, d_1}, + {i_2, d_2, cd_1, i_3, d_2, d_1}, + {i_2, d_2, cd_1, i_3, d_2}, + {i_2, d_2, cd_1, i_3}, + {i_2, d_2, cd_1}, + {i_2, d_2}, + {i_2}, + {}}); + // Here we note that the sequence that we are attempting to insert, viz. + // + // i_3.i_2.d_2.cd_1.d_2.d_1 + // + // is already equivalent to + // + // i_2.d_2.cd_1.i_3.d_2.d_1 + complex_tree.insert(Execution(), {i_3, i_2, d_2, cd_1, d_2, d_1}); + REQUIRE(complex_tree.get_num_nodes() == 16); + + // Here we note that the sequence that we are attempting to insert, viz. + // + // i_2.d_2.cd_1.d_1.i_3 + // + // is already equivalent to + // + // i_2.d_2.cd_1.i_3.d_2.d_1 + complex_tree.insert(Execution(), {i_2, d_2, cd_1, d_1, i_3}); + REQUIRE(complex_tree.get_num_nodes() == 16); + + // Here we note that the sequence that we are attempting to insert, viz. + // + // i_2.d_2.cd_1 + // + // is accounted for by an interior node of the tree. Since there is no + // "extra" portions that are different from what is already + // contained in the tree, nothing is added and the tree stays the same + complex_tree.insert(Execution(), {i_2, d_2, cd_1}); + REQUIRE(complex_tree.get_num_nodes() == 16); + } +} \ No newline at end of file diff --git a/src/mc/explo/odpor/odpor_forward.hpp b/src/mc/explo/odpor/odpor_forward.hpp new file mode 100644 index 0000000000..52388bcda1 --- /dev/null +++ b/src/mc/explo/odpor/odpor_forward.hpp @@ -0,0 +1,43 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/** @file odpor_forward.hpp + * + * Forward definitions for MC types specific to ODPOR + */ + +#ifndef SIMGRID_MC_ODPOR_FORWARD_HPP +#define SIMGRID_MC_ODPOR_FORWARD_HPP + +#include "src/mc/mc_forward.hpp" +#include +#include +#include + +namespace simgrid::mc::odpor { + +using PartialExecution = std::list>; + +class Event; +class Execution; +class ReversibleRaceCalculator; +class WakeupTree; +class WakeupTreeNode; +class WakeupTreeIterator; + +} // namespace simgrid::mc::odpor + +namespace simgrid::mc { + +// Permit ODPOR or SDPOR to be used as namespaces +// Many of the structures overlap, so it doesn't +// make sense to some in one and not the other. +// Having one for each algorithm makes the corresponding +// code easier to read +namespace sdpor = simgrid::mc::odpor; + +} // namespace simgrid::mc + +#endif diff --git a/src/mc/explo/odpor/odpor_tests_private.hpp b/src/mc/explo/odpor/odpor_tests_private.hpp new file mode 100644 index 0000000000..cd76ba3ea3 --- /dev/null +++ b/src/mc/explo/odpor/odpor_tests_private.hpp @@ -0,0 +1,51 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/** @file odpor_tests_private.hpp + * + * A private header file for all ODPOR tests + */ + +#ifndef SIMGRID_MC_ODPOR_TEST_PRIVATE_HPP +#define SIMGRID_MC_ODPOR_TEST_PRIVATE_HPP + +#include "src/mc/explo/udpor/udpor_tests_private.hpp" +#include "src/mc/transition/Transition.hpp" + +namespace simgrid::mc::odpor { + +struct DependentIfSameValueAction : public Transition { +private: + const int value; + +public: + DependentIfSameValueAction(Type type, aid_t issuer, int value, int times_considered = 0) + : Transition(type, issuer, times_considered), value(value) + { + } + DependentIfSameValueAction(aid_t issuer, int value, int times_considered = 0) + : Transition(simgrid::mc::Transition::Type::UNKNOWN, issuer, times_considered), value(value) + { + } + + // Dependent only with DependentAction (i.e. not itself) + bool depends(const Transition* other) const override + { + if (aid_ == other->aid_) { + return true; + } + + if (const auto* same_value = dynamic_cast(other); same_value != nullptr) { + return value == same_value->value; + } + + // `DependentAction` is dependent with everyone who's not the `IndependentAction` + return dynamic_cast(other) != nullptr; + } +}; + +} // namespace simgrid::mc::odpor + +#endif diff --git a/src/mc/explo/simgrid_mc.cpp b/src/mc/explo/simgrid_mc.cpp index afd997a249..51871357ee 100644 --- a/src/mc/explo/simgrid_mc.cpp +++ b/src/mc/explo/simgrid_mc.cpp @@ -1,28 +1,27 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "simgrid/sg_config.hpp" -#include "src/internal_config.h" #include "src/mc/explo/Exploration.hpp" #include "src/mc/mc_config.hpp" #include "src/mc/mc_exit.hpp" +#include "src/simgrid/sg_config.hpp" #if HAVE_SMPI #include "smpi/smpi.h" #endif -#include -#include -#include +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(mc); + +using namespace simgrid::mc; int main(int argc, char** argv) { xbt_assert(argc >= 2, "Missing arguments"); // Currently, we need this before sg_config_init: - _sg_do_model_check = 1; + simgrid::mc::set_model_checking_mode(simgrid::mc::ModelCheckingMode::CHECKER_SIDE); // The initialization function can touch argv. // We make a copy of argv before modifying it in order to pass the original value to the model-checked application: @@ -30,32 +29,26 @@ int main(int argc, char** argv) xbt_log_init(&argc, argv); #if HAVE_SMPI - smpi_init_options(); // only performed once + smpi_init_options(); // that's OK to call it twice, and we need it ASAP #endif sg_config_init(&argc, argv); - simgrid::mc::ExplorationAlgorithm algo; + std::unique_ptr explo; + if (_sg_mc_comms_determinism || _sg_mc_send_determinism) - algo = simgrid::mc::ExplorationAlgorithm::CommDeterminism; + explo = std::unique_ptr( + create_communication_determinism_checker(argv_copy, get_model_checking_reduction())); else if (_sg_mc_unfolding_checker) - algo = simgrid::mc::ExplorationAlgorithm::UDPOR; - else if (_sg_mc_property_file.get().empty()) - algo = simgrid::mc::ExplorationAlgorithm::Safety; + explo = std::unique_ptr(create_udpor_checker(argv_copy)); else - algo = simgrid::mc::ExplorationAlgorithm::Liveness; + explo = std::unique_ptr(create_dfs_exploration(argv_copy, get_model_checking_reduction())); - int res = SIMGRID_MC_EXIT_SUCCESS; - std::unique_ptr checker{simgrid::mc::Api::get().initialize(argv_copy.data(), algo)}; + ExitStatus status; try { - checker->run(); - } catch (const simgrid::mc::DeadlockError&) { - res = SIMGRID_MC_EXIT_DEADLOCK; - } catch (const simgrid::mc::TerminationError&) { - res = SIMGRID_MC_EXIT_NON_TERMINATION; - } catch (const simgrid::mc::LivenessError&) { - res = SIMGRID_MC_EXIT_LIVENESS; + explo->run(); + status = ExitStatus::SUCCESS; + } catch (const McError& e) { + status = e.value; } - simgrid::mc::Api::get().s_close(); - checker.release(); // FIXME: this line should not exist, but it segfaults in liveness - return res; + return static_cast(status); } diff --git a/src/mc/explo/udpor/Comb.hpp b/src/mc/explo/udpor/Comb.hpp new file mode 100644 index 0000000000..ab0ec7a08e --- /dev/null +++ b/src/mc/explo/udpor/Comb.hpp @@ -0,0 +1,92 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_UDPOR_COMB_HPP +#define SIMGRID_MC_UDPOR_COMB_HPP + +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" +#include "src/mc/explo/udpor/udpor_forward.hpp" +#include "src/xbt/utils/iter/variable_for_loop.hpp" + +#include +#include +#include +#include + +namespace simgrid::mc::udpor { + +/** + * @brief An individual element of a `Comb`, i.e. a + * sequence of `const UnfoldingEvent*`s + */ +using Spike = std::vector; + +/** + * @brief A two-dimensional data structure that is used + * to compute partial alternatives in UDPOR + * + * The comb data structure is described in the paper + * "Quasi-Optimal DPOR" by Nguyen et al. Formally, + * if `A` is a set: + * + * """ + * An **A-Comb C of size `n` (`n` a natural number)** + * is an *ordered* collection of spikes , + * where each spike is a sequence of elements over A. + * + * Furthermore, a **combination over C** is any tuple + * where a_i is a member of s_i + * """ + * + * The name probably comes from what the structure looks + * like if you draw it out. For example, if `A = {1, 2, 3, ..., 10}`, + * then a possible `A-comb` of size 8 might look like + * + * 1 2 3 4 5 6 + * 2 4 5 9 8 + * 10 9 2 1 1 + * 8 9 10 5 + * 1 + * 3 4 5 + * 1 4 4 5 1 6 + * 8 8 9 + * + * which, if you squint a bit, looks like a comb (albeit with some + * broken bristles [or spikes]). A combination is any selection of + * one element within each spike; e.g. (where _x_ denotes element `x` + * is selected) + * + * 1 2 _3_ 4 5 6 + * 2 _4_ 5 9 8 + * 10 9 2 _1_ 1 + * 8 _9_ 10 5 + * _1_ + * 3 4 _5_ + * 1 _4_ 4 5 1 6 + * _8_ 8 9 + * + * A `Comb` as described by this C++ class is a `U-comb`, where + * `U` is the set of events that UDPOR has explored. That is, + * the comb is over a set of events + */ +class Comb : public std::vector { +public: + explicit Comb(unsigned k) : std::vector(k) {} + Comb(const Comb& other) = default; + Comb(Comb&& other) = default; + Comb& operator=(const Comb& other) = default; + Comb& operator=(Comb&& other) = default; + + auto combinations_begin() const + { + std::vector> references; + std::transform(begin(), end(), std::back_inserter(references), [](const Spike& spike) { return std::cref(spike); }); + return simgrid::xbt::variable_for_loop(std::move(references)); + } + auto combinations_end() const { return simgrid::xbt::variable_for_loop(); } +}; + +} // namespace simgrid::mc::udpor +#endif diff --git a/src/mc/explo/udpor/Configuration.cpp b/src/mc/explo/udpor/Configuration.cpp new file mode 100644 index 0000000000..2dd00cb265 --- /dev/null +++ b/src/mc/explo/udpor/Configuration.cpp @@ -0,0 +1,247 @@ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/udpor/Configuration.hpp" +#include "src/mc/explo/udpor/Comb.hpp" +#include "src/mc/explo/udpor/History.hpp" +#include "src/mc/explo/udpor/Unfolding.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" +#include "src/mc/explo/udpor/maximal_subsets_iterator.hpp" +#include "src/xbt/utils/iter/variable_for_loop.hpp" +#include "xbt/asserts.h" + +#include +#include + +namespace simgrid::mc::udpor { + +Configuration::Configuration(std::initializer_list events) + : Configuration(EventSet(std::move(events))) +{ +} + +Configuration::Configuration(const UnfoldingEvent* e) : Configuration(e->get_local_config()) +{ + // The local configuration should always be a valid configuration. We + // check the invariant regardless as a sanity check +} + +Configuration::Configuration(const History& history) : Configuration(history.get_all_events()) {} + +Configuration::Configuration(const EventSet& events) : events_(events) +{ + if (not events_.is_valid_configuration()) { + throw std::invalid_argument("The events do not form a valid configuration"); + } + + // Since we add in topological order under `<`, we know that the "most-recent" + // transition executed by each actor will appear last + for (const UnfoldingEvent* e : get_topologically_sorted_events()) { + this->latest_event_mapping[e->get_actor()] = e; + } +} + +void Configuration::add_event(const UnfoldingEvent* e) +{ + if (e == nullptr) { + throw std::invalid_argument("Expected a nonnull `UnfoldingEvent*` but received NULL instead"); + } + + // The event is already a member of the configuration: there's + // nothing to do in this case + if (this->events_.contains(e)) { + return; + } + + // Preserves the property that the configuration is conflict-free + if (e->conflicts_with_any(this->events_)) { + throw std::invalid_argument("The newly added event conflicts with the events already " + "contained in the configuration. Adding this event violates " + "the property that a configuration is conflict-free"); + } + + this->events_.insert(e); + this->newest_event = e; + this->latest_event_mapping[e->get_actor()] = e; + + // Preserves the property that the configuration is causally closed + if (auto history = History(e); not this->events_.contains(history)) { + throw std::invalid_argument("The newly added event has dependencies " + "which are missing from this configuration"); + } +} + +bool Configuration::is_compatible_with(const UnfoldingEvent* e) const +{ + // 1. `e`'s history must be contained in the configuration; + // otherwise adding the event would violate the invariant + // that a configuration is causally-closed + // + // 2. `e` itself must not conflict with any events of + // the configuration; otherwise adding the event would + // violate the invariant that a configuration is conflict-free + return contains(e->get_history()) && (not e->conflicts_with_any(this->events_)); +} + +bool Configuration::is_compatible_with(const History& history) const +{ + // Note: We don't need to check if the `C` will be causally-closed + // after adding `history` to it since a) `C` itself is already + // causally-closed and b) the history is already causally closed + const auto event_diff = history.get_event_diff_with(*this); + + // The events that are contained outside of the configuration + // must themselves be free of conflicts. + if (not event_diff.is_conflict_free()) { + return false; + } + + // Now we need only ensure that there are no conflicts + // between events of the configuration and the events + // that lie outside of the configuration. There is no + // need to check if there are conflicts in `C`: we already + // know that it's conflict free + const auto begin = simgrid::xbt::variable_for_loop{{event_diff}, {this->events_}}; + const auto end = simgrid::xbt::variable_for_loop(); + return std::none_of(begin, end, [=](const auto event_pair) { + const UnfoldingEvent* e1 = *event_pair[0]; + const UnfoldingEvent* e2 = *event_pair[1]; + return e1->conflicts_with(e2); + }); +} + +std::vector Configuration::get_topologically_sorted_events() const +{ + return this->events_.get_topological_ordering(); +} + +std::vector Configuration::get_topologically_sorted_events_of_reverse_graph() const +{ + return this->events_.get_topological_ordering_of_reverse_graph(); +} + +EventSet Configuration::get_minimally_reproducible_events() const +{ + // The implementation exploits the following observations: + // + // To select the smallest reproducible set of events, we want + // to pick events that "knock out" a lot of others. Furthermore, + // we need to ensure that the events furthest down in the + // causality graph are also selected. If you combine these ideas, + // you're basically left with traversing the set of maximal + // subsets of C! And we have an iterator for that already! + // + // The next observation is that the moment we don't increase in size + // the current maximal set (or decrease the number of events), + // we know that the prior set `S` covered the entire history of C and + // was maximal. Subsequent sets will miss events earlier in the + // topological ordering that appear in `S` + EventSet minimally_reproducible_events; + + for (const auto& maximal_set : maximal_subsets_iterator_wrapper(*this)) { + if (maximal_set.size() > minimally_reproducible_events.size()) { + minimally_reproducible_events = maximal_set; + } else { + // The moment we see the iterator generate a set of size + // that is not monotonically increasing, we can stop: + // the set prior was the minimally-reproducible one + return minimally_reproducible_events; + } + } + return minimally_reproducible_events; +} + +std::optional Configuration::compute_alternative_to(const EventSet& D, const Unfolding& U) const +{ + // A full alternative can be computed by checking against everything in D + return compute_k_partial_alternative_to(D, U, D.size()); +} + +std::optional Configuration::compute_k_partial_alternative_to(const EventSet& D, const Unfolding& U, + size_t k) const +{ + // 1. Select k (of |D|, whichever is smaller) arbitrary events e_1, ..., e_k from D + const size_t k_alt_size = std::min(k, D.size()); + const auto D_hat = [&k_alt_size, &D]() { + std::vector D_hat(k_alt_size); + // TODO: Since any subset suffices for computing `k`-partial alternatives, + // potentially select intelligently here (e.g. perhaps pick events + // with transitions that we know are totally independent). This may be + // especially important if the enumeration is the slowest part of + // UDPOR + // + // For now, simply pick the first `k` events + std::copy_n(D.begin(), k_alt_size, D_hat.begin()); + return D_hat; + }(); + + // 2. Build a U-comb of size k, where spike `s_i` contains + // all events in conflict with `e_i` + // + // 3. EXCEPT those events e' for which [e'] + C is not a configuration or + // [e'] intersects D + // + // NOTE: This is an expensive operation as we must traverse the entire unfolding + // and compute `C.is_compatible_with(History)` for every event in the structure :/. + // A later performance improvement would be to incorporate the work of Nguyen et al. + // into SimGrid which associated additonal data structures with each unfolding event. + // Since that is a rather complicated addition, we defer it to a later time... + Comb comb(k); + + for (const auto* e : U) { + for (size_t i = 0; i < k_alt_size; i++) { + const UnfoldingEvent* e_i = D_hat[i]; + if (const auto e_local_config = History(e); + e_i->conflicts_with(e) and (not D.intersects(e_local_config)) and is_compatible_with(e_local_config)) { + comb[i].push_back(e); + } + } + } + + // 4. Find any such combination in comb satisfying + // ~(e_i' # e_j') for i != j + // + // NOTE: This is a VERY expensive operation: it enumerates all possible + // ways to select an element from each spike. Unfortunately there's no + // way around the enumeration, as computing a full alternative in general is + // NP-complete (although computing the k-partial alternative is polynomial in + // the number of events) + const auto map_events = [](const std::vector& spikes) { + std::vector events; + for (const auto& event_in_spike : spikes) { + events.push_back(*event_in_spike); + } + return EventSet(events); + }; + const auto alternative = + std::find_if(comb.combinations_begin(), comb.combinations_end(), + [&map_events](const auto& vector) { return map_events(vector).is_conflict_free(); }); + + // No such alternative exists + if (alternative == comb.combinations_end()) { + return std::nullopt; + } + + // 5. J := [e_1] + [e_2] + ... + [e_k] is a k-partial alternative + return Configuration(History(map_events(*alternative))); +} + +std::optional Configuration::get_latest_event_of(aid_t aid) const +{ + if (const auto latest_event = latest_event_mapping.find(aid); latest_event != latest_event_mapping.end()) { + return std::optional{latest_event->second}; + } + return std::nullopt; +} + +std::optional Configuration::get_latest_action_of(aid_t aid) const +{ + if (const auto latest_event = get_latest_event_of(aid); latest_event.has_value()) { + return std::optional{latest_event.value()->get_transition()}; + } + return std::nullopt; +} + +} // namespace simgrid::mc::udpor diff --git a/src/mc/explo/udpor/Configuration.hpp b/src/mc/explo/udpor/Configuration.hpp new file mode 100644 index 0000000000..b1f6f933d2 --- /dev/null +++ b/src/mc/explo/udpor/Configuration.hpp @@ -0,0 +1,219 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_UDPOR_CONFIGURATION_HPP +#define SIMGRID_MC_UDPOR_CONFIGURATION_HPP + +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/udpor_forward.hpp" + +#include +#include +#include + +namespace simgrid::mc::udpor { + +class Configuration { +public: + Configuration() = default; + Configuration(const Configuration&) = default; + Configuration& operator=(Configuration const&) = default; + Configuration(Configuration&&) = default; + + explicit Configuration(const UnfoldingEvent* event); + explicit Configuration(const EventSet& events); + explicit Configuration(const History& history); + explicit Configuration(std::initializer_list events); + + auto begin() const { return this->events_.begin(); } + auto end() const { return this->events_.end(); } + auto cbegin() const { return this->events_.cbegin(); } + auto cend() const { return this->events_.cend(); } + + bool contains(const UnfoldingEvent* e) const { return this->events_.contains(e); } + bool contains(const EventSet& events) const { return events.is_subset_of(this->events_); } + const EventSet& get_events() const { return this->events_; } + const UnfoldingEvent* get_latest_event() const { return this->newest_event; } + std::string to_string() const { return this->events_.to_string(); } + + /** + * @brief Insert a new event into the configuration + * + * When the newly added event is inserted into the configuration, + * an assertion is made to ensure that the configuration remains + * valid, i.e. that the newly added event's dependencies are contained + * within the configuration. + * + * @param e the event to add to the configuration. If the event is + * already a part of the configuration, calling this method has no + * effect. + * + * @throws an invalid argument exception is raised should the event + * be missing one of its dependencies + * + * @note: UDPOR technically enforces the invariant that all newly-added events + * will ensure that the configuration is valid. We perform extra checks to ensure + * that UDPOR is implemented as expected. There is a performance penalty that + * should be noted: checking for maximality requires ensuring that all events in the + * configuration have their dependencies containes within the configuration, which + * essentially means performing a BFS/DFS over the configuration using a History object. + * However, since the slowest part of UDPOR involves enumerating all + * subsets of maximal events and computing k-partial alternatives (the + * latter definitively an NP-hard problem when optimal), Amdahl's law suggests + * we shouldn't focus so much on this (let alone the additional benefit of the + * assertions) + */ + void add_event(const UnfoldingEvent* e); + + /** + * @brief Whether or not the given event can be added to + * this configuration while preserving that the configuration + * is causally closed and conflict-free + * + * A configuration `C` is compatible with an event iff + * the event can be added to `C` while preserving that + * the configuration is causally closed and conflict-free. + * + * The method effectively answers the following question: + * + * "Is `C + {e}` a valid configuration?" + */ + bool is_compatible_with(const UnfoldingEvent* e) const; + + /** + * @brief Whether or not the events in the given history can be added to + * this configuration while keeping the set of events causally closed + * and conflict-free + * + * A configuration `C` is compatible with a history iff all + * events of the history can be added to `C` while preserving + * that the configuration is causally closed and conflict-free. + * + * The method effectively answers the following question: + * + * "Is `C + (U_i [e_i])` a valid configuration?" + */ + bool is_compatible_with(const History& history) const; + + std::optional compute_alternative_to(const EventSet& D, const Unfolding& U) const; + std::optional compute_k_partial_alternative_to(const EventSet& D, const Unfolding& U, size_t k) const; + + /** + * @brief Orders the events of the configuration such that + * "more recent" events (i.e. those that are farther down in + * the event structure's dependency chain) come after those + * that appeared "farther in the past" + * + * @returns a vector `V` with the following property: + * + * 1. Let i(e) := C -> I map events to their indices in `V`. + * For every pair of events e, e' in C, if e < e' then i(e) < i(e') + * + * Intuitively, events that are closer to the "bottom" of the event + * structure appear farther along in the list than those that appear + * closer to the "top" + */ + std::vector get_topologically_sorted_events() const; + + /** + * @brief Orders the events of the configuration such that + * "more recent" events (i.e. those that are farther down in + * the event structure's dependency chain) come before those + * that appear "farther in the past" + * + * @note The events of the event structure are arranged such that + * e < e' implies a directed edge from e to e'. However, it is + * also useful to be able to traverse the *reverse* graph (for + * example when computing the compatibility graph of a configuration), + * hence the distinction between "reversed" and the method + * "Configuration::get_topologically_sorted_events()" + * + * @returns a vector `V` with the following property: + * + * 1. Let i(e) := C -> I map events to their indices in `V`. + * For every pair of events e, e' in C, if e < e' then i(e) > i(e') + * + * Intuitively, events that are closer to the "top" of the event + * structure appear farther along in the list than those that appear + * closer to the "bottom" + */ + std::vector get_topologically_sorted_events_of_reverse_graph() const; + + /** + * @brief Computes the smallest set of events whose collective histories + * capture all events of this configuration + * + * @invariant The set of all events in the collective histories + * of the events returned by this method is equal to the set of events + * in this configuration + * + * @returns the smallest set of events whose events generates + * this configuration (denoted `config(E)`) + */ + EventSet get_minimally_reproducible_events() const; + + /** + * @brief Determines the event in the configuration whose associated + * transition is the latest of the given actor + * + * @invariant: At most one event in the configuration will correspond + * to `preEvt(C, a)` for any action `a`. This can be argued by contradiction. + * + * If there were more than one event (`e` and `e'`) in any configuration whose + * associated transitions `a` were run by the same actor at the same step, then they + * could not be causally related (`<`) since `a` could not be enabled in + * both subconfigurations C' and C'' containing the hypothetical events + * `e` and `e` + `e'`. Since they would not be contained in each other's histories, + * they would be in conflict, which cannot happen between any pair of events + * in a configuration. Thus `e` and `e'` cannot exist simultaneously + */ + std::optional get_latest_event_of(aid_t) const; + /** + * @brief Determines the most recent transition of the given actor + * in this configuration, or `pre(a)` as denoted in the thesis of + * The Anh Pham + * + * Conceptually, the execution of an interleaving of the transitions + * (i.e. a topological ordering) of a configuration yields a unique + * state `state(C)`. Since actions taken by the same actor are always + * dependent with one another, any such interleaving always yields a + * unique + * + * @returns the most recent transition of the given actor + * in this configuration, or `std::nullopt` if there are no transitions + * in this configuration run by the given actor + */ + std::optional get_latest_action_of(aid_t aid) const; + std::optional pre_event(aid_t aid) const { return get_latest_event_of(aid); } + +private: + /** + * @brief The most recent event added to the configuration + */ + const UnfoldingEvent* newest_event = nullptr; + + /** + * @brief The events which make up this configuration + * + * @invariant For each event `e` in `events_`, the set of + * dependencies of `e` is also contained in `events_` + * + * @invariant For each pair of events `e` and `e'` in + * `events_`, `e` and `e'` are not in conflict + */ + EventSet events_; + + /** + * @brief Maps actors to the latest events which + * are executed by the actor + * + * @invariant: The events that are contained in the map + * are also contained in the set `events_` + */ + std::unordered_map latest_event_mapping; +}; + +} // namespace simgrid::mc::udpor +#endif diff --git a/src/mc/explo/udpor/Configuration_test.cpp b/src/mc/explo/udpor/Configuration_test.cpp new file mode 100644 index 0000000000..a20f38214d --- /dev/null +++ b/src/mc/explo/udpor/Configuration_test.cpp @@ -0,0 +1,1367 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/udpor/Configuration.hpp" +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/History.hpp" +#include "src/mc/explo/udpor/Unfolding.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" +#include "src/mc/explo/udpor/maximal_subsets_iterator.hpp" +#include "src/mc/explo/udpor/udpor_tests_private.hpp" + +#include + +using namespace simgrid::mc; +using namespace simgrid::mc::udpor; + +TEST_CASE("simgrid::mc::udpor::Configuration: Constructing Configurations") +{ + // The following tests concern the given event structure: + // e1 + // / + // e2 + // / + // e3 + // / / + // e4 e5 + UnfoldingEvent e1(EventSet(), std::make_shared(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(1)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(2)); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared(3)); + UnfoldingEvent e5(EventSet({&e3}), std::make_shared(4)); + + SECTION("Creating a configuration without events") + { + Configuration C; + REQUIRE(C.get_events().empty()); + REQUIRE(C.get_latest_event() == nullptr); + } + + SECTION("Creating a configuration with events (test violation of being causally closed)") + { + // 5 choose 0 = 1 test + REQUIRE_NOTHROW(Configuration({&e1})); + + // 5 choose 1 = 5 tests + REQUIRE_THROWS_AS(Configuration({&e2}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e3}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e4}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e5}), std::invalid_argument); + + // 5 choose 2 = 10 tests + REQUIRE_NOTHROW(Configuration({&e1, &e2})); + REQUIRE_THROWS_AS(Configuration({&e1, &e3}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e1, &e4}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e1, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e2, &e3}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e2, &e4}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e2, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e3, &e4}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e3, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e4, &e5}), std::invalid_argument); + + // 5 choose 3 = 10 tests + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3})); + REQUIRE_THROWS_AS(Configuration({&e1, &e2, &e4}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e1, &e2, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e1, &e3, &e4}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e1, &e3, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e1, &e4, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e2, &e3, &e4}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e2, &e3, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e2, &e4, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e3, &e4, &e5}), std::invalid_argument); + + // 5 choose 4 = 5 tests + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3, &e4})); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3, &e5})); + REQUIRE_THROWS_AS(Configuration({&e1, &e2, &e4, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e1, &e3, &e4, &e5}), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e2, &e3, &e4, &e5}), std::invalid_argument); + + // 5 choose 5 = 1 test + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3, &e4, &e5})); + } +} + +TEST_CASE("simgrid::mc::udpor::Configuration: Adding Events") +{ + // The following tests concern the given event structure: + // e1 + // / + // e2 + // / + // / / + // e3 e4 + UnfoldingEvent e1(EventSet(), std::make_shared(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(1)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(2)); + UnfoldingEvent e4(EventSet({&e2}), std::make_shared(3)); + + REQUIRE_THROWS_AS(Configuration().add_event(nullptr), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration().add_event(&e2), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration().add_event(&e3), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration().add_event(&e4), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e1}).add_event(&e3), std::invalid_argument); + REQUIRE_THROWS_AS(Configuration({&e1}).add_event(&e4), std::invalid_argument); + + REQUIRE_NOTHROW(Configuration().add_event(&e1)); + REQUIRE_NOTHROW(Configuration({&e1}).add_event(&e1)); + REQUIRE_NOTHROW(Configuration({&e1}).add_event(&e2)); + REQUIRE_NOTHROW(Configuration({&e1, &e2}).add_event(&e1)); + REQUIRE_NOTHROW(Configuration({&e1, &e2}).add_event(&e2)); + REQUIRE_NOTHROW(Configuration({&e1, &e2}).add_event(&e3)); + REQUIRE_NOTHROW(Configuration({&e1, &e2}).add_event(&e4)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3}).add_event(&e1)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3}).add_event(&e2)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3}).add_event(&e3)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3}).add_event(&e4)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e4}).add_event(&e1)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e4}).add_event(&e2)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e4}).add_event(&e3)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e4}).add_event(&e4)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3, &e4}).add_event(&e1)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3, &e4}).add_event(&e2)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3, &e4}).add_event(&e3)); + REQUIRE_NOTHROW(Configuration({&e1, &e2, &e3, &e4}).add_event(&e4)); +} + +TEST_CASE("simgrid::mc::udpor::Configuration: Topological Sort Order") +{ + // The following tests concern the given event structure: + // e1 + // / + // e2 + // / + // e3 + // / + // e4 + UnfoldingEvent e1(EventSet(), std::make_shared(1)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(2)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(3)); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared(4)); + + SECTION("Topological ordering for entire set") + { + Configuration C{&e1, &e2, &e3, &e4}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3, &e4}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e4, &e3, &e2, &e1}); + } + + SECTION("Topological ordering for subsets") + { + SECTION("No elements") + { + Configuration C; + REQUIRE(C.get_topologically_sorted_events() == std::vector{}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == std::vector{}); + } + + SECTION("e1 only") + { + Configuration C{&e1}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == std::vector{&e1}); + } + + SECTION("e1 and e2 only") + { + Configuration C{&e1, &e2}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1, &e2}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == std::vector{&e2, &e1}); + } + + SECTION("e1, e2, and e3 only") + { + Configuration C{&e1, &e2, &e3}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e3, &e2, &e1}); + } + } +} + +TEST_CASE("simgrid::mc::udpor::Configuration: Topological Sort Order More Complicated") +{ + // The following tests concern the given event structure: + // e1 + // / + // e2 + // / + // e3 + // / / + // e4 e6 + // / + // e5 + UnfoldingEvent e1(EventSet(), std::make_shared(1)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(2)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(3)); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared(4)); + UnfoldingEvent e5(EventSet({&e4}), std::make_shared(5)); + UnfoldingEvent e6(EventSet({&e3}), std::make_shared(6)); + + SECTION("Topological ordering for subsets") + { + SECTION("No elements") + { + Configuration C; + REQUIRE(C.get_topologically_sorted_events() == std::vector{}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == std::vector{}); + } + + SECTION("e1 only") + { + Configuration C{&e1}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == std::vector{&e1}); + } + + SECTION("e1 and e2 only") + { + Configuration C{&e1, &e2}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1, &e2}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == std::vector{&e2, &e1}); + } + + SECTION("e1, e2, and e3 only") + { + Configuration C{&e1, &e2, &e3}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e3, &e2, &e1}); + } + + SECTION("e1, e2, e3, and e6 only") + { + Configuration C{&e1, &e2, &e3, &e6}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3, &e6}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e6, &e3, &e2, &e1}); + } + + SECTION("e1, e2, e3, and e4 only") + { + Configuration C{&e1, &e2, &e3, &e4}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3, &e4}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e4, &e3, &e2, &e1}); + } + + SECTION("e1, e2, e3, e4, and e5 only") + { + Configuration C{&e1, &e2, &e3, &e4, &e5}; + REQUIRE(C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3, &e4, &e5}); + REQUIRE(C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e5, &e4, &e3, &e2, &e1}); + } + + SECTION("e1, e2, e3, e4 and e6 only") + { + // In this case, e4 and e6 are interchangeable. Hence, we have to check + // if the sorting gives us *any* of the combinations + Configuration C{&e1, &e2, &e3, &e4, &e6}; + REQUIRE((C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3, &e4, &e6} || + C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3, &e6, &e4})); + REQUIRE((C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e6, &e4, &e3, &e2, &e1} || + C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e4, &e6, &e3, &e2, &e1})); + } + + SECTION("Topological ordering for entire set") + { + // In this case, e4/e5 are both interchangeable with e6. Hence, again we have to check + // if the sorting gives us *any* of the combinations + Configuration C{&e1, &e2, &e3, &e4, &e5, &e6}; + REQUIRE( + (C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3, &e4, &e5, &e6} || + C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3, &e4, &e6, &e5} || + C.get_topologically_sorted_events() == std::vector{&e1, &e2, &e3, &e6, &e4, &e5})); + REQUIRE((C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e6, &e5, &e4, &e3, &e2, &e1} || + C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e5, &e6, &e4, &e3, &e2, &e1} || + C.get_topologically_sorted_events_of_reverse_graph() == + std::vector{&e5, &e4, &e6, &e3, &e2, &e1})); + } + } +} + +TEST_CASE("simgrid::mc::udpor::Configuration: Topological Sort Order Very Complicated") +{ + // The following tests concern the given event structure: + // e1 + // / / + // e2 e8 + // / / / / + // e3 / / / + // / / / e11 + // e4 e6 e7 + // / / / / + // e5 e9 e10 + // / / / + // / / / + // [ e12 ] + UnfoldingEvent e1(EventSet(), std::make_shared(1)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(2)); + UnfoldingEvent e8(EventSet({&e1}), std::make_shared(3)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(4)); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared(5)); + UnfoldingEvent e5(EventSet({&e4}), std::make_shared(6)); + UnfoldingEvent e6(EventSet({&e4}), std::make_shared(7)); + UnfoldingEvent e7(EventSet({&e2, &e8}), std::make_shared(8)); + UnfoldingEvent e9(EventSet({&e6, &e7}), std::make_shared(9)); + UnfoldingEvent e10(EventSet({&e7}), std::make_shared(10)); + UnfoldingEvent e11(EventSet({&e8}), std::make_shared(11)); + UnfoldingEvent e12(EventSet({&e5, &e9, &e10}), std::make_shared(12)); + Configuration C{&e1, &e2, &e3, &e4, &e5, &e6, &e7, &e8, &e9, &e10, &e11, &e12}; + + SECTION("Test every combination of the maximal configuration (forward graph)") + { + // To test this, we ensure that for the `i`th event + // in `ordered_events`, each event in `ordered_events[0...(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(1)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(2)); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared(3)); + UnfoldingEvent e5(EventSet({&e1}), std::make_shared(4)); + UnfoldingEvent e6(EventSet({&e5}), std::make_shared(5)); + UnfoldingEvent e7(EventSet({&e6}), std::make_shared(6)); + UnfoldingEvent e8(EventSet({&e6}), std::make_shared(7)); + + SECTION("Iteration over an empty configuration yields only the empty set") + { + Configuration C; + maximal_subsets_iterator first(C); + maximal_subsets_iterator last; + + REQUIRE(*first == EventSet()); + ++first; + REQUIRE(first == last); + } + + SECTION("Check counts of maximal event sets discovered") + { + std::unordered_map maximal_subset_counts; + + Configuration C{&e1, &e2, &e3, &e4, &e5, &e6, &e7, &e8}; + maximal_subsets_iterator first(C); + maximal_subsets_iterator last; + + for (; first != last; ++first) { + maximal_subset_counts[(*first).size()]++; + } + + // First, ensure that there are only sets of size 0, 1, 2, and 3 + CHECK(maximal_subset_counts.size() == 4); + + // The empty set should appear only once + REQUIRE(maximal_subset_counts[0] == 1); + + // 8 is the number of nodes in the graph + REQUIRE(maximal_subset_counts[1] == 8); + + // 13 = 3 * 4 (each of the left branch can combine with one in the right branch) + 1 (e7 + e8) + REQUIRE(maximal_subset_counts[2] == 13); + + // e7 + e8 must be included, so that means we can combine from the left branch + REQUIRE(maximal_subset_counts[3] == 3); + } + + SECTION("Check counts of maximal event sets discovered with a filter") + { + std::unordered_map maximal_subset_counts; + + Configuration C{&e1, &e2, &e3, &e4, &e5, &e6, &e7, &e8}; + + SECTION("Filter with events part of initial maximal set") + { + EventSet interesting_bunch{&e2, &e4, &e7, &e8}; + + maximal_subsets_iterator first( + C, [&interesting_bunch](const UnfoldingEvent* e) { return interesting_bunch.contains(e); }); + maximal_subsets_iterator last; + + for (; first != last; ++first) { + const auto& event_set = *first; + // Only events in `interesting_bunch` can appear: thus no set + // should include anything else other than `interesting_bunch` + REQUIRE(event_set.is_subset_of(interesting_bunch)); + REQUIRE(event_set.is_maximal()); + maximal_subset_counts[event_set.size()]++; + } + + // The empty set should (still) appear only once + REQUIRE(maximal_subset_counts[0] == 1); + + // 4 is the number of nodes in the `interesting_bunch` + REQUIRE(maximal_subset_counts[1] == 4); + + // 5 = 2 * 2 (each of the left branch can combine with one in the right branch) + 1 (e7 + e8) + REQUIRE(maximal_subset_counts[2] == 5); + + // e7 + e8 must be included, so that means we can combine from the left branch (only e2 and e4) + REQUIRE(maximal_subset_counts[3] == 2); + + // There are no subsets of size 4 (or higher, but that + // is tested by asserting each maximal set traversed is a subset) + REQUIRE(maximal_subset_counts[4] == 0); + } + + SECTION("Filter with interesting subset not initially part of the maximal set") + { + EventSet interesting_bunch{&e3, &e5, &e6}; + + maximal_subsets_iterator first( + C, [&interesting_bunch](const UnfoldingEvent* e) { return interesting_bunch.contains(e); }); + maximal_subsets_iterator last; + + for (; first != last; ++first) { + const auto& event_set = *first; + // Only events in `interesting_bunch` can appear: thus no set + // should include anything else other than `interesting_bunch` + REQUIRE(event_set.is_subset_of(interesting_bunch)); + REQUIRE(event_set.is_maximal()); + maximal_subset_counts[event_set.size()]++; + } + + // The empty set should (still) appear only once + REQUIRE(maximal_subset_counts[0] == 1); + + // 3 is the number of nodes in the `interesting_bunch` + REQUIRE(maximal_subset_counts[1] == 3); + + // 2 = e3, e5 and e3, e6 + REQUIRE(maximal_subset_counts[2] == 2); + + // There are no subsets of size 3 (or higher, but that + // is tested by asserting each maximal set traversed is a subset) + REQUIRE(maximal_subset_counts[3] == 0); + } + } +} + +TEST_CASE("simgrid::mc::udpor::maximal_subsets_iterator: Stress Test for Maximal Subsets Iteration") +{ + // The following tests concern the given event structure: + // e1 + // / / + // e2 e3 + // / / / / + // +------* e4 *e5 e6 e7 + // | / /// / / + // | e8 e9 e10 + // | / / /\ / + // | e11 e12 e13 e14 e15 + // | / / / / / / + // +-> e16 e17 e18 + UnfoldingEvent e1(EventSet(), std::make_shared(1)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(2)); + UnfoldingEvent e3(EventSet({&e1}), std::make_shared(3)); + UnfoldingEvent e4(EventSet({&e2}), std::make_shared(4)); + UnfoldingEvent e5(EventSet({&e2}), std::make_shared(5)); + UnfoldingEvent e6(EventSet({&e3}), std::make_shared(6)); + UnfoldingEvent e7(EventSet({&e3}), std::make_shared(7)); + UnfoldingEvent e8(EventSet({&e4}), std::make_shared(8)); + UnfoldingEvent e9(EventSet({&e4, &e5, &e6}), std::make_shared(9)); + UnfoldingEvent e10(EventSet({&e6, &e7}), std::make_shared(10)); + UnfoldingEvent e11(EventSet({&e8}), std::make_shared(11)); + UnfoldingEvent e12(EventSet({&e8}), std::make_shared(12)); + UnfoldingEvent e13(EventSet({&e9}), std::make_shared(13)); + UnfoldingEvent e14(EventSet({&e9}), std::make_shared(14)); + UnfoldingEvent e15(EventSet({&e10}), std::make_shared(15)); + UnfoldingEvent e16(EventSet({&e5, &e11}), std::make_shared(16)); + UnfoldingEvent e17(EventSet({&e12, &e13, &e14}), std::make_shared(17)); + UnfoldingEvent e18(EventSet({&e14, &e15}), std::make_shared(18)); + Configuration C{&e1, &e2, &e3, &e4, &e5, &e6, &e7, &e8, &e9, &e10, &e11, &e12, &e13, &e14, &e15, &e16, &e17, &e18}; + + SECTION("Every subset iterated over is maximal") + { + maximal_subsets_iterator first(C); + maximal_subsets_iterator last; + + // Make sure we actually have something to iterate over + REQUIRE(first != last); + + for (; first != last; ++first) { + REQUIRE((*first).size() <= C.get_events().size()); + REQUIRE((*first).is_maximal()); + } + } + + SECTION("Test that the maximal set ordering is equivalent to that of the configuration's events") + { + maximal_subsets_iterator first_config(C); + maximal_subsets_iterator first_events(C.get_events()); + maximal_subsets_iterator last; + + // Make sure we actually have something to iterate over + REQUIRE(first_config != last); + REQUIRE(first_config == first_events); + REQUIRE(first_events != last); + + for (; first_config != last; ++first_config, ++first_events) { + // first_events and first_config should always be at the same location + REQUIRE(first_events != last); + const auto& first_config_set = *first_config; + const auto& first_events_set = *first_events; + + REQUIRE(first_config_set.size() <= C.get_events().size()); + REQUIRE(first_config_set.is_maximal()); + REQUIRE(first_events_set == first_config_set); + } + + // Iteration with events directly should now also be finished + REQUIRE(first_events == last); + } +} + +TEST_CASE("simgrid::mc::udpor::Configuration: Latest Transitions") +{ + // The following tests concern the given event structure (labeled as "event(actor)") + // e1(1) + // / / + // e2(1) e3(2) + // / // / + // e4(3) e5(2) e6(1) + // / / + // e7(1) e8(1) + const auto t1 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto t2 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto t3 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto t4 = std::make_shared(Transition::Type::UNKNOWN, 3); + const auto t5 = std::make_shared(Transition::Type::UNKNOWN, 2); + const auto t6 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto t7 = std::make_shared(Transition::Type::UNKNOWN, 1); + const auto t8 = std::make_shared(Transition::Type::UNKNOWN, 1); + + const UnfoldingEvent e1(EventSet(), t1); + const UnfoldingEvent e2(EventSet({&e1}), t2); + const UnfoldingEvent e3(EventSet({&e1}), t3); + const UnfoldingEvent e4(EventSet({&e2}), t4); + const UnfoldingEvent e5(EventSet({&e2, &e3}), t5); + const UnfoldingEvent e6(EventSet({&e3}), t6); + const UnfoldingEvent e7(EventSet({&e5}), t7); + const UnfoldingEvent e8(EventSet({&e5}), t8); + + SECTION("Test that the latest events are correct on initialization") + { + SECTION("Empty configuration has no events") + { + Configuration C; + REQUIRE_FALSE(C.get_latest_event_of(1).has_value()); + REQUIRE_FALSE(C.get_latest_event_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_event_of(3).has_value()); + + REQUIRE_FALSE(C.get_latest_action_of(1).has_value()); + REQUIRE_FALSE(C.get_latest_action_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_action_of(3).has_value()); + } + + SECTION("Missing two actors") + { + Configuration C{&e1}; + REQUIRE(C.get_latest_event_of(1).has_value()); + REQUIRE(C.get_latest_event_of(1).value() == &e1); + + REQUIRE_FALSE(C.get_latest_event_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_event_of(3).has_value()); + + REQUIRE(C.get_latest_action_of(1).has_value()); + REQUIRE(C.get_latest_action_of(1).value() == t1.get()); + + REQUIRE_FALSE(C.get_latest_action_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_action_of(3).has_value()); + } + + SECTION("Two events with one actor yields the latest event") + { + Configuration C{&e1, &e2}; + REQUIRE(C.get_latest_event_of(1).has_value()); + REQUIRE(C.get_latest_event_of(1).value() == &e2); + + REQUIRE_FALSE(C.get_latest_event_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_event_of(3).has_value()); + + REQUIRE(C.get_latest_action_of(1).has_value()); + REQUIRE(C.get_latest_action_of(1).value() == t2.get()); + + REQUIRE_FALSE(C.get_latest_action_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_action_of(3).has_value()); + } + + SECTION("Two events with two actors") + { + Configuration C{&e1, &e3}; + REQUIRE(C.get_latest_event_of(1).has_value()); + REQUIRE(C.get_latest_event_of(1).value() == &e1); + + REQUIRE(C.get_latest_event_of(2).has_value()); + REQUIRE(C.get_latest_event_of(2).value() == &e3); + + REQUIRE_FALSE(C.get_latest_event_of(3).has_value()); + + REQUIRE(C.get_latest_action_of(1).has_value()); + REQUIRE(C.get_latest_action_of(1).value() == t1.get()); + + REQUIRE(C.get_latest_action_of(2).has_value()); + REQUIRE(C.get_latest_action_of(2).value() == t3.get()); + + REQUIRE_FALSE(C.get_latest_action_of(3).has_value()); + } + + SECTION("Three different actors actors") + { + Configuration C{&e1, &e2, &e3, &e4, &e5}; + REQUIRE(C.get_latest_event_of(1).has_value()); + REQUIRE(C.get_latest_event_of(1).value() == &e2); + + REQUIRE(C.get_latest_event_of(2).has_value()); + REQUIRE(C.get_latest_event_of(2).value() == &e5); + + REQUIRE(C.get_latest_event_of(3).has_value()); + REQUIRE(C.get_latest_event_of(3).value() == &e4); + + REQUIRE(C.get_latest_action_of(1).has_value()); + REQUIRE(C.get_latest_action_of(1).value() == t2.get()); + + REQUIRE(C.get_latest_action_of(2).has_value()); + REQUIRE(C.get_latest_action_of(2).value() == t5.get()); + + REQUIRE(C.get_latest_action_of(3).has_value()); + REQUIRE(C.get_latest_action_of(3).value() == t4.get()); + } + } + + SECTION("Test that the latest events are correct when adding new events") + { + Configuration C; + REQUIRE_FALSE(C.get_latest_event_of(1).has_value()); + REQUIRE_FALSE(C.get_latest_event_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_event_of(3).has_value()); + REQUIRE_FALSE(C.get_latest_action_of(1).has_value()); + REQUIRE_FALSE(C.get_latest_action_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_action_of(3).has_value()); + + C.add_event(&e1); + REQUIRE(C.get_latest_event_of(1).has_value()); + REQUIRE(C.get_latest_event_of(1).value() == &e1); + REQUIRE_FALSE(C.get_latest_event_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_event_of(3).has_value()); + REQUIRE(C.get_latest_action_of(1).has_value()); + REQUIRE(C.get_latest_action_of(1).value() == t1.get()); + REQUIRE_FALSE(C.get_latest_action_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_action_of(3).has_value()); + + C.add_event(&e2); + REQUIRE(C.get_latest_event_of(1).has_value()); + REQUIRE(C.get_latest_event_of(1).value() == &e2); + REQUIRE_FALSE(C.get_latest_event_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_event_of(3).has_value()); + REQUIRE(C.get_latest_action_of(1).has_value()); + REQUIRE(C.get_latest_action_of(1).value() == t2.get()); + REQUIRE_FALSE(C.get_latest_action_of(2).has_value()); + REQUIRE_FALSE(C.get_latest_action_of(3).has_value()); + + C.add_event(&e3); + REQUIRE(C.get_latest_event_of(1).has_value()); + REQUIRE(C.get_latest_event_of(1).value() == &e2); + REQUIRE(C.get_latest_event_of(2).has_value()); + REQUIRE(C.get_latest_event_of(2).value() == &e3); + REQUIRE_FALSE(C.get_latest_event_of(3).has_value()); + REQUIRE(C.get_latest_action_of(1).has_value()); + REQUIRE(C.get_latest_action_of(1).value() == t2.get()); + REQUIRE(C.get_latest_action_of(2).has_value()); + REQUIRE(C.get_latest_action_of(2).value() == t3.get()); + REQUIRE_FALSE(C.get_latest_action_of(3).has_value()); + + C.add_event(&e4); + REQUIRE(C.get_latest_event_of(1).has_value()); + REQUIRE(C.get_latest_event_of(1).value() == &e2); + REQUIRE(C.get_latest_event_of(2).has_value()); + REQUIRE(C.get_latest_event_of(2).value() == &e3); + REQUIRE(C.get_latest_event_of(3).has_value()); + REQUIRE(C.get_latest_event_of(3).value() == &e4); + REQUIRE(C.get_latest_action_of(1).has_value()); + REQUIRE(C.get_latest_action_of(1).value() == t2.get()); + REQUIRE(C.get_latest_action_of(2).has_value()); + REQUIRE(C.get_latest_action_of(2).value() == t3.get()); + REQUIRE(C.get_latest_action_of(3).has_value()); + REQUIRE(C.get_latest_action_of(3).value() == t4.get()); + + C.add_event(&e5); + REQUIRE(C.get_latest_event_of(1).has_value()); + REQUIRE(C.get_latest_event_of(1).value() == &e2); + REQUIRE(C.get_latest_event_of(2).has_value()); + REQUIRE(C.get_latest_event_of(2).value() == &e5); + REQUIRE(C.get_latest_event_of(3).has_value()); + REQUIRE(C.get_latest_event_of(3).value() == &e4); + REQUIRE(C.get_latest_action_of(1).has_value()); + REQUIRE(C.get_latest_action_of(1).value() == t2.get()); + REQUIRE(C.get_latest_action_of(2).has_value()); + REQUIRE(C.get_latest_action_of(2).value() == t5.get()); + REQUIRE(C.get_latest_action_of(3).has_value()); + REQUIRE(C.get_latest_action_of(3).value() == t4.get()); + } +} + +TEST_CASE("simgrid::mc::udpor::Configuration: Computing Full Alternatives in Reader/Writer Example") +{ + // The following tests concern the given event structure that is given as + // an example in figure 1 of the original UDPOR paper. + // e0 + // / / / + // e1 e4 e7 + // / / // / + // / / e5 e8 e9 + // e2 e3 / / + // e6 e10 + // + // Theses tests walk through exactly the configurations and sets of `D` that + // UDPOR COULD encounter as it walks through the unfolding. Note that + // if there are multiple alternatives to any given configuration, UDPOR can + // continue searching any one of them. The sequence assumes UDPOR first picks `e1`, + // then `e4`, and then `e7` + Unfolding U; + + auto e0 = std::make_unique( + EventSet(), std::make_shared(Transition::Type::UNKNOWN, 0)); + const auto* e0_handle = e0.get(); + + auto e1 = std::make_unique(EventSet({e0_handle}), + std::make_shared(Transition::Type::UNKNOWN, 0)); + const auto* e1_handle = e1.get(); + + auto e2 = std::make_unique( + EventSet({e1_handle}), std::make_shared(Transition::Type::UNKNOWN, 1)); + const auto* e2_handle = e2.get(); + + auto e3 = std::make_unique( + EventSet({e1_handle}), std::make_shared(Transition::Type::UNKNOWN, 2)); + const auto* e3_handle = e3.get(); + + auto e4 = std::make_unique( + EventSet({e0_handle}), std::make_shared(Transition::Type::UNKNOWN, 1)); + const auto* e4_handle = e4.get(); + + auto e5 = std::make_unique(EventSet({e4_handle}), + std::make_shared(Transition::Type::UNKNOWN, 0)); + const auto* e5_handle = e5.get(); + + auto e6 = std::make_unique( + EventSet({e5_handle}), std::make_shared(Transition::Type::UNKNOWN, 2)); + const auto* e6_handle = e6.get(); + + auto e7 = std::make_unique( + EventSet({e0_handle}), std::make_shared(Transition::Type::UNKNOWN, 2)); + const auto* e7_handle = e7.get(); + + auto e8 = std::make_unique(EventSet({e4_handle, e7_handle}), + std::make_shared(Transition::Type::UNKNOWN, 0)); + const auto* e8_handle = e8.get(); + + auto e9 = std::make_unique(EventSet({e7_handle}), + std::make_shared(Transition::Type::UNKNOWN, 0)); + const auto* e9_handle = e9.get(); + + auto e10 = std::make_unique( + EventSet({e9_handle}), std::make_shared(Transition::Type::UNKNOWN, 1)); + const auto* e10_handle = e10.get(); + + SECTION("Alternative computation call 1") + { + // During the first call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / + // / / + // e2 e3 + // + // C := {e0, e1, e2} and `Explore(C, D, A)` picked `e3` + // (since en(C') where C' := {e0, e1, e2, e3} is empty + // [so UDPOR will simply return when C' is reached]) + // + // Thus the computation is (since D is empty at first) + // + // Alt(C, D + {e}) --> Alt({e0, e1, e2}, {e3}) + // + // where U is given above. There are no alternatives in + // this case since `e4` and `e7` conflict with `e1` (so + // they cannot be added to C to form a configuration) + const Configuration C{e0_handle, e1_handle, e2_handle}; + const EventSet D_plus_e{e3_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e7)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE_FALSE(alternative.has_value()); + } + + SECTION("Alternative computation call 2") + { + // During the second call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / + // / / + // e2 e3 + // + // C := {e0, e1} and `Explore(C, D, A)` picked `e2`. + // + // Thus the computation is (since D is still empty) + // + // Alt(C, D + {e}) --> Alt({e0, e1}, {e2}) + // + // where U is given above. There are no alternatives in + // this case since `e4` and `e7` conflict with `e1` (so + // they cannot be added to C to form a configuration) and + // e3 is NOT in conflict with either e0 or e1 + const Configuration C{e0_handle, e1_handle}; + const EventSet D_plus_e{e2_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e7)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE_FALSE(alternative.has_value()); + } + + SECTION("Alternative computation call 3") + { + // During the thrid call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / + // / / + // e2 e3 + // + // C := {e0} and `Explore(C, D, A)` picked `e1`. + // + // Thus the computation is (since D is still empty) + // + // Alt(C, D + {e}) --> Alt({e0}, {e1}) + // + // where U is given above. There are two alternatives in this case: + // {e0, e4} and {e0, e7}. Either one would be a valid choice for + // UDPOR, so we must check for the precense of either + const Configuration C{e0_handle}; + const EventSet D_plus_e{e1_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e7)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE(alternative.has_value()); + + // The first alternative that is found is the one that is chosen. Since + // traversal over the elements of an unordered_set<> are not guaranteed, + // both {e0, e4} and {e0, e7} are valid alternatives + REQUIRE((alternative.value().get_events() == EventSet({e0_handle, e4_handle}) || + alternative.value().get_events() == EventSet({e0_handle, e7_handle}))); + } + + SECTION("Alternative computation call 4") + { + // During the fourth call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / / // + // / / e5 e8 + // e2 e3 / + // e6 + // + // C := {e0, e4, e5} and `Explore(C, D, A)` picked `e6` + // (since en(C') where C' := {e0, e4, e5, e6} is empty + // [so UDPOR will simply return when C' is reached]) + // + // Thus the computation is (since D is {e1}) + // + // Alt(C, D + {e}) --> Alt({e0, e4, e5}, {e1, e6}) + // + // where U is given above. There are no alternatives in this + // case, since: + // + // 1.`e2/e3` are eliminated since their histories contain `e1` + // 2. `e7/e8` are eliminated because they conflict with `e5` + const Configuration C{e0_handle, e4_handle, e5_handle}; + const EventSet D_plus_e{e1_handle, e6_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e6)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE_FALSE(alternative.has_value()); + } + + SECTION("Alternative computation call 5") + { + // During the fifth call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / / // + // / / e5 e8 + // e2 e3 / + // e6 + // + // C := {e0, e4} and `Explore(C, D, A)` picked `e5` + // (since en(C') where C' := {e0, e4, e5, e6} is empty + // [so UDPOR will simply return when C' is reached]) + // + // Thus the computation is (since D is {e1}) + // + // Alt(C, D + {e}) --> Alt({e0, e4}, {e1, e5}) + // + // where U is given above. There are THREE alternatives in this case, + // viz. {e0, e7}, {e0, e4, e7} and {e0, e4, e7, e8}. + // + // To continue the search, UDPOR computes J / C which in this + // case gives {e7, e8}. Since `e8` is not in en(C), UDPOR will + // choose `e7` next and add `e5` to `D` + const Configuration C{e0_handle, e4_handle}; + const EventSet D_plus_e{e1_handle, e5_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e6)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + REQUIRE(U.size() == 8); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE(alternative.has_value()); + REQUIRE((alternative.value().get_events() == EventSet({e0_handle, e7_handle}) || + alternative.value().get_events() == EventSet({e0_handle, e4_handle, e7_handle}) || + alternative.value().get_events() == EventSet({e0_handle, e4_handle, e7_handle, e8_handle}))); + } + + SECTION("Alternative computation call 6") + { + // During the sixth call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / / // / + // / / e5 e8 e9 + // e2 e3 / + // e6 + // + // C := {e0, e4, e7} and `Explore(C, D, A)` picked `e8` + // (since en(C') where C' := {e0, e4, e7, e8} is empty + // [so UDPOR will simply return when C' is reached]) + // + // Thus the computation is (since D is {e1, e5} [see the last step]) + // + // Alt(C, D + {e}) --> Alt({e0, e4, e7}, {e1, e5, e8}) + // + // where U is given above. There are no alternatives in this case + // since all `e9` conflicts with `e4` and all other events of `U` + // are eliminated since their history intersects `D` + const Configuration C{e0_handle, e4_handle, e7_handle}; + const EventSet D_plus_e{e1_handle, e5_handle, e8_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e6)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + U.insert(std::move(e9)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE_FALSE(alternative.has_value()); + } + + SECTION("Alternative computation call 7") + { + // During the seventh call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / / // / + // / / e5 e8 e9 + // e2 e3 / + // e6 + // + // C := {e0, e4} and `Explore(C, D, A)` picked `e7` + // + // Thus the computation is (since D is {e1, e5} [see call 5]) + // + // Alt(C, D + {e}) --> Alt({e0, e4}, {e1, e5, e7}) + // + // where U is given above. There are no alternatives again in this case + // since all `e9` conflicts with `e4` and all other events of `U` + // are eliminated since their history intersects `D` + const Configuration C{e0_handle, e4_handle}; + const EventSet D_plus_e{e1_handle, e5_handle, e7_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e6)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + U.insert(std::move(e9)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE_FALSE(alternative.has_value()); + } + + SECTION("Alternative computation call 8") + { + // During the eigth call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / / // / + // / / e5 e8 e9 + // e2 e3 / + // e6 + // + // C := {e0} and `Explore(C, D, A)` picked `e4`. At this + // point, UDPOR finished its recursive search of {e0, e4} + // after having finished {e0, e1} prior. + // + // Thus the computation is (since D = {e1}) + // + // Alt(C, D + {e}) --> Alt({e0}, {e1, e4}) + // + // where U is given above. There is one alternative in this + // case, viz {e0, e7, e9} since + // 1. e9 conflicts with e4 in D + // 2. e7 conflicts with e1 in D + // 3. the set {e7, e9} is conflict-free since `e7 < e9` + // 4. all other events are eliminated since their histories + // intersect D + // + // UDPOR will continue its recursive search following `e7` + // and add `e4` to D + const Configuration C{e0_handle}; + const EventSet D_plus_e{e1_handle, e4_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e6)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + U.insert(std::move(e9)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE(alternative.has_value()); + REQUIRE(alternative.value().get_events() == EventSet({e0_handle, e7_handle, e9_handle})); + } + + SECTION("Alternative computation call 9") + { + // During the ninth call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / / // / + // / / e5 e8 e9 + // e2 e3 / / + // e6 e10 + // + // C := {e0, e7, e9} and `Explore(C, D, A)` picked `e10`. + // (since en(C') where C' := {e0, e7, e9, e10} is empty + // [so UDPOR will simply return when C' is reached]). + // + // Thus the computation is (since D = {e1, e4} [see the previous step]) + // + // Alt(C, D + {e}) --> Alt({e0}, {e1, e4, e10}) + // + // where U is given above. There are no alternatives in this case + const Configuration C{e0_handle, e7_handle, e9_handle}; + const EventSet D_plus_e{e1_handle, e4_handle, e10_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e6)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + U.insert(std::move(e9)); + U.insert(std::move(e10)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE_FALSE(alternative.has_value()); + } + + SECTION("Alternative computation call 10") + { + // During the tenth call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / / // / + // / / e5 e8 e9 + // e2 e3 / / + // e6 e10 + // + // C := {e0, e7} and `Explore(C, D, A)` picked `e9`. + // + // Thus the computation is (since D = {e1, e4} [see call 8]) + // + // Alt(C, D + {e}) --> Alt({e0}, {e1, e4, e9}) + // + // where U is given above. There are no alternatives in this case + const Configuration C{e0_handle, e7_handle}; + const EventSet D_plus_e{e1_handle, e4_handle, e9_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e6)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + U.insert(std::move(e9)); + U.insert(std::move(e10)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE_FALSE(alternative.has_value()); + } + + SECTION("Alternative computation call 11 (final call)") + { + // During the eleventh and final call to Alt(C, D + {e}), + // UDPOR believes `U` to be the following: + // + // e0 + // / / / + // e1 e4 e7 + // / / // / + // / / e5 e8 e9 + // e2 e3 / / + // e6 e10 + // + // C := {e0} and `Explore(C, D, A)` picked `e7`. + // + // Thus the computation is (since D = {e1, e4} [see call 8]) + // + // Alt(C, D + {e}) --> Alt({e0}, {e1, e4, e7}) + // + // where U is given above. There are no alternatives in this case: + // everyone is eliminated! + const Configuration C{e0_handle, e7_handle}; + const EventSet D_plus_e{e1_handle, e4_handle, e9_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e6)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + U.insert(std::move(e9)); + U.insert(std::move(e10)); + + const auto alternative = C.compute_alternative_to(D_plus_e, U); + REQUIRE_FALSE(alternative.has_value()); + } + + SECTION("Alternative computation next") + { + SECTION("Followed {e0, e7} first") + { + const EventSet D{e1_handle, e7_handle}; + const Configuration C{e0_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e5)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + U.insert(std::move(e9)); + U.insert(std::move(e10)); + + const auto alternative = C.compute_alternative_to(D, U); + REQUIRE(alternative.has_value()); + + // In this case, only {e0, e4} is a valid alternative + REQUIRE(alternative.value().get_events() == EventSet({e0_handle, e4_handle, e5_handle})); + } + + SECTION("Followed {e0, e4} first") + { + const EventSet D{e1_handle, e4_handle}; + const Configuration C{e0_handle}; + + REQUIRE(U.empty()); + U.insert(std::move(e0)); + U.insert(std::move(e1)); + U.insert(std::move(e2)); + U.insert(std::move(e3)); + U.insert(std::move(e4)); + U.insert(std::move(e5)); + U.insert(std::move(e6)); + U.insert(std::move(e7)); + U.insert(std::move(e8)); + U.insert(std::move(e9)); + + const auto alternative = C.compute_alternative_to(D, U); + REQUIRE(alternative.has_value()); + + // In this case, only {e0, e7} is a valid alternative + REQUIRE(alternative.value().get_events() == EventSet({e0_handle, e7_handle, e9_handle})); + } + } +} diff --git a/src/mc/explo/udpor/EventSet.cpp b/src/mc/explo/udpor/EventSet.cpp new file mode 100644 index 0000000000..929234e2a0 --- /dev/null +++ b/src/mc/explo/udpor/EventSet.cpp @@ -0,0 +1,288 @@ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/Configuration.hpp" +#include "src/mc/explo/udpor/History.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" +#include "src/xbt/utils/iter/variable_for_loop.hpp" + +#include +#include + +namespace simgrid::mc::udpor { + +EventSet::EventSet(const Configuration& config) : EventSet(config.get_events()) {} + +void EventSet::remove(const UnfoldingEvent* e) +{ + this->events_.erase(e); +} + +void EventSet::subtract(const EventSet& other) +{ + this->events_ = std::move(subtracting(other).events_); +} + +void EventSet::subtract(const Configuration& config) +{ + subtract(config.get_events()); +} + +EventSet EventSet::subtracting(const EventSet& other) const +{ + std::unordered_set result = this->events_; + + for (const UnfoldingEvent* e : other.events_) + result.erase(e); + + return EventSet(std::move(result)); +} + +EventSet EventSet::subtracting(const Configuration& config) const +{ + return subtracting(config.get_events()); +} + +EventSet EventSet::subtracting(const UnfoldingEvent* e) const +{ + auto result = this->events_; + result.erase(e); + return EventSet(std::move(result)); +} + +void EventSet::insert(const UnfoldingEvent* e) +{ + this->events_.insert(e); +} + +void EventSet::form_union(const EventSet& other) +{ + this->events_ = std::move(make_union(other).events_); +} + +void EventSet::form_union(const Configuration& config) +{ + form_union(config.get_events()); +} + +EventSet EventSet::make_union(const UnfoldingEvent* e) const +{ + auto result = this->events_; + result.insert(e); + return EventSet(std::move(result)); +} + +EventSet EventSet::make_union(const EventSet& other) const +{ + std::unordered_set result = this->events_; + + for (const UnfoldingEvent* e : other.events_) + result.insert(e); + + return EventSet(std::move(result)); +} + +EventSet EventSet::make_union(const Configuration& config) const +{ + return make_union(config.get_events()); +} + +EventSet EventSet::make_intersection(const EventSet& other) const +{ + std::unordered_set result; + + for (const UnfoldingEvent* e : other.events_) { + if (contains(e)) { + result.insert(e); + } + } + + return EventSet(std::move(result)); +} + +EventSet EventSet::get_local_config() const +{ + return History(*this).get_all_events(); +} + +size_t EventSet::size() const +{ + return this->events_.size(); +} + +bool EventSet::empty() const +{ + return this->events_.empty(); +} + +bool EventSet::contains(const UnfoldingEvent* e) const +{ + return this->events_.find(e) != this->events_.end(); +} + +bool EventSet::contains_equivalent_to(const UnfoldingEvent* e) const +{ + return std::find_if(begin(), end(), [=](const UnfoldingEvent* e_in_set) { return *e == *e_in_set; }) != end(); +} + +bool EventSet::is_subset_of(const EventSet& other) const +{ + // If there is some element not contained in `other`, then + // the set difference will contain that element and the + // result won't be empty + return subtracting(other).empty(); +} + +bool EventSet::is_valid_configuration() const +{ + /// @invariant: A collection of events `E` is a configuration + /// if and only if following while following the history of + /// each event `e` of `E` you remain in `E`. In other words, you + /// only see events from set `E` + /// + /// The simple proof is based on the definition of a configuration + /// which requires that all events have their history contained + /// in the set + const History history(*this); + return contains(history) && is_conflict_free(); +} + +bool EventSet::contains(const History& history) const +{ + return std::all_of(history.begin(), history.end(), [=](const UnfoldingEvent* e) { return this->contains(e); }); +} + +bool EventSet::intersects(const History& history) const +{ + return std::any_of(history.begin(), history.end(), [=](const UnfoldingEvent* e) { return this->contains(e); }); +} + +bool EventSet::intersects(const EventSet& other) const +{ + return std::any_of(other.begin(), other.end(), [=](const UnfoldingEvent* e) { return this->contains(e); }); +} + +EventSet EventSet::get_largest_maximal_subset() const +{ + const History history(*this); + return history.get_all_maximal_events(); +} + +bool EventSet::is_maximal() const +{ + // A set of events is maximal if no event from + // the original set is ruled out when traversing + // the history of the events + return *this == this->get_largest_maximal_subset(); +} + +bool EventSet::is_conflict_free() const +{ + const auto begin = simgrid::xbt::variable_for_loop{{*this}, {*this}}; + const auto end = simgrid::xbt::variable_for_loop(); + return std::none_of(begin, end, [=](const auto event_pair) { + const UnfoldingEvent* e1 = *event_pair[0]; + const UnfoldingEvent* e2 = *event_pair[1]; + return e1->conflicts_with(e2); + }); +} + +std::vector EventSet::get_topological_ordering() const +{ + // This is essentially an implementation of detecting cycles + // in a graph with coloring, except it makes a topological + // ordering out of it + if (empty()) { + return std::vector(); + } + + std::stack event_stack; + std::vector topological_ordering; + EventSet unknown_events = *this; + EventSet temporarily_marked_events; + EventSet permanently_marked_events; + + while (not unknown_events.empty()) { + EventSet discovered_events; + event_stack.push(*unknown_events.begin()); + + while (not event_stack.empty()) { + const UnfoldingEvent* evt = event_stack.top(); + discovered_events.insert(evt); + + if (not temporarily_marked_events.contains(evt)) { + // If this event hasn't yet been marked, do + // so now so that if we both see it + // again in a child we can detect a cycle + temporarily_marked_events.insert(evt); + + EventSet immediate_causes = evt->get_immediate_causes(); + if (not immediate_causes.empty() && immediate_causes.is_subset_of(temporarily_marked_events)) { + throw std::invalid_argument("Attempted to perform a topological sort on a configuration " + "whose contents contain a cycle. The configuration (and the graph " + "connecting all of the events) is an invalid event structure"); + } + immediate_causes.subtract(discovered_events); + immediate_causes.subtract(permanently_marked_events); + std::for_each(immediate_causes.begin(), immediate_causes.end(), + [&event_stack](const UnfoldingEvent* cause) { event_stack.push(cause); }); + } else { + unknown_events.remove(evt); + temporarily_marked_events.remove(evt); + permanently_marked_events.insert(evt); + + // In moving this event to the end of the list, + // we are saying this events "happens before" other + // events that are added later. + if (this->contains(evt)) { + topological_ordering.push_back(evt); + } + + // Only now do we remove the event, i.e. once + // we've processed the same event twice + event_stack.pop(); + } + } + } + return topological_ordering; +} + +std::vector EventSet::get_topological_ordering_of_reverse_graph() const +{ + // The implementation exploits the property that + // a topological sorting S^R of the reverse graph G^R + // of some graph G is simply the reverse of any + // topological sorting S of G. + auto topological_events = get_topological_ordering(); + std::reverse(topological_events.begin(), topological_events.end()); + return topological_events; +} + +std::string EventSet::to_string() const +{ + std::string contents; + + for (const auto* event : *this) { + contents += event->to_string(); + contents += " + "; + } + + return contents; +} + +std::vector EventSet::move_into_vector() const&& +{ + std::vector contents; + contents.reserve(size()); + + for (auto&& event : *this) { + contents.push_back(event); + } + + return contents; +} + +} // namespace simgrid::mc::udpor diff --git a/src/mc/explo/udpor/EventSet.hpp b/src/mc/explo/udpor/EventSet.hpp new file mode 100644 index 0000000000..32be66f70a --- /dev/null +++ b/src/mc/explo/udpor/EventSet.hpp @@ -0,0 +1,175 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_UDPOR_EVENT_SET_HPP +#define SIMGRID_MC_UDPOR_EVENT_SET_HPP + +#include "src/mc/explo/udpor/udpor_forward.hpp" + +#include +#include +#include +#include +#include +#include + +namespace simgrid::mc::udpor { + +class EventSet { +private: + std::unordered_set events_; + +public: + EventSet() = default; + EventSet(const EventSet&) = default; + EventSet& operator=(const EventSet&) = default; + EventSet& operator=(EventSet&&) = default; + EventSet(EventSet&&) = default; + explicit EventSet(const Configuration& config); + explicit EventSet(const std::vector& raw_events) + : events_(raw_events.begin(), raw_events.end()) + { + } + explicit EventSet(std::unordered_set&& raw_events) : events_(std::move(raw_events)) {} + explicit EventSet(std::initializer_list event_list) : events_(std::move(event_list)) {} + + auto begin() const { return this->events_.begin(); } + auto end() const { return this->events_.end(); } + auto cbegin() const { return this->events_.cbegin(); } + auto cend() const { return this->events_.cend(); } + + void remove(const UnfoldingEvent*); + void subtract(const EventSet&); + void subtract(const Configuration&); + EventSet subtracting(const UnfoldingEvent*) const; + EventSet subtracting(const EventSet&) const; + EventSet subtracting(const Configuration&) const; + + void insert(const UnfoldingEvent*); + void form_union(const EventSet&); + void form_union(const Configuration&); + EventSet make_union(const UnfoldingEvent*) const; + EventSet make_union(const EventSet&) const; + EventSet make_union(const Configuration&) const; + EventSet make_intersection(const EventSet&) const; + EventSet get_local_config() const; + + size_t size() const; + bool empty() const; + + bool contains(const UnfoldingEvent*) const; + bool contains(const History&) const; + bool contains_equivalent_to(const UnfoldingEvent*) const; + bool intersects(const EventSet&) const; + bool intersects(const History&) const; + bool is_subset_of(const EventSet&) const; + + bool operator==(const EventSet& other) const { return this->events_ == other.events_; } + bool operator!=(const EventSet& other) const { return this->events_ != other.events_; } + std::string to_string() const; + + /** + * @brief Whether or not this set of events could + * represent a configuration + */ + bool is_valid_configuration() const; + + /** + * @brief Whether or not this set of events is + * a *maximal event set*, i.e. whether each element + * of the set causes none of the others + * + * A set of events `E` is said to be _maximal_ if + * it is causally-free. Formally, + * + * 1. For each event `e` in `E`, there is no event + * `e'` in `E` such that `e < e'` + */ + bool is_maximal() const; + + /** + * @brief Whether or not this set of events is + * free of conflicts + * + * A set of events `E` is said to be _conflict free_ + * if + * + * 1. For each event `e` in `E`, there is no event + * `e'` in `E` such that `e # e'` where `#` is the + * conflict relation over the unfolding from + * which the events `E` are derived + * + * @note: This method makes use only of the causality + * tree of the events in the set; i.e. it determines conflicts + * based solely on the unfolding and the definition of + * conflict in an unfolding. Some clever techniques + * exist for computing conflicts with specialized transition + * types (only mutexes if I remember correctly) that was + * referenced in The Anh Pham's thesis. This would require + * keeping track of information *outside* of any given + * set and probably doesn't work for all types of transitions + * anyway. + */ + bool is_conflict_free() const; + + /** + * @brief Produces the largest subset of this + * set of events which is maximal + */ + EventSet get_largest_maximal_subset() const; + + /** + * @brief Orders the events of the set such that + * "more recent" events (i.e. those that are farther down in + * the event structure's dependency chain) come after those + * that appeared "farther in the past" + * + * @returns a vector `V` with the following property: + * + * 1. Let i(e) := C -> I map events to their indices in `V`. + * For every pair of events e, e' in C, if e < e' then i(e) < i(e') + * + * Intuitively, events that are closer to the "bottom" of the event + * structure appear farther along in the list than those that appear + * closer to the "top" + */ + std::vector get_topological_ordering() const; + + /** + * @brief Orders the events of set such that + * "more recent" events (i.e. those that are farther down in + * the event structure's dependency chain) come before those + * that appear "farther in the past" + * + * @note The events of the event structure are arranged such that + * e < e' implies a directed edge from e to e'. However, it is + * also useful to be able to traverse the *reverse* graph (for + * example when computing the compatibility graph of a configuration), + * hence the distinction between "reversed" and the method + * "EventSet::get_topological_ordering()" + * + * @returns a vector `V` with the following property: + * + * 1. Let i(e) := C -> I map events to their indices in `V`. + * For every pair of events e, e' in C, if e < e' then i(e) > i(e') + * + * Intuitively, events that are closer to the "top" of the event + * structure appear farther along in the list than those that appear + * closer to the "bottom" + */ + std::vector get_topological_ordering_of_reverse_graph() const; + + /** + * @brief Moves the event set into a list + */ + std::vector move_into_vector() const&&; + + using iterator = decltype(events_)::iterator; + using const_iterator = decltype(events_)::const_iterator; + using value_type = decltype(events_)::value_type; +}; + +} // namespace simgrid::mc::udpor +#endif diff --git a/src/mc/explo/udpor/EventSet_test.cpp b/src/mc/explo/udpor/EventSet_test.cpp new file mode 100644 index 0000000000..4c8287ccb2 --- /dev/null +++ b/src/mc/explo/udpor/EventSet_test.cpp @@ -0,0 +1,1144 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/History.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" +#include "src/mc/explo/udpor/udpor_tests_private.hpp" +#include "src/xbt/utils/iter/LazyPowerset.hpp" + +using namespace simgrid::xbt; +using namespace simgrid::mc::udpor; + +TEST_CASE("simgrid::mc::udpor::EventSet: Initial conditions when creating sets") +{ + SECTION("Initialization with no elements") + { + SECTION("Default initializer") + { + EventSet event_set; + REQUIRE(event_set.size() == 0); + REQUIRE(event_set.empty()); + } + + SECTION("Set initializer") + { + EventSet event_set({}); + REQUIRE(event_set.size() == 0); + REQUIRE(event_set.empty()); + } + + SECTION("List initialization") + { + EventSet event_set{}; + REQUIRE(event_set.size() == 0); + REQUIRE(event_set.empty()); + } + } + + SECTION("Initialization with one or more elements") + { + UnfoldingEvent e1; + UnfoldingEvent e2; + UnfoldingEvent e3; + + SECTION("Set initializer") + { + EventSet event_set({&e1, &e2, &e3}); + REQUIRE(event_set.size() == 3); + REQUIRE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + } + + SECTION("List initialization") + { + EventSet event_set{&e1, &e2, &e3}; + REQUIRE(event_set.size() == 3); + REQUIRE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + } + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Insertions") +{ + EventSet event_set; + UnfoldingEvent e1; + UnfoldingEvent e2; + UnfoldingEvent e3; + + SECTION("Inserting unique elements") + { + event_set.insert(&e1); + REQUIRE(event_set.size() == 1); + REQUIRE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.empty()); + + event_set.insert(&e2); + REQUIRE(event_set.size() == 2); + REQUIRE(event_set.contains(&e2)); + REQUIRE_FALSE(event_set.empty()); + + SECTION("Check contains inserted elements") + { + REQUIRE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE_FALSE(event_set.contains(&e3)); + } + } + + SECTION("Inserting duplicate elements") + { + event_set.insert(&e1); + REQUIRE(event_set.size() == 1); + REQUIRE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.empty()); + + event_set.insert(&e1); + REQUIRE(event_set.size() == 1); + REQUIRE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.empty()); + + SECTION("Check contains inserted elements") + { + REQUIRE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.contains(&e2)); + REQUIRE_FALSE(event_set.contains(&e3)); + } + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Deletions") +{ + UnfoldingEvent e1; + UnfoldingEvent e2; + UnfoldingEvent e3; + UnfoldingEvent e4; + EventSet event_set({&e1, &e2, &e3}); + + SECTION("Remove an element already present") + { + REQUIRE(event_set.contains(&e1)); + + // Recall that event_set = {e2, e3} + event_set.remove(&e1); + + // Check that + // 1. the size decreases by exactly 1 + // 2. the set remains unempty + // 3. the other elements are still contained in the set + REQUIRE(event_set.size() == 2); + REQUIRE_FALSE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + + SECTION("Remove a single element more than once") + { + // Recall that event_set = {e2, e3} + event_set.remove(&e1); + REQUIRE(event_set.size() == 2); + REQUIRE_FALSE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + } + + SECTION("Remove more than one element") + { + // Recall that event_set = {e3} + event_set.remove(&e2); + + REQUIRE(event_set.size() == 1); + REQUIRE_FALSE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + REQUIRE_FALSE(event_set.empty()); + + // Recall that event_set = {} + event_set.remove(&e3); + + REQUIRE(event_set.size() == 0); + REQUIRE_FALSE(event_set.contains(&e1)); + REQUIRE_FALSE(event_set.contains(&e2)); + REQUIRE_FALSE(event_set.contains(&e3)); + REQUIRE(event_set.empty()); + } + } + + SECTION("Remove an element absent from the set") + { + REQUIRE_FALSE(event_set.contains(&e4)); + + // Recall that event_set = {e1, e2, e3} + event_set.remove(&e4); + REQUIRE(event_set.size() == 3); + REQUIRE(event_set.contains(&e1)); + REQUIRE(event_set.contains(&e2)); + REQUIRE(event_set.contains(&e3)); + + // Ensure e4 isn't somehow added + REQUIRE_FALSE(event_set.contains(&e4)); + REQUIRE_FALSE(event_set.empty()); + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Set Equality") +{ + UnfoldingEvent e1; + UnfoldingEvent e2; + UnfoldingEvent e3; + UnfoldingEvent e4; + EventSet A{&e1, &e2, &e3}; + EventSet B{&e1, &e2, &e3}; + EventSet C{&e1, &e2, &e3}; + + SECTION("Equality implies containment") + { + REQUIRE(A == B); + + for (const auto& e : A) { + REQUIRE(B.contains(e)); + } + + for (const auto& e : B) { + REQUIRE(A.contains(e)); + } + } + + SECTION("Containment implies equality") + { + for (const auto& e : A) { + REQUIRE(B.contains(e)); + } + + for (const auto& e : C) { + REQUIRE(C.contains(e)); + } + + REQUIRE(A == C); + } + + SECTION("Equality is an equivalence relation") + { + // Reflexive + REQUIRE(A == A); + REQUIRE(B == B); + REQUIRE(C == C); + + // Symmetric + REQUIRE(A == B); + REQUIRE(B == A); + REQUIRE(A == C); + REQUIRE(C == A); + REQUIRE(B == C); + REQUIRE(C == B); + + // Transitive + REQUIRE(A == B); + REQUIRE(B == C); + REQUIRE(A == C); + } + + SECTION("Equality after copy (assignment + constructor)") + { + EventSet A_copy = A; + EventSet A_copy2(A); + + REQUIRE(A == A_copy); + REQUIRE(A == A_copy2); + } + + SECTION("Equality after move constructor") + { + EventSet A_copy = A; + EventSet A_move(std::move(A)); + REQUIRE(A_move == A_copy); + } + + SECTION("Equality after move-assignment") + { + EventSet A_copy = A; + EventSet A_move = std::move(A); + REQUIRE(A_move == A_copy); + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Set Union Tests") +{ + UnfoldingEvent e1; + UnfoldingEvent e2; + UnfoldingEvent e3; + UnfoldingEvent e4; + + // C = A + B + EventSet A{&e1, &e2, &e3}; + EventSet B{&e2, &e3, &e4}; + EventSet C{&e1, &e2, &e3, &e4}; + EventSet D{&e1, &e3}; + + SECTION("Unions with no effect") + { + EventSet A_copy = A; + + SECTION("Self union") + { + // A = A union A + EventSet A_union = A.make_union(A); + REQUIRE(A == A_union); + + A.form_union(A); + REQUIRE(A == A_copy); + } + + SECTION("Union with empty set") + { + // A = A union empty set + EventSet A_union = A.make_union(EventSet()); + REQUIRE(A == A_union); + + A.form_union(EventSet()); + REQUIRE(A == A_copy); + } + + SECTION("Union with an equivalent set") + { + // A = A union B if B == A + EventSet A_equiv{&e1, &e2, &e3}; + REQUIRE(A == A_equiv); + + EventSet A_union = A.make_union(A_equiv); + REQUIRE(A_union == A_copy); + + A.form_union(A_equiv); + REQUIRE(A == A_copy); + } + + SECTION("Union with a subset") + { + // A = A union D if D is a subset of A + EventSet A_union = A.make_union(D); + REQUIRE(A == A_union); + + A.form_union(D); + REQUIRE(A == A_copy); + } + } + + SECTION("Unions with partial overlaps") + { + EventSet A_union_B = A.make_union(B); + REQUIRE(A_union_B == C); + + A.form_union(B); + REQUIRE(A == C); + + EventSet B_union_D = B.make_union(D); + REQUIRE(B_union_D == C); + + B.form_union(D); + REQUIRE(B == C); + } + + SECTION("Set union properties") + { + SECTION("Union operator is symmetric") + { + EventSet A_union_B = A.make_union(B); + EventSet B_union_A = B.make_union(A); + REQUIRE(A_union_B == B_union_A); + } + + SECTION("Union operator commutes") + { + // The last SECTION tested pair-wise + // equivalence, so we only check + // one of each pai + EventSet AD = A.make_union(D); + EventSet AC = A.make_union(C); + EventSet CD = D.make_union(C); + + EventSet ADC = AD.make_union(C); + EventSet ACD = AC.make_union(D); + EventSet CDA = CD.make_union(A); + + REQUIRE(ADC == ACD); + REQUIRE(ACD == CDA); + + // Test `form_union()` in the same way + + EventSet A_copy = A; + EventSet C_copy = C; + EventSet D_copy = D; + + A.form_union(C_copy); + A.form_union(D_copy); + + D.form_union(A_copy); + D.form_union(C_copy); + + C.form_union(A); + C.form_union(D); + + REQUIRE(A == D); + REQUIRE(C == D); + REQUIRE(A == C); + } + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Set Difference Tests") +{ + UnfoldingEvent e1; + UnfoldingEvent e2; + UnfoldingEvent e3; + UnfoldingEvent e4; + + // C = A + B + // A is a subset of C + // B is a subset of C + // D is a subset of A and C + // E is a subset of B and C + // F is a subset of A, C, and D + EventSet A{&e1, &e2, &e3}; + EventSet B{&e2, &e3, &e4}; + EventSet C{&e1, &e2, &e3, &e4}; + EventSet D{&e1, &e3}; + EventSet E{&e4}; + EventSet F{&e1}; + + SECTION("Difference with no effect") + { + SECTION("Difference with empty set") + { + EventSet A_copy = A.subtracting(EventSet()); + REQUIRE(A == A_copy); + + A.subtract(EventSet()); + REQUIRE(A == A_copy); + } + + SECTION("Difference with empty intersection") + { + // A intersection E = empty set + EventSet A_copy = A.subtracting(E); + REQUIRE(A == A_copy); + + A.subtract(E); + REQUIRE(A == A_copy); + + EventSet D_copy = D.subtracting(E); + REQUIRE(D == D_copy); + + D.subtract(E); + REQUIRE(D == D_copy); + } + } + + SECTION("Difference with some overlap") + { + // A - B = {&e1} = F + EventSet A_minus_B = A.subtracting(B); + REQUIRE(A_minus_B == F); + + // B - D = {&e2, &e4} + EventSet B_minus_D = B.subtracting(D); + REQUIRE(B_minus_D == EventSet({&e2, &e4})); + } + + SECTION("Difference with complete overlap") + { + SECTION("Difference with same set gives empty set") + { + REQUIRE(A.subtracting(A) == EventSet()); + REQUIRE(B.subtracting(B) == EventSet()); + REQUIRE(C.subtracting(C) == EventSet()); + REQUIRE(D.subtracting(D) == EventSet()); + REQUIRE(E.subtracting(E) == EventSet()); + REQUIRE(F.subtracting(F) == EventSet()); + } + + SECTION("Difference with superset gives empty set") + { + REQUIRE(A.subtracting(C) == EventSet()); + REQUIRE(B.subtracting(C) == EventSet()); + REQUIRE(D.subtracting(A) == EventSet()); + REQUIRE(D.subtracting(C) == EventSet()); + REQUIRE(E.subtracting(B) == EventSet()); + REQUIRE(E.subtracting(C) == EventSet()); + REQUIRE(F.subtracting(A) == EventSet()); + REQUIRE(F.subtracting(C) == EventSet()); + REQUIRE(F.subtracting(D) == EventSet()); + } + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Subset Tests") +{ + UnfoldingEvent e1; + UnfoldingEvent e2; + UnfoldingEvent e3; + UnfoldingEvent e4; + + // A is a subset of C only + // B is a subset of C only + // D is a subset of C and A + // D is NOT a subset of B + // B is NOT a subset of D + // ... + EventSet A{&e1, &e2, &e3}; + EventSet B{&e2, &e3, &e4}; + EventSet C{&e1, &e2, &e3, &e4}; + EventSet D{&e1, &e3}; + EventSet E{&e2, &e3}; + EventSet F{&e1, &e2, &e3}; + + SECTION("Subset operator properties") + { + SECTION("Subset operator is not commutative") + { + REQUIRE(A.is_subset_of(C)); + REQUIRE_FALSE(C.is_subset_of(A)); + + SECTION("Commutativity implies equality and vice versa") + { + REQUIRE(A.is_subset_of(F)); + REQUIRE(F.is_subset_of(A)); + REQUIRE(A == F); + + REQUIRE(C == C); + REQUIRE(A.is_subset_of(F)); + REQUIRE(F.is_subset_of(A)); + } + } + + SECTION("Subset operator is transitive") + { + REQUIRE(D.is_subset_of(A)); + REQUIRE(A.is_subset_of(C)); + REQUIRE(D.is_subset_of(C)); + REQUIRE(E.is_subset_of(B)); + REQUIRE(B.is_subset_of(C)); + REQUIRE(E.is_subset_of(C)); + } + + SECTION("Subset operator is reflexive") + { + REQUIRE(A.is_subset_of(A)); + REQUIRE(B.is_subset_of(B)); + REQUIRE(C.is_subset_of(C)); + REQUIRE(D.is_subset_of(D)); + REQUIRE(E.is_subset_of(E)); + REQUIRE(F.is_subset_of(F)); + } + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Testing Configurations") +{ + // The following tests concern the given event structure: + // e1 + // / / + // e2 e5 + // / / / + // e3 e4 e6 + // The tests enumerate all possible subsets of the events + // in the structure and test whether those subsets are + // maximal and/or valid configurations + UnfoldingEvent e1(EventSet(), std::make_shared(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(1)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(2)); + UnfoldingEvent e4(EventSet({&e2}), std::make_shared(3)); + UnfoldingEvent e5(EventSet({&e1}), std::make_shared(4)); + UnfoldingEvent e6(EventSet({&e5}), std::make_shared(5)); + + SECTION("Valid Configurations") + { + SECTION("The empty set is valid") + { + REQUIRE(EventSet().is_valid_configuration()); + } + + SECTION("The set with only the root event is valid") + { + REQUIRE(EventSet({&e1}).is_valid_configuration()); + } + + SECTION("All sets of maximal events are valid configurations") + { + REQUIRE(EventSet({&e1}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e3}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e4}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e5}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e5, &e6}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e5}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e5, &e6}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e3, &e4}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e3, &e5}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e4, &e5}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_valid_configuration()); + } + } + + SECTION("Configuration checks") + { + // 6 choose 0 = 1 test + REQUIRE(EventSet().is_valid_configuration()); + + // 6 choose 1 = 6 tests + REQUIRE(EventSet({&e1}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e3}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e4}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e6}).is_valid_configuration()); + + // 6 choose 2 = 15 tests + REQUIRE(EventSet({&e1, &e2}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e3}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e4}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e3}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e4}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e3, &e4}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e3, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e3, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e4, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e4, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e5, &e6}).is_valid_configuration()); + + // 6 choose 3 = 20 tests + REQUIRE(EventSet({&e1, &e2, &e3}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e4}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e4}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e4, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e4, &e6}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e4}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e4, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e4, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e3, &e4, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e3, &e4, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e3, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e4, &e5, &e6}).is_valid_configuration()); + + // 6 choose 4 = 15 tests + REQUIRE(EventSet({&e1, &e2, &e3, &e4}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e3, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e6}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e4, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e6}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e4, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e4, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e3, &e4, &e5, &e6}).is_valid_configuration()); + + // 6 choose 5 = 6 tests + REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e6}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e3, &e5, &e6}).is_valid_configuration()); + REQUIRE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5, &e6}).is_valid_configuration()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5, &e6}).is_valid_configuration()); + + // 6 choose 6 = 1 test + REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_valid_configuration()); + } + + SECTION("Maximal event sets") + { + // 6 choose 0 = 1 test + REQUIRE(EventSet().is_maximal()); + + // 6 choose 1 = 6 tests + REQUIRE(EventSet({&e1}).is_maximal()); + REQUIRE(EventSet({&e2}).is_maximal()); + REQUIRE(EventSet({&e3}).is_maximal()); + REQUIRE(EventSet({&e4}).is_maximal()); + REQUIRE(EventSet({&e5}).is_maximal()); + REQUIRE(EventSet({&e6}).is_maximal()); + + // 6 choose 2 = 15 tests + REQUIRE_FALSE(EventSet({&e1, &e2}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e3}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e4}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e3}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e4}).is_maximal()); + REQUIRE(EventSet({&e2, &e5}).is_maximal()); + REQUIRE(EventSet({&e2, &e6}).is_maximal()); + REQUIRE(EventSet({&e3, &e4}).is_maximal()); + REQUIRE(EventSet({&e3, &e5}).is_maximal()); + REQUIRE(EventSet({&e3, &e6}).is_maximal()); + REQUIRE(EventSet({&e4, &e5}).is_maximal()); + REQUIRE(EventSet({&e4, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e5, &e6}).is_maximal()); + + // 6 choose 3 = 20 tests + REQUIRE_FALSE(EventSet({&e1, &e2, &e3}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e4}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e4}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e4, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e4, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e4}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e4, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e4, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e5, &e6}).is_maximal()); + REQUIRE(EventSet({&e3, &e4, &e5}).is_maximal()); + REQUIRE(EventSet({&e3, &e4, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e3, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e4, &e5, &e6}).is_maximal()); + + // 6 choose 4 = 15 tests + REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e4, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e4, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e3, &e4, &e5, &e6}).is_maximal()); + + // 6 choose 5 = 6 tests + REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5, &e6}).is_maximal()); + REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5, &e6}).is_maximal()); + + // 6 choose 6 = 1 test + REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_maximal()); + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Moving into a collection") +{ + UnfoldingEvent e1; + UnfoldingEvent e2; + UnfoldingEvent e3; + UnfoldingEvent e4; + + EventSet A({&e1}); + EventSet B({&e1, &e2}); + EventSet C({&e1, &e2, &e3}); + EventSet D({&e1, &e2, &e3, &e4}); + + EventSet A_copy = A; + EventSet B_copy = B; + EventSet C_copy = C; + EventSet D_copy = D; + + const std::vector actual_A = std::move(A).move_into_vector(); + const std::vector actual_B = std::move(B).move_into_vector(); + const std::vector actual_C = std::move(C).move_into_vector(); + const std::vector actual_D = std::move(D).move_into_vector(); + + EventSet A_copy_remade(actual_A); + EventSet B_copy_remade(actual_B); + EventSet C_copy_remade(actual_C); + EventSet D_copy_remade(actual_D); + + REQUIRE(A_copy == A_copy_remade); + REQUIRE(B_copy == B_copy_remade); + REQUIRE(C_copy == C_copy_remade); + REQUIRE(D_copy == D_copy_remade); +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Checking conflicts") +{ + // The following tests concern the given event structure: + // e1 + // / / + // e2 e5 + // / / / + // e3 e4 e6 + // The tests enumerate all possible subsets of the events + // in the structure and test whether those subsets contain + // conflicts. + // + // Each test assigns different transitions to each event to + // make the scenarios more interesting + + SECTION("No conflicts throughout the whole structure with independent actions") + { + UnfoldingEvent e1(EventSet(), std::make_shared(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(1)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(2)); + UnfoldingEvent e4(EventSet({&e2}), std::make_shared(3)); + UnfoldingEvent e5(EventSet({&e1}), std::make_shared(4)); + UnfoldingEvent e6(EventSet({&e5}), std::make_shared(5)); + + // 6 choose 0 = 1 test + CHECK(EventSet().is_conflict_free()); + + // 6 choose 1 = 6 tests + CHECK(EventSet({&e1}).is_conflict_free()); + CHECK(EventSet({&e2}).is_conflict_free()); + CHECK(EventSet({&e3}).is_conflict_free()); + CHECK(EventSet({&e4}).is_conflict_free()); + CHECK(EventSet({&e5}).is_conflict_free()); + CHECK(EventSet({&e6}).is_conflict_free()); + + // 6 choose 2 = 15 tests + CHECK(EventSet({&e1, &e2}).is_conflict_free()); + CHECK(EventSet({&e1, &e3}).is_conflict_free()); + CHECK(EventSet({&e1, &e4}).is_conflict_free()); + CHECK(EventSet({&e1, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e3}).is_conflict_free()); + CHECK(EventSet({&e2, &e4}).is_conflict_free()); + CHECK(EventSet({&e2, &e5}).is_conflict_free()); + CHECK(EventSet({&e2, &e6}).is_conflict_free()); + CHECK(EventSet({&e3, &e4}).is_conflict_free()); + CHECK(EventSet({&e3, &e5}).is_conflict_free()); + CHECK(EventSet({&e3, &e6}).is_conflict_free()); + CHECK(EventSet({&e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e5, &e6}).is_conflict_free()); + + // 6 choose 3 = 20 tests + CHECK(EventSet({&e1, &e2, &e3}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e4}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e4}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e3, &e4}).is_conflict_free()); + CHECK(EventSet({&e2, &e3, &e5}).is_conflict_free()); + CHECK(EventSet({&e2, &e3, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e2, &e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e3, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e3, &e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e3, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e4, &e5, &e6}).is_conflict_free()); + + // 6 choose 4 = 15 tests + CHECK(EventSet({&e1, &e2, &e3, &e4}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e3, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e3, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e4, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e3, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e2, &e3, &e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e3, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e4, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e3, &e4, &e5, &e6}).is_conflict_free()); + + // 6 choose 5 = 6 tests + CHECK(EventSet({&e1, &e2, &e3, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e3, &e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e3, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e4, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e4, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e3, &e4, &e5, &e6}).is_conflict_free()); + + // 6 choose 6 = 1 test + CHECK(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_conflict_free()); + } + + SECTION("Conflicts throughout the whole structure with dependent actions (except with DFS sets)") + { + // Since all actions are dependent, if a set contains a "fork" or divergent histories, + // we expect the collections to contain conflicts + UnfoldingEvent e1(EventSet(), std::make_shared()); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared()); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared()); + UnfoldingEvent e4(EventSet({&e2}), std::make_shared()); + UnfoldingEvent e5(EventSet({&e1}), std::make_shared()); + UnfoldingEvent e6(EventSet({&e5}), std::make_shared()); + + // 6 choose 0 = 1 test + // There are no events even to be in conflict with + CHECK(EventSet().is_conflict_free()); + + // 6 choose 1 = 6 tests + // Sets of size 1 should have no conflicts + CHECK(EventSet({&e1}).is_conflict_free()); + CHECK(EventSet({&e2}).is_conflict_free()); + CHECK(EventSet({&e3}).is_conflict_free()); + CHECK(EventSet({&e4}).is_conflict_free()); + CHECK(EventSet({&e5}).is_conflict_free()); + CHECK(EventSet({&e6}).is_conflict_free()); + + // 6 choose 2 = 15 tests + CHECK(EventSet({&e1, &e2}).is_conflict_free()); + CHECK(EventSet({&e1, &e3}).is_conflict_free()); + CHECK(EventSet({&e1, &e4}).is_conflict_free()); + CHECK(EventSet({&e1, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e3}).is_conflict_free()); + CHECK(EventSet({&e2, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e5, &e6}).is_conflict_free()); + + // 6 choose 3 = 20 tests + CHECK(EventSet({&e1, &e2, &e3}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e4, &e5, &e6}).is_conflict_free()); + + // 6 choose 4 = 15 tests + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e4, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e4, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e4, &e5, &e6}).is_conflict_free()); + + // 6 choose 5 = 6 tests + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e4, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e4, &e5, &e6}).is_conflict_free()); + + // 6 choose 6 = 1 test + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_conflict_free()); + } + + SECTION("Conditional conflicts") + { + UnfoldingEvent e1(EventSet(), std::make_shared(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(1)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(2)); + UnfoldingEvent e4(EventSet({&e2}), std::make_shared(3)); + UnfoldingEvent e5(EventSet({&e1}), std::make_shared(4)); + UnfoldingEvent e6(EventSet({&e5}), std::make_shared(5)); + + // 6 choose 0 = 1 test + // There are no events even to be in conflict with + CHECK(EventSet().is_conflict_free()); + + // 6 choose 1 = 6 tests + // Sets of size 1 should still have no conflicts + CHECK(EventSet({&e1}).is_conflict_free()); + CHECK(EventSet({&e2}).is_conflict_free()); + CHECK(EventSet({&e3}).is_conflict_free()); + CHECK(EventSet({&e4}).is_conflict_free()); + CHECK(EventSet({&e5}).is_conflict_free()); + CHECK(EventSet({&e6}).is_conflict_free()); + + // 6 choose 2 = 15 tests + CHECK(EventSet({&e1, &e2}).is_conflict_free()); + CHECK(EventSet({&e1, &e3}).is_conflict_free()); + CHECK(EventSet({&e1, &e4}).is_conflict_free()); + CHECK(EventSet({&e1, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e3}).is_conflict_free()); + CHECK(EventSet({&e2, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e5}).is_conflict_free()); + + // Although e2 and e6 are not directly dependent, + // e2 conflicts with e5 which causes e6 + CHECK_FALSE(EventSet({&e2, &e6}).is_conflict_free()); + CHECK(EventSet({&e3, &e4}).is_conflict_free()); + + // Likewise, since e2 and e5 conflict and e2 causes + // e3, so e3 and e5 conflict + CHECK_FALSE(EventSet({&e3, &e5}).is_conflict_free()); + CHECK(EventSet({&e3, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e5, &e6}).is_conflict_free()); + + // 6 choose 3 = 20 tests + CHECK(EventSet({&e1, &e2, &e3}).is_conflict_free()); + CHECK(EventSet({&e1, &e2, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e4, &e6}).is_conflict_free()); + CHECK(EventSet({&e1, &e5, &e6}).is_conflict_free()); + CHECK(EventSet({&e2, &e3, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e3, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e4, &e5, &e6}).is_conflict_free()); + + // 6 choose 4 = 15 tests + CHECK(EventSet({&e1, &e2, &e3, &e4}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e5}).is_conflict_free()); + + // e2 is dependent with e6 + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e4, &e5}).is_conflict_free()); + CHECK(EventSet({&e1, &e3, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e4, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e4, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e3, &e4, &e5, &e6}).is_conflict_free()); + + // 6 choose 5 = 6 tests + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e1, &e3, &e4, &e5, &e6}).is_conflict_free()); + CHECK_FALSE(EventSet({&e2, &e3, &e4, &e5, &e6}).is_conflict_free()); + + // 6 choose 6 = 1 test + CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_conflict_free()); + } +} + +TEST_CASE("simgrid::mc::udpor::EventSet: Topological Ordering Property Observed for Every Possible Subset") +{ + // The following tests concern the given event structure: + // e1 + // / / + // e2 e6 + // / / / + // e3 / / + // / / / + // e4 e5 e7 + UnfoldingEvent e1(EventSet(), std::make_shared()); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared()); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared()); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared()); + UnfoldingEvent e5(EventSet({&e3}), std::make_shared()); + UnfoldingEvent e6(EventSet({&e1}), std::make_shared()); + UnfoldingEvent e7(EventSet({&e2, &e6}), std::make_shared()); + + const EventSet all_events{&e1, &e2, &e3, &e4, &e5, &e6, &e7}; + + for (const auto& subset_of_iterators : make_powerset_iter(all_events)) { + // Verify that the topological ordering property holds for every subset + + const EventSet subset = [&subset_of_iterators]() { + EventSet subset_local; + for (const auto& iter : subset_of_iterators) { + subset_local.insert(*iter); + } + return subset_local; + }(); + + // To test this, we verify that at each point none of the events + // that follow after any particular event `e` are contained in + // `e`'s history + EventSet invalid_events = subset; + for (const auto* e : subset.get_topological_ordering()) { + for (const auto* e_hist : History(e)) { + if (e_hist == e) + continue; + REQUIRE_FALSE(invalid_events.contains(e_hist)); + } + invalid_events.remove(e); + } + + // To test this, we verify that at each point none of the events + // that we've processed in the ordering are ever seen again + // in anybody else's history + EventSet events_seen; + for (const auto* e : subset.get_topological_ordering_of_reverse_graph()) { + for (const auto* e_hist : History(e)) { + // Unlike the test above, we DO want to ensure + // that `e` itself ALSO isn't yet seen + + // If this event has been "seen" before, + // this implies that event `e` appears later + // in the list than one of its ancestors + REQUIRE_FALSE(events_seen.contains(e_hist)); + } + events_seen.insert(e); + } + } +} diff --git a/src/mc/explo/udpor/ExtensionSetCalculator.cpp b/src/mc/explo/udpor/ExtensionSetCalculator.cpp new file mode 100644 index 0000000000..e928105cc2 --- /dev/null +++ b/src/mc/explo/udpor/ExtensionSetCalculator.cpp @@ -0,0 +1,636 @@ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/udpor/ExtensionSetCalculator.hpp" +#include "src/mc/explo/udpor/Configuration.hpp" +#include "src/mc/explo/udpor/History.hpp" +#include "src/mc/explo/udpor/Unfolding.hpp" + +#include +#include +#include +#include + +using namespace simgrid::mc; + +namespace simgrid::mc::udpor { + +EventSet ExtensionSetCalculator::partially_extend(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + using Action = Transition::Type; + using Handler = std::function)>; + using HandlerMap = std::unordered_map; + + const static HandlerMap handlers = { + {Action::COMM_ASYNC_RECV, &ExtensionSetCalculator::partially_extend_CommRecv}, + {Action::COMM_ASYNC_SEND, &ExtensionSetCalculator::partially_extend_CommSend}, + {Action::COMM_WAIT, &ExtensionSetCalculator::partially_extend_CommWait}, + {Action::COMM_TEST, &ExtensionSetCalculator::partially_extend_CommTest}, + {Action::MUTEX_ASYNC_LOCK, &ExtensionSetCalculator::partially_extend_MutexAsyncLock}, + {Action::MUTEX_UNLOCK, &ExtensionSetCalculator::partially_extend_MutexUnlock}, + {Action::MUTEX_WAIT, &ExtensionSetCalculator::partially_extend_MutexWait}, + {Action::MUTEX_TEST, &ExtensionSetCalculator::partially_extend_MutexTest}, + {Action::ACTOR_JOIN, &ExtensionSetCalculator::partially_extend_ActorJoin}}; + + if (const auto handler = handlers.find(action->type_); handler != handlers.end()) { + return handler->second(C, U, std::move(action)); + } else { + xbt_die("There is currently no specialized computation for the transition " + "'%s' for computing extension sets in UDPOR, so the model checker cannot " + "determine how to proceed. Please submit a bug report requesting " + "that the transition be supported in SimGrid using UDPOR and consider " + "using the other model-checking algorithms supported by SimGrid instead " + "in the meantime", + action->to_string().c_str()); + } +} + +EventSet ExtensionSetCalculator::partially_extend_CommSend(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + EventSet exC; + + const auto send_action = std::static_pointer_cast(action); + const auto pre_event_a_C = C.pre_event(send_action->aid_); + const unsigned sender_mailbox = send_action->get_mailbox(); + + // 1. Create `e' := ` and add `e'` to `ex(C)` + // NOTE: If `preEvt(a, C)` doesn't exist, we're effectively asking + // about `config({})` + if (pre_event_a_C.has_value()) { + const auto* e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), send_action); + exC.insert(e_prime); + } else { + const auto* e_prime = U->discover_event(EventSet(), send_action); + exC.insert(e_prime); + } + + // 2. foreach e ∈ C s.t. λ(e) ∈ {AsyncSend(m, _), TestAny(Com)} where + // Com contains a matching c' = AsyncReceive(m, _) with `action` + for (const auto e : C) { + const bool transition_type_check = [&]() { + const auto* async_send = dynamic_cast(e->get_transition()); + return async_send && async_send->get_mailbox() == sender_mailbox; + // TODO: Add `TestAny` dependency + }(); + + if (transition_type_check) { + EventSet K = EventSet({e, pre_event_a_C.value_or(e)}).get_largest_maximal_subset(); + + // TODO: Check D_K(a, lambda(e)) (only matters in the case of CommTest) + const auto e_prime = U->discover_event(std::move(K), send_action); + exC.insert(e_prime); + } + } + + // TODO: Add `TestAny` dependency case + return exC; +} + +EventSet ExtensionSetCalculator::partially_extend_CommRecv(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + EventSet exC; + + const auto recv_action = std::static_pointer_cast(action); + const unsigned recv_mailbox = recv_action->get_mailbox(); + const auto pre_event_a_C = C.pre_event(recv_action->aid_); + + // 1. Create `e' := ` and add `e'` to `ex(C)` + if (pre_event_a_C.has_value()) { + const auto* e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), recv_action); + exC.insert(e_prime); + } else { + const auto* e_prime = U->discover_event(EventSet(), recv_action); + exC.insert(e_prime); + } + + // 2. foreach e ∈ C s.t. λ(e) ∈ {AsyncSend(m, _), TestAny(Com)} where + // Com contains a matching c' = AsyncReceive(m, _) with a + for (const auto e : C) { + const bool transition_type_check = [&]() { + const auto* async_recv = dynamic_cast(e->get_transition()); + return async_recv && async_recv->get_mailbox() == recv_mailbox; + // TODO: Add `TestAny` dependency + }(); + + if (transition_type_check) { + EventSet K = EventSet({e, pre_event_a_C.value_or(e)}).get_largest_maximal_subset(); + + // TODO: Check D_K(a, lambda(e)) (ony matters in the case of TestAny) + if (true) { + const auto* e_prime = U->discover_event(std::move(K), recv_action); + exC.insert(e_prime); + } + } + } + + // TODO: Add `TestAny` dependency case + return exC; +} + +EventSet ExtensionSetCalculator::partially_extend_CommWait(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + EventSet exC; + + const auto wait_action = std::static_pointer_cast(action); + const auto wait_comm = wait_action->get_comm(); + const auto pre_event_a_C = C.pre_event(wait_action->aid_); + + // Determine the _issuer_ of the communication of the `CommWait` event + // in `C`. The issuer of the `CommWait` in `C` is the event in `C` + // whose transition is the `CommRecv` or `CommSend` whose resulting + // communication this `CommWait` waits on + const auto issuer = std::find_if(C.begin(), C.end(), [&](const UnfoldingEvent* e) { + if (const auto* e_issuer_receive = dynamic_cast(e->get_transition())) { + return e_issuer_receive->aid_ == wait_action->aid_ && wait_comm == e_issuer_receive->get_comm(); + } + + if (const auto* e_issuer_send = dynamic_cast(e->get_transition())) { + return e_issuer_send->aid_ == wait_action->aid_ && wait_comm == e_issuer_send->get_comm(); + } + + return false; + }); + xbt_assert(issuer != C.end(), + "Invariant violation! A (supposedly) enabled `CommWait` transition " + "waiting on communication %u should not be enabled: the receive/send " + "transition which generated the communication is not an action taken " + "to reach state(C) (the state of the configuration), which should " + "be an impossibility if `%s` is enabled. Please report this as " + "a bug in SimGrid's UDPOR implementation", + wait_action->get_comm(), wait_action->to_string(false).c_str()); + const UnfoldingEvent* e_issuer = *issuer; + const History e_issuer_history(e_issuer); + + // 1. if `a` is enabled at state(config({preEvt(a,C)})), then + // create `e' := ` and add `e'` to `ex(C)` + // + // First, if `pre_event_a_C == std::nullopt`, then there is nothing to + // do: `CommWait` will never be enabled in the empty configuration (at + // least two actions must be executed before) + if (pre_event_a_C.has_value(); const auto* unwrapped_pre_event = pre_event_a_C.value()) { + // A necessary condition is that the issuer be present in + // config({preEvt(a, C)}); otherwise, the `CommWait` could not + // be enabled since the communication on which it waits would not + // have been created for it! + if (const auto config_pre_event = History(unwrapped_pre_event); config_pre_event.contains(e_issuer)) { + // If the issuer is a `CommRecv` (resp. `CommSend`), then we check that there + // are at least as many `CommSend` (resp. `CommRecv`) transitions in `config_pre_event` + // as needed to reach the receive/send number that is `issuer`. + // ... + // ... + if (const auto* e_issuer_receive = dynamic_cast(e_issuer->get_transition())) { + const unsigned issuer_mailbox = e_issuer_receive->get_mailbox(); + + // Check from the config -> how many sends have there been + const unsigned send_position = + std::count_if(config_pre_event.begin(), config_pre_event.end(), [=](const auto e) { + const auto* e_send = dynamic_cast(e->get_transition()); + return e_send && e_send->get_mailbox() == issuer_mailbox; + }); + + // Check from e_issuer -> what place is the issuer in? + const unsigned receive_position = + std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto e) { + const auto* e_receive = dynamic_cast(e->get_transition()); + return e_receive && e_receive->get_mailbox() == issuer_mailbox; + }); + + if (send_position >= receive_position) { + exC.insert(U->discover_event(EventSet({unwrapped_pre_event}), wait_action)); + } + + } else if (const auto* e_issuer_send = dynamic_cast(e_issuer->get_transition())) { + const unsigned issuer_mailbox = e_issuer_send->get_mailbox(); + + // Check from e_issuer -> what place is the issuer in? + const unsigned send_position = + std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto e) { + const auto* e_send = dynamic_cast(e->get_transition()); + return e_send && e_send->get_mailbox() == issuer_mailbox; + }); + + // Check from the config -> how many sends have there been + const unsigned receive_position = + std::count_if(config_pre_event.begin(), config_pre_event.end(), [=](const auto e) { + const auto* e_receive = dynamic_cast(e->get_transition()); + return e_receive && e_receive->get_mailbox() == issuer_mailbox; + }); + + if (send_position <= receive_position) { + exC.insert(U->discover_event(EventSet({unwrapped_pre_event}), wait_action)); + } + + } else { + xbt_die("The transition which created the communication on which `%s` waits " + "is neither an async send nor an async receive. The current UDPOR " + "implementation does not know how to check if `CommWait` is enabled in " + "this case. Was a new transition added?", + e_issuer->get_transition()->to_string().c_str()); + } + } + } + + // 3. foreach event e in C do + if (const auto* e_issuer_send = dynamic_cast(e_issuer->get_transition())) { + for (const auto e : C) { + // If the provider of the communication for `CommWait` is a + // `CommSend(m)`, then we only care about `e` if `λ(e) == `CommRecv(m)`. + // All other actions would be independent with the wait action (including + // another `CommSend` to the same mailbox: `CommWait` is "waiting" for its + // corresponding receive action) + if (e->get_transition()->type_ != Transition::Type::COMM_ASYNC_RECV) { + continue; + } + + const auto issuer_mailbox = e_issuer_send->get_mailbox(); + if (const auto* e_recv = dynamic_cast(e->get_transition()); + e_recv->get_mailbox() != issuer_mailbox) { + continue; + } + + // If the `issuer` is not in `config(K)`, this implies that + // `WaitAny()` is always disabled in `config(K)`; hence, it + // is independent of any transition in `config(K)` (according + // to formal definition of independence) + auto K = EventSet({e, pre_event_a_C.value_or(e)}); + const auto config_K = History(K); + if (not config_K.contains(e_issuer)) { + continue; + } + + // What send # is the issuer + const unsigned send_position = + std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto ev) { + const auto* e_send = dynamic_cast(ev->get_transition()); + return e_send && e_send->get_mailbox() == issuer_mailbox; + }); + + // What receive # is the event `e`? + const unsigned receive_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto ev) { + const auto* e_receive = dynamic_cast(ev->get_transition()); + return e_receive && e_receive->get_mailbox() == issuer_mailbox; + }); + + if (send_position == receive_position) { + exC.insert(U->discover_event(std::move(K), wait_action)); + } + } + } else if (const auto* e_issuer_recv = dynamic_cast(e_issuer->get_transition())) { + for (const auto e : C) { + // If the provider of the communication for `CommWait` is a + // `CommRecv(m)`, then we only care about `e` if `λ(e) == `CommSend(m)`. + // All other actions would be independent with the wait action (including + // another `CommRecv` to the same mailbox: `CommWait` is "waiting" for its + // corresponding send action) + if (e->get_transition()->type_ != Transition::Type::COMM_ASYNC_SEND) { + continue; + } + + const auto issuer_mailbox = e_issuer_recv->get_mailbox(); + if (const auto* e_send = dynamic_cast(e->get_transition()); + e_send->get_mailbox() != issuer_mailbox) { + continue; + } + + // If the `issuer` is not in `config(K)`, this implies that + // `WaitAny()` is always disabled in `config(K)`; hence, it + // is independent of any transition in `config(K)` (according + // to formal definition of independence) + auto K = EventSet({e, pre_event_a_C.value_or(e)}); + const auto config_K = History(K); + if (not config_K.contains(e_issuer)) { + continue; + } + + // What receive # is the event `e`? + const unsigned send_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto ev) { + const auto* e_send = dynamic_cast(ev->get_transition()); + return e_send && e_send->get_mailbox() == issuer_mailbox; + }); + + // What send # is the issuer + const unsigned receive_position = + std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto ev) { + const auto* e_receive = dynamic_cast(ev->get_transition()); + return e_receive && e_receive->get_mailbox() == issuer_mailbox; + }); + + if (send_position == receive_position) { + exC.insert(U->discover_event(std::move(K), wait_action)); + } + } + } else { + xbt_die("The transition which created the communication on which `%s` waits " + "is neither an async send nor an async receive. The current UDPOR " + "implementation does not know how to check if `CommWait` is enabled in " + "this case. Was a new transition added?", + e_issuer->get_transition()->to_string().c_str()); + } + + return exC; +} + +EventSet ExtensionSetCalculator::partially_extend_CommTest(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + EventSet exC; + + const auto test_action = std::static_pointer_cast(action); + const auto test_comm = test_action->get_comm(); + const auto test_aid = test_action->aid_; + const auto pre_event_a_C = C.pre_event(test_action->aid_); + + // Add the previous event as a dependency (if it's there) + if (pre_event_a_C.has_value()) { + const auto e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), test_action); + exC.insert(e_prime); + } + + // Determine the _issuer_ of the communication of the `CommTest` event + // in `C`. The issuer of the `CommTest` in `C` is the event in `C` + // whose transition is the `CommRecv` or `CommSend` whose resulting + // communication this `CommTest` tests on + const auto issuer = std::find_if(C.begin(), C.end(), [=](const UnfoldingEvent* e) { + if (const auto* e_issuer_receive = dynamic_cast(e->get_transition())) { + return e_issuer_receive->aid_ == test_aid && test_comm == e_issuer_receive->get_comm(); + } + + if (const auto* e_issuer_send = dynamic_cast(e->get_transition())) { + return e_issuer_send->aid_ == test_aid && test_comm == e_issuer_send->get_comm(); + } + + return false; + }); + xbt_assert(issuer != C.end(), + "An enabled `CommTest` transition (%s) is testing a communication" + "%u not created by a receive/send " + "transition. SimGrid cannot currently handle test actions " + "under which a test is performed on a communication that was " + "not directly created by a receive/send operation of the same actor.", + test_action->to_string(false).c_str(), test_action->get_comm()); + const UnfoldingEvent* e_issuer = *issuer; + const History e_issuer_history(e_issuer); + + // 3. foreach event e in C do + if (const auto* e_issuer_send = dynamic_cast(e_issuer->get_transition())) { + for (const auto e : C) { + // If the provider of the communication for `CommTest` is a + // `CommSend(m)`, then we only care about `e` if `λ(e) == `CommRecv(m)`. + // All other actions would be independent with the test action (including + // another `CommSend` to the same mailbox: `CommTest` is testing the + // corresponding receive action) + if (e->get_transition()->type_ != Transition::Type::COMM_ASYNC_RECV) { + continue; + } + + const auto issuer_mailbox = e_issuer_send->get_mailbox(); + + if (const auto* e_recv = dynamic_cast(e->get_transition()); + e_recv->get_mailbox() != issuer_mailbox) { + continue; + } + + // If the `issuer` is not in `config(K)`, this implies that + // `CommTest()` is always disabled in `config(K)`; hence, it + // is independent of any transition in `config(K)` (according + // to formal definition of independence) + auto K = EventSet({e, pre_event_a_C.value_or(e)}); + const auto config_K = History(K); + if (not config_K.contains(e_issuer)) { + continue; + } + + // What send # is the issuer + const unsigned send_position = + std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto ev) { + const auto* e_send = dynamic_cast(ev->get_transition()); + return e_send && e_send->get_mailbox() == issuer_mailbox; + }); + + // What receive # is the event `e`? + const unsigned receive_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto ev) { + const auto* e_receive = dynamic_cast(ev->get_transition()); + return e_receive && e_receive->get_mailbox() == issuer_mailbox; + }); + + if (send_position == receive_position) { + exC.insert(U->discover_event(std::move(K), test_action)); + } + } + } else if (const auto* e_issuer_recv = dynamic_cast(e_issuer->get_transition())) { + for (const auto e : C) { + // If the provider of the communication for `CommTest` is a + // `CommRecv(m)`, then we only care about `e` if `λ(e) == `CommSend(m)`. + // All other actions would be independent with the wait action (including + // another `CommRecv` to the same mailbox: `CommWait` is "waiting" for its + // corresponding send action) + if (e->get_transition()->type_ != Transition::Type::COMM_ASYNC_SEND) { + continue; + } + + const auto issuer_mailbox = e_issuer_recv->get_mailbox(); + if (const auto* e_send = dynamic_cast(e->get_transition()); + e_send->get_mailbox() != issuer_mailbox) { + continue; + } + + // If the `issuer` is not in `config(K)`, this implies that + // `WaitAny()` is always disabled in `config(K)`; hence, it + // is independent of any transition in `config(K)` (according + // to formal definition of independence) + auto K = EventSet({e, pre_event_a_C.value_or(e)}); + const auto config_K = History(K); + if (not config_K.contains(e_issuer)) { + continue; + } + + // What receive # is the event `e`? + const unsigned send_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto ev) { + const auto* e_send = dynamic_cast(ev->get_transition()); + return e_send && e_send->get_mailbox() == issuer_mailbox; + }); + + // What send # is the issuer + const unsigned receive_position = + std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto ev) { + const auto* e_receive = dynamic_cast(ev->get_transition()); + return e_receive && e_receive->get_mailbox() == issuer_mailbox; + }); + + if (send_position == receive_position) { + exC.insert(U->discover_event(std::move(K), test_action)); + } + } + } else { + xbt_die("The transition which created the communication on which `%s` waits " + "is neither an async send nor an async receive. The current UDPOR " + "implementation does not know how to check if `CommWait` is enabled in " + "this case. Was a new transition added?", + e_issuer->get_transition()->to_string().c_str()); + } + return exC; +} + +EventSet ExtensionSetCalculator::partially_extend_MutexAsyncLock(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + EventSet exC; + const auto mutex_lock = std::static_pointer_cast(action); + const auto pre_event_a_C = C.pre_event(mutex_lock->aid_); + + // for each event e in C + // 1. If lambda(e) := pre(a) -> add it. Note that if + // pre_event_a_C.has_value() == false, this implies `C` is + // empty or which we treat as implicitly containing the bottom event + if (pre_event_a_C.has_value()) { + const auto e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), mutex_lock); + exC.insert(e_prime); + } else { + const auto e_prime = U->discover_event(EventSet(), mutex_lock); + exC.insert(e_prime); + } + + // for each event e in C + for (const auto e : C) { + // Check for other locks on the same mutex + if (const auto* e_mutex = dynamic_cast(e->get_transition()); + e_mutex->type_ == Transition::Type::MUTEX_ASYNC_LOCK && mutex_lock->get_mutex() == e_mutex->get_mutex()) { + auto K = EventSet({e, pre_event_a_C.value_or(e)}); + exC.insert(U->discover_event(std::move(K), mutex_lock)); + } + } + return exC; +} + +EventSet ExtensionSetCalculator::partially_extend_MutexUnlock(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + EventSet exC; + const auto mutex_unlock = std::static_pointer_cast(action); + const auto pre_event_a_C = C.pre_event(mutex_unlock->aid_); + + // for each event e in C + // 1. If lambda(e) := pre(a) -> add it. Note that if + // pre_event_a_C.has_value() == false, this implies `C` is + // empty or which we treat as implicitly containing the bottom event + if (pre_event_a_C.has_value()) { + const auto e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), mutex_unlock); + exC.insert(e_prime); + } else { + const auto e_prime = U->discover_event(EventSet(), mutex_unlock); + exC.insert(e_prime); + } + + // for each event e in C + for (const auto e : C) { + // Check for MutexTest + if (const auto* e_mutex = dynamic_cast(e->get_transition()); + e_mutex->type_ == Transition::Type::MUTEX_TEST || e_mutex->type_ == Transition::Type::MUTEX_WAIT) { + // TODO: Check if dependent or not + // This entails getting information about + // the relative position of the mutex in the queue, which + // again means we need more context... + auto K = EventSet({e, pre_event_a_C.value_or(e)}); + exC.insert(U->discover_event(std::move(K), mutex_unlock)); + } + } + return exC; +} + +EventSet ExtensionSetCalculator::partially_extend_MutexWait(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + EventSet exC; + const auto mutex_wait = std::static_pointer_cast(action); + const auto pre_event_a_C = C.pre_event(mutex_wait->aid_); + + // for each event e in C + // 1. If lambda(e) := pre(a) -> add it. In the case of MutexWait, we also check that the + // actor which is executing the MutexWait is the owner of the mutex + if (pre_event_a_C.has_value() && mutex_wait->get_owner() == mutex_wait->aid_) { + const auto e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), mutex_wait); + exC.insert(e_prime); + } else { + const auto e_prime = U->discover_event(EventSet(), mutex_wait); + exC.insert(e_prime); + } + + // for each event e in C + for (const auto e : C) { + // Check for any unlocks + if (const auto* e_mutex = dynamic_cast(e->get_transition()); + e_mutex != nullptr && e_mutex->type_ == Transition::Type::MUTEX_UNLOCK) { + // TODO: Check if dependent or not + // This entails getting information about + // the relative position of the mutex in the queue, which + // again means we need more context... + auto K = EventSet({e, pre_event_a_C.value_or(e)}); + exC.insert(U->discover_event(std::move(K), mutex_wait)); + } + } + return exC; +} + +EventSet ExtensionSetCalculator::partially_extend_MutexTest(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + EventSet exC; + const auto mutex_test = std::static_pointer_cast(action); + const auto pre_event_a_C = C.pre_event(mutex_test->aid_); + + // for each event e in C + // 1. If lambda(e) := pre(a) -> add it. Note that if + // pre_event_a_C.has_value() == false, this implies `C` is + // empty or which we treat as implicitly containing the bottom event + if (pre_event_a_C.has_value()) { + const auto e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), mutex_test); + exC.insert(e_prime); + } else { + const auto e_prime = U->discover_event(EventSet(), mutex_test); + exC.insert(e_prime); + } + + // for each event e in C + for (const auto e : C) { + // Check for any unlocks + if (const auto* e_mutex = dynamic_cast(e->get_transition()); + e_mutex != nullptr && e_mutex->type_ == Transition::Type::MUTEX_UNLOCK) { + // TODO: Check if dependent or not + // This entails getting information about + // the relative position of the mutex in the queue, which + // again means we need more context... + auto K = EventSet({e, pre_event_a_C.value_or(e)}); + exC.insert(U->discover_event(std::move(K), mutex_test)); + } + } + return exC; +} + +EventSet ExtensionSetCalculator::partially_extend_ActorJoin(const Configuration& C, Unfolding* U, + std::shared_ptr action) +{ + EventSet exC; + + const auto join_action = std::static_pointer_cast(action); + + // Handling ActorJoin is very simple: it is independent with all + // other transitions. Thus the only event it could possibly depend + // on is pre(a, C) or the root + if (const auto pre_event_a_C = C.pre_event(join_action->aid_); pre_event_a_C.has_value()) { + const auto e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), join_action); + exC.insert(e_prime); + } else { + const auto e_prime = U->discover_event(EventSet(), join_action); + exC.insert(e_prime); + } + + return exC; +} + +} // namespace simgrid::mc::udpor diff --git a/src/mc/explo/udpor/ExtensionSetCalculator.hpp b/src/mc/explo/udpor/ExtensionSetCalculator.hpp new file mode 100644 index 0000000000..cd68c9c7ff --- /dev/null +++ b/src/mc/explo/udpor/ExtensionSetCalculator.hpp @@ -0,0 +1,45 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_UDPOR_EVENTSETCALCULATOR_HPP +#define SIMGRID_MC_UDPOR_EVENTSETCALCULATOR_HPP + +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/udpor_forward.hpp" +#include "src/mc/transition/Transition.hpp" +#include "src/mc/transition/TransitionActor.hpp" +#include "src/mc/transition/TransitionAny.hpp" +#include "src/mc/transition/TransitionComm.hpp" +#include "src/mc/transition/TransitionObjectAccess.hpp" +#include "src/mc/transition/TransitionRandom.hpp" +#include "src/mc/transition/TransitionSynchro.hpp" + +#include + +namespace simgrid::mc::udpor { + +/** + * @brief Computes incrementally the portion of the extension set for a new configuration `C` + */ +struct ExtensionSetCalculator final { +private: + static EventSet partially_extend_CommSend(const Configuration&, Unfolding*, std::shared_ptr); + static EventSet partially_extend_CommRecv(const Configuration&, Unfolding*, std::shared_ptr); + static EventSet partially_extend_CommWait(const Configuration&, Unfolding*, std::shared_ptr); + static EventSet partially_extend_CommTest(const Configuration&, Unfolding*, std::shared_ptr); + + static EventSet partially_extend_MutexAsyncLock(const Configuration&, Unfolding*, std::shared_ptr); + static EventSet partially_extend_MutexWait(const Configuration&, Unfolding*, std::shared_ptr); + static EventSet partially_extend_MutexTest(const Configuration&, Unfolding*, std::shared_ptr); + static EventSet partially_extend_MutexUnlock(const Configuration&, Unfolding*, std::shared_ptr); + + static EventSet partially_extend_ActorJoin(const Configuration&, Unfolding*, std::shared_ptr); + +public: + static EventSet partially_extend(const Configuration&, Unfolding*, std::shared_ptr); +}; + +} // namespace simgrid::mc::udpor +#endif diff --git a/src/mc/explo/udpor/ExtensionSet_test.cpp b/src/mc/explo/udpor/ExtensionSet_test.cpp new file mode 100644 index 0000000000..a3953ba37a --- /dev/null +++ b/src/mc/explo/udpor/ExtensionSet_test.cpp @@ -0,0 +1,295 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/udpor/Configuration.hpp" +#include "src/mc/explo/udpor/ExtensionSetCalculator.hpp" +#include "src/mc/explo/udpor/History.hpp" +#include "src/mc/explo/udpor/Unfolding.hpp" + +using namespace simgrid::mc; +using namespace simgrid::mc::udpor; + +TEST_CASE("simgrid::mc::udpor: Testing Computation with AsyncSend/AsyncReceive Only") +{ + // This test checks that the unfolding constructed for the very + // simple program described below is extended correctly. Each + // step of UDPOR is observed to ensure that computations are carried + // out correctly. The program described is simply: + // + // 1 2 + // AsyncSend(m) AsyncRecv(m) + // + // The unfolding of the simple program is as follows: + // + // ⊥ + // / / + // (a) 1: AsyncSend(m) (b) 2: AsyncRecv(m) + + const int times_considered = 0; + const int tag = 0; + const unsigned mbox = 0; + const uintptr_t comm = 0; + + Unfolding U; + + SECTION("Computing ex({⊥}) with 1: AsyncSend") + { + // Consider the extension with `1: AsyncSend(m)` + Configuration C; + aid_t issuer = 1; + + const auto async_send = std::make_shared(issuer, times_considered, comm, mbox, tag); + const auto incremental_exC = ExtensionSetCalculator::partially_extend(C, &U, async_send); + + // Check that the events have been added to `U` + REQUIRE(U.size() == 1); + + // Make assertions about the contents of ex(C) + UnfoldingEvent e(EventSet(), async_send); + REQUIRE(incremental_exC.contains_equivalent_to(&e)); + } + + SECTION("Computing ex({⊥}) with 2: AsyncRecv") + { + // Consider the extension with `2: AsyncRecv(m)` + Configuration C; + aid_t issuer = 2; + + const auto async_recv = std::make_shared(issuer, times_considered, comm, mbox, tag); + const auto incremental_exC = ExtensionSetCalculator::partially_extend(C, &U, async_recv); + + // Check that the events have been added to `U` + REQUIRE(U.size() == 1); + + // Make assertions about the contents of ex(C) + UnfoldingEvent e(EventSet(), async_recv); + REQUIRE(incremental_exC.contains_equivalent_to(&e)); + } + + SECTION("Computing ex({⊥}) fully") + { + // Consider the extension with `1: AsyncSend(m)` + Configuration C; + + const auto async_send = std::make_shared(1, times_considered, comm, mbox, tag); + const auto incremental_exC_send = ExtensionSetCalculator::partially_extend(C, &U, async_send); + + // Check that the events have been added to `U` + REQUIRE(U.size() == 1); + + // Make assertions about the contents of ex(C) + UnfoldingEvent e_send(EventSet(), async_send); + REQUIRE(incremental_exC_send.contains_equivalent_to(&e_send)); + + // Consider the extension with `2: AsyncRecv(m)` + const auto async_recv = std::make_shared(2, times_considered, comm, mbox, tag); + const auto incremental_exC_recv = ExtensionSetCalculator::partially_extend(C, &U, async_recv); + + // Check that the events have been added to `U` + REQUIRE(U.size() == 2); + + // Make assertions about the contents of ex(C) + UnfoldingEvent e_recv(EventSet(), async_recv); + REQUIRE(incremental_exC_recv.contains_equivalent_to(&e_recv)); + } + + SECTION("Computing the full sequence of extensions") + { + Configuration C; + + // Consider the extension with `1: AsyncSend(m)` + const auto async_send = std::make_shared(1, times_considered, comm, mbox, tag); + const auto incremental_exC_send = ExtensionSetCalculator::partially_extend(C, &U, async_send); + + // Check that event `a` has been added to `U` + REQUIRE(U.size() == 1); + UnfoldingEvent e_send(EventSet(), async_send); + REQUIRE(incremental_exC_send.contains_equivalent_to(&e_send)); + + // Consider the extension with `2: AsyncRecv(m)` + const auto async_recv = std::make_shared(2, times_considered, comm, mbox, tag); + const auto incremental_exC_recv = ExtensionSetCalculator::partially_extend(C, &U, async_recv); + + // Check that event `b` has been added to `U` + REQUIRE(U.size() == 2); + UnfoldingEvent e_recv(EventSet(), async_recv); + REQUIRE(incremental_exC_recv.contains_equivalent_to(&e_recv)); + + // At this point, UDPOR will pick one of the two events equivalent to + // `e_recv` and e`_send` + + // Suppose it picks the event labeled `a` in the graph above first + // (ultimately, UDPOR will choose to search both directions since + // {⊥, b} will be an alternative to {⊥, a}) + + const auto* e_a = *incremental_exC_send.begin(); + const auto* e_b = *incremental_exC_recv.begin(); + + SECTION("Pick `a` first (ex({⊥, a}))") + { + // After picking `a`, we need only consider the extensions + // possible with `2: AsyncRecv(m)` since actor 1 no longer + // has any actions to run + Configuration C_with_send{e_a}; + const auto incremental_exC_with_send = ExtensionSetCalculator::partially_extend(C_with_send, &U, async_recv); + + // Check that event `b` has not been duplicated + REQUIRE(U.size() == 2); + + // Indeed, in this case we assert that the SAME identity has been + // supplied by the unfolding (it should note that `ex({⊥, a})` + // and `ex({⊥})` have an overlapping event `b`) + REQUIRE(incremental_exC_with_send.contains(e_b)); + } + + SECTION("Pick `b` first (ex({⊥, b}))") + { + // After picking `b`, we need only consider the extensions + // possible with `1: AsyncSend(m)` since actor 2 no longer + // has any actions to run + Configuration C_with_recv{e_b}; + const auto incremental_exC_with_recv = ExtensionSetCalculator::partially_extend(C_with_recv, &U, async_send); + + // Check that event `a` has not been duplicated + REQUIRE(U.size() == 2); + + // Indeed, in this case we assert that the SAME identity has been + // supplied by the unfolding (it should note that `ex({⊥, b})` + // and `ex({⊥})` have an overlapping event `a`) + REQUIRE(incremental_exC_with_recv.contains(e_a)); + } + } +} + +TEST_CASE("simgrid::mc::udpor: Testing Waits, Receives, and Sends") +{ + // We're going to follow UDPOR down one path of computation + // in a relatively simple program (although the unfolding quickly + // becomes quite complex) + // + // 1 2 + // AsyncSend(m) AsyncRecv(m) + // Wait(m) Wait(m) + // + // The unfolding of the simple program is as follows: + // ⊥ + // / / + // (a) 1: AsyncSend(m) (b) 2: AsyncRecv(m) + // | \ / | + // | \ / | + // | / \ | + // | / \ | + // (c) 1: Wait(m) (d) 2: Wait(m) + const int times_considered = 0; + const int tag = 0; + const unsigned mbox = 0; + const uintptr_t comm = 0x800; + const bool timeout = false; + + Unfolding U; + const auto comm_send = std::make_shared(1, times_considered, comm, mbox, tag); + const auto comm_recv = std::make_shared(2, times_considered, comm, mbox, tag); + const auto comm_wait_1 = std::make_shared(1, times_considered, timeout, comm, 1, 2, mbox); + const auto comm_wait_2 = std::make_shared(2, times_considered, timeout, comm, 1, 2, mbox); + + // 1. UDPOR will attempt to expand first ex({⊥}) + + // --- ex({⊥}) --- + const auto incremental_exC_send = ExtensionSetCalculator::partially_extend(Configuration(), &U, comm_send); + // Assert that event `a` has been added + UnfoldingEvent e_send(EventSet(), comm_send); + REQUIRE(incremental_exC_send.size() == 1); + REQUIRE(incremental_exC_send.contains_equivalent_to(&e_send)); + REQUIRE(U.size() == 1); + + const auto incremental_exC_recv = ExtensionSetCalculator::partially_extend(Configuration(), &U, comm_recv); + // Assert that event `b` has been added + UnfoldingEvent e_recv(EventSet(), comm_recv); + REQUIRE(incremental_exC_recv.size() == 1); + REQUIRE(incremental_exC_recv.contains_equivalent_to(&e_recv)); + REQUIRE(U.size() == 2); + // --- ex({⊥}) --- + + // 2. UDPOR will then attempt to expand ex({⊥, a}) or ex({⊥, b}). Both have + // parallel effects and should simply return events already added to ex(C) + // + // NOTE: Note that only once actor is enabled in both cases, meaning that + // we need only consider one incremental expansion for each + + const auto* e_a = *incremental_exC_send.begin(); + const auto* e_b = *incremental_exC_recv.begin(); + + // --- ex({⊥, a}) --- + const auto incremental_exC_recv2 = ExtensionSetCalculator::partially_extend(Configuration({e_a}), &U, comm_recv); + // Assert that no event has been added and that + // e_b is contained in the extension set + REQUIRE(incremental_exC_recv2.size() == 1); + REQUIRE(incremental_exC_recv2.contains(e_b)); + + // Here, `e_a` shouldn't be added again + REQUIRE(U.size() == 2); + // --- ex({⊥, a}) --- + + // --- ex({⊥, b}) --- + const auto incremental_exC_send2 = ExtensionSetCalculator::partially_extend(Configuration({e_b}), &U, comm_send); + // Assert that no event has been added and that + // e_a is contained in the extension set + REQUIRE(incremental_exC_send2.size() == 1); + REQUIRE(incremental_exC_send2.contains(e_a)); + + // Here, `e_b` shouldn't be added again + REQUIRE(U.size() == 2); + // --- ex({⊥, b}) --- + + // 3. Expanding from ex({⊥, a, b}) brings in both `CommWait` events since they + // become enabled as soon as the communication has been paired + + // --- ex({⊥, a, b}) --- + const auto incremental_exC_wait_actor_1 = + ExtensionSetCalculator::partially_extend(Configuration({e_a, e_b}), &U, comm_wait_1); + // Assert that events `c` has been added + UnfoldingEvent e_wait_1(EventSet({e_a, e_b}), comm_wait_1); + REQUIRE(incremental_exC_wait_actor_1.size() == 1); + REQUIRE(incremental_exC_wait_actor_1.contains_equivalent_to(&e_wait_1)); + REQUIRE(U.size() == 3); + + const auto incremental_exC_wait_actor_2 = + ExtensionSetCalculator::partially_extend(Configuration({e_a, e_b}), &U, comm_wait_2); + // Assert that events `d` has been added + UnfoldingEvent e_wait_2(EventSet({e_a, e_b}), comm_wait_2); + REQUIRE(incremental_exC_wait_actor_2.size() == 1); + REQUIRE(incremental_exC_wait_actor_2.contains_equivalent_to(&e_wait_2)); + REQUIRE(U.size() == 4); + // --- ex({⊥, a, b}) --- + + // 4. Expanding from either wait action should simply yield the other event + // with a wait action associated with it. + // This is analogous to the scenario before with send and receive + // ex({⊥, a, b, c}) or ex({⊥, a, b, d}) + + const auto* e_c = *incremental_exC_wait_actor_1.begin(); + const auto* e_d = *incremental_exC_wait_actor_2.begin(); + + // --- ex({⊥, a, b, d}) --- + const auto incremental_exC_wait_actor_1_2 = + ExtensionSetCalculator::partially_extend(Configuration({e_a, e_b, e_d}), &U, comm_wait_1); + // Assert that no event has been added and that + // `e_c` is contained in the extension set + REQUIRE(incremental_exC_wait_actor_1_2.size() == 1); + REQUIRE(incremental_exC_wait_actor_1_2.contains(e_c)); + REQUIRE(U.size() == 4); + // --- ex({⊥, a, b, d}) --- + + // --- ex({⊥, a, b, c}) --- + const auto incremental_exC_wait_actor_2_2 = + ExtensionSetCalculator::partially_extend(Configuration({e_a, e_b, e_c}), &U, comm_wait_2); + // Assert that no event has been added and that + // `e_d` is contained in the extension set + REQUIRE(incremental_exC_wait_actor_2_2.size() == 1); + REQUIRE(incremental_exC_wait_actor_2_2.contains(e_d)); + REQUIRE(U.size() == 4); + // --- ex({⊥, a, b, c}) --- +} diff --git a/src/mc/explo/udpor/History.cpp b/src/mc/explo/udpor/History.cpp new file mode 100644 index 0000000000..d9d43d3133 --- /dev/null +++ b/src/mc/explo/udpor/History.cpp @@ -0,0 +1,104 @@ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/udpor/History.hpp" +#include "src/mc/explo/udpor/Configuration.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" + +#include + +namespace simgrid::mc::udpor { + +History::Iterator::Iterator(const EventSet& initial_events, optional_configuration config) + : frontier(initial_events), maximal_events(initial_events), configuration(config) +{ + // NOTE: Only events in the initial set of events can ever hope to have + // a chance at being a maximal event, since all other events in + // the search are generate by looking at dependencies of these events + // and all subsequent events that are added by the iterator +} + +void History::Iterator::increment() +{ + if (not frontier.empty()) { + // "Pop" the event at the "front" + const UnfoldingEvent* e = *frontier.begin(); + frontier.remove(e); + + // If there is a configuration and if the + // event is in it, skip it: the event and + // all of its immediate causes do not need to + // be searched since the configuration contains + // them (configuration invariant) + if (configuration.has_value() && configuration->get().contains(e)) { + return; + } + + // Mark this event as seen + current_history.insert(e); + + // Perform the expansion with all viable expansions + EventSet candidates = e->get_immediate_causes(); + + maximal_events.subtract(candidates); + + candidates.subtract(current_history); + frontier.form_union(candidates); + } +} + +const UnfoldingEvent* const& History::Iterator::dereference() const +{ + return *frontier.begin(); +} + +bool History::Iterator::equal(const Iterator& other) const +{ + // If what the iterator sees next is the same, we consider them + // to be the same iterator. This way, once the iterator has completed + // its search, it will be "equal" to an iterator searching nothing + return this->frontier == other.frontier; +} + +EventSet History::get_all_events() const +{ + auto first = this->begin(); + const auto last = this->end(); + + for (; first != last; ++first) + ; + + return first.current_history; +} + +EventSet History::get_all_maximal_events() const +{ + auto first = this->begin(); + const auto last = this->end(); + + for (; first != last; ++first) + ; + + return first.maximal_events; +} + +bool History::contains(const UnfoldingEvent* e) const +{ + return std::any_of(this->begin(), this->end(), [=](const UnfoldingEvent* e_hist) { return e == e_hist; }); +} + +EventSet History::get_event_diff_with(const Configuration& config) const +{ + auto wrapped_config = std::optional>{config}; + auto first = Iterator(events_, wrapped_config); + const auto last = this->end(); + + for (; first != last; ++first) + ; + + return first.current_history; +} + +} // namespace simgrid::mc::udpor diff --git a/src/mc/explo/udpor/History.hpp b/src/mc/explo/udpor/History.hpp new file mode 100644 index 0000000000..dc17c27e58 --- /dev/null +++ b/src/mc/explo/udpor/History.hpp @@ -0,0 +1,150 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_UDPOR_HISTORY_HPP +#define SIMGRID_MC_UDPOR_HISTORY_HPP + +#include "src/mc/explo/udpor/Configuration.hpp" +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/udpor_forward.hpp" + +#include +#include +#include +#include + +namespace simgrid::mc::udpor { + +/** + * @brief Conceptually describes the local configuration(s) of + * an event or a collection of events, encoding the history of + * the events without needing to actually fully compute all of + * the events contained in the history + * + * When you create an instance of `History`, you are effectively + * making a "lazy" configuration whose elements are the set of + * causes of a given event (if the `History` constists of a single + * event) or the union of all causes of all events (if the + * `History` consists of a set of events). + * + * Using a `History` object to represent the history of a set of + * events is more efficient (and reads more easily) than first + * computing the entire history of each of the events separately + * and combining the results. The former can take advantage of the + * fact that the histories of a set of events overlap greatly, and + * thus only a single BFS/DFS search over the event structure needs + * to be performed instead of many isolated searches for each event. + * + * The same observation also allows you to compute the difference between + * a configuration and a history of a set of events. This is used + * in UDPOR, for example, when determing the difference J / C and + * when using K-partial alternatives (which computes J as the union + * of histories of events) + */ +class History { +private: + /** + * @brief The events whose history this instance describes + */ + EventSet events_; + +public: + History(const History&) = default; + History& operator=(History const&) = default; + History(History&&) = default; + + explicit History(const UnfoldingEvent* e) : events_({e}) {} + explicit History(EventSet event_set = EventSet()) : events_(std::move(event_set)) {} + explicit History(std::initializer_list list) : events_(std::move(list)) {} + + auto begin() const { return Iterator(events_); } + auto end() const { return Iterator(EventSet()); } + + /** + * @brief Whether or not the given event is contained in the history + * + * @note If you only need to determine whether a few events are contained + * in a history, prefer this method. If, however, you wish to repeatedly + * determine over time (e.g. over the course of a computation) whether + * some event is part of the history, it may be better to first compute + * all events (see `History::get_all_events()`) and reuse this set + * + * @param e the event to check + * @returns whether or not `e` is contained in the collection + */ + bool contains(const UnfoldingEvent* e) const; + + /** + * @brief Computes all events in the history described by this instance + * + * Sometimes, it is useful to compute the entire set of events that + * comprise the history of some event `e` of some set of events `E`. + * This method performs that computation. + * + * @returns the set of all causal dependencies of all events this + * history represents. Equivalently, the method returns the full + * dependency graph for all events in this history + */ + EventSet get_all_events() const; + + /** + * @brief Computes all events in the history described by this instance + * which are maximal (intuitively, those events which cause no others + * or are the "most recent") + */ + EventSet get_all_maximal_events() const; + + /** + * @brief Computes the set of events that are not contained + * in the given configuration + * + * A configuration is a causally-closed, conflict-free set + * of events. Thus, you can determine which events lie outside + * of a configuration during the search more efficiently: the moment + * you discover an event contained in the configuration, you + * do not need to search that event or any of its ancestors as + * they will all be contained in the configuration + */ + EventSet get_event_diff_with(const Configuration& config) const; + +private: + /** + * @brief An iterator which traverses the history of a set of events + */ + struct Iterator : boost::iterator_facade { + public: + using optional_configuration = std::optional>; + Iterator(const EventSet& initial_events, optional_configuration config = std::nullopt); + + private: + /// @brief Points in the graph from where to continue the search + EventSet frontier; + + /// @brief What the iterator currently believes to be the + /// entire history of the events in the graph it traverses + EventSet current_history = EventSet(); + + /// @brief What the iterator currently believes + // to be the set of maximal events + EventSet maximal_events; + optional_configuration configuration; + + // boost::iterator_facade<...> interface to implement + void increment(); + bool equal(const Iterator& other) const; + + const UnfoldingEvent* const& dereference() const; + + // Allows boost::iterator_facade<...> to function properly + friend class boost::iterator_core_access; + + // Allow the `History` class to use some of the + // computation of the iterator + friend History; + }; +}; + +} // namespace simgrid::mc::udpor +#endif diff --git a/src/mc/explo/udpor/History_test.cpp b/src/mc/explo/udpor/History_test.cpp new file mode 100644 index 0000000000..55065a3e91 --- /dev/null +++ b/src/mc/explo/udpor/History_test.cpp @@ -0,0 +1,215 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/udpor/History.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" + +using namespace simgrid::mc::udpor; + +TEST_CASE("simgrid::mc::udpor::History: History generation") +{ + // The following tests concern the given event tree + // e1 + // / / + // e2 e6 + // | \ \ / / + // e3 e4 e5 e7 + UnfoldingEvent e1; + UnfoldingEvent e2{&e1}; + UnfoldingEvent e6{&e1}; + UnfoldingEvent e3{&e2}; + UnfoldingEvent e4{&e2}; + UnfoldingEvent e5{&e2, &e6}; + UnfoldingEvent e7{&e6}; + + SECTION("History with no events") + { + History history; + REQUIRE(history.get_all_events() == EventSet()); + REQUIRE_FALSE(history.contains(&e1)); + REQUIRE_FALSE(history.contains(&e2)); + REQUIRE_FALSE(history.contains(&e3)); + REQUIRE_FALSE(history.contains(&e4)); + REQUIRE_FALSE(history.contains(&e5)); + REQUIRE_FALSE(history.contains(&e6)); + REQUIRE_FALSE(history.contains(&e7)); + } + + SECTION("Histories with a single event") + { + SECTION("Root event's history has a single event") + { + History history(&e1); + REQUIRE(history.get_all_events() == EventSet({&e1})); + } + + SECTION("Check node e2") + { + History history(&e2); + REQUIRE(history.get_all_events() == EventSet({&e1, &e2})); + REQUIRE(history.contains(&e1)); + REQUIRE(history.contains(&e2)); + REQUIRE_FALSE(history.contains(&e3)); + REQUIRE_FALSE(history.contains(&e4)); + REQUIRE_FALSE(history.contains(&e5)); + REQUIRE_FALSE(history.contains(&e6)); + REQUIRE_FALSE(history.contains(&e7)); + } + + SECTION("Check node e3") + { + History history(&e3); + REQUIRE(history.get_all_events() == EventSet({&e1, &e2, &e3})); + REQUIRE(history.contains(&e1)); + REQUIRE(history.contains(&e2)); + REQUIRE(history.contains(&e3)); + REQUIRE_FALSE(history.contains(&e4)); + REQUIRE_FALSE(history.contains(&e5)); + REQUIRE_FALSE(history.contains(&e6)); + REQUIRE_FALSE(history.contains(&e7)); + } + + SECTION("Check node e4") + { + History history(&e4); + REQUIRE(history.get_all_events() == EventSet({&e1, &e2, &e4})); + REQUIRE(history.contains(&e1)); + REQUIRE(history.contains(&e2)); + REQUIRE_FALSE(history.contains(&e3)); + REQUIRE(history.contains(&e4)); + REQUIRE_FALSE(history.contains(&e5)); + REQUIRE_FALSE(history.contains(&e6)); + REQUIRE_FALSE(history.contains(&e7)); + } + + SECTION("Check node e5") + { + History history(&e5); + REQUIRE(history.get_all_events() == EventSet({&e1, &e2, &e6, &e5})); + REQUIRE(history.contains(&e1)); + REQUIRE(history.contains(&e2)); + REQUIRE_FALSE(history.contains(&e3)); + REQUIRE_FALSE(history.contains(&e4)); + REQUIRE(history.contains(&e5)); + REQUIRE(history.contains(&e6)); + REQUIRE_FALSE(history.contains(&e7)); + } + + SECTION("Check node e6") + { + History history(&e6); + REQUIRE(history.get_all_events() == EventSet({&e1, &e6})); + REQUIRE(history.contains(&e1)); + REQUIRE_FALSE(history.contains(&e2)); + REQUIRE_FALSE(history.contains(&e3)); + REQUIRE_FALSE(history.contains(&e4)); + REQUIRE_FALSE(history.contains(&e5)); + REQUIRE(history.contains(&e6)); + REQUIRE_FALSE(history.contains(&e7)); + } + + SECTION("Check node e7") + { + History history(&e7); + REQUIRE(history.get_all_events() == EventSet({&e1, &e6, &e7})); + REQUIRE(history.contains(&e1)); + REQUIRE_FALSE(history.contains(&e2)); + REQUIRE_FALSE(history.contains(&e3)); + REQUIRE_FALSE(history.contains(&e4)); + REQUIRE_FALSE(history.contains(&e5)); + REQUIRE(history.contains(&e6)); + REQUIRE(history.contains(&e7)); + } + } + + SECTION("Histories with multiple nodes") + { + SECTION("Nodes contained in the same branch") + { + History history_e1e2(EventSet({&e1, &e2})); + REQUIRE(history_e1e2.get_all_events() == EventSet({&e1, &e2})); + REQUIRE(history_e1e2.contains(&e1)); + REQUIRE(history_e1e2.contains(&e2)); + REQUIRE_FALSE(history_e1e2.contains(&e3)); + REQUIRE_FALSE(history_e1e2.contains(&e4)); + REQUIRE_FALSE(history_e1e2.contains(&e5)); + REQUIRE_FALSE(history_e1e2.contains(&e6)); + REQUIRE_FALSE(history_e1e2.contains(&e7)); + + History history_e1e3(EventSet({&e1, &e3})); + REQUIRE(history_e1e3.get_all_events() == EventSet({&e1, &e2, &e3})); + REQUIRE(history_e1e3.contains(&e1)); + REQUIRE(history_e1e3.contains(&e2)); + REQUIRE(history_e1e3.contains(&e3)); + REQUIRE_FALSE(history_e1e3.contains(&e4)); + REQUIRE_FALSE(history_e1e3.contains(&e5)); + REQUIRE_FALSE(history_e1e3.contains(&e6)); + REQUIRE_FALSE(history_e1e3.contains(&e7)); + + History history_e6e7(EventSet({&e6, &e7})); + REQUIRE(history_e6e7.get_all_events() == EventSet({&e1, &e6, &e7})); + REQUIRE(history_e6e7.contains(&e1)); + REQUIRE_FALSE(history_e6e7.contains(&e2)); + REQUIRE_FALSE(history_e6e7.contains(&e3)); + REQUIRE_FALSE(history_e6e7.contains(&e4)); + REQUIRE_FALSE(history_e6e7.contains(&e5)); + REQUIRE(history_e6e7.contains(&e6)); + REQUIRE(history_e6e7.contains(&e7)); + } + + SECTION("Nodes with the same ancestor") + { + History history_e3e5(EventSet({&e3, &e5})); + REQUIRE(history_e3e5.get_all_events() == EventSet({&e1, &e2, &e3, &e5, &e6})); + REQUIRE(history_e3e5.contains(&e1)); + REQUIRE(history_e3e5.contains(&e2)); + REQUIRE(history_e3e5.contains(&e3)); + REQUIRE_FALSE(history_e3e5.contains(&e4)); + REQUIRE(history_e3e5.contains(&e5)); + REQUIRE(history_e3e5.contains(&e6)); + REQUIRE_FALSE(history_e3e5.contains(&e7)); + } + + SECTION("Nodes with different ancestors") + { + History history_e4e7(EventSet({&e4, &e7})); + REQUIRE(history_e4e7.get_all_events() == EventSet({&e1, &e2, &e4, &e6, &e7})); + REQUIRE(history_e4e7.contains(&e1)); + REQUIRE(history_e4e7.contains(&e2)); + REQUIRE_FALSE(history_e4e7.contains(&e3)); + REQUIRE(history_e4e7.contains(&e4)); + REQUIRE_FALSE(history_e4e7.contains(&e5)); + REQUIRE(history_e4e7.contains(&e6)); + REQUIRE(history_e4e7.contains(&e7)); + } + + SECTION("Large number of nodes") + { + History history_e2356(EventSet({&e2, &e3, &e5, &e6})); + REQUIRE(history_e2356.get_all_events() == EventSet({&e1, &e2, &e3, &e5, &e6})); + REQUIRE(history_e2356.contains(&e1)); + REQUIRE(history_e2356.contains(&e2)); + REQUIRE(history_e2356.contains(&e3)); + REQUIRE_FALSE(history_e2356.contains(&e4)); + REQUIRE(history_e2356.contains(&e5)); + REQUIRE(history_e2356.contains(&e6)); + REQUIRE_FALSE(history_e2356.contains(&e7)); + } + + SECTION("History of the entire graph yields the entire graph") + { + History history(EventSet({&e1, &e2, &e3, &e4, &e5, &e6, &e7})); + REQUIRE(history.get_all_events() == EventSet({&e1, &e2, &e3, &e4, &e5, &e6, &e7})); + REQUIRE(history.contains(&e1)); + REQUIRE(history.contains(&e2)); + REQUIRE(history.contains(&e3)); + REQUIRE(history.contains(&e4)); + REQUIRE(history.contains(&e5)); + REQUIRE(history.contains(&e6)); + REQUIRE(history.contains(&e7)); + } + } +} diff --git a/src/mc/explo/udpor/Unfolding.cpp b/src/mc/explo/udpor/Unfolding.cpp new file mode 100644 index 0000000000..587d4e93c8 --- /dev/null +++ b/src/mc/explo/udpor/Unfolding.cpp @@ -0,0 +1,77 @@ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/udpor/Unfolding.hpp" + +#include + +namespace simgrid::mc::udpor { + +void Unfolding::mark_finished(const EventSet& events) +{ + for (const auto* e : events) { + mark_finished(e); + } +} + +void Unfolding::mark_finished(const UnfoldingEvent* e) +{ + if (e == nullptr) { + throw std::invalid_argument("Expected a non-null pointer to an event, but received NULL"); + } + this->U.remove(e); + this->G.insert(e); +} + +const UnfoldingEvent* Unfolding::insert(std::unique_ptr e) +{ + const UnfoldingEvent* handle = e.get(); + if (auto loc = this->global_events_.find(handle); loc != this->global_events_.end()) { + // This is bad: someone wrapped the raw event address twice + // in two different unique ptrs and attempted to + // insert it into the unfolding... + throw std::invalid_argument("Attempted to insert an unfolding event owned twice." + "This will result in a double free error and must be fixed."); + } + + // Attempt to search first for an event in `U`. If it exists, we use that event + // instead of `e` since it is semantically equivalent to `e` (i.e. `e` is + // effectively already contained in the unfolding) + if (auto loc = std::find_if(U.begin(), U.end(), [=](const auto e_i) { return *e_i == *handle; }); loc != U.end()) { + // Return the handle to that event and ignore adding in a duplicate event + return *loc; + } + + // Then look for `e` in `G`. It's possible `e` was already constructed + // in the past, in which case we can simply re-use it. + // + // Note, though, that in this case we must move the event in `G` into + // `U`: we've inserted `e` into the unfolding, so we expect it to be in `U` + if (auto loc = std::find_if(G.begin(), G.end(), [=](const auto e_i) { return *e_i == *handle; }); loc != G.end()) { + const auto* e_equiv = *loc; + G.remove(e_equiv); + U.insert(e_equiv); + return e_equiv; + } + + // Otherwise `e` is truly a "new" event + this->U.insert(handle); + this->event_handles.insert(handle); + this->global_events_[handle] = std::move(e); + return handle; +} + +EventSet Unfolding::get_immediate_conflicts_of(const UnfoldingEvent* e) const +{ + EventSet immediate_conflicts; + for (const auto* event : U) { + if (event->immediately_conflicts_with(e)) { + immediate_conflicts.insert(event); + } + } + return immediate_conflicts; +} + +} // namespace simgrid::mc::udpor diff --git a/src/mc/explo/udpor/Unfolding.hpp b/src/mc/explo/udpor/Unfolding.hpp new file mode 100644 index 0000000000..3fa80f219d --- /dev/null +++ b/src/mc/explo/udpor/Unfolding.hpp @@ -0,0 +1,123 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_UDPOR_UNFOLDING_HPP +#define SIMGRID_MC_UDPOR_UNFOLDING_HPP + +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" +#include "src/mc/explo/udpor/udpor_forward.hpp" + +#include +#include + +namespace simgrid::mc::udpor { + +class Unfolding { +public: + Unfolding() = default; + Unfolding& operator=(Unfolding&&) = default; + Unfolding(Unfolding&&) = default; + + auto begin() const { return this->event_handles.begin(); } + auto end() const { return this->event_handles.end(); } + auto cbegin() const { return this->event_handles.cbegin(); } + auto cend() const { return this->event_handles.cend(); } + size_t size() const { return this->event_handles.size(); } + bool empty() const { return this->event_handles.empty(); } + + /** + * @brief Moves an event from UDPOR's global set `U` to + * the global set `G` + */ + void mark_finished(const UnfoldingEvent* e); + + /** + * @brief Moves all events in a set from UDPOR's global + * set `U` to the global set `G` + */ + void mark_finished(const EventSet& events); + + /// @brief Adds a new event `e` to the Unfolding if that + /// event is not equivalent to any of those already contained + /// in the unfolding + const UnfoldingEvent* insert(std::unique_ptr e); + + /** + * @brief Informs the unfolding of a (potentially) new event + * + * The unfolding of a concurrent program is a well-defined + * structure. Given the labeled transition system (LTS) of + * a program, the unfolding of that program can be determined + * algorithmically. However, UDPOR does not a priori know the structure of the + * unfolding as it performs its exploration. Thus, events in the + * unfolding are "discovered" as they are encountered, specifically + * when computing the extension sets of the configurations that + * UDPOR decides to search. + * + * This lends itself to the following problem: the extension sets + * of two different configurations may overlap one another. That + * is, for two configurations C and C' explored by UDPOR where C != C', + * + * ex(C) - ex(C') != empty + * + * Hence, when extending both `C` and `C'`, any events contained in + * the intersection of ex(C) and ex(C') will be attempted to be added + * twice. The unfolding will notice that these events have already + * been added and simply return the event already added to the unfolding + * + * @tparam ...Args arguments passed to the `UnfoldingEvent` constructor + * @return the handle to either the newly created event OR + * to an equivalent event that was already noted by the unfolding + * at some point in the past + */ + template const UnfoldingEvent* discover_event(Args&&... args) + { + auto candidate_event = std::make_unique(std::forward(args)...); + return insert(std::move(candidate_event)); + } + + /// @brief Computes "#ⁱ_U(e)" for the given event, where `U` is the set + /// of the events in this unfolding + EventSet get_immediate_conflicts_of(const UnfoldingEvent*) const; + +private: + /** + * @brief All of the events that are currently are a part of the unfolding + * + * @invariant Each unfolding event maps itself to the owner of that event, + * i.e. the unique pointer that manages the data at the address. The Unfolding owns all + * of the addresses that are referenced by EventSet instances and Configuration + * instances. UDPOR guarantees that events are persisted for as long as necessary + */ + std::unordered_map> global_events_; + + /** + * @brief: The collection of events in the unfolding + * + * @invariant: All of the events in this set are elements of `global_events_` + * and is kept updated at the same time as `global_events_` + * + * @note: This is for the convenience of iteration over the unfolding + */ + EventSet event_handles; + + /** + * @brief: The collection of events in the unfolding that are "important" + */ + EventSet U; + + /** + * @brief The "irrelevant" portions of the unfolding that do not need to be kept + * around to ensure that UDPOR functions correctly + * + * The set `G` is another global variable maintained by the UDPOR algorithm which + * is used to keep track of all events which used to be important to UDPOR. + */ + EventSet G; +}; + +} // namespace simgrid::mc::udpor +#endif diff --git a/src/mc/explo/udpor/UnfoldingEvent.cpp b/src/mc/explo/udpor/UnfoldingEvent.cpp new file mode 100644 index 0000000000..8651a2ac42 --- /dev/null +++ b/src/mc/explo/udpor/UnfoldingEvent.cpp @@ -0,0 +1,147 @@ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" +#include "src/mc/explo/udpor/History.hpp" + +#include +#include +#include + +namespace simgrid::mc::udpor { + +UnfoldingEvent::UnfoldingEvent(std::initializer_list init_list) + : UnfoldingEvent(EventSet(std::move(init_list))) +{ +} + +UnfoldingEvent::UnfoldingEvent(EventSet immediate_causes, std::shared_ptr transition) + : associated_transition(std::move(transition)), immediate_causes(std::move(immediate_causes)) +{ + static uint64_t event_id = 0; + this->id = ++event_id; +} + +bool UnfoldingEvent::operator==(const UnfoldingEvent& other) const +{ + // Intrinsic identity check + if (this == &other) { + return true; + } + // Two events are equivalent iff: + // 1. they have the same action + // 2. they have the same history + // + // NOTE: All unfolding event objects are created in reference to + // an `Unfolding` object which owns them. Hence, the references + // they contain to other events in the unfolding can + // be used as intrinsic identities (i.e. we don't need to + // recursively check if each of our causes has a `==` in + // the other event's causes) + return associated_transition->aid_ == other.associated_transition->aid_ && + associated_transition->type_ == other.associated_transition->type_ && + associated_transition->times_considered_ == other.associated_transition->times_considered_ && + this->immediate_causes == other.immediate_causes; +} + +std::string UnfoldingEvent::to_string() const +{ + std::string dependencies_string; + + dependencies_string += "["; + for (const auto* e : immediate_causes) { + dependencies_string += " "; + dependencies_string += e->to_string(); + dependencies_string += " and "; + } + dependencies_string += "]"; + + return xbt::string_printf("Event %lu, Actor %ld: %s (%lu dependencies: %s)", this->id, associated_transition->aid_, + associated_transition->to_string().c_str(), immediate_causes.size(), + dependencies_string.c_str()); +} + +EventSet UnfoldingEvent::get_history() const +{ + EventSet local_config = get_local_config(); + local_config.remove(this); + return local_config; +} + +EventSet UnfoldingEvent::get_local_config() const +{ + return History(this).get_all_events(); +} + +bool UnfoldingEvent::related_to(const UnfoldingEvent* other) const +{ + return this->in_history_of(other) || other->in_history_of(this); +} + +bool UnfoldingEvent::in_history_of(const UnfoldingEvent* other) const +{ + return History(other).contains(this); +} + +bool UnfoldingEvent::conflicts_with(const UnfoldingEvent* other) const +{ + // Events that have a causal relation never are in conflict + // in an unfolding structure. Two events in conflict must + // not be contained in each other's histories + if (related_to(other)) { + return false; + } + + const EventSet my_history = get_local_config(); + const EventSet other_history = other->get_local_config(); + const EventSet unique_to_me = my_history.subtracting(other_history); + const EventSet unique_to_other = other_history.subtracting(my_history); + + const bool conflicts_with_me = std::any_of(unique_to_me.begin(), unique_to_me.end(), + [&](const UnfoldingEvent* e) { return e->is_dependent_with(other); }); + const bool conflicts_with_other = std::any_of(unique_to_other.begin(), unique_to_other.end(), + [&](const UnfoldingEvent* e) { return e->is_dependent_with(this); }); + return conflicts_with_me || conflicts_with_other; +} + +bool UnfoldingEvent::conflicts_with_any(const EventSet& events) const +{ + return std::any_of(events.begin(), events.end(), [&](const auto e) { return e->conflicts_with(this); }); +} + +bool UnfoldingEvent::immediately_conflicts_with(const UnfoldingEvent* other) const +{ + // They have to be in conflict at a minimum + if (not conflicts_with(other)) { + return false; + } + + auto combined_events = History(EventSet{this, other}).get_all_events(); + + // See the definition of immediate conflicts in the original paper on UDPOR + combined_events.remove(this); + if (not combined_events.is_valid_configuration()) + return false; + combined_events.insert(this); + + combined_events.remove(other); + if (not combined_events.is_valid_configuration()) + return false; + combined_events.insert(other); + + return true; +} + +bool UnfoldingEvent::is_dependent_with(const Transition* t) const +{ + return associated_transition->depends(t); +} + +bool UnfoldingEvent::is_dependent_with(const UnfoldingEvent* other) const +{ + return is_dependent_with(other->associated_transition.get()); +} + +} // namespace simgrid::mc::udpor diff --git a/src/mc/explo/udpor/UnfoldingEvent.hpp b/src/mc/explo/udpor/UnfoldingEvent.hpp new file mode 100644 index 0000000000..98f40ad996 --- /dev/null +++ b/src/mc/explo/udpor/UnfoldingEvent.hpp @@ -0,0 +1,104 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_UDPOR_UNFOLDING_EVENT_HPP +#define SIMGRID_MC_UDPOR_UNFOLDING_EVENT_HPP + +#include "src/mc/explo/udpor/EventSet.hpp" +#include "src/mc/explo/udpor/udpor_forward.hpp" +#include "src/mc/transition/Transition.hpp" + +#include +#include +#include + +namespace simgrid::mc::udpor { + +class UnfoldingEvent { +public: + explicit UnfoldingEvent(std::initializer_list init_list); + UnfoldingEvent(EventSet immediate_causes = EventSet(), + std::shared_ptr transition = std::make_unique()); + + UnfoldingEvent(const UnfoldingEvent&) = default; + UnfoldingEvent& operator=(UnfoldingEvent const&) = default; + UnfoldingEvent(UnfoldingEvent&&) = default; + + EventSet get_history() const; + EventSet get_local_config() const; + bool in_history_of(const UnfoldingEvent* other) const; + + /** + * @brief Whether or not the given event is a decendant + * of or an ancestor of the given event + */ + bool related_to(const UnfoldingEvent* other) const; + + /// @brief Whether or not this event is in conflict with + /// the given one (i.e. whether `this # other`) + bool conflicts_with(const UnfoldingEvent* other) const; + + /// @brief Whether or not this event is in conflict with + /// any event in the given set + bool conflicts_with_any(const EventSet& events) const; + + /// @brief Computes "this #ⁱ other" + bool immediately_conflicts_with(const UnfoldingEvent* other) const; + bool is_dependent_with(const Transition*) const; + bool is_dependent_with(const UnfoldingEvent* other) const; + + unsigned get_id() const { return this->id; } + aid_t get_actor() const { return get_transition()->aid_; } + const EventSet& get_immediate_causes() const { return this->immediate_causes; } + Transition* get_transition() const { return this->associated_transition.get(); } + + void set_transition(std::shared_ptr t) { this->associated_transition = std::move(t); } + + std::string to_string() const; + + bool operator==(const UnfoldingEvent&) const; + bool operator!=(const UnfoldingEvent& other) const { return not(*this == other); } + +private: + /** + * @brief The transition that UDPOR "attaches" to this + * specific event for later use while computing e.g. extension + * sets + * + * The transition points to that of a particular actor + * in the state reached by the configuration C (recall + * this is denoted `state(C)`) that excludes this event. + * In other words, this transition was the "next" event + * of the actor that executes it in `state(C)`. + */ + std::shared_ptr associated_transition; + + /** + * @brief The "immediate" causes of this event. + * + * An event `e` is an immediate cause of an event `e'` if + * + * 1. e < e' + * 2. There is no event `e''` in E such that + * `e < e''` and `e'' < e'` + * + * Intuitively, an immediate cause "happened right before" + * this event was executed. It is sufficient to store + * only the immediate causes of any event `e`, as any indirect + * causes of that event would either be an indirect cause + * or an immediate cause of the immediate causes of `e`, and + * so on. + */ + EventSet immediate_causes; + + /** + * @brief An identifier which is used to sort events + * deterministically + */ + unsigned long id = 0; +}; + +} // namespace simgrid::mc::udpor +#endif \ No newline at end of file diff --git a/src/mc/explo/udpor/UnfoldingEvent_test.cpp b/src/mc/explo/udpor/UnfoldingEvent_test.cpp new file mode 100644 index 0000000000..df316fdb7b --- /dev/null +++ b/src/mc/explo/udpor/UnfoldingEvent_test.cpp @@ -0,0 +1,554 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" +#include "src/mc/explo/udpor/udpor_tests_private.hpp" + +using namespace simgrid::mc; +using namespace simgrid::mc::udpor; + +TEST_CASE("simgrid::mc::udpor::UnfoldingEvent: Semantic Equivalence Tests") +{ + UnfoldingEvent e1(EventSet(), std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + UnfoldingEvent e3(EventSet({&e1}), std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + UnfoldingEvent e4(EventSet({&e1}), std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + + UnfoldingEvent e5(EventSet({&e1, &e3, &e2}), std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + UnfoldingEvent e6(EventSet({&e1, &e3, &e2}), std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + UnfoldingEvent e7(EventSet({&e1, &e3, &e2}), std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + + SECTION("Equivalence is an equivalence relation") + { + SECTION("Equivalence is reflexive") + { + REQUIRE(e1 == e1); + REQUIRE(e2 == e2); + REQUIRE(e3 == e3); + REQUIRE(e4 == e4); + } + + SECTION("Equivalence is symmetric") + { + REQUIRE(e2 == e3); + REQUIRE(e3 == e2); + REQUIRE(e3 == e4); + REQUIRE(e4 == e3); + REQUIRE(e2 == e4); + REQUIRE(e4 == e2); + } + + SECTION("Equivalence is transitive") + { + REQUIRE(e2 == e3); + REQUIRE(e3 == e4); + REQUIRE(e2 == e4); + REQUIRE(e5 == e6); + REQUIRE(e6 == e7); + REQUIRE(e5 == e7); + } + } + + SECTION("Equivalence fails with different actors") + { + UnfoldingEvent e1_diff_actor(EventSet(), std::make_shared(Transition::Type::UNKNOWN, 1, 0)); + UnfoldingEvent e2_diff_actor(EventSet({&e1}), std::make_shared(Transition::Type::UNKNOWN, 1, 0)); + UnfoldingEvent e5_diff_actor(EventSet({&e1, &e3, &e2}), + std::make_shared(Transition::Type::UNKNOWN, 1, 0)); + REQUIRE(e1 != e1_diff_actor); + REQUIRE(e1 != e2_diff_actor); + REQUIRE(e1 != e5_diff_actor); + } + + SECTION("Equivalence fails with different transition types") + { + // NOTE: We're comparing the transition `type_` field directly. To avoid + // modifying the `Type` enum that exists in `Transition` just for the tests, + // we instead provide different values of `Transition::Type` to simulate + // the different types + UnfoldingEvent e1_diff_transition(EventSet(), + std::make_shared(Transition::Type::ACTOR_JOIN, 0, 0)); + UnfoldingEvent e2_diff_transition(EventSet({&e1}), + std::make_shared(Transition::Type::ACTOR_JOIN, 0, 0)); + UnfoldingEvent e5_diff_transition(EventSet({&e1, &e3, &e2}), + std::make_shared(Transition::Type::ACTOR_JOIN, 0, 0)); + REQUIRE(e1 != e1_diff_transition); + REQUIRE(e1 != e2_diff_transition); + REQUIRE(e1 != e5_diff_transition); + } + + SECTION("Equivalence fails with different `times_considered`") + { + // With a different number for `times_considered`, we know + UnfoldingEvent e1_diff_considered(EventSet(), std::make_shared(Transition::Type::UNKNOWN, 0, 1)); + UnfoldingEvent e2_diff_considered(EventSet({&e1}), + std::make_shared(Transition::Type::UNKNOWN, 0, 1)); + UnfoldingEvent e5_diff_considered(EventSet({&e1, &e3, &e2}), + std::make_shared(Transition::Type::UNKNOWN, 0, 1)); + REQUIRE(e1 != e1_diff_considered); + REQUIRE(e1 != e2_diff_considered); + REQUIRE(e1 != e5_diff_considered); + } + + SECTION("Equivalence fails with different immediate histories of events") + { + UnfoldingEvent e1_diff_hist(EventSet({&e2}), std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + UnfoldingEvent e2_diff_hist(EventSet({&e3}), std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + UnfoldingEvent e5_diff_hist(EventSet({&e1, &e2}), + std::make_shared(Transition::Type::UNKNOWN, 0, 0)); + REQUIRE(e1 != e1_diff_hist); + REQUIRE(e1 != e2_diff_hist); + REQUIRE(e1 != e5_diff_hist); + } +} + +TEST_CASE("simgrid::mc::udpor::UnfoldingEvent: Dependency/Conflict Tests") +{ + SECTION("Properties of the relations") + { + // The following tests concern the given event structure: + // e1 + // / / + // e2 e6 + // / / / + // e3 / / + // / / / + // e4 e5 e7 + // + // e5 and e6 are in conflict, e5 and e7 are in conflict, e2 and e6, and e2 ands e7 are in conflict + UnfoldingEvent e1(EventSet(), std::make_shared(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(0)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(0)); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared(1)); + UnfoldingEvent e5(EventSet({&e3}), std::make_shared(1)); + UnfoldingEvent e6(EventSet({&e1}), std::make_shared(2)); + UnfoldingEvent e7(EventSet({&e6, &e2}), std::make_shared(3)); + + SECTION("Dependency relation properties") + { + SECTION("Dependency is reflexive") + { + REQUIRE(e2.is_dependent_with(&e2)); + REQUIRE(e5.is_dependent_with(&e5)); + } + + SECTION("Dependency is symmetric") + { + REQUIRE(e2.is_dependent_with(&e6)); + REQUIRE(e6.is_dependent_with(&e2)); + } + + SECTION("Dependency is NOT necessarily transitive") + { + REQUIRE(e1.is_dependent_with(&e5)); + REQUIRE(e5.is_dependent_with(&e7)); + REQUIRE_FALSE(e1.is_dependent_with(&e7)); + } + } + + SECTION("Conflict relation properties") + { + SECTION("Conflict relation is irreflexive") + { + REQUIRE_FALSE(e1.conflicts_with(&e1)); + REQUIRE_FALSE(e2.conflicts_with(&e2)); + REQUIRE_FALSE(e3.conflicts_with(&e3)); + REQUIRE_FALSE(e4.conflicts_with(&e4)); + REQUIRE_FALSE(e5.conflicts_with(&e5)); + REQUIRE_FALSE(e6.conflicts_with(&e6)); + REQUIRE_FALSE(e7.conflicts_with(&e7)); + + REQUIRE_FALSE(e1.immediately_conflicts_with(&e1)); + REQUIRE_FALSE(e2.immediately_conflicts_with(&e2)); + REQUIRE_FALSE(e3.immediately_conflicts_with(&e3)); + REQUIRE_FALSE(e4.immediately_conflicts_with(&e4)); + REQUIRE_FALSE(e5.immediately_conflicts_with(&e5)); + REQUIRE_FALSE(e6.immediately_conflicts_with(&e6)); + REQUIRE_FALSE(e7.immediately_conflicts_with(&e7)); + } + + SECTION("Conflict relation is symmetric") + { + REQUIRE(e5.conflicts_with(&e6)); + REQUIRE(e6.conflicts_with(&e5)); + REQUIRE(e5.immediately_conflicts_with(&e4)); + REQUIRE(e4.immediately_conflicts_with(&e5)); + } + } + } + + SECTION("Testing with no dependencies whatsoever") + { + // The following tests concern the given event structure: + // e1 + // / / + // e2 e6 + // / / / + // e3 / / + // / / / + // e4 e5 e7 + UnfoldingEvent e1(EventSet(), std::make_shared(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(1)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(2)); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared(3)); + UnfoldingEvent e5(EventSet({&e3}), std::make_shared(4)); + UnfoldingEvent e6(EventSet({&e1}), std::make_shared(5)); + UnfoldingEvent e7(EventSet({&e6, &e2}), std::make_shared(6)); + + // Since everyone's actions are independent of one another, we expect + // that there are no conflicts between each pair of events (except with + // the same event itself) + SECTION("Mutual dependencies") + { + CHECK(e1.is_dependent_with(&e1)); + CHECK_FALSE(e1.is_dependent_with(&e2)); + CHECK_FALSE(e1.is_dependent_with(&e3)); + CHECK_FALSE(e1.is_dependent_with(&e4)); + CHECK_FALSE(e1.is_dependent_with(&e5)); + CHECK_FALSE(e1.is_dependent_with(&e6)); + CHECK_FALSE(e1.is_dependent_with(&e7)); + + CHECK(e2.is_dependent_with(&e2)); + CHECK_FALSE(e2.is_dependent_with(&e3)); + CHECK_FALSE(e2.is_dependent_with(&e4)); + CHECK_FALSE(e2.is_dependent_with(&e5)); + CHECK_FALSE(e2.is_dependent_with(&e6)); + CHECK_FALSE(e2.is_dependent_with(&e7)); + + CHECK(e3.is_dependent_with(&e3)); + CHECK_FALSE(e3.is_dependent_with(&e4)); + CHECK_FALSE(e3.is_dependent_with(&e5)); + CHECK_FALSE(e3.is_dependent_with(&e6)); + CHECK_FALSE(e3.is_dependent_with(&e7)); + + CHECK(e4.is_dependent_with(&e4)); + CHECK_FALSE(e4.is_dependent_with(&e5)); + CHECK_FALSE(e4.is_dependent_with(&e6)); + CHECK_FALSE(e4.is_dependent_with(&e7)); + + CHECK(e5.is_dependent_with(&e5)); + CHECK_FALSE(e5.is_dependent_with(&e6)); + CHECK_FALSE(e5.is_dependent_with(&e7)); + + CHECK(e6.is_dependent_with(&e6)); + CHECK_FALSE(e6.is_dependent_with(&e7)); + + CHECK(e7.is_dependent_with(&e7)); + } + + SECTION("Mutual conflicts") + { + CHECK_FALSE(e1.conflicts_with(&e1)); + CHECK_FALSE(e1.conflicts_with(&e2)); + CHECK_FALSE(e1.conflicts_with(&e3)); + CHECK_FALSE(e1.conflicts_with(&e4)); + CHECK_FALSE(e1.conflicts_with(&e5)); + CHECK_FALSE(e1.conflicts_with(&e6)); + CHECK_FALSE(e1.conflicts_with(&e7)); + + CHECK_FALSE(e2.conflicts_with(&e1)); + CHECK_FALSE(e2.conflicts_with(&e2)); + CHECK_FALSE(e2.conflicts_with(&e3)); + CHECK_FALSE(e2.conflicts_with(&e4)); + CHECK_FALSE(e2.conflicts_with(&e5)); + CHECK_FALSE(e2.conflicts_with(&e6)); + CHECK_FALSE(e2.conflicts_with(&e7)); + + CHECK_FALSE(e3.conflicts_with(&e1)); + CHECK_FALSE(e3.conflicts_with(&e2)); + CHECK_FALSE(e3.conflicts_with(&e3)); + CHECK_FALSE(e3.conflicts_with(&e4)); + CHECK_FALSE(e3.conflicts_with(&e5)); + CHECK_FALSE(e3.conflicts_with(&e6)); + CHECK_FALSE(e3.conflicts_with(&e7)); + + CHECK_FALSE(e4.conflicts_with(&e1)); + CHECK_FALSE(e4.conflicts_with(&e2)); + CHECK_FALSE(e4.conflicts_with(&e3)); + CHECK_FALSE(e4.conflicts_with(&e4)); + CHECK_FALSE(e4.conflicts_with(&e5)); + CHECK_FALSE(e4.conflicts_with(&e6)); + CHECK_FALSE(e4.conflicts_with(&e7)); + + CHECK_FALSE(e5.conflicts_with(&e1)); + CHECK_FALSE(e5.conflicts_with(&e2)); + CHECK_FALSE(e5.conflicts_with(&e3)); + CHECK_FALSE(e5.conflicts_with(&e4)); + CHECK_FALSE(e5.conflicts_with(&e5)); + CHECK_FALSE(e5.conflicts_with(&e6)); + CHECK_FALSE(e5.conflicts_with(&e7)); + + CHECK_FALSE(e6.conflicts_with(&e1)); + CHECK_FALSE(e6.conflicts_with(&e2)); + CHECK_FALSE(e6.conflicts_with(&e3)); + CHECK_FALSE(e6.conflicts_with(&e4)); + CHECK_FALSE(e6.conflicts_with(&e5)); + CHECK_FALSE(e6.conflicts_with(&e6)); + CHECK_FALSE(e6.conflicts_with(&e7)); + + CHECK_FALSE(e7.conflicts_with(&e1)); + CHECK_FALSE(e7.conflicts_with(&e2)); + CHECK_FALSE(e7.conflicts_with(&e3)); + CHECK_FALSE(e7.conflicts_with(&e4)); + CHECK_FALSE(e7.conflicts_with(&e5)); + CHECK_FALSE(e7.conflicts_with(&e6)); + CHECK_FALSE(e7.conflicts_with(&e7)); + } + } + + SECTION("Testing with some conflicts") + { + // The following tests concern the given event structure: + // e1 + // / / + // e2 e6 + // / / / + // e3 / / + // / / / + // e4 e5 e7 + UnfoldingEvent e1(EventSet(), std::make_shared(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(1)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(2)); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared(3)); + UnfoldingEvent e5(EventSet({&e3}), std::make_shared(4)); + UnfoldingEvent e6(EventSet({&e1}), std::make_shared(5)); + UnfoldingEvent e7(EventSet({&e6, &e2}), std::make_shared(6)); + + // Since everyone's actions are independent of one another, we expect + // that there are no conflicts between each pair of events (except the pair + // with the event and itself) + SECTION("Mutual dependencies") + { + CHECK(e1.is_dependent_with(&e1)); + CHECK(e1.is_dependent_with(&e2)); + CHECK_FALSE(e1.is_dependent_with(&e3)); + CHECK_FALSE(e1.is_dependent_with(&e4)); + CHECK_FALSE(e1.is_dependent_with(&e5)); + CHECK_FALSE(e1.is_dependent_with(&e6)); + CHECK(e1.is_dependent_with(&e7)); + + CHECK(e2.is_dependent_with(&e2)); + CHECK_FALSE(e2.is_dependent_with(&e3)); + CHECK_FALSE(e2.is_dependent_with(&e4)); + CHECK_FALSE(e2.is_dependent_with(&e5)); + CHECK_FALSE(e2.is_dependent_with(&e6)); + CHECK(e2.is_dependent_with(&e7)); + + CHECK(e3.is_dependent_with(&e3)); + CHECK_FALSE(e3.is_dependent_with(&e4)); + CHECK_FALSE(e3.is_dependent_with(&e5)); + CHECK_FALSE(e3.is_dependent_with(&e6)); + CHECK_FALSE(e3.is_dependent_with(&e7)); + + CHECK(e4.is_dependent_with(&e4)); + CHECK_FALSE(e4.is_dependent_with(&e5)); + CHECK_FALSE(e4.is_dependent_with(&e6)); + CHECK_FALSE(e4.is_dependent_with(&e7)); + + CHECK(e5.is_dependent_with(&e5)); + CHECK_FALSE(e5.is_dependent_with(&e6)); + CHECK_FALSE(e5.is_dependent_with(&e7)); + + CHECK(e6.is_dependent_with(&e6)); + CHECK_FALSE(e6.is_dependent_with(&e7)); + + CHECK(e7.is_dependent_with(&e7)); + } + + SECTION("Mutual conflicts") + { + // Although e1 is dependent with e1, e2, and e7, + // since they are related to one another, they are not + // considered to be in conflict + CHECK_FALSE(e1.conflicts_with(&e1)); + CHECK_FALSE(e1.conflicts_with(&e2)); + CHECK_FALSE(e1.conflicts_with(&e3)); + CHECK_FALSE(e1.conflicts_with(&e4)); + CHECK_FALSE(e1.conflicts_with(&e5)); + CHECK_FALSE(e1.conflicts_with(&e6)); + CHECK_FALSE(e1.conflicts_with(&e7)); + + // Same goes for e2 with e2 and e7 + CHECK_FALSE(e2.conflicts_with(&e1)); + CHECK_FALSE(e2.conflicts_with(&e2)); + CHECK_FALSE(e2.conflicts_with(&e3)); + CHECK_FALSE(e2.conflicts_with(&e4)); + CHECK_FALSE(e2.conflicts_with(&e5)); + CHECK_FALSE(e2.conflicts_with(&e6)); + CHECK_FALSE(e2.conflicts_with(&e7)); + + CHECK_FALSE(e3.conflicts_with(&e1)); + CHECK_FALSE(e3.conflicts_with(&e2)); + CHECK_FALSE(e3.conflicts_with(&e3)); + CHECK_FALSE(e3.conflicts_with(&e4)); + CHECK_FALSE(e3.conflicts_with(&e5)); + CHECK_FALSE(e3.conflicts_with(&e6)); + CHECK_FALSE(e3.conflicts_with(&e7)); + + CHECK_FALSE(e4.conflicts_with(&e1)); + CHECK_FALSE(e4.conflicts_with(&e2)); + CHECK_FALSE(e4.conflicts_with(&e3)); + CHECK_FALSE(e4.conflicts_with(&e4)); + CHECK_FALSE(e4.conflicts_with(&e5)); + CHECK_FALSE(e4.conflicts_with(&e6)); + CHECK_FALSE(e4.conflicts_with(&e7)); + + CHECK_FALSE(e5.conflicts_with(&e1)); + CHECK_FALSE(e5.conflicts_with(&e2)); + CHECK_FALSE(e5.conflicts_with(&e3)); + CHECK_FALSE(e5.conflicts_with(&e4)); + CHECK_FALSE(e5.conflicts_with(&e5)); + CHECK_FALSE(e5.conflicts_with(&e6)); + CHECK_FALSE(e5.conflicts_with(&e7)); + + CHECK_FALSE(e6.conflicts_with(&e1)); + CHECK_FALSE(e6.conflicts_with(&e2)); + CHECK_FALSE(e6.conflicts_with(&e3)); + CHECK_FALSE(e6.conflicts_with(&e4)); + CHECK_FALSE(e6.conflicts_with(&e5)); + CHECK_FALSE(e6.conflicts_with(&e6)); + CHECK_FALSE(e6.conflicts_with(&e7)); + + CHECK_FALSE(e7.conflicts_with(&e1)); + CHECK_FALSE(e7.conflicts_with(&e2)); + CHECK_FALSE(e7.conflicts_with(&e3)); + CHECK_FALSE(e7.conflicts_with(&e4)); + CHECK_FALSE(e7.conflicts_with(&e5)); + CHECK_FALSE(e7.conflicts_with(&e6)); + CHECK_FALSE(e7.conflicts_with(&e7)); + } + } + + SECTION("More complicated conflicts") + { + // The following tests concern the given event structure: + // e1 + // / / + // e2 e6 + // / / + // e3 / + // / / e7 + // e4 e5 + UnfoldingEvent e1(EventSet(), std::make_shared(0)); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared(1)); + UnfoldingEvent e3(EventSet({&e2}), std::make_shared(2)); + UnfoldingEvent e4(EventSet({&e3}), std::make_shared(3)); + UnfoldingEvent e5(EventSet({&e3}), std::make_shared(4)); + UnfoldingEvent e6(EventSet({&e1}), std::make_shared(5)); + UnfoldingEvent e7(EventSet({&e6}), std::make_shared(6)); + + CHECK_FALSE(e1.conflicts_with(&e1)); + CHECK_FALSE(e1.conflicts_with(&e2)); + CHECK_FALSE(e1.conflicts_with(&e3)); + CHECK_FALSE(e1.conflicts_with(&e4)); + CHECK_FALSE(e1.conflicts_with(&e5)); + CHECK_FALSE(e1.conflicts_with(&e6)); + CHECK_FALSE(e1.conflicts_with(&e7)); + + // e2 conflicts with e6. Since e6 < e7, + // e2 also conflicts with e7 + CHECK_FALSE(e2.conflicts_with(&e1)); + CHECK_FALSE(e2.conflicts_with(&e2)); + CHECK_FALSE(e2.conflicts_with(&e3)); + CHECK_FALSE(e2.conflicts_with(&e4)); + CHECK_FALSE(e2.conflicts_with(&e5)); + CHECK(e2.conflicts_with(&e6)); + REQUIRE(e2.conflicts_with(&e7)); + + // e3 and e6 are dependent and unrelated, so they conflict + CHECK_FALSE(e3.conflicts_with(&e1)); + CHECK_FALSE(e3.conflicts_with(&e2)); + CHECK_FALSE(e3.conflicts_with(&e3)); + CHECK_FALSE(e3.conflicts_with(&e4)); + CHECK_FALSE(e3.conflicts_with(&e5)); + CHECK(e3.conflicts_with(&e6)); + CHECK_FALSE(e3.conflicts_with(&e7)); + + // Since e3 and e6 conflict and e3 < e4, e4 and e6 conflict + CHECK_FALSE(e4.conflicts_with(&e1)); + CHECK_FALSE(e4.conflicts_with(&e2)); + CHECK_FALSE(e4.conflicts_with(&e3)); + CHECK_FALSE(e4.conflicts_with(&e4)); + CHECK_FALSE(e4.conflicts_with(&e5)); + CHECK(e4.conflicts_with(&e6)); + CHECK_FALSE(e4.conflicts_with(&e7)); + + // Likewise for e5 + CHECK_FALSE(e5.conflicts_with(&e1)); + CHECK_FALSE(e5.conflicts_with(&e2)); + CHECK_FALSE(e5.conflicts_with(&e3)); + CHECK_FALSE(e5.conflicts_with(&e4)); + CHECK_FALSE(e5.conflicts_with(&e5)); + CHECK(e5.conflicts_with(&e6)); + CHECK_FALSE(e5.conflicts_with(&e7)); + + // Conflicts are symmetric + CHECK_FALSE(e6.conflicts_with(&e1)); + CHECK(e6.conflicts_with(&e2)); + CHECK(e6.conflicts_with(&e3)); + CHECK(e6.conflicts_with(&e4)); + CHECK(e6.conflicts_with(&e5)); + CHECK_FALSE(e6.conflicts_with(&e6)); + CHECK_FALSE(e6.conflicts_with(&e7)); + + CHECK_FALSE(e7.conflicts_with(&e1)); + CHECK(e7.conflicts_with(&e2)); + CHECK_FALSE(e7.conflicts_with(&e3)); + CHECK_FALSE(e7.conflicts_with(&e4)); + CHECK_FALSE(e7.conflicts_with(&e5)); + CHECK_FALSE(e7.conflicts_with(&e6)); + CHECK_FALSE(e7.conflicts_with(&e7)); + } +} + +TEST_CASE("simgrid::mc::udpor::UnfoldingEvent: Immediate Conflicts + Conflicts Stress Test") +{ + // The following tests concern the given event structure: + // e1 + // / / / + // e2 e3 e4 + // / / / + // e5 e10 + // / + // e6 + // / / + // e7 e8 + // / + // e9 + // + // Immediate conflicts: + // e2 + e3 + // e3 + e4 + // e2 + e4 + // + // NOTE: e7 + e8 ARE NOT in immediate conflict! The reason is that + // the set of events {e8, e6, e5, e3, e4, e1} is not a valid configuration, + // (nor is {e7, e6, e5, e3, e4, e1}) + // + // NOTE: e2/e3 + e10 are NOT in immediate conflict! EVEN THOUGH {e1, e4, e10} + // is a valid configuration, {e1, e2/e3, e4} is not (since e2/e3 and e4 conflict) + UnfoldingEvent e1(EventSet(), std::make_shared()); + UnfoldingEvent e2(EventSet({&e1}), std::make_shared()); + UnfoldingEvent e3(EventSet({&e1}), std::make_shared()); + UnfoldingEvent e4(EventSet({&e1}), std::make_shared()); + UnfoldingEvent e5(EventSet({&e3, &e4}), std::make_shared()); + UnfoldingEvent e6(EventSet({&e5}), std::make_shared()); + UnfoldingEvent e7(EventSet({&e6}), std::make_shared()); + UnfoldingEvent e8(EventSet({&e6}), std::make_shared()); + UnfoldingEvent e9(EventSet({&e8}), std::make_shared()); + UnfoldingEvent e10(EventSet({&e4}), std::make_shared()); + + REQUIRE(e2.immediately_conflicts_with(&e3)); + REQUIRE(e3.immediately_conflicts_with(&e4)); + REQUIRE(e2.immediately_conflicts_with(&e4)); + + REQUIRE(e2.conflicts_with(&e10)); + REQUIRE(e3.conflicts_with(&e10)); + REQUIRE(e7.conflicts_with(&e8)); + REQUIRE_FALSE(e2.immediately_conflicts_with(&e10)); + REQUIRE_FALSE(e3.immediately_conflicts_with(&e10)); + REQUIRE_FALSE(e7.immediately_conflicts_with(&e8)); +} \ No newline at end of file diff --git a/src/mc/explo/udpor/Unfolding_test.cpp b/src/mc/explo/udpor/Unfolding_test.cpp new file mode 100644 index 0000000000..5ee5df2083 --- /dev/null +++ b/src/mc/explo/udpor/Unfolding_test.cpp @@ -0,0 +1,47 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/3rd-party/catch.hpp" +#include "src/mc/explo/udpor/Unfolding.hpp" +#include "src/mc/explo/udpor/udpor_tests_private.hpp" + +using namespace simgrid::mc; +using namespace simgrid::mc::udpor; + +TEST_CASE("simgrid::mc::udpor::Unfolding: Creating an unfolding") +{ + Unfolding unfolding; + REQUIRE(unfolding.size() == 0); + REQUIRE(unfolding.empty()); +} + +TEST_CASE("simgrid::mc::udpor::Unfolding: Inserting and marking events with an unfolding") +{ + Unfolding unfolding; + auto e1 = std::make_unique( + EventSet(), std::make_shared(Transition::Type::UNKNOWN, 0)); + auto e2 = + std::make_unique(EventSet(), std::make_shared(Transition::Type::UNKNOWN, 1)); + const auto* e1_handle = e1.get(); + const auto* e2_handle = e2.get(); + + unfolding.insert(std::move(e1)); + REQUIRE(unfolding.size() == 1); + REQUIRE_FALSE(unfolding.empty()); + + unfolding.insert(std::move(e2)); + REQUIRE(unfolding.size() == 2); + REQUIRE_FALSE(unfolding.empty()); + + unfolding.mark_finished(e1_handle); + REQUIRE(unfolding.size() == 2); + REQUIRE_FALSE(unfolding.empty()); + + unfolding.mark_finished(e2_handle); + REQUIRE(unfolding.size() == 2); + REQUIRE_FALSE(unfolding.empty()); +} + +TEST_CASE("simgrid::mc::udpor::Unfolding: Checking all immediate conflicts restricted to an unfolding") {} diff --git a/src/mc/explo/udpor/maximal_subsets_iterator.cpp b/src/mc/explo/udpor/maximal_subsets_iterator.cpp new file mode 100644 index 0000000000..6c2dee3ce6 --- /dev/null +++ b/src/mc/explo/udpor/maximal_subsets_iterator.cpp @@ -0,0 +1,186 @@ +#include "src/mc/explo/udpor/maximal_subsets_iterator.hpp" +#include "src/mc/explo/udpor/UnfoldingEvent.hpp" +#include "xbt/asserts.h" + +#include + +namespace simgrid::mc::udpor { + +maximal_subsets_iterator::maximal_subsets_iterator(const EventSet& events, + const std::optional& filter, + std::optional maximum_subset_size) + : maximum_subset_size(maximum_subset_size), current_maximal_set({EventSet()}) +{ + auto candidate_ordering = events.get_topological_ordering_of_reverse_graph(); + if (filter.has_value()) { + // Only store the events in the ordering that "matter" to us + std::copy_if(std::move_iterator(candidate_ordering.begin()), std::move_iterator(candidate_ordering.end()), + std::back_inserter(topological_ordering), filter.value()); + } else { + topological_ordering = std::move(candidate_ordering); + } +} + +void maximal_subsets_iterator::increment() +{ + // Termination condition + if (current_maximal_set == std::nullopt) { + return; + } + + // Stop immediately if there's nothing to search + if (topological_ordering.empty()) { + current_maximal_set = std::nullopt; + return; + } + + const auto next_event_ref = [&]() { + if (not has_started_searching) { + has_started_searching = true; + return bookkeeper.find_next_candidate_event(topological_ordering.begin(), topological_ordering.end()); + } else { + return continue_traversal_of_maximal_events_tree(); + } + }(); + + // Out of events: we've finished + if (next_event_ref == topological_ordering.end()) { + current_maximal_set = std::nullopt; + return; + } + + // We found some other event `e'` which is not in causally related with anything + // that currently exists in `current_maximal_set`, so add it in + add_element_to_current_maximal_set(*next_event_ref); + backtrack_points.push(next_event_ref); +} + +maximal_subsets_iterator::topological_order_position +maximal_subsets_iterator::continue_traversal_of_maximal_events_tree() +{ + // Nothing needs to be done if there isn't anyone to search for... + if (backtrack_points.empty()) { + return topological_ordering.end(); + } + + xbt_assert(current_maximal_set.has_value(), "Traversal continued even after the termination condition " + "was met. Please verify that the termination condition " + "of the iterator has not been modified"); + + // 1. First, check if we can keep expanding from the + // maximal set that we currently have + if (can_grow_maximal_set()) { + // This is an iterator which points to the latest event `e` that + // was added to what is currently the maximal set + const auto latest_event_ref = backtrack_points.top(); + + // Look for the next event to test with what we currently + // have based on the conflicts we've already kept track of. + // + // NOTE: We only need to search FROM `e` and not + // from the beginning of the topological sort. The fact that the + // set is topologically ordered ensures that removing `e` + // will not change whether or not to now allow someone before `e` + // in the ordering (otherwise, they would have to be in `e`'s history + // and therefore would come after `e`) + const auto next_event_ref = bookkeeper.find_next_candidate_event(latest_event_ref, topological_ordering.end()); + + // If we can expand from what we currently have, we can stop + if (next_event_ref != topological_ordering.end()) { + return next_event_ref; + } + } + + // Otherwise, we backtrack: we repeatedly pop off events that we know we + // are finished with + while (not backtrack_points.empty()) { + // Note: it is important to remove the element FIRST before performing + // the search, as removal may enable dependencies of `e` to be selected + const auto latest_event_ref = backtrack_points.top(); + remove_element_from_current_maximal_set(*latest_event_ref); + backtrack_points.pop(); + + // We begin the search AFTER the event we popped: we only want + // to consider those events that could be added AFTER `e` and + // not `e` itself again + const auto next_event_ref = bookkeeper.find_next_candidate_event(latest_event_ref + 1, topological_ordering.end()); + if (next_event_ref != topological_ordering.end()) { + return next_event_ref; + } + } + return topological_ordering.end(); +} + +bool maximal_subsets_iterator::Bookkeeper::is_candidate_event(const UnfoldingEvent* e) const +{ + if (const auto e_count = event_counts.find(e); e_count != event_counts.end()) { + return e_count->second == 0; + } + return true; +} + +void maximal_subsets_iterator::add_element_to_current_maximal_set(const UnfoldingEvent* e) +{ + xbt_assert(can_grow_maximal_set(), "Attempting to add an event to the maximal set " + "when doing so would increase the size past the " + "prescribed limit. This indicates that detecting when " + "to stop growing the maximal set when continuing the " + "search is broken"); + xbt_assert(current_maximal_set.has_value(), "Attempting to add an event to the maximal set " + "when iteration has completed. This indicates that " + "the termination condition for the iterator is broken"); + current_maximal_set.value().insert(e); + bookkeeper.mark_included_in_maximal_set(e); +} + +void maximal_subsets_iterator::remove_element_from_current_maximal_set(const UnfoldingEvent* e) +{ + xbt_assert(current_maximal_set.has_value(), "Attempting to remove an event to the maximal set " + "when iteration has completed. This indicates that " + "the termination condition for the iterator is broken"); + current_maximal_set.value().remove(e); + bookkeeper.mark_removed_from_maximal_set(e); +} + +bool maximal_subsets_iterator::can_grow_maximal_set() const +{ + if (not current_maximal_set.has_value()) { + return true; + } + if (maximum_subset_size.has_value()) { + return current_maximal_set.value().size() < maximum_subset_size.value(); + } + return true; +} + +maximal_subsets_iterator::topological_order_position +maximal_subsets_iterator::Bookkeeper::find_next_candidate_event(topological_order_position first, + topological_order_position last) const +{ + return std::find_if(first, last, [&](const UnfoldingEvent* e) { return is_candidate_event(e); }); +} + +void maximal_subsets_iterator::Bookkeeper::mark_included_in_maximal_set(const UnfoldingEvent* e) +{ + const auto e_local_config = e->get_local_config(); + for (const auto* e_hist : e_local_config) { + event_counts[e_hist]++; + } +} + +void maximal_subsets_iterator::Bookkeeper::mark_removed_from_maximal_set(const UnfoldingEvent* e) +{ + const auto e_local_config = e->get_local_config(); + for (const auto* e_hist : e_local_config) { + xbt_assert(event_counts.find(e_hist) != event_counts.end(), + "Invariant Violation: Attempted to remove an event which was not previously added"); + xbt_assert(event_counts[e_hist] > 0, "Invariant Violation: An event `e` had a count of `0` at this point " + "of the bookkeeping, which means that it is a candidate maximal event. " + "Yet some event that `e'` which contains `e` in its history was removed " + "first. This incidates that the topological sorting of events of the " + "configuration has failed and should be investigated first"); + event_counts[e_hist]--; + } +} + +} // namespace simgrid::mc::udpor diff --git a/src/mc/explo/udpor/maximal_subsets_iterator.hpp b/src/mc/explo/udpor/maximal_subsets_iterator.hpp new file mode 100644 index 0000000000..49872d809a --- /dev/null +++ b/src/mc/explo/udpor/maximal_subsets_iterator.hpp @@ -0,0 +1,157 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_UDPOR_MAXIMAL_SUBSETS_ITERATOR_HPP +#define SIMGRID_MC_UDPOR_MAXIMAL_SUBSETS_ITERATOR_HPP + +#include "src/mc/explo/udpor/Configuration.hpp" +#include "src/xbt/utils/iter/iterator_wrapping.hpp" + +#include +#include +#include +#include +#include + +namespace simgrid::mc::udpor { + +/** + * @brief An iterator over the tree of sets of (non-empty) maximal events that + * can be generated from a given set of events + * + * This iterator traverses all possible sets of maximal events that + * can be formed from some subset of events of an unfolding, + * each of which satisfy a predicate. + * + * Iteration over the maximal events of a configuration is an important + * step in computing the extension set of a configuration for an action + * whose identity is not "exploitable" (i.e. one whose type information cannot + * help us narrow down our search). + */ +struct maximal_subsets_iterator + : public boost::iterator_facade { +public: + // A function which answers the question "do I need to consider maximal sets + // that contain this node?" + using node_filter_function = std::function; + using topological_order_position = std::vector::const_iterator; + + maximal_subsets_iterator() = default; + explicit maximal_subsets_iterator(const Configuration& config, + const std::optional& filter = std::nullopt, + std::optional maximum_subset_size = std::nullopt) + : maximal_subsets_iterator(config.get_events(), filter, maximum_subset_size) + { + } + explicit maximal_subsets_iterator(const EventSet& events, + const std::optional& filter = std::nullopt, + std::optional maximum_subset_size = std::nullopt); + +private: + std::vector topological_ordering; + + // The boolean is a bit of an annoyance, but it works. Effectively, + // there's no way to distinguish between "we're starting the search + // after the empty set" and "we've finished the search" since the resulting + // maximal set and backtracking point stack will both be empty in both cases + bool has_started_searching = false; + std::optional maximum_subset_size = std::nullopt; + std::optional current_maximal_set = std::nullopt; + std::stack> backtrack_points; + + /** + * @brief A small class which provides functionality for managing + * the "counts" as the iterator proceeds forward in time + * + * As an instance of the `maximal_subsets_iterator` traverses + * the configuration, it keeps track of how many events + * further down in the causality tree have been signaled as in-conflict + * with events that are its current maximal event set (i.e. + * its `current_maximal_set`) + */ + struct Bookkeeper { + public: + using topological_order_position = maximal_subsets_iterator::topological_order_position; + + void mark_included_in_maximal_set(const UnfoldingEvent*); + void mark_removed_from_maximal_set(const UnfoldingEvent*); + topological_order_position find_next_candidate_event(topological_order_position first, + topological_order_position last) const; + + private: + std::unordered_map event_counts; + + /// @brief Whether or not the given event, according to the + /// bookkeeping that has been done thus far, can be added to the + /// current candidate maximal set + bool is_candidate_event(const UnfoldingEvent*) const; + }; + Bookkeeper bookkeeper; + + void add_element_to_current_maximal_set(const UnfoldingEvent*); + void remove_element_from_current_maximal_set(const UnfoldingEvent*); + + /** + * @brief Moves to the next node in the topological ordering + * by continuing the search in the tree of maximal event sets + * from where we currently believe we are in the tree + * + * At each stage of the iteration, the iterator points to + * a maximal event set that can be thought of as `R` + `A`: + * + * | R | A + * +--------+ + * + * where `R` is some set of events and `A` is another event. + * + * The iterator first tries expansion from `R` + `A`. If it finds + * node `B` to expand, this means that there is a node in the tree of + * maximal event sets of `C` (the configuration traversed) such that + * `R` + `A` + `B` needs to be checked. + * + * If no such node is found, then the iterator must check `R` + + * some other node AFTER `A`. The new set of possibilities potentially + * includes some of `A`'s dependencies, so their counts are decremented + * prior to searching. + * + * @note: This method is a mutating method: it manipulates the + * iterator such that the iterator refers to the next maximal + * set sans the element returned. The `increment()` function performs + * the rest of the work needed to actually complete the transition + * + * @returns an iterator poiting to the event that should next + * be added to the set of maximal events if such an event exists, + * or to the end of the topological ordering if no such event exists + */ + topological_order_position continue_traversal_of_maximal_events_tree(); + + /** + * @brief: Whether or not the current maximal set can + * grow based on the size limit imposed on the maximal + * sets that can be produced + */ + bool can_grow_maximal_set() const; + + // boost::iterator_facade<...> interface to implement + void increment(); + bool equal(const maximal_subsets_iterator& other) const { return current_maximal_set == other.current_maximal_set; } + const EventSet& dereference() const + { + static const EventSet empty_set; + if (current_maximal_set.has_value()) { + return current_maximal_set.value(); + } + return empty_set; + } + + // Allows boost::iterator_facade<...> to function properly + friend class boost::iterator_core_access; +}; + +template +using maximal_subsets_iterator_wrapper = simgrid::xbt::iterator_wrapping; + +} // namespace simgrid::mc::udpor +#endif diff --git a/src/mc/explo/udpor/udpor_forward.hpp b/src/mc/explo/udpor/udpor_forward.hpp new file mode 100644 index 0000000000..a279b8f884 --- /dev/null +++ b/src/mc/explo/udpor/udpor_forward.hpp @@ -0,0 +1,30 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/** @file udpor_forward.hpp + * + * Forward definitions for MC types specific to UDPOR + */ + +#ifndef SIMGRID_MC_UDPOR_FORWARD_HPP +#define SIMGRID_MC_UDPOR_FORWARD_HPP + +#include "src/mc/mc_forward.hpp" +#include + +namespace simgrid::mc::udpor { + +class Comb; +struct ExtensionSetCalculator; +class EventSet; +class Configuration; +class History; +class Unfolding; +class UnfoldingEvent; +struct maximal_subsets_iterator; + +} // namespace simgrid::mc::udpor + +#endif diff --git a/src/mc/explo/udpor/udpor_tests_private.hpp b/src/mc/explo/udpor/udpor_tests_private.hpp new file mode 100644 index 0000000000..de2ed37dce --- /dev/null +++ b/src/mc/explo/udpor/udpor_tests_private.hpp @@ -0,0 +1,80 @@ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/** @file udpor_tests_private.hpp + * + * A private header file for tests involving events in + * configurations + */ + +#ifndef SIMGRID_MC_UDPOR_TEST_PRIVATE_HPP +#define SIMGRID_MC_UDPOR_TEST_PRIVATE_HPP + +#include "src/mc/transition/Transition.hpp" + +namespace simgrid::mc::udpor { + +struct IndependentAction : public Transition { + IndependentAction() = default; + IndependentAction(Type type, aid_t issuer, int times_considered = 0) : Transition(type, issuer, times_considered) {} + IndependentAction(aid_t issuer, int times_considered = 0) + : IndependentAction(simgrid::mc::Transition::Type::UNKNOWN, issuer, times_considered) + { + } + + // Independent with everyone else (even if run by the same actor). NOTE: This is + // only for the convenience of testing: in general, transitions are dependent with + // one another if run by the same actor + bool depends(const Transition* other) const override + { + if (aid_ == other->aid_) { + return true; + } + return false; + } +}; + +struct DependentAction : public Transition { + DependentAction() = default; + DependentAction(Type type, aid_t issuer, int times_considered = 0) : Transition(type, issuer, times_considered) {} + DependentAction(aid_t issuer, int times_considered = 0) + : DependentAction(simgrid::mc::Transition::Type::UNKNOWN, issuer, times_considered) + { + } + + // Dependent with everyone else (except IndependentAction) + bool depends(const Transition* other) const override + { + if (aid_ == other->aid_) { + return true; + } + return dynamic_cast(other) == nullptr; + } +}; + +struct ConditionallyDependentAction : public Transition { + ConditionallyDependentAction() = default; + ConditionallyDependentAction(Type type, aid_t issuer, int times_considered = 0) + : Transition(type, issuer, times_considered) + { + } + ConditionallyDependentAction(aid_t issuer, int times_considered = 0) + : ConditionallyDependentAction(simgrid::mc::Transition::Type::UNKNOWN, issuer, times_considered) + { + } + + // Dependent only with DependentAction (i.e. not itself) + bool depends(const Transition* other) const override + { + if (aid_ == other->aid_) { + return true; + } + return dynamic_cast(other) != nullptr; + } +}; + +} // namespace simgrid::mc::udpor + +#endif diff --git a/src/mc/inspect/DwarfExpression.cpp b/src/mc/inspect/DwarfExpression.cpp deleted file mode 100644 index 45c7c89d22..0000000000 --- a/src/mc/inspect/DwarfExpression.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include - -#include "src/mc/AddressSpace.hpp" -#include "src/mc/inspect/DwarfExpression.hpp" -#include "src/mc/inspect/Frame.hpp" -#include "src/mc/inspect/LocationList.hpp" -#include "src/mc/inspect/ObjectInformation.hpp" -#include "src/mc/inspect/mc_dwarf.hpp" -#include "src/mc/mc_private.hpp" - -namespace simgrid::dwarf { - -void execute(const Dwarf_Op* ops, std::size_t n, const ExpressionContext& context, ExpressionStack& stack) -{ - for (size_t i = 0; i != n; ++i) { - const Dwarf_Op* op = ops + i; - std::uint8_t atom = op->atom; - intptr_t first; - intptr_t second; - - switch (atom) { - // Push the CFA (Canonical Frame Address): - case DW_OP_call_frame_cfa: - /* See 6.4 of DWARF4 (http://dwarfstd.org/doc/DWARF4.pdf#page=140): - * - * > Typically, the CFA is defined to be the value of the stack - * > pointer at the call site in the previous frame (which may be - * > different from its value on entry to the current frame). - * - * We need to unwind the frame in order to get the SP of the parent - * frame. - * - * Warning: the CFA returned by libunwind (UNW_X86_64_RSP, etc.) - * is the SP of the *current* frame. */ - if (context.cursor) { - // Get frame: - unw_cursor_t cursor = *(context.cursor); - unw_step(&cursor); - - unw_word_t res; - unw_get_reg(&cursor, UNW_REG_SP, &res); - stack.push(res); - break; - } - throw evaluation_error("Missing cursor"); - - // Frame base: - case DW_OP_fbreg: - stack.push((std::uintptr_t)context.frame_base + op->number); - break; - - // Address from the base address of this ELF object. - // Push the address on the stack (base_address + argument). - case DW_OP_addr: - if (context.object_info) { - Dwarf_Off addr = (Dwarf_Off)(std::uintptr_t)context.object_info->base_address() + op->number; - stack.push(addr); - break; - } - throw evaluation_error("No base address"); - - // ***** Stack manipulation: - - // Push another copy/duplicate the value at the top of the stack: - case DW_OP_dup: - stack.dup(); - break; - - // Pop/drop the top of the stack: - case DW_OP_drop: - (void)stack.pop(); - break; - - case DW_OP_swap: - stack.swap(); - break; - - // Duplicate the value under the top of the stack: - case DW_OP_over: - stack.push(stack.top(1)); - break; - - // ***** Operations: - // Those usually take the top of the stack and the next value as argument - // and replace the top of the stack with the computed value - // (stack.top() += stack.before_top()). - - case DW_OP_plus: - first = stack.pop(); - second = stack.pop(); - stack.push(first + second); - break; - - case DW_OP_mul: - first = stack.pop(); - second = stack.pop(); - stack.push(first * second); - break; - - case DW_OP_plus_uconst: - stack.top() += op->number; - break; - - case DW_OP_not: - stack.top() = ~stack.top(); - break; - - case DW_OP_neg: - stack.top() = -(intptr_t)stack.top(); - break; - - case DW_OP_minus: - first = stack.pop(); - second = stack.pop(); - stack.push(second - first); - break; - - case DW_OP_and: - first = stack.pop(); - second = stack.pop(); - stack.push(first & second); - break; - - case DW_OP_or: - first = stack.pop(); - second = stack.pop(); - stack.push(first | second); - break; - - case DW_OP_xor: - first = stack.pop(); - second = stack.pop(); - stack.push(first ^ second); - break; - - case DW_OP_nop: - break; - - // ***** Deference (memory fetch) - - case DW_OP_deref_size: - throw evaluation_error("Unsupported operation"); - - case DW_OP_deref: - // Computed address: - if (not context.address_space) - throw evaluation_error("Missing address space"); - context.address_space->read_bytes(&stack.top(), sizeof(uintptr_t), mc::remote(stack.top())); - break; - - default: - - // Registers: - if (static const std::unordered_set registers = - {DW_OP_breg0, DW_OP_breg1, DW_OP_breg2, DW_OP_breg3, DW_OP_breg4, DW_OP_breg5, DW_OP_breg6, - DW_OP_breg7, DW_OP_breg8, DW_OP_breg9, DW_OP_breg10, DW_OP_breg11, DW_OP_breg12, DW_OP_breg13, - DW_OP_breg14, DW_OP_breg15, DW_OP_breg16, DW_OP_breg17, DW_OP_breg18, DW_OP_breg19, DW_OP_breg20, - DW_OP_breg21, DW_OP_breg22, DW_OP_breg23, DW_OP_breg24, DW_OP_breg25, DW_OP_breg26, DW_OP_breg27, - DW_OP_breg28, DW_OP_breg29, DW_OP_breg30, DW_OP_breg31}; - registers.count(atom) > 0) { - // Push register + constant: - int register_id = dwarf_register_to_libunwind(op->atom - DW_OP_breg0); - unw_word_t res; - if (not context.cursor) - throw evaluation_error("Missing stack context"); - unw_get_reg(context.cursor, register_id, &res); - stack.push(res + op->number); - break; - } - - // ***** Constants: - - // Short constant literals: - if (static const std::unordered_set literals = {DW_OP_lit0, DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, - DW_OP_lit4, DW_OP_lit5, DW_OP_lit6, DW_OP_lit7, - DW_OP_lit8, DW_OP_lit9, DW_OP_lit10, DW_OP_lit11, - DW_OP_lit12, DW_OP_lit13, DW_OP_lit14, DW_OP_lit15, - DW_OP_lit16, DW_OP_lit17, DW_OP_lit18, DW_OP_lit19, - DW_OP_lit20, DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, - DW_OP_lit24, DW_OP_lit25, DW_OP_lit26, DW_OP_lit27, - DW_OP_lit28, DW_OP_lit29, DW_OP_lit30, DW_OP_lit31}; - literals.count(atom) > 0) { - // Push a literal/constant on the stack: - stack.push(atom - DW_OP_lit0); - break; - } - - // General constants: - if (static const std::unordered_set constants = {DW_OP_const1u, DW_OP_const2u, DW_OP_const4u, - DW_OP_const8u, DW_OP_const1s, DW_OP_const2s, - DW_OP_const4s, DW_OP_const8s, DW_OP_constu, - DW_OP_consts}; - constants.count(atom) > 0) { - // Push the constant argument on the stack. - stack.push(op->number); - break; - } - - // Not handled: - throw evaluation_error("Unsupported operation"); - } - } -} - -} // namespace simgrid::dwarf diff --git a/src/mc/inspect/DwarfExpression.hpp b/src/mc/inspect/DwarfExpression.hpp deleted file mode 100644 index 8e6cfd3b3d..0000000000 --- a/src/mc/inspect/DwarfExpression.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_DWARF_EXPRESSION_HPP -#define SIMGRID_MC_DWARF_EXPRESSION_HPP - -#include -#include - -#include -#include // runtime_error -#include -#include - -#include -#include - -#include "src/mc/inspect/mc_dwarf.hpp" -#include "src/mc/mc_forward.hpp" - -/** @file DwarfExpression.hpp - * - * Evaluation of DWARF location expressions. - */ - -namespace simgrid::dwarf { - -/** A DWARF expression - * - * DWARF defines a simple stack-based VM for evaluating expressions - * (such as locations of variables, etc.): a DWARF expression is - * just a sequence of dwarf instructions. We currently directly use - * `Dwarf_Op` from `dwarf.h` for dwarf instructions. - */ -using DwarfExpression = std::vector; - -/** Context of evaluation of a DWARF expression - * - * Some DWARF instructions need to read the CPU registers, - * the process memory, etc. All those information are gathered in - * the evaluation context. - */ -struct ExpressionContext { - /** CPU state (registers) */ - unw_cursor_t* cursor = nullptr; - void* frame_base = nullptr; - const mc::AddressSpace* address_space = nullptr; /** Address space used to read memory */ - mc::ObjectInformation* object_info = nullptr; -}; - -/** When an error happens in the execution of a DWARF expression */ -class evaluation_error : public std::runtime_error { -public: - using std::runtime_error::runtime_error; -}; - -/** A stack for evaluating a DWARF expression - * - * DWARF expressions work by manipulating a stack of integer values. - */ -class ExpressionStack { -public: - using value_type = std::uintptr_t; - static constexpr std::size_t MAX_SIZE = 64; - -private: - // Values of the stack (the top is stack_[size_ - 1]): - std::array stack_{{0}}; - size_t size_ = 0; - -public: - // Access: - std::size_t size() const { return size_; } - bool empty() const { return size_ == 0; } - void clear() { size_ = 0; } - uintptr_t& operator[](int i) { return stack_[i]; } - uintptr_t const& operator[](int i) const { return stack_[i]; } - - /** Top of the stack */ - value_type& top() - { - if (size_ == 0) - throw evaluation_error("Empty stack"); - return stack_[size_ - 1]; - } - - /** Access the i-th element from the top of the stack */ - value_type& top(unsigned i) - { - if (size_ < i) - throw evaluation_error("Invalid element"); - return stack_[size_ - 1 - i]; - } - - /** Push a value on the top of the stack */ - void push(value_type value) - { - if (size_ == stack_.size()) - throw evaluation_error("DWARF stack overflow"); - stack_[size_] = value; - size_++; - } - - /* Pop a value from the top of the stack */ - value_type pop() - { - if (size_ == 0) - throw evaluation_error("DWARF stack underflow"); - --size_; - return stack_[size_]; - } - - // These are DWARF operations (DW_OP_foo): - - /* Push a copy of the top-value (DW_OP_dup) */ - void dup() { push(top()); } - - /* Swap the two top-most values */ - void swap() { std::swap(top(), top(1)); } -}; - -/** Executes a DWARF expression - * - * @param ops DWARF expression instructions - * @param n number of instructions - * @param context evaluation context (registers, memory, etc.) - * @param stack DWARf stack where the operations are executed - */ -void execute(const Dwarf_Op* ops, std::size_t n, ExpressionContext const& context, ExpressionStack& stack); - -/** Executes/evaluates a DWARF expression - * - * @param expression DWARF expression to execute - * @param context evaluation context (registers, memory, etc.) - * @param stack DWARf stack where the operations are executed - */ -inline void execute(simgrid::dwarf::DwarfExpression const& expression, ExpressionContext const& context, - ExpressionStack& stack) -{ - execute(expression.data(), expression.size(), context, stack); -} - -} // namespace simgrid::dwarf - -#endif diff --git a/src/mc/inspect/Frame.cpp b/src/mc/inspect/Frame.cpp deleted file mode 100644 index 5934de2a50..0000000000 --- a/src/mc/inspect/Frame.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include - -#include "xbt/sysdep.h" - -#include "src/mc/inspect/Frame.hpp" - -namespace simgrid::mc { - -void* Frame::frame_base(unw_cursor_t& unw_cursor) const -{ - simgrid::dwarf::Location location = - simgrid::dwarf::resolve(frame_base_location, object_info, &unw_cursor, nullptr, nullptr); - if (location.in_memory()) - return location.address(); - else if (location.in_register()) { - // This is a special case. - // The register is not the location of the frame base - // (a frame base cannot be located in a register). - // Instead, DWARF defines this to mean that the register - // contains the address of the frame base. - unw_word_t word; - unw_get_reg(&unw_cursor, location.register_id(), &word); - return (void*)word; - } else - xbt_die("Unexpected location type"); -} - -} // namespace simgrid::mc diff --git a/src/mc/inspect/Frame.hpp b/src/mc/inspect/Frame.hpp deleted file mode 100644 index 1cc4d57915..0000000000 --- a/src/mc/inspect/Frame.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_FRAME_HPP -#define SIMGRID_MC_FRAME_HPP - -#include -#include - -#include "xbt/base.h" -#include "xbt/range.hpp" - -#include "src/mc/inspect/LocationList.hpp" -#include "src/mc/inspect/Variable.hpp" -#include "src/mc/mc_forward.hpp" - -namespace simgrid::mc { - -/** Debug information about a given function or scope within a function */ -class Frame { -public: - /** Kind of scope (DW_TAG_subprogram, DW_TAG_inlined_subroutine, etc.) */ - int tag = DW_TAG_invalid; - - /** Name of the function (if it is a function) */ - std::string name; - - /** Range of instruction addresses for which this scope is valid */ - simgrid::xbt::Range range{0, 0}; - - simgrid::dwarf::LocationList frame_base_location; - - /** List of the variables (sorted by name) */ - std::vector variables; - - /* Unique identifier for this scope (in the object_info) - * - * This is the global DWARF offset of the DIE. */ - unsigned long int id = 0; - - std::vector scopes; - - /** Value of `DW_AT_abstract_origin` - * - * For inlined subprograms, this is the ID of the - * parent function. - */ - unsigned long int abstract_origin_id = 0; - - simgrid::mc::ObjectInformation* object_info = nullptr; - - void* frame_base(unw_cursor_t& unw_cursor) const; - void remove_variable(char* name); -}; -} // namespace simgrid::mc - -#endif diff --git a/src/mc/inspect/LocationList.cpp b/src/mc/inspect/LocationList.cpp deleted file mode 100644 index 8cf649c021..0000000000 --- a/src/mc/inspect/LocationList.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/inspect/LocationList.hpp" -#include "src/mc/inspect/ObjectInformation.hpp" -#include "src/mc/inspect/mc_dwarf.hpp" - -#include "xbt/asserts.h" -#include "xbt/log.h" -#include "xbt/sysdep.h" - -#include -#include -#include -#include - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(mc_dwarf); - -namespace simgrid::dwarf { - -/** Resolve a location expression */ -Location resolve(simgrid::dwarf::DwarfExpression const& expression, simgrid::mc::ObjectInformation* object_info, - unw_cursor_t* c, void* frame_pointer_address, const simgrid::mc::AddressSpace* address_space) -{ - simgrid::dwarf::ExpressionContext context; - context.frame_base = frame_pointer_address; - context.cursor = c; - context.address_space = address_space; - context.object_info = object_info; - - if (not expression.empty() && expression[0].atom >= DW_OP_reg0 && expression[0].atom <= DW_OP_reg31) { - int dwarf_register = expression[0].atom - DW_OP_reg0; - xbt_assert(c, "Missing frame context for register operation DW_OP_reg%i", dwarf_register); - return Location(dwarf_register_to_libunwind(dwarf_register)); - } - - simgrid::dwarf::ExpressionStack stack; - simgrid::dwarf::execute(expression, context, stack); - return Location((void*)stack.top()); -} - -// TODO, move this in a method of LocationList -static simgrid::dwarf::DwarfExpression const* find_expression(simgrid::dwarf::LocationList const& locations, - unw_word_t ip) -{ - for (simgrid::dwarf::LocationListEntry const& entry : locations) - if (entry.valid_for_ip(ip)) - return &entry.expression(); - return nullptr; -} - -Location resolve(simgrid::dwarf::LocationList const& locations, simgrid::mc::ObjectInformation* object_info, - unw_cursor_t* c, void* frame_pointer_address, const simgrid::mc::AddressSpace* address_space) -{ - unw_word_t ip = 0; - if (c) - xbt_assert(unw_get_reg(c, UNW_REG_IP, &ip) == 0, "Could not resolve IP"); - simgrid::dwarf::DwarfExpression const* expression = find_expression(locations, ip); - xbt_assert(expression != nullptr, "Could not resolve location"); - return simgrid::dwarf::resolve(*expression, object_info, c, frame_pointer_address, address_space); -} - -LocationList location_list(const simgrid::mc::ObjectInformation& info, Dwarf_Attribute& attr) -{ - LocationList locations; - std::ptrdiff_t offset = 0; - while (true) { - Dwarf_Addr base; - Dwarf_Addr start; - Dwarf_Addr end; - Dwarf_Op* ops; - std::size_t len; - - offset = dwarf_getlocations(&attr, offset, &base, &start, &end, &ops, &len); - - if (offset == -1) - XBT_WARN("Error while loading location list: %s", dwarf_errmsg(-1)); - if (offset <= 0) - break; - - auto base_address = reinterpret_cast(info.base_address()); - - LocationListEntry::range_type range; - if (start == 0) - // If start == 0, this is not a location list: - range = {0, UINT64_MAX}; - else - range = {base_address + start, base_address + end}; - - locations.emplace_back(DwarfExpression(ops, ops + len), range); - } - - return locations; -} -} // namespace simgrid::dwarf diff --git a/src/mc/inspect/LocationList.hpp b/src/mc/inspect/LocationList.hpp deleted file mode 100644 index 12c79f0716..0000000000 --- a/src/mc/inspect/LocationList.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_OBJECT_LOCATION_H -#define SIMGRID_MC_OBJECT_LOCATION_H - -#include "xbt/base.h" -#include "xbt/range.hpp" - -#include "src/mc/inspect/DwarfExpression.hpp" -#include "src/mc/mc_base.hpp" -#include "src/mc/mc_forward.hpp" - -#include -#include - -namespace simgrid::dwarf { - -/** A DWARF expression with optional validity constraints */ -class LocationListEntry { -public: - using range_type = simgrid::xbt::Range; - -private: - DwarfExpression expression_; - // By default, the expression is always valid: - range_type range_ = {0, UINT64_MAX}; - -public: - LocationListEntry() = default; - LocationListEntry(DwarfExpression expression, range_type range) : expression_(std::move(expression)), range_(range) {} - explicit LocationListEntry(DwarfExpression expression) : expression_(std::move(expression)), range_({0, UINT64_MAX}) - { - } - - DwarfExpression& expression() { return expression_; } - DwarfExpression const& expression() const { return expression_; } - bool valid_for_ip(unw_word_t ip) const { return range_.contain(ip); } -}; - -using LocationList = std::vector; - -/** Location of some variable in memory - * - * The variable is located either in memory of a register. - */ -class Location { -private: - void* memory_ = nullptr; - int register_id_ = 0; - -public: - explicit Location(void* x) : memory_(x) {} - explicit Location(int register_id) : register_id_(register_id) {} - // Type of location: - bool in_register() const { return memory_ == nullptr; } - bool in_memory() const { return memory_ != nullptr; } - - // Get the location: - void* address() const { return memory_; } - int register_id() const { return register_id_; } -}; - -XBT_PRIVATE -Location resolve(simgrid::dwarf::DwarfExpression const& expression, simgrid::mc::ObjectInformation* object_info, - unw_cursor_t* c, void* frame_pointer_address, const simgrid::mc::AddressSpace* address_space); - -Location resolve(simgrid::dwarf::LocationList const& locations, simgrid::mc::ObjectInformation* object_info, - unw_cursor_t* c, void* frame_pointer_address, const simgrid::mc::AddressSpace* address_space); - -XBT_PRIVATE -simgrid::dwarf::LocationList location_list(const simgrid::mc::ObjectInformation& info, Dwarf_Attribute& attr); - -} // namespace simgrid::dwarf - -#endif diff --git a/src/mc/inspect/ObjectInformation.cpp b/src/mc/inspect/ObjectInformation.cpp deleted file mode 100644 index 968d3aab77..0000000000 --- a/src/mc/inspect/ObjectInformation.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include // PROT_READ and friends -#include - -#include "src/mc/inspect/Frame.hpp" -#include "src/mc/inspect/ObjectInformation.hpp" -#include "src/mc/inspect/Variable.hpp" -#include "src/mc/mc_private.hpp" -#include "xbt/file.hpp" - -namespace simgrid::mc { - -/* For an executable object, addresses are virtual address (there is no offset) i.e. - * \f$\text{virtual address} = \{dwarf address}\f$ - * - * For a shared object, the addresses are offset from the beginning of the shared object (the base address of the - * mapped shared object must be used as offset - * i.e. \f$\text{virtual address} = \text{shared object base address} - * + \text{dwarf address}\f$. - */ -void* ObjectInformation::base_address() const -{ - // For an executable (more precisely for an ET_EXEC) the base it 0: - if (this->executable()) - return nullptr; - - // For an a shared-object (ET_DYN, including position-independent executables) the base address is its lowest address: - void* result = this->start_exec; - if (this->start_rw != nullptr && result > (void*)this->start_rw) - result = this->start_rw; - if (this->start_ro != nullptr && result > (void*)this->start_ro) - result = this->start_ro; - return result; -} - -Frame* ObjectInformation::find_function(const void* ip) -{ - ensure_dwarf_loaded(); - - /* This is implemented by binary search on a sorted array. - * - * We do quite a lot of those so we want this to be cache efficient. - * We pack the only information we need in the index entries in order - * to successfully do the binary search. We do not need the high_pc - * during the binary search (only at the end) so it is not included - * in the index entry. We could use parallel arrays as well. - * - * Note the usage of reverse iterators to match the correct interval. - */ - auto pos = std::lower_bound(this->functions_index.rbegin(), this->functions_index.rend(), ip, - [](auto const& func, auto const* addr) { return func.low_pc > addr; }); - - /* At this point, the search is over. - * Either we have found the correct function or we do not know - * any function corresponding to this instruction address. - * Only at the point do we dereference the function pointer. */ - return (pos != this->functions_index.rend() && reinterpret_cast(ip) < pos->function->range.end()) - ? pos->function - : nullptr; -} - -const Variable* ObjectInformation::find_variable(const char* var_name) -{ - ensure_dwarf_loaded(); - - auto pos = std::lower_bound(this->global_variables.begin(), this->global_variables.end(), var_name, - [](auto const& var, const char* name) { return var.name < name; }); - return (pos != this->global_variables.end() && pos->name == var_name) ? &(*pos) : nullptr; -} - -void ObjectInformation::remove_global_variable(const char* var_name) -{ - // Binary search: - auto pos1 = std::lower_bound(this->global_variables.begin(), this->global_variables.end(), var_name, - [](auto const& var, const char* name) { return var.name < name; }); - // Find the whole range: - auto pos2 = std::upper_bound(pos1, this->global_variables.end(), var_name, - [](const char* name, auto const& var) { return name < var.name; }); - // Remove the whole range: - this->global_variables.erase(pos1, pos2); -} - -/** Ignore a local variable in a scope - * - * Ignore all instances of variables with a given name in any (possibly inlined) subprogram with a given namespaced - * name. - * - * @param var_name Name of the local variable to ignore - * @param subprogram_name Name of the subprogram to ignore (nullptr for any) - * @param subprogram (possibly inlined) Subprogram of the scope current scope - * @param scope Current scope - */ -static void remove_local_variable(Frame& scope, const char* var_name, const char* subprogram_name, - Frame const& subprogram) -{ - // If the current subprogram matches the given name: - if (subprogram_name == nullptr || (not subprogram.name.empty() && subprogram.name == subprogram_name)) { - // Try to find the variable and remove it: - - // Binary search: - auto pos = std::lower_bound(scope.variables.begin(), scope.variables.end(), var_name, - [](auto const& var, const char* name) { return var.name < name; }); - if (pos != scope.variables.end() && pos->name == var_name) { - // Variable found, remove it: - scope.variables.erase(pos); - } - } - - // And recursive processing in nested scopes: - for (Frame& nested_scope : scope.scopes) { - // The new scope may be an inlined subroutine, in this case we want to use its - // namespaced name in recursive calls: - Frame const& nested_subprogram = nested_scope.tag == DW_TAG_inlined_subroutine ? nested_scope : subprogram; - remove_local_variable(nested_scope, var_name, subprogram_name, nested_subprogram); - } -} - -void ObjectInformation::remove_local_variable(const char* var_name, const char* subprogram_name) -{ - for (auto& [_, entry] : this->subprograms) - mc::remove_local_variable(entry, var_name, subprogram_name, entry); -} - -/** @brief Fills the position of the segments (executable, read-only, read/write) */ -// TODO, use the ELF segment information for more robustness -void find_object_address(std::vector const& maps, ObjectInformation* result) -{ - const int PROT_RW = PROT_READ | PROT_WRITE; - const int PROT_RX = PROT_READ | PROT_EXEC; - - std::string name = xbt::Path(result->file_name).get_base_name(); - - for (size_t i = 0; i < maps.size(); ++i) { - simgrid::xbt::VmMap const& reg = maps[i]; - if (reg.pathname.empty() || name != simgrid::xbt::Path(reg.pathname).get_base_name()) - continue; - - // This is the non-GNU_RELRO-part of the data segment: - if (reg.prot == PROT_RW) { - xbt_assert(not result->start_rw, "Multiple read-write segments for %s, not supported", maps[i].pathname.c_str()); - result->start_rw = (char*)reg.start_addr; - result->end_rw = (char*)reg.end_addr; - - // The next VMA might be end of the data segment: - if (i + 1 < maps.size() && maps[i + 1].pathname.empty() && maps[i + 1].prot == PROT_RW && - maps[i + 1].start_addr == reg.end_addr) - result->end_rw = (char*)maps[i + 1].end_addr; - } - - // This is the text segment: - else if (reg.prot == PROT_RX) { - xbt_assert(not result->start_exec, "Multiple executable segments for %s, not supported", - maps[i].pathname.c_str()); - result->start_exec = (char*)reg.start_addr; - result->end_exec = (char*)reg.end_addr; - - // The next VMA might be end of the data segment: - if (i + 1 < maps.size() && maps[i + 1].pathname.empty() && maps[i + 1].prot == PROT_RW && - maps[i + 1].start_addr == reg.end_addr) { - result->start_rw = (char*)maps[i + 1].start_addr; - result->end_rw = (char*)maps[i + 1].end_addr; - } - } - - // This is the GNU_RELRO-part of the data segment: - else if (reg.prot == PROT_READ) { - xbt_assert(not result->start_ro, - "Multiple read-only segments for %s, not supported. Compiling with the following may help: " - "-g -Wl,-znorelro -Wl,-znoseparate-code", - maps[i].pathname.c_str()); - result->start_ro = (char*)reg.start_addr; - result->end_ro = (char*)reg.end_addr; - } - } - - result->start = result->start_rw; - if ((const void*)result->start_ro < result->start) - result->start = result->start_ro; - if ((const void*)result->start_exec < result->start) - result->start = result->start_exec; - - result->end = result->end_rw; - if (result->end_ro && (const void*)result->end_ro > result->end) - result->end = result->end_ro; - if (result->end_exec && (const void*)result->end_exec > result->end) - result->end = result->end_exec; - - xbt_assert(result->start_exec || result->start_rw || result->start_ro); -} - -} // namespace simgrid::mc diff --git a/src/mc/inspect/ObjectInformation.hpp b/src/mc/inspect/ObjectInformation.hpp deleted file mode 100644 index 0f3a61489b..0000000000 --- a/src/mc/inspect/ObjectInformation.hpp +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_OBJECT_INFORMATION_HPP -#define SIMGRID_MC_OBJECT_INFORMATION_HPP - -#include -#include -#include -#include - -#include "src/mc/inspect/Frame.hpp" -#include "src/mc/inspect/Type.hpp" -#include "src/mc/mc_forward.hpp" -#include "src/xbt/memory_map.hpp" - -#include "src/smpi/include/private.hpp" - -namespace simgrid::mc { - -/** An entry in the functions index - * - * See the code of ObjectInformation::find_function. - */ -struct FunctionIndexEntry { - void* low_pc; - simgrid::mc::Frame* function; -}; - -/** Information about an ELF module (executable or shared object) - * - * This contains all the information we need about an executable or - * shared-object in the model-checked process: - * - * - where it is located in the virtual address space; - * - * - where are located its different memory mappings in the the - * virtual address space; - * - * - all the debugging (DWARF) information - * - types, - * - location of the functions and their local variables, - * - global variables, - * - * - etc. - */ -class ObjectInformation { - bool dwarf_loaded = false; // Lazily loads the dwarf info - -public: - void ensure_dwarf_loaded(); // Used by functions that need the dwarf - ObjectInformation() = default; - - // Not copiable: - ObjectInformation(ObjectInformation const&) = delete; - ObjectInformation& operator=(ObjectInformation const&) = delete; - - // Flag: - static const int Executable = 1; - - /** Bitfield of flags */ - int flags = 0; - std::string file_name; - const void* start = nullptr; - const void* end = nullptr; - // Location of its text segment: - char* start_exec = nullptr; - char* end_exec = nullptr; - // Location of the read-only part of its data segment: - char* start_rw = nullptr; - char* end_rw = nullptr; - // Location of the read/write part of its data segment: - char* start_ro = nullptr; - char* end_ro = nullptr; - - /** All of its subprograms indexed by their address */ - std::unordered_map subprograms; - - /** Index of functions by instruction address - * - * We need to efficiently find the function from any given instruction - * address inside its range. This index is sorted by low_pc - * - * The entries are sorted by low_pc and a binary search can be used to look - * them up. In order to have a better cache locality, we only keep the - * information we need for the lookup in this vector. We could probably - * replace subprograms by an ordered vector of Frame and replace this one b - * a parallel `std::vector`. - */ - std::vector functions_index; - - std::vector global_variables; - - /** Types indexed by DWARF ID */ - std::unordered_map types; - - /** Types indexed by name - * - * Different compilation units have their separate type definitions - * (for the same type). When we find an opaque type in one compilation unit, - * we use this in order to try to find its definition in another compilation - * unit. - */ - std::unordered_map full_types_by_name; - - /** Whether this module is an executable - * - * More precisely we check if this is an ET_EXE ELF. These ELF files - * use fixed addresses instead of base-address relative addresses. - * Position independent executables are in fact ET_DYN. - */ - bool executable() const { return this->flags & simgrid::mc::ObjectInformation::Executable; } - - /** Base address of the module - * - * All the location information in ELF and DWARF are expressed as an offsets - * from this base address: - * - * - location of the functions and global variables - * - * - the DWARF instruction `OP_addr` pushes this on the DWARF stack. - **/ - void* base_address() const; - - /** Find a function by instruction address - * - * Loads the dwarf information on need. - * - * @param ip instruction address - * @return corresponding function (if any) or nullptr - */ - simgrid::mc::Frame* find_function(const void* ip); - - /** Find a global variable by name - * - * Loads the dwarf information on need. - * - * This is used to ignore global variables and to find well-known variables - * (`__mmalloc_default_mdp`). - * - * @param name scopes name of the global variable (`myproject::Foo::count`) - * @return corresponding variable (if any) or nullptr - */ - const simgrid::mc::Variable* find_variable(const char* name); - - /** Remove a global variable (in order to ignore it) - * - * This is used to ignore a global variable for the snapshot comparison. - */ - void remove_global_variable(const char* name); - - /** Remove a local variables (in order to ignore it) - * - * @param name Name of the local variable - * @param scope scopes name name of the function (myproject::Foo::count) or null for all functions - */ - void remove_local_variable(const char* name, const char* scope); -}; - -XBT_PRIVATE std::shared_ptr createObjectInformation(std::vector const& maps, - const char* name); - -/** Augment the current module with information about the other ones */ -XBT_PRIVATE void postProcessObjectInformation(const simgrid::mc::RemoteProcess* process, - simgrid::mc::ObjectInformation* info); -} // namespace simgrid::mc - -#endif diff --git a/src/mc/inspect/Type.hpp b/src/mc/inspect/Type.hpp deleted file mode 100644 index 6870ea8ddf..0000000000 --- a/src/mc/inspect/Type.hpp +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_TYPE_HPP -#define SIMGRID_MC_TYPE_HPP - -#include - -#include -#include - -#include - -#include "xbt/asserts.h" -#include "xbt/base.h" - -#include "src/mc/inspect/LocationList.hpp" -#include "src/mc/mc_forward.hpp" - -namespace simgrid::mc { - -/** A member of a structure, union - * - * Inheritance is seen as a special member as well. - */ -class Member { -public: - using flags_type = int; - static constexpr flags_type INHERITANCE_FLAG = 1; - static constexpr flags_type VIRTUAL_POINTER_FLAG = 2; - - Member() = default; - - /** Whether this member represent some inherited part of the object */ - flags_type flags = 0; - - /** Name of the member (if any) */ - std::string name; - - /** DWARF location expression for locating the location of the member */ - simgrid::dwarf::DwarfExpression location_expression; - - std::size_t byte_size = 0; // Do we really need this? - - unsigned type_id = 0; - simgrid::mc::Type* type = nullptr; - - bool isInheritance() const { return this->flags & INHERITANCE_FLAG; } - bool isVirtualPointer() const { return this->flags & VIRTUAL_POINTER_FLAG; } - - /** Whether the member is at a fixed offset from the base address */ - bool has_offset_location() const - { - // Recognize the expression `DW_OP_plus_uconst(offset)`: - return location_expression.size() == 1 && location_expression[0].atom == DW_OP_plus_uconst; - } - - /** Get the offset of the member - * - * This is only valid is the member is at a fixed offset from the base. - * This is often the case (for C types, C++ type without virtual - * inheritance). - * - * If the location is more complex, the location expression has - * to be evaluated (which might need accessing the memory). - */ - int offset() const - { - xbt_assert(this->has_offset_location()); - return this->location_expression[0].number; - } - - /** Set the location of the member as a fixed offset */ - void offset(int new_offset) - { - // Set the expression to be `DW_OP_plus_uconst(offset)`: - Dwarf_Op op; - op.atom = DW_OP_plus_uconst; - op.number = new_offset; - this->location_expression = {op}; - } -}; - -/** A type in the model-checked program */ -class Type { -public: - Type() = default; - - /** The DWARF TAG of the type (e.g. DW_TAG_array_type) */ - int type = 0; - unsigned id = 0; /* Offset in the section (in hexadecimal form) */ - std::string name; /* Name of the type */ - int byte_size = 0; /* Size in bytes */ - int element_count = 0; /* Number of elements for array type */ - unsigned type_id = 0; /* DW_AT_type id */ - std::vector members; /* if DW_TAG_structure_type, DW_TAG_class_type, DW_TAG_union_type*/ - - simgrid::mc::Type* subtype = nullptr; // DW_AT_type - simgrid::mc::Type* full_type = nullptr; // The same (but more complete) type -}; - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/inspect/Variable.hpp b/src/mc/inspect/Variable.hpp deleted file mode 100644 index 2f837942d7..0000000000 --- a/src/mc/inspect/Variable.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_VARIABLE_HPP -#define SIMGRID_MC_VARIABLE_HPP - -#include - -#include - -#include "src/mc/inspect/LocationList.hpp" -#include "src/mc/mc_forward.hpp" - -namespace simgrid::mc { - -/** A variable (global or local) in the model-checked program */ -class Variable { -public: - Variable() = default; - std::uint32_t id = 0; - bool global = false; - std::string name; - unsigned type_id = 0; - simgrid::mc::Type* type = nullptr; - - /** Address of the variable (if it is fixed) */ - void* address = nullptr; - - /** Description of the location of the variable (if it's not fixed) */ - simgrid::dwarf::LocationList location_list; - - /** Offset of validity of the variable (DW_AT_start_scope) - * - * This is an offset from the variable scope beginning. This variable - * is only valid starting from this offset. - */ - std::size_t start_scope = 0; - - simgrid::mc::ObjectInformation* object_info = nullptr; -}; - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/inspect/mc_dwarf.cpp b/src/mc/inspect/mc_dwarf.cpp deleted file mode 100644 index 553ec19cf6..0000000000 --- a/src/mc/inspect/mc_dwarf.cpp +++ /dev/null @@ -1,1209 +0,0 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/simgrid/util.hpp" -#include "xbt/log.h" -#include "xbt/string.hpp" -#include "xbt/sysdep.h" -#include - -#include "src/mc/inspect/ObjectInformation.hpp" -#include "src/mc/inspect/Variable.hpp" -#include "src/mc/inspect/mc_dwarf.hpp" -#include "src/mc/mc_private.hpp" -#include "src/mc/remote/RemoteProcess.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dwarf, mc, "DWARF processing"); - -/** @brief The default DW_TAG_lower_bound for a given DW_AT_language. - * - * The default for a given language is defined in the DWARF spec. - * - * @param language constant as defined by the DWARf spec - */ -static uint64_t MC_dwarf_default_lower_bound(int lang); - -/** @brief Computes the the element_count of a DW_TAG_enumeration_type DIE - * - * This is the number of elements in a given array dimension. - * - * A reference of the compilation unit (DW_TAG_compile_unit) is - * needed because the default lower bound (when there is no DW_AT_lower_bound) - * depends of the language of the compilation unit (DW_AT_language). - * - * @param die DIE for the DW_TAG_enumeration_type or DW_TAG_subrange_type - * @param unit DIE of the DW_TAG_compile_unit - */ -static uint64_t MC_dwarf_subrange_element_count(Dwarf_Die* die, Dwarf_Die* unit); - -/** @brief Computes the number of elements of a given DW_TAG_array_type. - * - * @param die DIE for the DW_TAG_array_type - */ -static uint64_t MC_dwarf_array_element_count(Dwarf_Die* die, Dwarf_Die* unit); - -/** @brief Process a DIE - * - * @param info the resulting object for the library/binary file (output) - * @param die the current DIE - * @param unit the DIE of the compile unit of the current DIE - * @param frame containing frame if any - */ -static void MC_dwarf_handle_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns); - -/** @brief Process a type DIE - */ -static void MC_dwarf_handle_type_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns); - -/** @brief Calls MC_dwarf_handle_die on all children of the given die - * - * @param info the resulting object for the library/binary file (output) - * @param die the current DIE - * @param unit the DIE of the compile unit of the current DIE - * @param frame containing frame if any - */ -static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns); - -/** @brief Handle a variable (DW_TAG_variable or other) - * - * @param info the resulting object for the library/binary file (output) - * @param die the current DIE - * @param unit the DIE of the compile unit of the current DIE - * @param frame containing frame if any - */ -static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, const Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns); - -/** @brief Get the DW_TAG_type of the DIE - * - * @param die DIE - * @return DW_TAG_type attribute as a new string (nullptr if none) - */ -static std::uint64_t MC_dwarf_at_type(Dwarf_Die* die); - -namespace simgrid::dwarf { - -enum class TagClass { Unknown, Type, Subprogram, Variable, Scope, Namespace }; - -/*** Class of forms defined in the DWARF standard */ -enum class FormClass { - Unknown, - Address, // Location in the program's address space - Block, // Arbitrary block of bytes - Constant, - String, - Flag, // Boolean value - Reference, // Reference to another DIE - ExprLoc, // DWARF expression/location description - LinePtr, - LocListPtr, - MacPtr, - RangeListPtr -}; - -static TagClass classify_tag(int tag) -{ - static const std::unordered_map map = { - {DW_TAG_array_type, TagClass::Type}, {DW_TAG_class_type, TagClass::Type}, - {DW_TAG_enumeration_type, TagClass::Type}, {DW_TAG_typedef, TagClass::Type}, - {DW_TAG_pointer_type, TagClass::Type}, {DW_TAG_reference_type, TagClass::Type}, - {DW_TAG_rvalue_reference_type, TagClass::Type}, {DW_TAG_string_type, TagClass::Type}, - {DW_TAG_structure_type, TagClass::Type}, {DW_TAG_subroutine_type, TagClass::Type}, - {DW_TAG_union_type, TagClass::Type}, {DW_TAG_ptr_to_member_type, TagClass::Type}, - {DW_TAG_set_type, TagClass::Type}, {DW_TAG_subrange_type, TagClass::Type}, - {DW_TAG_base_type, TagClass::Type}, {DW_TAG_const_type, TagClass::Type}, - {DW_TAG_file_type, TagClass::Type}, {DW_TAG_packed_type, TagClass::Type}, - {DW_TAG_volatile_type, TagClass::Type}, {DW_TAG_restrict_type, TagClass::Type}, - {DW_TAG_interface_type, TagClass::Type}, {DW_TAG_unspecified_type, TagClass::Type}, - {DW_TAG_shared_type, TagClass::Type}, - - {DW_TAG_subprogram, TagClass::Subprogram}, - - {DW_TAG_variable, TagClass::Variable}, {DW_TAG_formal_parameter, TagClass::Variable}, - - {DW_TAG_lexical_block, TagClass::Scope}, {DW_TAG_try_block, TagClass::Scope}, - {DW_TAG_catch_block, TagClass::Scope}, {DW_TAG_inlined_subroutine, TagClass::Scope}, - {DW_TAG_with_stmt, TagClass::Scope}, - - {DW_TAG_namespace, TagClass::Namespace}}; - - auto res = map.find(tag); - return res != map.end() ? res->second : TagClass::Unknown; -} - -/** @brief Find the DWARF data class for a given DWARF data form - * - * This mapping is defined in the DWARF spec. - * - * @param form The form (values taken from the DWARF spec) - * @return An internal representation for the corresponding class - * */ -static FormClass classify_form(int form) -{ - static const std::unordered_map map = { - {DW_FORM_addr, FormClass::Address}, - - {DW_FORM_block2, FormClass::Block}, {DW_FORM_block4, FormClass::Block}, - {DW_FORM_block, FormClass::Block}, {DW_FORM_block1, FormClass::Block}, - - {DW_FORM_data1, FormClass::Constant}, {DW_FORM_data2, FormClass::Constant}, - {DW_FORM_data4, FormClass::Constant}, {DW_FORM_data8, FormClass::Constant}, - {DW_FORM_udata, FormClass::Constant}, {DW_FORM_sdata, FormClass::Constant}, -#if _ELFUTILS_PREREQ(0, 171) - {DW_FORM_implicit_const, FormClass::Constant}, -#endif - - {DW_FORM_string, FormClass::String}, {DW_FORM_strp, FormClass::String}, - - {DW_FORM_ref_addr, FormClass::Reference}, {DW_FORM_ref1, FormClass::Reference}, - {DW_FORM_ref2, FormClass::Reference}, {DW_FORM_ref4, FormClass::Reference}, - {DW_FORM_ref8, FormClass::Reference}, {DW_FORM_ref_udata, FormClass::Reference}, - - {DW_FORM_flag, FormClass::Flag}, {DW_FORM_flag_present, FormClass::Flag}, - - {DW_FORM_exprloc, FormClass::ExprLoc} - - // TODO sec offset - // TODO indirect - }; - - auto res = map.find(form); - return res != map.end() ? res->second : FormClass::Unknown; -} - -/** @brief Get the name of the tag of a given DIE - * - * @param die DIE - * @return name of the tag of this DIE - */ -inline XBT_PRIVATE const char* tagname(Dwarf_Die* die) -{ - return tagname(dwarf_tag(die)); -} - -} // namespace simgrid::dwarf - -// ***** Attributes - -/** @brief Get an attribute of a given DIE as a string - * - * @param die the DIE - * @param attribute attribute - * @return value of the given attribute of the given DIE - */ -static const char* MC_dwarf_attr_integrate_string(Dwarf_Die* die, int attribute) -{ - Dwarf_Attribute attr; - if (not dwarf_attr_integrate(die, attribute, &attr)) - return nullptr; - else - return dwarf_formstring(&attr); -} - -static Dwarf_Off MC_dwarf_attr_integrate_dieoffset(Dwarf_Die* die, int attribute) -{ - Dwarf_Attribute attr; - if (dwarf_hasattr_integrate(die, attribute) == 0) - return 0; - dwarf_attr_integrate(die, attribute, &attr); - Dwarf_Die subtype_die; - xbt_assert(dwarf_formref_die(&attr, &subtype_die) != nullptr, "Could not find DIE"); - return dwarf_dieoffset(&subtype_die); -} - -/** @brief Find the type/subtype (DW_AT_type) for a DIE - * - * @param die the DIE - * @return DW_AT_type reference as a global offset in hexadecimal (or nullptr) - */ -static std::uint64_t MC_dwarf_at_type(Dwarf_Die* die) -{ - return MC_dwarf_attr_integrate_dieoffset(die, DW_AT_type); -} - -static uint64_t MC_dwarf_attr_integrate_addr(Dwarf_Die* die, int attribute) -{ - Dwarf_Attribute attr; - if (dwarf_attr_integrate(die, attribute, &attr) == nullptr) - return 0; - Dwarf_Addr value; - if (dwarf_formaddr(&attr, &value) == 0) - return (uint64_t)value; - else - return 0; -} - -static uint64_t MC_dwarf_attr_integrate_uint(Dwarf_Die* die, int attribute, uint64_t default_value) -{ - Dwarf_Attribute attr; - if (dwarf_attr_integrate(die, attribute, &attr) == nullptr) - return default_value; - Dwarf_Word value; - return dwarf_formudata(dwarf_attr_integrate(die, attribute, &attr), &value) == 0 ? (uint64_t)value : default_value; -} - -static bool MC_dwarf_attr_flag(Dwarf_Die* die, int attribute, bool integrate) -{ - Dwarf_Attribute attr; - if ((integrate ? dwarf_attr_integrate(die, attribute, &attr) : dwarf_attr(die, attribute, &attr)) == nullptr) - return false; - - bool result; - xbt_assert(not dwarf_formflag(&attr, &result), "Unexpected form for attribute %s", - simgrid::dwarf::attrname(attribute)); - return result; -} - -/** @brief Find the default lower bound for a given language - * - * The default lower bound of an array (when DW_TAG_lower_bound - * is missing) depends on the language of the compilation unit. - * - * @param lang Language of the compilation unit (values defined in the DWARF spec) - * @return Default lower bound of an array in this compilation unit - * */ -static uint64_t MC_dwarf_default_lower_bound(int lang) -{ - const std::unordered_map map = { - {DW_LANG_C, 0}, {DW_LANG_C89, 0}, {DW_LANG_C99, 0}, {DW_LANG_C11, 0}, - {DW_LANG_C_plus_plus, 0}, {DW_LANG_C_plus_plus_11, 0}, {DW_LANG_C_plus_plus_14, 0}, {DW_LANG_D, 0}, - {DW_LANG_Java, 0}, {DW_LANG_ObjC, 0}, {DW_LANG_ObjC_plus_plus, 0}, {DW_LANG_Python, 0}, - {DW_LANG_UPC, 0}, - - {DW_LANG_Ada83, 1}, {DW_LANG_Ada95, 1}, {DW_LANG_Fortran77, 1}, {DW_LANG_Fortran90, 1}, - {DW_LANG_Fortran95, 1}, {DW_LANG_Fortran03, 1}, {DW_LANG_Fortran08, 1}, {DW_LANG_Modula2, 1}, - {DW_LANG_Pascal83, 1}, {DW_LANG_PL1, 1}, {DW_LANG_Cobol74, 1}, {DW_LANG_Cobol85, 1}}; - - auto res = map.find(lang); - xbt_assert(res != map.end(), "No default DW_TAG_lower_bound for language %i and none given", lang); - return res->second; -} - -/** @brief Finds the number of elements in a DW_TAG_subrange_type or DW_TAG_enumeration_type DIE - * - * @param die the DIE - * @param unit DIE of the compilation unit - * @return number of elements in the range - * */ -static uint64_t MC_dwarf_subrange_element_count(Dwarf_Die* die, Dwarf_Die* unit) -{ - xbt_assert(dwarf_tag(die) == DW_TAG_enumeration_type || dwarf_tag(die) == DW_TAG_subrange_type, - "MC_dwarf_subrange_element_count called with DIE of type %s", simgrid::dwarf::tagname(die)); - - // Use DW_TAG_count if present: - if (dwarf_hasattr_integrate(die, DW_AT_count)) - return MC_dwarf_attr_integrate_uint(die, DW_AT_count, 0); - // Otherwise compute DW_TAG_upper_bound-DW_TAG_lower_bound + 1: - - if (not dwarf_hasattr_integrate(die, DW_AT_upper_bound)) - // This is not really 0, but the code expects this (we do not know): - return 0; - - uint64_t upper_bound = MC_dwarf_attr_integrate_uint(die, DW_AT_upper_bound, static_cast(-1)); - - uint64_t lower_bound = 0; - if (dwarf_hasattr_integrate(die, DW_AT_lower_bound)) - lower_bound = MC_dwarf_attr_integrate_uint(die, DW_AT_lower_bound, static_cast(-1)); - else - lower_bound = MC_dwarf_default_lower_bound(dwarf_srclang(unit)); - return upper_bound - lower_bound + 1; -} - -/** @brief Finds the number of elements in an array type (DW_TAG_array_type) - * - * The compilation unit might be needed because the default lower - * bound depends on the language of the compilation unit. - * - * @param die the DIE of the DW_TAG_array_type - * @param unit the DIE of the compilation unit - * @return number of elements in this array type - * */ -static uint64_t MC_dwarf_array_element_count(Dwarf_Die* die, Dwarf_Die* unit) -{ - xbt_assert(dwarf_tag(die) == DW_TAG_array_type, "MC_dwarf_array_element_count called with DIE of type %s", - simgrid::dwarf::tagname(die)); - - int result = 1; - Dwarf_Die child; - for (int res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) { - int child_tag = dwarf_tag(&child); - if (child_tag == DW_TAG_subrange_type || child_tag == DW_TAG_enumeration_type) - result *= MC_dwarf_subrange_element_count(&child, unit); - } - return result; -} - -// ***** Variable - -/** Sort the variable by name and address. - * - * We could use boost::container::flat_set instead. - */ -static bool MC_compare_variable(simgrid::mc::Variable const& a, simgrid::mc::Variable const& b) -{ - int cmp = a.name.compare(b.name); - if (cmp < 0) - return true; - else if (cmp > 0) - return false; - else - return a.address < b.address; -} - -// ***** simgrid::mc::Type* - -/** @brief Initialize the location of a member of a type - * (DW_AT_data_member_location of a DW_TAG_member). - * - * @param type a type (struct, class) - * @param member the member of the type - * @param child DIE of the member (DW_TAG_member) - */ -static void MC_dwarf_fill_member_location(const simgrid::mc::Type* type, simgrid::mc::Member* member, Dwarf_Die* child) -{ - xbt_assert(not dwarf_hasattr(child, DW_AT_data_bit_offset), "Can't groke DW_AT_data_bit_offset."); - - if (not dwarf_hasattr_integrate(child, DW_AT_data_member_location)) { - xbt_assert(type->type == DW_TAG_union_type, - "Missing DW_AT_data_member_location field in DW_TAG_member %s of type <%" PRIx64 ">%s", - member->name.c_str(), (uint64_t)type->id, type->name.c_str()); - return; - } - - Dwarf_Attribute attr; - dwarf_attr_integrate(child, DW_AT_data_member_location, &attr); - int form = dwarf_whatform(&attr); - simgrid::dwarf::FormClass form_class = simgrid::dwarf::classify_form(form); - switch (form_class) { - case simgrid::dwarf::FormClass::ExprLoc: - case simgrid::dwarf::FormClass::Block: - // Location expression: - { - Dwarf_Op* expr; - size_t len; - xbt_assert(not dwarf_getlocation(&attr, &expr, &len), - "Could not read location expression DW_AT_data_member_location in DW_TAG_member %s of type <%" PRIx64 - ">%s", - MC_dwarf_attr_integrate_string(child, DW_AT_name), (uint64_t)type->id, type->name.c_str()); - member->location_expression = simgrid::dwarf::DwarfExpression(expr, expr + len); - break; - } - case simgrid::dwarf::FormClass::Constant: - // Offset from the base address of the object: - { - Dwarf_Word offset; - xbt_assert(not dwarf_formudata(&attr, &offset), "Cannot get %s location <%" PRIx64 ">%s", - MC_dwarf_attr_integrate_string(child, DW_AT_name), (uint64_t)type->id, type->name.c_str()); - member->offset(offset); - break; - } - - default: - // includes FormClass::LocListPtr (reference to a location list: TODO) and FormClass::Reference (it's supposed to - // be possible in DWARF2 but I couldn't find its semantic in the spec) - xbt_die("Can't handle form class (%d) / form 0x%x as DW_AT_member_location", (int)form_class, (unsigned)form); - } -} - -/** @brief Populate the list of members of a type - * - * @param info ELF object containing the type DIE - * @param die DIE of the type - * @param unit DIE of the compilation unit containing the type DIE - * @param type the type - */ -static void MC_dwarf_add_members(const simgrid::mc::ObjectInformation* /*info*/, Dwarf_Die* die, - const Dwarf_Die* /*unit*/, simgrid::mc::Type* type) -{ - Dwarf_Die child; - xbt_assert(type->members.empty()); - for (int res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) { - int tag = dwarf_tag(&child); - if (tag == DW_TAG_member || tag == DW_TAG_inheritance) { - // Skip declarations: - if (MC_dwarf_attr_flag(&child, DW_AT_declaration, false)) - continue; - - // Skip compile time constants: - if (dwarf_hasattr(&child, DW_AT_const_value)) - continue; - - // TODO, we should use another type (because is is not a type but a member) - simgrid::mc::Member member; - if (tag == DW_TAG_inheritance) - member.flags |= simgrid::mc::Member::INHERITANCE_FLAG; - - const char* name = MC_dwarf_attr_integrate_string(&child, DW_AT_name); - if (name) - member.name = name; - // Those base names are used by GCC and clang for virtual table pointers - // respectively ("__vptr$ClassName", "__vptr.ClassName"): - if (member.name.rfind("__vptr$", 0) == 0 || member.name.rfind("__vptr.", 0) == 0) - member.flags |= simgrid::mc::Member::VIRTUAL_POINTER_FLAG; - // A cleaner solution would be to check against the type: - // --- - // tag: DW_TAG_member - // name: "_vptr$Foo" - // type: - // # Type for a pointer to a vtable - // tag: DW_TAG_pointer_type - // type: - // # Type for a vtable: - // tag: DW_TAG_pointer_type - // name: "__vtbl_ptr_type" - // type: - // tag: DW_TAG_subroutine_type - // type: - // tag: DW_TAG_base_type - // name: "int" - // --- - - member.byte_size = MC_dwarf_attr_integrate_uint(&child, DW_AT_byte_size, 0); - member.type_id = MC_dwarf_at_type(&child); - - if (dwarf_hasattr(&child, DW_AT_data_bit_offset)) { - XBT_WARN("Can't groke DW_AT_data_bit_offset for %s", name); - continue; - } - - MC_dwarf_fill_member_location(type, &member, &child); - - xbt_assert(member.type_id, "Missing type for member %s of <%" PRIx64 ">%s", member.name.c_str(), - (uint64_t)type->id, type->name.c_str()); - - type->members.push_back(std::move(member)); - } - } -} - -/** @brief Create a MC type object from a DIE - * - * @param info current object info object - * @param die DIE (for a given type) - * @param unit compilation unit of the current DIE - * @return MC representation of the type - */ -static simgrid::mc::Type MC_dwarf_die_to_type(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns) -{ - simgrid::mc::Type type; - type.type = dwarf_tag(die); - type.name = std::string(); - type.element_count = -1; - - // Global Offset - type.id = dwarf_dieoffset(die); - - const char* prefix = ""; - switch (type.type) { - case DW_TAG_structure_type: - prefix = "struct "; - break; - case DW_TAG_union_type: - prefix = "union "; - break; - case DW_TAG_class_type: - prefix = "class "; - break; - default: - prefix = ""; - } - - const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name); - if (name != nullptr) { - if (ns) - type.name = simgrid::xbt::string_printf("%s%s::%s", prefix, ns, name); - else - type.name = simgrid::xbt::string_printf("%s%s", prefix, name); - } - - type.type_id = MC_dwarf_at_type(die); - - // Some compilers do not emit DW_AT_byte_size for pointer_type, - // so we fill this. We currently assume that the model-checked process is in - // the same architecture.. - if (type.type == DW_TAG_pointer_type) - type.byte_size = sizeof(void*); - - // Computation of the byte_size - if (dwarf_hasattr_integrate(die, DW_AT_byte_size)) - type.byte_size = MC_dwarf_attr_integrate_uint(die, DW_AT_byte_size, 0); - else if (type.type == DW_TAG_array_type || type.type == DW_TAG_structure_type || type.type == DW_TAG_class_type) { - Dwarf_Word size; - if (dwarf_aggregate_size(die, &size) == 0) - type.byte_size = size; - } - - switch (type.type) { - case DW_TAG_array_type: - type.element_count = MC_dwarf_array_element_count(die, unit); - // TODO, handle DW_byte_stride and (not) DW_bit_stride - break; - - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_rvalue_reference_type: - break; - - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: - MC_dwarf_add_members(info, die, unit, &type); - MC_dwarf_handle_children(info, die, unit, frame, - ns ? simgrid::xbt::string_printf("%s::%s", ns, name).c_str() : type.name.c_str()); - break; - - default: - XBT_DEBUG("Unhandled type: %d (%s)", type.type, simgrid::dwarf::tagname(type.type)); - break; - } - - return type; -} - -static void MC_dwarf_handle_type_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns) -{ - simgrid::mc::Type type = MC_dwarf_die_to_type(info, die, unit, frame, ns); - auto& t = (info->types[type.id] = std::move(type)); - if (not t.name.empty() && type.byte_size != 0) - info->full_types_by_name[t.name] = &t; -} - -static std::unique_ptr MC_die_to_variable(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, - const Dwarf_Die* /*unit*/, - const simgrid::mc::Frame* frame, const char* ns) -{ - // Skip declarations: - if (MC_dwarf_attr_flag(die, DW_AT_declaration, false)) - return nullptr; - - // Skip compile time constants: - if (dwarf_hasattr(die, DW_AT_const_value)) - return nullptr; - - Dwarf_Attribute attr_location; - if (dwarf_attr(die, DW_AT_location, &attr_location) == nullptr) - // No location: do not add it ? - return nullptr; - - auto variable = std::make_unique(); - variable->id = dwarf_dieoffset(die); - variable->global = frame == nullptr; // Can be override base on DW_AT_location - variable->object_info = info; - - const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name); - if (name) - variable->name = name; - variable->type_id = MC_dwarf_at_type(die); - - int form = dwarf_whatform(&attr_location); - simgrid::dwarf::FormClass form_class; - if (form == DW_FORM_sec_offset) - form_class = simgrid::dwarf::FormClass::Constant; - else - form_class = simgrid::dwarf::classify_form(form); - switch (form_class) { - case simgrid::dwarf::FormClass::ExprLoc: - case simgrid::dwarf::FormClass::Block: - // Location expression: - { - Dwarf_Op* expr; - size_t len; - xbt_assert(not dwarf_getlocation(&attr_location, &expr, &len), - "Could not read location expression in DW_AT_location " - "of variable <%" PRIx64 ">%s", - (uint64_t)variable->id, variable->name.c_str()); - - if (len == 1 && expr[0].atom == DW_OP_addr) { - variable->global = true; - auto offset = static_cast(expr[0].number); - auto base = reinterpret_cast(info->base_address()); - variable->address = reinterpret_cast(base + offset); - } else - variable->location_list = { - simgrid::dwarf::LocationListEntry(simgrid::dwarf::DwarfExpression(expr, expr + len))}; - - break; - } - - case simgrid::dwarf::FormClass::LocListPtr: - case simgrid::dwarf::FormClass::Constant: - // Reference to location list: - variable->location_list = simgrid::dwarf::location_list(*info, attr_location); - break; - - default: - xbt_die("Unexpected form 0x%x (%i), class 0x%x (%i) list for location in <%" PRIx64 ">%s", (unsigned)form, form, - (unsigned)form_class, (int)form_class, (uint64_t)variable->id, variable->name.c_str()); - } - - // Handle start_scope: - if (dwarf_hasattr(die, DW_AT_start_scope)) { - Dwarf_Attribute attr; - dwarf_attr(die, DW_AT_start_scope, &attr); - form = dwarf_whatform(&attr); - form_class = simgrid::dwarf::classify_form(form); - if (form_class == simgrid::dwarf::FormClass::Constant) { - Dwarf_Word value; - variable->start_scope = dwarf_formudata(&attr, &value) == 0 ? (size_t)value : 0; - } else { - // TODO: FormClass::RangeListPtr - xbt_die("Unhandled form 0x%x, class 0x%X for DW_AT_start_scope of variable %s", (unsigned)form, - (unsigned)form_class, name == nullptr ? "?" : name); - } - } - - if (ns && variable->global) - variable->name = std::string(ns) + "::" + variable->name; - - // The current code needs a variable name, - // generate a fake one: - static int mc_anonymous_variable_index = 0; - if (variable->name.empty()) { - variable->name = "@anonymous#" + std::to_string(mc_anonymous_variable_index); - mc_anonymous_variable_index++; - } - return variable; -} - -static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, const Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns) -{ - std::unique_ptr variable = MC_die_to_variable(info, die, unit, frame, ns); - if (not variable) - return; - // Those arrays are sorted later: - if (variable->global) - info->global_variables.push_back(std::move(*variable)); - else if (frame != nullptr) - frame->variables.push_back(std::move(*variable)); - else - xbt_die("No frame for this local variable"); -} - -static void MC_dwarf_handle_scope_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit, - simgrid::mc::Frame* parent_frame, const char* ns) -{ - // TODO, handle DW_TAG_type/DW_TAG_location for DW_TAG_with_stmt - int tag = dwarf_tag(die); - simgrid::dwarf::TagClass klass = simgrid::dwarf::classify_tag(tag); - - // (Template) Subprogram declaration: - if (klass == simgrid::dwarf::TagClass::Subprogram && MC_dwarf_attr_flag(die, DW_AT_declaration, false)) - return; - - if (klass == simgrid::dwarf::TagClass::Scope) - xbt_assert(parent_frame, "No parent scope for this scope"); - - simgrid::mc::Frame frame; - frame.tag = tag; - frame.id = dwarf_dieoffset(die); - frame.object_info = info; - - if (klass == simgrid::dwarf::TagClass::Subprogram) { - const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name); - if (name && ns) - frame.name = std::string(ns) + "::" + name; - else if (name) - frame.name = name; - } - - frame.abstract_origin_id = MC_dwarf_attr_integrate_dieoffset(die, DW_AT_abstract_origin); - - // This is the base address for DWARF addresses. - // Relocated addresses are offset from this base address. - // See DWARF4 spec 7.5 - auto base = reinterpret_cast(info->base_address()); - - // TODO, support DW_AT_ranges - uint64_t low_pc = MC_dwarf_attr_integrate_addr(die, DW_AT_low_pc); - frame.range.begin() = low_pc ? base + low_pc : 0; - if (low_pc) { - // DW_AT_high_pc: - Dwarf_Attribute attr; - xbt_assert(dwarf_attr_integrate(die, DW_AT_high_pc, &attr), "Missing DW_AT_high_pc matching with DW_AT_low_pc"); - - Dwarf_Sword offset; - Dwarf_Addr high_pc; - - switch (simgrid::dwarf::classify_form(dwarf_whatform(&attr))) { - // DW_AT_high_pc if an offset from the low_pc: - case simgrid::dwarf::FormClass::Constant: - - xbt_assert(dwarf_formsdata(&attr, &offset) == 0, "Could not read constant"); - frame.range.end() = frame.range.begin() + offset; - break; - - // DW_AT_high_pc is a relocatable address: - case simgrid::dwarf::FormClass::Address: - xbt_assert(dwarf_formaddr(&attr, &high_pc) == 0, "Could not read address"); - frame.range.end() = base + high_pc; - break; - - default: - xbt_die("Unexpected class for DW_AT_high_pc"); - } - } - - if (klass == simgrid::dwarf::TagClass::Subprogram) { - Dwarf_Attribute attr_frame_base; - if (dwarf_attr_integrate(die, DW_AT_frame_base, &attr_frame_base)) - frame.frame_base_location = simgrid::dwarf::location_list(*info, attr_frame_base); - } - - // Handle children: - MC_dwarf_handle_children(info, die, unit, &frame, ns); - - // We sort them in order to have an (somewhat) efficient by name - // lookup: - boost::range::sort(frame.variables, MC_compare_variable); - - // Register it: - if (klass == simgrid::dwarf::TagClass::Subprogram) - info->subprograms[frame.id] = std::move(frame); - else if (klass == simgrid::dwarf::TagClass::Scope) - parent_frame->scopes.push_back(std::move(frame)); -} - -static void mc_dwarf_handle_namespace_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns) -{ - const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name); - xbt_assert(not frame, "Unexpected namespace in a subprogram"); - char* new_ns = ns == nullptr ? xbt_strdup(name) : bprintf("%s::%s", ns, name); - MC_dwarf_handle_children(info, die, unit, frame, new_ns); - xbt_free(new_ns); -} - -static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns) -{ - // For each child DIE: - Dwarf_Die child; - for (int res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) - MC_dwarf_handle_die(info, &child, unit, frame, ns); -} - -static void MC_dwarf_handle_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit, - simgrid::mc::Frame* frame, const char* ns) -{ - int tag = dwarf_tag(die); - simgrid::dwarf::TagClass klass = simgrid::dwarf::classify_tag(tag); - switch (klass) { - // Type: - case simgrid::dwarf::TagClass::Type: - MC_dwarf_handle_type_die(info, die, unit, frame, ns); - break; - - // Subprogram or scope: - case simgrid::dwarf::TagClass::Subprogram: - case simgrid::dwarf::TagClass::Scope: - MC_dwarf_handle_scope_die(info, die, unit, frame, ns); - return; - - // Variable: - case simgrid::dwarf::TagClass::Variable: - MC_dwarf_handle_variable_die(info, die, unit, frame, ns); - break; - - case simgrid::dwarf::TagClass::Namespace: - mc_dwarf_handle_namespace_die(info, die, unit, frame, ns); - break; - - default: - break; - } -} - -static Elf64_Half get_type(Elf* elf) -{ - if (const Elf64_Ehdr* ehdr64 = elf64_getehdr(elf)) - return ehdr64->e_type; - if (const Elf32_Ehdr* ehdr32 = elf32_getehdr(elf)) - return ehdr32->e_type; - xbt_die("Could not get ELF heeader"); -} - -static void read_dwarf_info(simgrid::mc::ObjectInformation* info, Dwarf* dwarf) -{ - // For each compilation unit: - Dwarf_Off offset = 0; - Dwarf_Off next_offset = 0; - size_t length; - - while (dwarf_nextcu(dwarf, offset, &next_offset, &length, nullptr, nullptr, nullptr) == 0) { - if (Dwarf_Die unit_die; dwarf_offdie(dwarf, offset + length, &unit_die) != nullptr) - MC_dwarf_handle_children(info, &unit_die, &unit_die, nullptr, nullptr); - offset = next_offset; - } -} - -/** Get the build-id (NT_GNU_BUILD_ID) from the ELF file - * - * This build-id may is used to locate an external debug (DWARF) file - * for this ELF file. - * - * @param elf libelf handle for an ELF file - * @return build-id for this ELF file (or an empty vector if none is found) - */ -static std::vector get_build_id(Elf* elf) -{ -#ifdef __linux - // Summary: the GNU build ID is stored in a ("GNU, NT_GNU_BUILD_ID) note - // found in a PT_NOTE entry in the program header table. - - size_t phnum; - xbt_assert(elf_getphdrnum(elf, &phnum) == 0, "Could not read program headers"); - - // Iterate over the program headers and find the PT_NOTE ones: - for (size_t i = 0; i < phnum; ++i) { - GElf_Phdr phdr_temp; - const GElf_Phdr* phdr = gelf_getphdr(elf, i, &phdr_temp); - if (phdr->p_type != PT_NOTE) - continue; - - Elf_Data* data = elf_getdata_rawchunk(elf, phdr->p_offset, phdr->p_filesz, ELF_T_NHDR); - - // Iterate over the notes and find the NT_GNU_BUILD_ID one: - size_t pos = 0; - while (pos < data->d_size) { - GElf_Nhdr nhdr; - // Location of the name within Elf_Data: - size_t name_pos; - size_t desc_pos; - pos = gelf_getnote(data, pos, &nhdr, &name_pos, &desc_pos); - // A build ID note is identified by the pair ("GNU", NT_GNU_BUILD_ID) - // (a namespace and a type within this namespace): - if (nhdr.n_type == NT_GNU_BUILD_ID && nhdr.n_namesz == sizeof("GNU") && - memcmp((char*)data->d_buf + name_pos, "GNU", sizeof("GNU")) == 0) { - XBT_DEBUG("Found GNU/NT_GNU_BUILD_ID note"); - char* start = (char*)data->d_buf + desc_pos; - char* end = start + nhdr.n_descsz; - return std::vector(start, end); - } - } - } -#endif - return std::vector(); -} - -/** Binary data to hexadecimal */ -static inline std::array to_hex(std::uint8_t byte) -{ - constexpr std::array hexdigits{ - {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}}; - // Horrid double braces! - // Apparently, this is needed in C++11 (not in C++14). - return {{hexdigits[byte >> 4], hexdigits[byte & 0xF]}}; -} - -/** Binary data to hexadecimal */ -static std::string to_hex(const char* data, std::size_t count) -{ - std::string res; - res.resize(2 * count); - for (std::size_t i = 0; i < count; i++) - std::copy_n(cbegin(to_hex(data[i])), 2, &res[2 * i]); - return res; -} - -/** Binary data to hexadecimal */ -static std::string to_hex(std::vector const& data) -{ - return to_hex(data.data(), data.size()); -} - -/** Base directories for external debug files */ -static constexpr auto debug_paths = { - "/usr/lib/debug/", - "/usr/local/lib/debug/", -}; - -/** Locate an external debug file from the NT_GNU_BUILD_ID - * - * This is one of the mechanisms used for - * [separate debug files](https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html). - */ -// Example: -// /usr/lib/debug/.build-id/0b/dc77f1c29aea2b14ff5acd9a19ab3175ffdeae.debug -static int find_by_build_id(std::vector id) -{ - std::string filename; - std::string hex = to_hex(id); - for (const char* const& debug_path : debug_paths) { - // Example: - filename = std::string(debug_path) + ".build-id/" + to_hex(id.data(), 1) + '/' + - to_hex(id.data() + 1, id.size() - 1) + ".debug"; - XBT_DEBUG("Checking debug file: %s", filename.c_str()); - if (int fd = open(filename.c_str(), O_RDONLY); fd != -1) { - XBT_DEBUG("Found debug file: %s\n", hex.c_str()); - return fd; - } - xbt_assert(errno != ENOENT, "Could not open file: %s", strerror(errno)); - } - XBT_DEBUG("No debug info found for build ID %s\n", hex.data()); - return -1; -} - -/** @brief Populate the debugging information of the given ELF object - * - * Read the DWARF information of the ELF object and populate the - * lists of types, variables, functions. - */ -static void MC_load_dwarf(simgrid::mc::ObjectInformation* info) -{ - xbt_assert(elf_version(EV_CURRENT) != EV_NONE, "libelf initialization error"); - - // Open the ELF file: - int fd = open(info->file_name.c_str(), O_RDONLY); - xbt_assert(fd >= 0, "Could not open file %s", info->file_name.c_str()); - Elf* elf = elf_begin(fd, ELF_C_READ, nullptr); - xbt_assert(elf != nullptr && elf_kind(elf) == ELF_K_ELF, "%s is not an ELF file", info->file_name.c_str()); - - // Remember if this is a `ET_EXEC` (fixed location) or `ET_DYN`: - if (get_type(elf) == ET_EXEC) - info->flags |= simgrid::mc::ObjectInformation::Executable; - - // Read DWARF debug information in the file: - if (Dwarf* dwarf = dwarf_begin_elf(elf, DWARF_C_READ, nullptr)) { - read_dwarf_info(info, dwarf); - dwarf_end(dwarf); - elf_end(elf); - close(fd); - return; - } - - // If there was no DWARF in the file, try to find it in a separate file. - // Different methods might be used to store the DWARF information: - // * GNU NT_GNU_BUILD_ID - // * .gnu_debuglink - // See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html - // for reference of what we are doing. - - // Try with NT_GNU_BUILD_ID: we find the build ID in the ELF file and then - // use this ID to find the file in some known locations in the filesystem. - if (std::vector build_id = get_build_id(elf); not build_id.empty()) { - elf_end(elf); - close(fd); - - // Find the debug file using the build id: - fd = find_by_build_id(build_id); - xbt_assert(fd != -1, - "Missing debug info for %s with build-id %s\n" - "You might want to install the suitable debugging package.\n", - info->file_name.c_str(), to_hex(build_id).c_str()); - - // Load the DWARF info from this file: - XBT_DEBUG("Load DWARF for %s", info->file_name.c_str()); - Dwarf* dwarf = dwarf_begin(fd, DWARF_C_READ); - xbt_assert(dwarf != nullptr, "No DWARF info for %s", info->file_name.c_str()); - read_dwarf_info(info, dwarf); - dwarf_end(dwarf); - close(fd); - return; - } - - // TODO, try to find DWARF info using .gnu_debuglink. - - elf_end(elf); - close(fd); - xbt_die("Debugging information not found for %s\n" - "Try recompiling with -g\n", - info->file_name.c_str()); -} - -// ***** Functions index - -static void MC_make_functions_index(simgrid::mc::ObjectInformation* info) -{ - info->functions_index.clear(); - - for (auto& [_, e] : info->subprograms) { - if (e.range.begin() == 0) - continue; - simgrid::mc::FunctionIndexEntry entry; - entry.low_pc = (void*)e.range.begin(); - entry.function = &e; - info->functions_index.push_back(entry); - } - - info->functions_index.shrink_to_fit(); - - // Sort the array by low_pc: - boost::range::sort(info->functions_index, - [](simgrid::mc::FunctionIndexEntry const& a, simgrid::mc::FunctionIndexEntry const& b) { - return a.low_pc < b.low_pc; - }); -} - -static void MC_post_process_variables(simgrid::mc::ObjectInformation* info) -{ - // Someone needs this to be sorted but who? - boost::range::sort(info->global_variables, MC_compare_variable); - - for (simgrid::mc::Variable& variable : info->global_variables) - if (variable.type_id) - variable.type = simgrid::util::find_map_ptr(info->types, variable.type_id); -} - -static void mc_post_process_scope(simgrid::mc::ObjectInformation* info, simgrid::mc::Frame* scope) -{ - if (scope->tag == DW_TAG_inlined_subroutine) { - // Attach correct namespaced name in inlined subroutine: - auto i = info->subprograms.find(scope->abstract_origin_id); - xbt_assert(i != info->subprograms.end(), "Could not lookup abstract origin %" PRIx64, - (std::uint64_t)scope->abstract_origin_id); - scope->name = i->second.name; - } - - // Direct: - for (simgrid::mc::Variable& variable : scope->variables) - if (variable.type_id) - variable.type = simgrid::util::find_map_ptr(info->types, variable.type_id); - - // Recursive post-processing of nested-scopes: - for (simgrid::mc::Frame& nested_scope : scope->scopes) - mc_post_process_scope(info, &nested_scope); -} - -static simgrid::mc::Type* MC_resolve_type(simgrid::mc::ObjectInformation* info, unsigned type_id) -{ - if (not type_id) - return nullptr; - simgrid::mc::Type* type = simgrid::util::find_map_ptr(info->types, type_id); - if (type == nullptr) - return nullptr; - - // We already have the information on the type: - if (type->byte_size != 0) - return type; - - // Don't have a name, we can't find a more complete version: - if (type->name.empty()) - return type; - - // Try to find a more complete description of the type: - // We need to fix in order to support C++. - if (simgrid::mc::Type** subtype = simgrid::util::find_map_ptr(info->full_types_by_name, type->name)) - type = *subtype; - return type; -} - -static void MC_post_process_types(simgrid::mc::ObjectInformation* info) -{ - // Lookup "subtype" field: - for (auto& [_, i] : info->types) { - i.subtype = MC_resolve_type(info, i.type_id); - for (simgrid::mc::Member& member : i.members) - member.type = MC_resolve_type(info, member.type_id); - } -} - -namespace simgrid::mc { - -void ObjectInformation::ensure_dwarf_loaded() -{ - if (dwarf_loaded) - return; - dwarf_loaded = true; - - MC_load_dwarf(this); - MC_post_process_variables(this); - MC_post_process_types(this); - for (auto& [_, entry] : this->subprograms) - mc_post_process_scope(this, &entry); - MC_make_functions_index(this); -} - -/** @brief Finds information about a given shared object/executable */ -std::shared_ptr createObjectInformation(std::vector const& maps, const char* name) -{ - auto result = std::make_shared(); - result->file_name = name; - simgrid::mc::find_object_address(maps, result.get()); - return result; -} - -/*************************************************************************/ - -void postProcessObjectInformation(const RemoteProcess* process, ObjectInformation* info) -{ - for (auto& [_, t] : info->types) { - Type* type = &t; - Type* subtype = type; - while (subtype->type == DW_TAG_typedef || subtype->type == DW_TAG_volatile_type || - subtype->type == DW_TAG_const_type) - if (subtype->subtype) - subtype = subtype->subtype; - else - break; - - // Resolve full_type: - if (not subtype->name.empty() && subtype->byte_size == 0) - for (auto const& object_info : process->object_infos) { - auto i = object_info->full_types_by_name.find(subtype->name); - if (i != object_info->full_types_by_name.end() && not i->second->name.empty() && i->second->byte_size) { - type->full_type = i->second; - break; - } - } - else - type->full_type = subtype; - } -} - -} // namespace simgrid::mc - -namespace simgrid::dwarf { - -/** Convert a DWARF register into a libunwind register - * - * DWARF and libunwind does not use the same convention for numbering the - * registers on some architectures. The function makes the necessary - * conversion. - */ -int dwarf_register_to_libunwind(int dwarf_register) -{ -#if defined(__x86_64__) || defined(__aarch64__) - // It seems for this arch, DWARF and libunwind agree in the numbering: - return dwarf_register; -#elif defined(__i386__) - // Couldn't find the authoritative source of information for this. - // This is inspired from http://source.winehq.org/source/dlls/dbghelp/cpu_i386.c#L517. - constexpr std::array regs{ - {/* 0 */ UNW_X86_EAX, /* 1 */ UNW_X86_ECX, /* 2 */ UNW_X86_EDX, /* 3 */ UNW_X86_EBX, - /* 4 */ UNW_X86_ESP, /* 5 */ UNW_X86_EBP, /* 6 */ UNW_X86_ESI, /* 7 */ UNW_X86_EDI, - /* 8 */ UNW_X86_EIP, /* 9 */ UNW_X86_EFLAGS, /* 10 */ UNW_X86_CS, /* 11 */ UNW_X86_SS, - /* 12 */ UNW_X86_DS, /* 13 */ UNW_X86_ES, /* 14 */ UNW_X86_FS, /* 15 */ UNW_X86_GS, - /* 16 */ UNW_X86_ST0, /* 17 */ UNW_X86_ST1, /* 18 */ UNW_X86_ST2, /* 19 */ UNW_X86_ST3, - /* 20 */ UNW_X86_ST4, /* 21 */ UNW_X86_ST5, /* 22 */ UNW_X86_ST6, /* 23 */ UNW_X86_ST7}}; - return regs.at(dwarf_register); -#else -#error This architecture is not supported yet for DWARF expression evaluation. -#endif -} - -} // namespace simgrid::dwarf diff --git a/src/mc/inspect/mc_dwarf.hpp b/src/mc/inspect/mc_dwarf.hpp deleted file mode 100644 index b43ad14083..0000000000 --- a/src/mc/inspect/mc_dwarf.hpp +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_DWARF_HPP -#define SIMGRID_MC_DWARF_HPP - -#include "xbt/base.h" - -#include "src/mc/mc_forward.hpp" - -namespace simgrid::dwarf { - -XBT_PRIVATE const char* attrname(int attr); -XBT_PRIVATE const char* tagname(int tag); - -XBT_PRIVATE void* resolve_member(const void* base, const simgrid::mc::Type* type, const simgrid::mc::Member* member, - const simgrid::mc::AddressSpace* snapshot); - -XBT_PRIVATE -int dwarf_register_to_libunwind(int dwarf_register); - -} // namespace simgrid::dwarf - -#endif diff --git a/src/mc/inspect/mc_dwarf_attrnames.cpp b/src/mc/inspect/mc_dwarf_attrnames.cpp deleted file mode 100644 index 037c6d2bf5..0000000000 --- a/src/mc/inspect/mc_dwarf_attrnames.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/* Warning: autogenerated, do not edit! */ - -#include "src/mc/inspect/mc_dwarf.hpp" - -#include -#include - -namespace { -const std::unordered_map attrname_map = { - {0x01, "DW_AT_sibling"}, - {0x02, "DW_AT_location"}, - {0x03, "DW_AT_name"}, - {0x09, "DW_AT_ordering"}, - {0x0a, "DW_AT_subscr_data"}, - {0x0b, "DW_AT_byte_size"}, - {0x0c, "DW_AT_bit_offset"}, - {0x0d, "DW_AT_bit_size"}, - {0x0f, "DW_AT_element_list"}, - {0x10, "DW_AT_stmt_list"}, - {0x11, "DW_AT_low_pc"}, - {0x12, "DW_AT_high_pc"}, - {0x13, "DW_AT_language"}, - {0x14, "DW_AT_member"}, - {0x15, "DW_AT_discr"}, - {0x16, "DW_AT_discr_value"}, - {0x17, "DW_AT_visibility"}, - {0x18, "DW_AT_import"}, - {0x19, "DW_AT_string_length"}, - {0x1a, "DW_AT_common_reference"}, - {0x1b, "DW_AT_comp_dir"}, - {0x1c, "DW_AT_const_value"}, - {0x1d, "DW_AT_containing_type"}, - {0x1e, "DW_AT_default_value"}, - {0x20, "DW_AT_inline"}, - {0x21, "DW_AT_is_optional"}, - {0x22, "DW_AT_lower_bound"}, - {0x25, "DW_AT_producer"}, - {0x27, "DW_AT_prototyped"}, - {0x2a, "DW_AT_return_addr"}, - {0x2c, "DW_AT_start_scope"}, - {0x2e, "DW_AT_bit_stride"}, - {0x2f, "DW_AT_upper_bound"}, - {0x31, "DW_AT_abstract_origin"}, - {0x32, "DW_AT_accessibility"}, - {0x33, "DW_AT_address_class"}, - {0x34, "DW_AT_artificial"}, - {0x35, "DW_AT_base_types"}, - {0x36, "DW_AT_calling_convention"}, - {0x37, "DW_AT_count"}, - {0x38, "DW_AT_data_member_location"}, - {0x39, "DW_AT_decl_column"}, - {0x3a, "DW_AT_decl_file"}, - {0x3b, "DW_AT_decl_line"}, - {0x3c, "DW_AT_declaration"}, - {0x3d, "DW_AT_discr_list"}, - {0x3e, "DW_AT_encoding"}, - {0x3f, "DW_AT_external"}, - {0x40, "DW_AT_frame_base"}, - {0x41, "DW_AT_friend"}, - {0x42, "DW_AT_identifier_case"}, - {0x43, "DW_AT_macro_info"}, - {0x44, "DW_AT_namelist_item"}, - {0x45, "DW_AT_priority"}, - {0x46, "DW_AT_segment"}, - {0x47, "DW_AT_specification"}, - {0x48, "DW_AT_static_link"}, - {0x49, "DW_AT_type"}, - {0x4a, "DW_AT_use_location"}, - {0x4b, "DW_AT_variable_parameter"}, - {0x4c, "DW_AT_virtuality"}, - {0x4d, "DW_AT_vtable_elem_location"}, - {0x4e, "DW_AT_allocated"}, - {0x4f, "DW_AT_associated"}, - {0x50, "DW_AT_data_location"}, - {0x51, "DW_AT_byte_stride"}, - {0x52, "DW_AT_entry_pc"}, - {0x53, "DW_AT_use_UTF8"}, - {0x54, "DW_AT_extension"}, - {0x55, "DW_AT_ranges"}, - {0x56, "DW_AT_trampoline"}, - {0x57, "DW_AT_call_column"}, - {0x58, "DW_AT_call_file"}, - {0x59, "DW_AT_call_line"}, - {0x5a, "DW_AT_description"}, - {0x5b, "DW_AT_binary_scale"}, - {0x5c, "DW_AT_decimal_scale"}, - {0x5d, "DW_AT_small"}, - {0x5e, "DW_AT_decimal_sign"}, - {0x5f, "DW_AT_digit_count"}, - {0x60, "DW_AT_picture_string"}, - {0x61, "DW_AT_mutable"}, - {0x62, "DW_AT_threads_scaled"}, - {0x63, "DW_AT_explicit"}, - {0x64, "DW_AT_object_pointer"}, - {0x65, "DW_AT_endianity"}, - {0x66, "DW_AT_elemental"}, - {0x67, "DW_AT_pure"}, - {0x68, "DW_AT_recursive"}, - {0x69, "DW_AT_signature"}, - {0x6a, "DW_AT_main_subprogram"}, - {0x6b, "DW_AT_data_bit_offset"}, - {0x6c, "DW_AT_const_expr"}, - {0x6d, "DW_AT_enum_class"}, - {0x6e, "DW_AT_linkage_name"}, - {0x87, "DW_AT_noreturn"}, - {0x2000, "DW_AT_lo_user"}, - {0x2001, "DW_AT_MIPS_fde"}, - {0x2002, "DW_AT_MIPS_loop_begin"}, - {0x2003, "DW_AT_MIPS_tail_loop_begin"}, - {0x2004, "DW_AT_MIPS_epilog_begin"}, - {0x2005, "DW_AT_MIPS_loop_unroll_factor"}, - {0x2006, "DW_AT_MIPS_software_pipeline_depth"}, - {0x2007, "DW_AT_MIPS_linkage_name"}, - {0x2008, "DW_AT_MIPS_stride"}, - {0x2009, "DW_AT_MIPS_abstract_name"}, - {0x200a, "DW_AT_MIPS_clone_origin"}, - {0x200b, "DW_AT_MIPS_has_inlines"}, - {0x200c, "DW_AT_MIPS_stride_byte"}, - {0x200d, "DW_AT_MIPS_stride_elem"}, - {0x200e, "DW_AT_MIPS_ptr_dopetype"}, - {0x200f, "DW_AT_MIPS_allocatable_dopetype"}, - {0x2010, "DW_AT_MIPS_assumed_shape_dopetype"}, - {0x2011, "DW_AT_MIPS_assumed_size"}, - {0x2101, "DW_AT_sf_names"}, - {0x2102, "DW_AT_src_info"}, - {0x2103, "DW_AT_mac_info"}, - {0x2104, "DW_AT_src_coords"}, - {0x2105, "DW_AT_body_begin"}, - {0x2106, "DW_AT_body_end"}, - {0x2107, "DW_AT_GNU_vector"}, - {0x2108, "DW_AT_GNU_guarded_by"}, - {0x2109, "DW_AT_GNU_pt_guarded_by"}, - {0x210a, "DW_AT_GNU_guarded"}, - {0x210b, "DW_AT_GNU_pt_guarded"}, - {0x210c, "DW_AT_GNU_locks_excluded"}, - {0x210d, "DW_AT_GNU_exclusive_locks_required"}, - {0x210e, "DW_AT_GNU_shared_locks_required"}, - {0x210f, "DW_AT_GNU_odr_signature"}, - {0x2110, "DW_AT_GNU_template_name"}, - {0x2111, "DW_AT_GNU_call_site_value"}, - {0x2112, "DW_AT_GNU_call_site_data_value"}, - {0x2113, "DW_AT_GNU_call_site_target"}, - {0x2114, "DW_AT_GNU_call_site_target_clobbered"}, - {0x2115, "DW_AT_GNU_tail_call"}, - {0x2116, "DW_AT_GNU_all_tail_call_sites"}, - {0x2117, "DW_AT_GNU_all_call_sites"}, - {0x2118, "DW_AT_GNU_all_source_call_sites"}, - {0x2119, "DW_AT_GNU_macros"}, - {0x211a, "DW_AT_GNU_deleted"}, - {0x3fff, "DW_AT_hi_user"}, -}; -} - -namespace simgrid::dwarf { - -/** @brief Get the name of an attribute (DW_AT_*) from its code - * - * @param attr attribute code (see the DWARF specification) - * @return name of the attribute - */ -XBT_PRIVATE -const char* attrname(int attr) -{ - auto name = attrname_map.find(attr); - return name == attrname_map.end() ? "DW_AT_unknown" : name->second; -} - -} // namespace simgrid::dwarf diff --git a/src/mc/inspect/mc_dwarf_tagnames.cpp b/src/mc/inspect/mc_dwarf_tagnames.cpp deleted file mode 100644 index a75395b31f..0000000000 --- a/src/mc/inspect/mc_dwarf_tagnames.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/* Warning: autogenerated, do not edit! */ - -#include "src/mc/inspect/mc_dwarf.hpp" - -#include -#include - -namespace { -const std::unordered_map tagname_map = { - {0x00, "DW_TAG_invalid"}, - {0x01, "DW_TAG_array_type"}, - {0x02, "DW_TAG_class_type"}, - {0x03, "DW_TAG_entry_point"}, - {0x04, "DW_TAG_enumeration_type"}, - {0x05, "DW_TAG_formal_parameter"}, - {0x08, "DW_TAG_imported_declaration"}, - {0x0a, "DW_TAG_label"}, - {0x0b, "DW_TAG_lexical_block"}, - {0x0d, "DW_TAG_member"}, - {0x0f, "DW_TAG_pointer_type"}, - {0x10, "DW_TAG_reference_type"}, - {0x11, "DW_TAG_compile_unit"}, - {0x12, "DW_TAG_string_type"}, - {0x13, "DW_TAG_structure_type"}, - {0x15, "DW_TAG_subroutine_type"}, - {0x16, "DW_TAG_typedef"}, - {0x17, "DW_TAG_union_type"}, - {0x18, "DW_TAG_unspecified_parameters"}, - {0x19, "DW_TAG_variant"}, - {0x1a, "DW_TAG_common_block"}, - {0x1b, "DW_TAG_common_inclusion"}, - {0x1c, "DW_TAG_inheritance"}, - {0x1d, "DW_TAG_inlined_subroutine"}, - {0x1e, "DW_TAG_module"}, - {0x1f, "DW_TAG_ptr_to_member_type"}, - {0x20, "DW_TAG_set_type"}, - {0x21, "DW_TAG_subrange_type"}, - {0x22, "DW_TAG_with_stmt"}, - {0x23, "DW_TAG_access_declaration"}, - {0x24, "DW_TAG_base_type"}, - {0x25, "DW_TAG_catch_block"}, - {0x26, "DW_TAG_const_type"}, - {0x27, "DW_TAG_constant"}, - {0x28, "DW_TAG_enumerator"}, - {0x29, "DW_TAG_file_type"}, - {0x2a, "DW_TAG_friend"}, - {0x2b, "DW_TAG_namelist"}, - {0x2c, "DW_TAG_namelist_item"}, - {0x2d, "DW_TAG_packed_type"}, - {0x2e, "DW_TAG_subprogram"}, - {0x2f, "DW_TAG_template_type_parameter"}, - {0x30, "DW_TAG_template_value_parameter"}, - {0x31, "DW_TAG_thrown_type"}, - {0x32, "DW_TAG_try_block"}, - {0x33, "DW_TAG_variant_part"}, - {0x34, "DW_TAG_variable"}, - {0x35, "DW_TAG_volatile_type"}, - {0x36, "DW_TAG_dwarf_procedure"}, - {0x37, "DW_TAG_restrict_type"}, - {0x38, "DW_TAG_interface_type"}, - {0x39, "DW_TAG_namespace"}, - {0x3a, "DW_TAG_imported_module"}, - {0x3b, "DW_TAG_unspecified_type"}, - {0x3c, "DW_TAG_partial_unit"}, - {0x3d, "DW_TAG_imported_unit"}, - {0x3f, "DW_TAG_condition"}, - {0x40, "DW_TAG_shared_type"}, - {0x41, "DW_TAG_type_unit"}, - {0x42, "DW_TAG_rvalue_reference_type"}, - {0x43, "DW_TAG_template_alias"}, - {0x47, "DW_TAG_atomic_type"}, - {0x4080, "DW_TAG_lo_user"}, - {0x4081, "DW_TAG_MIPS_loop"}, - {0x4101, "DW_TAG_format_label"}, - {0x4102, "DW_TAG_function_template"}, - {0x4103, "DW_TAG_class_template"}, - {0x4104, "DW_TAG_GNU_BINCL"}, - {0x4105, "DW_TAG_GNU_EINCL"}, - {0x4106, "DW_TAG_GNU_template_template_param"}, - {0x4107, "DW_TAG_GNU_template_parameter_pack"}, - {0x4108, "DW_TAG_GNU_formal_parameter_pack"}, - {0x4109, "DW_TAG_GNU_call_site"}, - {0x410a, "DW_TAG_GNU_call_site_parameter"}, - {0xffff, "DW_TAG_hi_user"}, -}; -} - -namespace simgrid::dwarf { - -/** @brief Get the name of a dwarf tag (DW_TAG_*) from its code - * - * @param tag tag code (see the DWARF specification) - * @return name of the tag - */ -XBT_PRIVATE -const char* tagname(int tag) -{ - auto name = tagname_map.find(tag); - return name == tagname_map.end() ? "DW_TAG_unknown" : name->second; -} - -} // namespace simgrid::dwarf diff --git a/src/mc/inspect/mc_member.cpp b/src/mc/inspect/mc_member.cpp deleted file mode 100644 index 1ab3a18e33..0000000000 --- a/src/mc/inspect/mc_member.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/inspect/Type.hpp" -#include "src/mc/inspect/mc_dwarf.hpp" -#include "src/mc/mc_private.hpp" - -namespace simgrid::dwarf { - -/** Resolve snapshot in the process address space - * - * @param object Process address of the struct/class - * @param type Type of the struct/class - * @param member Member description - * @param snapshot Snapshot (or nullptr) - * @return Process address of the given member of the 'object' struct/class - */ -void* resolve_member(const void* base, const simgrid::mc::Type* /*type*/, const simgrid::mc::Member* member, - const simgrid::mc::AddressSpace* address_space) -{ - ExpressionContext state; - state.address_space = address_space; - - ExpressionStack stack; - stack.push((ExpressionStack::value_type)base); - simgrid::dwarf::execute(member->location_expression, state, stack); - return (void*)stack.top(); -} - -} // namespace simgrid::dwarf diff --git a/src/mc/inspect/mc_unw.cpp b/src/mc/inspect/mc_unw.cpp deleted file mode 100644 index 5806cacb08..0000000000 --- a/src/mc/inspect/mc_unw.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/** \file - * Libunwind support for mc_address_space objects. - */ - -// We need this for the register indices: -// #define _GNU_SOURCE - -#include "src/mc/inspect/mc_unw.hpp" -#include "src/mc/inspect/Frame.hpp" -#include "src/mc/remote/RemoteProcess.hpp" - -#include - -// On x86_64, libunwind unw_context_t has the same layout as ucontext_t: -#include -#include -#ifdef __FreeBSD__ -typedef register_t greg_t; -#endif - -#include - -namespace simgrid::mc { - -// ***** Implementation - -/** Get frame unwind information (libunwind method) - * - * Delegates to the local/ptrace implementation. - */ -int UnwindContext::find_proc_info(unw_addr_space_t /*as*/, unw_word_t ip, unw_proc_info_t* pip, int need_unwind_info, - void* arg) noexcept -{ - const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg; - return unw_get_accessors(context->process_->unw_underlying_addr_space) - ->find_proc_info(context->process_->unw_underlying_addr_space, ip, pip, need_unwind_info, - context->process_->unw_underlying_context); -} - -/** Release frame unwind information (libunwind method) - * - * Delegates to the local/ptrace implementation. - */ -void UnwindContext::put_unwind_info(unw_addr_space_t /*as*/, unw_proc_info_t* pip, void* arg) noexcept -{ - const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg; - return unw_get_accessors(context->process_->unw_underlying_addr_space) - ->put_unwind_info(context->process_->unw_underlying_addr_space, pip, context->process_->unw_underlying_context); -} - -/** (libunwind method) - * - * Not implemented. - */ -int UnwindContext::get_dyn_info_list_addr(unw_addr_space_t /*as*/, unw_word_t* dilap, void* arg) noexcept -{ - const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg; - return unw_get_accessors(context->process_->unw_underlying_addr_space) - ->get_dyn_info_list_addr(context->process_->unw_underlying_addr_space, dilap, - context->process_->unw_underlying_context); -} - -/** Read from the target address space memory (libunwind method) - * - * Delegates to the `simgrid::mc::Process*`. - */ -int UnwindContext::access_mem(unw_addr_space_t /*as*/, unw_word_t addr, unw_word_t* valp, int write, void* arg) noexcept -{ - const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg; - if (write) - return -UNW_EREADONLYREG; - context->address_space_->read_bytes(valp, sizeof(unw_word_t), remote(addr)); - return 0; -} - -void* UnwindContext::get_reg(unw_context_t* context, unw_regnum_t regnum) noexcept -{ -#ifdef __x86_64 - mcontext_t* mcontext = &context->uc_mcontext; - switch (regnum) { -#ifdef __linux__ - case UNW_X86_64_RAX: - return &mcontext->gregs[REG_RAX]; - case UNW_X86_64_RDX: - return &mcontext->gregs[REG_RDX]; - case UNW_X86_64_RCX: - return &mcontext->gregs[REG_RCX]; - case UNW_X86_64_RBX: - return &mcontext->gregs[REG_RBX]; - case UNW_X86_64_RSI: - return &mcontext->gregs[REG_RSI]; - case UNW_X86_64_RDI: - return &mcontext->gregs[REG_RDI]; - case UNW_X86_64_RBP: - return &mcontext->gregs[REG_RBP]; - case UNW_X86_64_RSP: - return &mcontext->gregs[REG_RSP]; - case UNW_X86_64_R8: - return &mcontext->gregs[REG_R8]; - case UNW_X86_64_R9: - return &mcontext->gregs[REG_R9]; - case UNW_X86_64_R10: - return &mcontext->gregs[REG_R10]; - case UNW_X86_64_R11: - return &mcontext->gregs[REG_R11]; - case UNW_X86_64_R12: - return &mcontext->gregs[REG_R12]; - case UNW_X86_64_R13: - return &mcontext->gregs[REG_R13]; - case UNW_X86_64_R14: - return &mcontext->gregs[REG_R14]; - case UNW_X86_64_R15: - return &mcontext->gregs[REG_R15]; - case UNW_X86_64_RIP: - return &mcontext->gregs[REG_RIP]; -#elif defined __FreeBSD__ - case UNW_X86_64_RAX: - return &mcontext->mc_rax; - case UNW_X86_64_RDX: - return &mcontext->mc_rdx; - case UNW_X86_64_RCX: - return &mcontext->mc_rcx; - case UNW_X86_64_RBX: - return &mcontext->mc_rbx; - case UNW_X86_64_RSI: - return &mcontext->mc_rsi; - case UNW_X86_64_RDI: - return &mcontext->mc_rdi; - case UNW_X86_64_RBP: - return &mcontext->mc_rbp; - case UNW_X86_64_RSP: - return &mcontext->mc_rsp; - case UNW_X86_64_R8: - return &mcontext->mc_r8; - case UNW_X86_64_R9: - return &mcontext->mc_r9; - case UNW_X86_64_R10: - return &mcontext->mc_r10; - case UNW_X86_64_R11: - return &mcontext->mc_r11; - case UNW_X86_64_R12: - return &mcontext->mc_r12; - case UNW_X86_64_R13: - return &mcontext->mc_r13; - case UNW_X86_64_R14: - return &mcontext->mc_r14; - case UNW_X86_64_R15: - return &mcontext->mc_r15; - case UNW_X86_64_RIP: - return &mcontext->mc_rip; -#else -#error "Unable to get register from ucontext, please add your case" -#endif - default: - return nullptr; - } -#else - return nullptr; -#endif -} - -/** Read a standard register (libunwind method) - */ -int UnwindContext::access_reg(unw_addr_space_t /*as*/, unw_regnum_t regnum, unw_word_t* valp, int write, - void* arg) noexcept -{ - auto* as_context = static_cast(arg); - unw_context_t* context = &as_context->unwind_context_; - if (write) - return -UNW_EREADONLYREG; - const greg_t* preg = (greg_t*)get_reg(context, regnum); - if (not preg) - return -UNW_EBADREG; - *valp = *preg; - return 0; -} - -/** Find information about a function (libunwind method) - */ -int UnwindContext::get_proc_name(unw_addr_space_t /*as*/, unw_word_t addr, char* bufp, size_t buf_len, unw_word_t* offp, - void* arg) noexcept -{ - const simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*)arg; - const simgrid::mc::Frame* frame = context->process_->find_function(remote(addr)); - if (not frame) - return -UNW_ENOINFO; - *offp = (unw_word_t)frame->range.begin() - addr; - - strncpy(bufp, frame->name.c_str(), buf_len); - if (bufp[buf_len - 1]) { - bufp[buf_len - 1] = 0; - return -UNW_ENOMEM; - } - - return 0; -} - -// ***** Init - -unw_addr_space_t UnwindContext::createUnwindAddressSpace() -{ - /** Virtual table for our `libunwind` implementation - * - * Stack unwinding on a `simgrid::mc::Process*` (for memory, unwinding information) - * and `ucontext_t` (for processor registers). - * - * It works with the `simgrid::mc::UnwindContext` context. - * - * Use nullptr as access_fpreg and resume, as we don't need them. - */ - unw_accessors_t accessors = {&find_proc_info, &put_unwind_info, &get_dyn_info_list_addr, &access_mem, &access_reg, - nullptr, nullptr, &get_proc_name}; - return unw_create_addr_space(&accessors, BYTE_ORDER); -} - -void UnwindContext::initialize(simgrid::mc::RemoteProcess* process, unw_context_t* c) -{ - this->address_space_ = process; - this->process_ = process; - - // Take a copy of the context for our own purpose: - this->unwind_context_ = *c; -#if SIMGRID_PROCESSOR_x86_64 || SIMGRID_PROCESSOR_i686 || defined(__aarch64__) -#ifdef __linux__ - // On x86_64, ucontext_t contains a pointer to itself for FP registers. - // We don't really need support for FR registers as they are caller saved - // and probably never use those fields as libunwind-x86_64 does not read - // FP registers from the unw_context_t - // Let's ignore this and see what happens: - this->unwind_context_.uc_mcontext.fpregs = nullptr; -#endif -#else - // Do we need to do any fixup like this? -#error Target CPU type is not handled. -#endif -} - -unw_cursor_t UnwindContext::cursor() -{ - unw_cursor_t cursor; - xbt_assert(process_ != nullptr && address_space_ != nullptr && - unw_init_remote(&cursor, process_->unw_addr_space, this) == 0, - "UnwindContext not initialized"); - return cursor; -} - -} // namespace simgrid::mc diff --git a/src/mc/inspect/mc_unw.hpp b/src/mc/inspect/mc_unw.hpp deleted file mode 100644 index 606dc63387..0000000000 --- a/src/mc/inspect/mc_unw.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_UNW_HPP -#define SIMGRID_MC_UNW_HPP - -/** @file - * Libunwind implementation for the model-checker - * - * Libunwind provides a pluggable stack unwinding API: the way the current - * registers and memory is accessed, the way unwinding information is found - * is pluggable. - * - * This component implements the libunwind API for he model-checker: - * - * * reading memory from a simgrid::mc::AddressSpace*; - * - * * reading stack registers from a saved snapshot (context). - * - * Parts of the libunwind information fetching is currently handled by the - * standard `libunwind` implementations (either the local one or the ptrace one) - * because parsing `.eh_frame` section is not fun and `libdw` does not help - * much here. - */ - -#include "src/mc/mc_forward.hpp" -#include "xbt/base.h" - -#include -#include - -namespace simgrid::unw { - -XBT_PRIVATE unw_addr_space_t create_addr_space(); -XBT_PRIVATE void* create_context(unw_addr_space_t as, pid_t pid); -} // namespace simgrid::unw - -namespace simgrid::mc { - -class UnwindContext { - simgrid::mc::AddressSpace* address_space_ = nullptr; - simgrid::mc::RemoteProcess* process_ = nullptr; - unw_context_t unwind_context_ = {}; - -public: - void initialize(simgrid::mc::RemoteProcess* process, unw_context_t* c); - unw_cursor_t cursor(); - -private: // Methods and virtual table for libunwind - static int find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t* pip, int need_unwind_info, - void* arg) noexcept; - static void put_unwind_info(unw_addr_space_t as, unw_proc_info_t* pip, void* arg) noexcept; - static int get_dyn_info_list_addr(unw_addr_space_t as, unw_word_t* dilap, void* arg) noexcept; - static int access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t* valp, int write, void* arg) noexcept; - static void* get_reg(unw_context_t* context, unw_regnum_t regnum) noexcept; - static int access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t* valp, int write, void* arg) noexcept; - static int get_proc_name(unw_addr_space_t as, unw_word_t addr, char* bufp, size_t buf_len, unw_word_t* offp, - void* arg) noexcept; - -public: - // Create a libunwind address space: - static unw_addr_space_t createUnwindAddressSpace(); -}; - -void dumpStack(FILE* file, unw_cursor_t* cursor); -} // namespace simgrid::mc - -#endif diff --git a/src/mc/inspect/mc_unw_vmread.cpp b/src/mc/inspect/mc_unw_vmread.cpp deleted file mode 100644 index 4515ea6ec5..0000000000 --- a/src/mc/inspect/mc_unw_vmread.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/inspect/mc_unw.hpp" -#include "src/mc/remote/RemoteProcess.hpp" - -#include -#include - -#include -#include -#include - -/** \file - * Libunwind namespace implementation using process_vm_readv. - */ - -/** Partial structure of libunwind-ptrace context in order to get the PID - * - * HACK, The context type for libunwind-race is an opaque type. - * We need to get the PID which is the first field. This is a hack - * which might break if the libunwind-ptrace structure changes. - */ -struct _UPT_info { - pid_t pid; - // Other things... -}; - -/** Get the PID of a `libunwind-ptrace` context - */ -static inline pid_t _UPT_getpid(void* arg) -{ - const _UPT_info* info = static_cast<_UPT_info*>(arg); - return info->pid; -} - -/** Read from the memory, avoid using `ptrace` (libunwind method) */ -static int access_mem(const unw_addr_space_t as, const unw_word_t addr, unw_word_t* const valp, const int write, - void* const arg) -{ - if (write) - return -UNW_EINVAL; - pid_t pid = _UPT_getpid(arg); - size_t size = sizeof(unw_word_t); - -#if HAVE_PROCESS_VM_READV /* linux but not freebsd */ - // process_vm_read implementation. - // This is only available since Linux 3.2. - - struct iovec local = {valp, size}; - struct iovec remote = {(void*)addr, size}; - if (ssize_t s = process_vm_readv(pid, &local, 1, &remote, 1, 0); s >= 0) { - if ((size_t)s != size) - return -UNW_EINVAL; - else - return 0; - } else if (errno != ENOSYS) { - return -UNW_EINVAL; - } -#endif - - // /proc/${pid}/mem implementation. - // On recent kernels, we do not need to ptrace the target process. - // On older kernels, it is necessary to ptrace the target process. - size_t count = size; - auto off = static_cast(addr); - auto* buf = reinterpret_cast(valp); - int fd = simgrid::mc::open_vm(pid, O_RDONLY); - if (fd < 0) - return -UNW_EINVAL; - - while (count > 0) { - ssize_t nread = pread(fd, buf, count, off); - if (nread == 0) { - close(fd); - return -UNW_EINVAL; - } - if (nread == -1) - // ptrace implementation. - // We need to have PTRACE_ATTACH-ed it before. - return _UPT_access_mem(as, addr, valp, write, arg); - - count -= nread; - buf += nread; - off += nread; - } - close(fd); - return 0; -} - -namespace simgrid::unw { - -unw_addr_space_t create_addr_space() -{ - /** Virtual table for our `libunwind-process_vm_readv` implementation. - * - * This implementation reuse most the code of `libunwind-ptrace` but - * does not use ptrace() to read the target process memory by - * `process_vm_readv()` or `/dev/${pid}/mem` if possible. - * - * Does not support any MC-specific behavior (privatization, snapshots) - * and `ucontext_t`. - * - * It works with `void*` contexts allocated with `_UPT_create(pid)`. - */ - // TODO, we could get rid of this if we properly stop the model-checked - // process before reading the memory. - unw_accessors_t accessors = {&_UPT_find_proc_info, &_UPT_put_unwind_info, &_UPT_get_dyn_info_list_addr, - &access_mem, &_UPT_access_reg, &_UPT_access_fpreg, - &_UPT_resume, &_UPT_get_proc_name}; - return unw_create_addr_space(&accessors, BYTE_ORDER); -} - -void* create_context(unw_addr_space_t /*as*/, pid_t pid) -{ - return _UPT_create(pid); -} - -} // namespace simgrid::unw diff --git a/src/include/mc/mc.h b/src/mc/mc.h similarity index 73% rename from src/include/mc/mc.h rename to src/mc/mc.h index 19decad5c4..017b09ee53 100644 --- a/src/include/mc/mc.h +++ b/src/mc/mc.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,7 +7,7 @@ #define MC_MC_H #include -#include /* our public interface (and definition of SIMGRID_HAVE_MC) */ +#include /* our public interface */ #ifdef __cplusplus XBT_PUBLIC void MC_process_clock_add(const simgrid::kernel::actor::ActorImpl*, double); diff --git a/src/mc/mc_base.cpp b/src/mc/mc_base.cpp index fe612c92ad..9791f51e71 100644 --- a/src/mc/mc_base.cpp +++ b/src/mc/mc_base.cpp @@ -1,48 +1,29 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/mc_base.hpp" -#include "mc/mc.h" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/activity/MutexImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" + +#include "src/mc/mc.h" #include "src/mc/mc_config.hpp" #include "src/mc/mc_replay.hpp" -#include "xbt/random.hpp" - -#if SIMGRID_HAVE_MC -#include "src/mc/ModelChecker.hpp" -#include "src/mc/Session.hpp" -#include "src/mc/remote/RemoteProcess.hpp" -#endif - XBT_LOG_NEW_DEFAULT_CATEGORY(mc, "All MC categories"); - -int MC_random(int min, int max) -{ -#if SIMGRID_HAVE_MC - xbt_assert(mc_model_checker == nullptr); -#endif - if (not MC_is_active() && not MC_record_replay_is_active()) { // no need to do a simcall in this case - static simgrid::xbt::random::XbtRandom prng; - return prng.uniform_int(min, max); - } - simgrid::kernel::actor::RandomSimcall observer{simgrid::kernel::actor::ActorImpl::self(), min, max}; - return simgrid::kernel::actor::simcall_answered([&observer] { return observer.get_value(); }, &observer); -} +bool simgrid_mc_replay_show_backtraces = false; namespace simgrid::mc { void execute_actors() { auto* engine = kernel::EngineImpl::get_instance(); -#if SIMGRID_HAVE_MC - xbt_assert(mc_model_checker == nullptr, "This must be called from the client"); -#endif + + XBT_DEBUG("execute_actors: %lu of %zu to run (%s)", engine->get_actor_to_run_count(), engine->get_actor_count(), + (MC_record_replay_is_active() ? "replay active" : "no replay")); while (engine->has_actors_to_run()) { engine->run_all_actors(); for (auto const& actor : engine->get_actors_that_ran()) { @@ -51,15 +32,6 @@ void execute_actors() actor->simcall_handle(0); } } -#if SIMGRID_HAVE_MC - engine->reset_actor_dynar(); - for (auto const& [_, actor] : engine->get_actor_list()) { - // Only visible requests remain at this point, and they all have an observer - actor->simcall_.mc_max_consider_ = actor->simcall_.observer_->get_max_consider(); - - engine->add_actor_to_dynar(actor); - } -#endif } /** @brief returns if there this transition can proceed in a finite amount of time @@ -73,12 +45,10 @@ void execute_actors() * transition for ever. * This is controlled in the is_enabled() method of the corresponding observers. */ -// Called from both MCer and MCed: bool actor_is_enabled(kernel::actor::ActorImpl* actor) { -#if SIMGRID_HAVE_MC - xbt_assert(mc_model_checker == nullptr, "This should be called from the client side"); -#endif + xbt_assert(get_model_checking_mode() != ModelCheckingMode::CHECKER_SIDE, + "This should be called from the client side"); // Now, we are in the client app, no need for remote memory reading. kernel::actor::Simcall* req = &actor->simcall_; @@ -98,13 +68,12 @@ bool actor_is_enabled(kernel::actor::ActorImpl* actor) */ bool request_is_visible(const kernel::actor::Simcall* req) { -#if SIMGRID_HAVE_MC - xbt_assert(mc_model_checker == nullptr, "This should be called from the client side"); -#endif - if (req->observer_ != nullptr) - return req->observer_->is_visible(); - else + xbt_assert(get_model_checking_mode() != ModelCheckingMode::CHECKER_SIDE, + "This should be called from the client side"); + + if (req->observer_ == nullptr) return false; + return req->observer_->is_visible(); } } // namespace simgrid::mc diff --git a/src/mc/mc_base.hpp b/src/mc/mc_base.hpp index 5d30ac9144..9b60b3d9b2 100644 --- a/src/mc/mc_base.hpp +++ b/src/mc/mc_base.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/mc/mc_client_api.cpp b/src/mc/mc_client_api.cpp index 7d110408b0..27e471d662 100644 --- a/src/mc/mc_client_api.cpp +++ b/src/mc/mc_client_api.cpp @@ -1,110 +1,55 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "src/mc/ModelChecker.hpp" -#include "src/mc/mc_ignore.hpp" +#include "simgrid/simix.hpp" +#include "src/kernel/actor/ActorImpl.hpp" +#include "src/mc/mc_config.hpp" #include "src/mc/mc_private.hpp" #include "src/mc/mc_record.hpp" #include "src/mc/mc_replay.hpp" #include "src/mc/remote/AppSide.hpp" #include "xbt/asserts.h" +#include "xbt/random.hpp" -/** @file mc_client_api.cpp - * - * This is the implementation of the API used by the user simulated program to - * communicate with the MC (declared in modelchecker.h). - */ +using namespace simgrid::mc; -// MC_random() is in mc_base.cpp +/* Implementation of the user API from the App to the Checker (see modelchecker.h) */ + +int MC_random(int min, int max) +{ + xbt_assert(get_model_checking_mode() != ModelCheckingMode::CHECKER_SIDE, + "This should be called from the client side"); + + if (not MC_is_active() && not MC_record_replay_is_active()) { // no need to do a simcall in this case + static simgrid::xbt::random::XbtRandom prng; + return prng.uniform_int(min, max); + } + simgrid::kernel::actor::RandomSimcall observer{simgrid::kernel::actor::ActorImpl::self(), min, max}; + return simgrid::kernel::actor::simcall_answered([&observer] { return observer.get_value(); }, &observer); +} void MC_assert(int prop) { - xbt_assert(mc_model_checker == nullptr); + // Cannot used xbt_assert here, or it would be an infinite recursion. + xbt_assert(get_model_checking_mode() != ModelCheckingMode::CHECKER_SIDE, + "This should be called from the client side"); +#if SIMGRID_HAVE_MC if (not prop) { if (MC_is_active()) - simgrid::mc::AppSide::get()->report_assertion_failure(); + AppSide::get()->report_assertion_failure(); if (MC_record_replay_is_active()) xbt_die("MC assertion failed"); } +#else + if (not prop) + xbt_die("Safety property violation detected without the model-checker"); +#endif } -void MC_cut() -{ - xbt_assert(mc_model_checker == nullptr); - if (not MC_is_active()) - return; - // FIXME, We want to do this in the model-checker: - xbt_die("MC_cut() not implemented"); -} - -void MC_ignore(void* addr, size_t size) -{ - xbt_assert(mc_model_checker == nullptr); - if (not MC_is_active()) - return; - simgrid::mc::AppSide::get()->ignore_memory(addr, size); -} - -void MC_automaton_new_propositional_symbol(const char* /*id*/, int (*/*fct*/)()) -{ - xbt_assert(mc_model_checker == nullptr); - if (not MC_is_active()) - return; - xbt_die("Support for client-side function proposition is not implemented: " - "use MC_automaton_new_propositional_symbol_pointer instead."); -} - -void MC_automaton_new_propositional_symbol_pointer(const char *name, int* value) -{ - xbt_assert(mc_model_checker == nullptr); - if (not MC_is_active()) - return; - simgrid::mc::AppSide::get()->declare_symbol(name, value); -} - -/** @brief Register a stack in the model checker - * - * The stacks are allocated in the heap. The MC handle them specifically - * when we analyze/compare the content of the heap so it must be told where - * they are with this function. - * - * @param stack Where the stack is - * @param actor Actor owning the stack - * @param context The context associated to that stack - * @param size Size of the stack - */ -void MC_register_stack_area(void* stack, ucontext_t* context, size_t size) -{ - xbt_assert(mc_model_checker == nullptr); - if (not MC_is_active()) - return; - simgrid::mc::AppSide::get()->declare_stack(stack, size, context); -} - -void MC_ignore_global_variable(const char* /*name*/) -{ - xbt_assert(mc_model_checker == nullptr); - if (not MC_is_active()) - return; - // TODO, send a message to the model_checker - xbt_die("Unimplemented"); -} - -void MC_ignore_heap(void *address, size_t size) -{ - xbt_assert(mc_model_checker == nullptr); - if (not MC_is_active()) - return; - simgrid::mc::AppSide::get()->ignore_heap(address, size); -} - -void MC_unignore_heap(void* address, size_t size) +int MC_is_active() { - xbt_assert(mc_model_checker == nullptr); - if (not MC_is_active()) - return; - simgrid::mc::AppSide::get()->unignore_heap(address, size); + return get_model_checking_mode() == ModelCheckingMode::APP_SIDE || + get_model_checking_mode() == ModelCheckingMode::CHECKER_SIDE; } diff --git a/src/mc/mc_config.cpp b/src/mc/mc_config.cpp index f33a8959a1..25f3090c76 100644 --- a/src/mc/mc_config.cpp +++ b/src/mc/mc_config.cpp @@ -1,67 +1,80 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/mc_config.hpp" #include "src/mc/mc_replay.hpp" -#include +#include "src/simgrid/sg_config.hpp" +#include -#if SIMGRID_HAVE_MC -#include "src/mc/mc_safety.hpp" -#include -#endif +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(xbt_cfg); -#if SIMGRID_HAVE_MC -namespace simgrid::mc { -/* Configuration support */ -simgrid::mc::ReductionMode reduction_mode = simgrid::mc::ReductionMode::unset; -} // namespace simgrid::mc -#else -#define _sg_do_model_check 0 -#endif +static simgrid::mc::ModelCheckingMode model_checking_mode = simgrid::mc::ModelCheckingMode::NONE; +simgrid::mc::ModelCheckingMode simgrid::mc::get_model_checking_mode() +{ + return model_checking_mode; +} +void simgrid::mc::set_model_checking_mode(simgrid::mc::ModelCheckingMode mode) +{ + model_checking_mode = mode; +} static void _mc_cfg_cb_check(const char* spec, bool more_check = true) { - xbt_assert(_sg_cfg_init_status == 0 || _sg_do_model_check || not more_check, - "You are specifying a %s after the initialization (through MSG_config?), but the program was not run " - "under the model-checker (with simgrid-mc)). This won't work, sorry.", + xbt_assert(_sg_cfg_init_status == 0 || MC_is_active() || MC_record_replay_is_active() || not more_check, + "Specifying a %s is only allowed within the model-checker. Please use simgrid-mc, or specify this option " + "after the replay path.", spec); } /* Replay (this part is enabled even if MC it disabled) */ simgrid::config::Flag _sg_mc_record_path{ "model-check/replay", "Model-check path to replay (as reported by SimGrid when a violation is reported)", "", - [](std::string_view value) { MC_record_path() = value; }}; + [](std::string_view value) { + if (value.empty()) // Ignore default value + return; + xbt_assert(simgrid::mc::get_model_checking_mode() == simgrid::mc::ModelCheckingMode::NONE || + simgrid::mc::get_model_checking_mode() == simgrid::mc::ModelCheckingMode::REPLAY, + "Specifying a MC replay path is not allowed when running the model-checker in mode %s. " + "Either remove the model-check/replay parameter, or execute your code out of simgrid-mc.", + to_c_str(simgrid::mc::get_model_checking_mode())); + simgrid::mc::set_model_checking_mode(simgrid::mc::ModelCheckingMode::REPLAY); + MC_record_path() = value; + }}; simgrid::config::Flag _sg_mc_timeout{ "model-check/timeout", "Whether to enable timeouts for wait requests", false, [](bool) { _mc_cfg_cb_check("value to enable/disable timeout for wait requests", not MC_record_replay_is_active()); }}; -#if SIMGRID_HAVE_MC -int _sg_do_model_check = 0; -int _sg_mc_max_visited_states = 0; +static simgrid::config::Flag cfg_mc_reduction{ + "model-check/reduction", "Specify the kind of exploration reduction (either none or DPOR)", "dpor", + [](std::string_view value) { + if (value != "none" && value != "dpor" && value != "sdpor" && value != "odpor" && value != "udpor") + xbt_die("configuration option 'model-check/reduction' must be one of the following: " + " 'none', 'dpor', 'sdpor', 'odpor', or 'udpor'"); + }}; -simgrid::config::Flag _sg_mc_checkpoint{ - "model-check/checkpoint", "Specify the amount of steps between checkpoints during stateful model-checking " - "(default: 0 => stateless verification). If value=1, one checkpoint is saved for each " - "step => faster verification, but huge memory consumption; higher values are good " - "compromises between speed and memory consumption.", - 0, [](int) { _mc_cfg_cb_check("checkpointing value"); }}; +simgrid::config::Flag _sg_mc_strategy{ + "model-check/strategy", + "Specify the the kind of heuristic to use for guided model-checking", + "none", + {{"none", "No specific strategy: simply pick the first available transition and act as a DFS."}, + {"max_match_comm", "Try to minimize the number of in-fly communication by appairing matching send and receive."}, + {"min_match_comm", + "Try to maximize the number of in-fly communication by not appairing matching send and receive."}, + {"uniform", "No specific strategy: choices are made randomly based on a uniform sampling."}}}; -simgrid::config::Flag _sg_mc_property_file{ - "model-check/property", "Name of the file containing the property, as formatted by the ltl2ba program.", "", - [](const std::string&) { _mc_cfg_cb_check("property"); }}; +simgrid::config::Flag _sg_mc_random_seed{"model-check/rand-seed", + "give a specific random seed to initialize the uniform distribution", 0, + [](int) { _mc_cfg_cb_check("Random seed"); }}; simgrid::config::Flag _sg_mc_comms_determinism{ - "model-check/communications-determinism", - "Whether to enable the detection of communication determinism", - false, + "model-check/communications-determinism", "Whether to enable the detection of communication determinism", false, [](bool) { _mc_cfg_cb_check("value to enable/disable the detection of determinism in the communications schemes"); }}; - simgrid::config::Flag _sg_mc_send_determinism{ "model-check/send-determinism", "Enable/disable the detection of send-determinism in the communications schemes", @@ -84,40 +97,28 @@ simgrid::config::Flag _sg_mc_buffering{ {"infty", "Infinite system buffering: MPI_Send returns immediately"}}, [](std::string_view) { _mc_cfg_cb_check("buffering mode"); }}; -static simgrid::config::Flag _sg_mc_reduce{ - "model-check/reduction", "Specify the kind of exploration reduction (either none or DPOR)", "dpor", - [](std::string_view value) { - _mc_cfg_cb_check("reduction strategy"); - - if (value == "none") - simgrid::mc::reduction_mode = simgrid::mc::ReductionMode::none; - else if (value == "dpor") - simgrid::mc::reduction_mode = simgrid::mc::ReductionMode::dpor; - else - xbt_die("configuration option model-check/reduction can only take 'none' or 'dpor' as a value"); - }}; - simgrid::config::Flag _sg_mc_max_depth{"model-check/max-depth", "Maximal exploration depth (default: 1000)", 1000, [](int) { _mc_cfg_cb_check("max depth value"); }}; -static simgrid::config::Flag _sg_mc_max_visited_states__{ - "model-check/visited", "Specify the number of visited state stored for state comparison reduction. If value=5, the " - "last 5 visited states are stored. If value=0 (the default), all states are stored.", - 0, [](int value) { - _mc_cfg_cb_check("number of stored visited states"); - _sg_mc_max_visited_states = value; - }}; - -simgrid::config::Flag _sg_mc_dot_output_file{ - "model-check/dot-output", - "Name of dot output file corresponding to graph state", - "", - [](const std::string&) { _mc_cfg_cb_check("file name for a dot output of graph state"); }}; - -simgrid::config::Flag _sg_mc_termination{ - "model-check/termination", "Whether to enable non progressive cycle detection", false, - [](bool) { _mc_cfg_cb_check("value to enable/disable the detection of non progressive cycles"); }}; - -#endif +simgrid::mc::ReductionMode simgrid::mc::get_model_checking_reduction() +{ + if (cfg_mc_reduction.get() == "none") { + return ReductionMode::none; + } else if (cfg_mc_reduction.get() == "dpor") { + return ReductionMode::dpor; + } else if (cfg_mc_reduction.get() == "sdpor") { + return ReductionMode::sdpor; + } else if (cfg_mc_reduction.get() == "odpor") { + return ReductionMode::odpor; + } else if (cfg_mc_reduction.get() == "udpor") { + XBT_INFO("No reduction will be used: " + "UDPOR has a dedicated invocation 'model-check/unfolding-checker' " + "but is not yet fully supported in SimGrid"); + return ReductionMode::none; + } else { + XBT_INFO("Unknown reduction mode: defaulting to no reduction"); + return ReductionMode::none; + } +} diff --git a/src/mc/mc_config.hpp b/src/mc/mc_config.hpp index e5232f7b25..621e06f3c3 100644 --- a/src/mc/mc_config.hpp +++ b/src/mc/mc_config.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,7 +9,14 @@ #include /********************************** Configuration of MC **************************************/ -extern "C" XBT_PUBLIC int _sg_do_model_check; +namespace simgrid::mc { +XBT_DECLARE_ENUM_CLASS(ReductionMode, none, dpor, sdpor, odpor); +XBT_DECLARE_ENUM_CLASS(ModelCheckingMode, NONE, APP_SIDE, CHECKER_SIDE, REPLAY); +ReductionMode get_model_checking_reduction(); // "model-check/reduction" == "DPOR" +XBT_PUBLIC ModelCheckingMode get_model_checking_mode(); +XBT_PUBLIC void set_model_checking_mode(ModelCheckingMode mode); +}; // namespace simgrid::mc + extern XBT_PUBLIC simgrid::config::Flag _sg_mc_buffering; extern XBT_PRIVATE simgrid::config::Flag _sg_mc_checkpoint; extern XBT_PUBLIC simgrid::config::Flag _sg_mc_property_file; @@ -18,8 +25,8 @@ extern XBT_PUBLIC simgrid::config::Flag _sg_mc_send_determinism; extern XBT_PUBLIC simgrid::config::Flag _sg_mc_unfolding_checker; extern XBT_PRIVATE simgrid::config::Flag _sg_mc_timeout; extern XBT_PRIVATE simgrid::config::Flag _sg_mc_max_depth; -extern "C" XBT_PUBLIC int _sg_mc_max_visited_states; +extern XBT_PRIVATE simgrid::config::Flag _sg_mc_random_seed; extern XBT_PRIVATE simgrid::config::Flag _sg_mc_dot_output_file; -extern XBT_PRIVATE simgrid::config::Flag _sg_mc_termination; +extern XBT_PUBLIC simgrid::config::Flag _sg_mc_strategy; #endif diff --git a/src/mc/mc_environ.h b/src/mc/mc_environ.h new file mode 100644 index 0000000000..a8ff230d05 --- /dev/null +++ b/src/mc/mc_environ.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef MC_ENVIRON_H +#define MC_ENVIRON_H + +/* Define macros for the name of environment variables used by the MC. Keep them in a separate file without any other + * includes, since it's also loaded from mmalloc. + */ + +/** Environment variable name used to pass the communication socket. + * + * It is set by `simgrid-mc` to enable MC support in the children processes. + */ +#define MC_ENV_SOCKET_FD "SIMGRID_MC_SOCKET_FD" + +/** Environment variable used to request additional system statistics. + */ +#define MC_ENV_SYSTEM_STATISTICS "SIMGRID_MC_SYSTEM_STATISTICS" + +#endif diff --git a/src/mc/mc_exit.hpp b/src/mc/mc_exit.hpp index 273384bd2c..234ea1466a 100644 --- a/src/mc/mc_exit.hpp +++ b/src/mc/mc_exit.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,22 +8,22 @@ #include "xbt/base.h" #include -constexpr int SIMGRID_MC_EXIT_SUCCESS = 0; -constexpr int SIMGRID_MC_EXIT_SAFETY = 1; -constexpr int SIMGRID_MC_EXIT_LIVENESS = 2; -constexpr int SIMGRID_MC_EXIT_DEADLOCK = 3; -constexpr int SIMGRID_MC_EXIT_NON_TERMINATION = 4; -constexpr int SIMGRID_MC_EXIT_NON_DETERMINISM = 5; -constexpr int SIMGRID_MC_EXIT_PROGRAM_CRASH = 6; - -constexpr int SIMGRID_MC_EXIT_ERROR = 63; - namespace simgrid::mc { -class XBT_PUBLIC DeadlockError : public std::exception { -}; -class XBT_PUBLIC TerminationError : public std::exception { + +enum class ExitStatus { + SUCCESS = 0, + SAFETY = 1, + LIVENESS = 2, + DEADLOCK = 3, + NON_TERMINATION = 4, + NON_DETERMINISM = 5, + PROGRAM_CRASH = 6, + ERROR = 63 }; -class XBT_PUBLIC LivenessError : public std::exception { + +struct McError : public std::exception { + const ExitStatus value; + explicit McError(ExitStatus v = ExitStatus::ERROR) : value(v) {} }; } // namespace simgrid::mc diff --git a/src/mc/mc_forward.hpp b/src/mc/mc_forward.hpp index df5257122f..6922bd77f6 100644 --- a/src/mc/mc_forward.hpp +++ b/src/mc/mc_forward.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,9 +15,8 @@ namespace simgrid::mc { class PageStore; class ChunkedData; -class ModelChecker; class AddressSpace; -class RemoteProcess; +class RemoteProcessMemory; class Snapshot; class ObjectInformation; class Member; @@ -25,13 +24,9 @@ class Type; class Variable; class Transition; class Frame; -class ActorInformation; class Session; class Exploration; } // namespace simgrid::mc -// TODO, try to get rid of the global ModelChecker variable -extern simgrid::mc::ModelChecker* mc_model_checker; - #endif diff --git a/src/mc/mc_global.cpp b/src/mc/mc_global.cpp index ef212045bf..d7962faca4 100644 --- a/src/mc/mc_global.cpp +++ b/src/mc/mc_global.cpp @@ -1,33 +1,14 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "mc/mc.h" #include "src/kernel/actor/ActorImpl.hpp" +#include "src/mc/mc.h" -#if SIMGRID_HAVE_MC -#include "src/mc/Session.hpp" -#include "src/mc/explo/Exploration.hpp" -#include "src/mc/inspect/mc_unw.hpp" -#include "src/mc/mc_config.hpp" -#include "src/mc/mc_private.hpp" -#include "src/mc/mc_safety.hpp" -#include "src/mc/remote/AppSide.hpp" -#include "src/mc/sosp/Snapshot.hpp" - -#include -#include -#include -#include -#include -#endif - -#ifndef _WIN32 #include #include #include -#endif XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_global, mc, "Logging specific to MC (global)"); @@ -37,63 +18,14 @@ std::vector processes_time; } -#if SIMGRID_HAVE_MC - -/* Dot output */ -FILE *dot_output = nullptr; - -void MC_init_dot_output() -{ - dot_output = fopen(_sg_mc_dot_output_file.get().c_str(), "w"); - xbt_assert(dot_output != nullptr, "Error open dot output file: %s", strerror(errno)); - - fprintf(dot_output, - "digraph graphname{\n fixedsize=true; rankdir=TB; ranksep=.25; edge [fontsize=12]; node [fontsize=10, shape=circle,width=.5 ]; graph [resolution=20, fontsize=10];\n"); -} - -namespace simgrid::mc { - -/* Liveness */ -xbt_automaton_t property_automaton = nullptr; - -/******************************* Core of MC *******************************/ -/**************************************************************************/ -void dumpStack(FILE* file, unw_cursor_t* cursor) -{ - int nframe = 0; - std::array buffer; - - unw_word_t off; - do { - const char* name = not unw_get_proc_name(cursor, buffer.data(), buffer.size(), &off) ? buffer.data() : "?"; - // Unmangle C++ names: - std::string realname = boost::core::demangle(name); - -#if defined(__x86_64__) - unw_word_t rip = 0; - unw_word_t rsp = 0; - unw_get_reg(cursor, UNW_X86_64_RIP, &rip); - unw_get_reg(cursor, UNW_X86_64_RSP, &rsp); - fprintf(file, " %i: %s (RIP=0x%" PRIx64 " RSP=0x%" PRIx64 ")\n", nframe, realname.c_str(), (std::uint64_t)rip, - (std::uint64_t)rsp); -#else - fprintf(file, " %i: %s\n", nframe, realname.c_str()); -#endif - - ++nframe; - } while (unw_step(cursor)); -} - -} // namespace simgrid::mc -#endif - double MC_process_clock_get(const simgrid::kernel::actor::ActorImpl* process) { - if (simgrid::mc::processes_time.empty()) - return 0; - if (process == nullptr) - return -1; - return simgrid::mc::processes_time.at(process->get_pid()); + if (process) { + auto pid = static_cast(process->get_pid()); + if (pid < simgrid::mc::processes_time.size()) + return simgrid::mc::processes_time[pid]; + } + return 0.0; } void MC_process_clock_add(const simgrid::kernel::actor::ActorImpl* process, double amount) diff --git a/src/mc/mc_hash.cpp b/src/mc/mc_hash.cpp deleted file mode 100644 index 8b667d00e2..0000000000 --- a/src/mc/mc_hash.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include - -#include "xbt/log.h" - -#include "mc/datatypes.h" -#include "src/mc/mc_hash.hpp" -#include "src/mc/mc_private.hpp" -#include "src/mc/sosp/Snapshot.hpp" -#include - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_hash, mc, "Logging specific to mc_hash"); - -namespace simgrid::mc { - -namespace { - -class djb_hash { - hash_type state_ = 5381LL; - -public: - template - void update(T& x) - { - state_ = (state_ << 5) + state_ + x; - } - hash_type value() const { return state_; } -}; - -} - -hash_type hash(Snapshot const& snapshot) -{ - XBT_DEBUG("START hash %ld", snapshot.num_state_); - djb_hash hash; - // TODO: - // * nb_processes - // * heap_bytes_used - // * root variables - // * basic stack frame information - // * stack frame local variables - XBT_DEBUG("END hash %ld", snapshot.num_state_); - return hash.value(); -} - -} // namespace simgrid::mc diff --git a/src/mc/mc_hash.hpp b/src/mc/mc_hash.hpp deleted file mode 100644 index 03110a7654..0000000000 --- a/src/mc/mc_hash.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_HASH_HPP -#define SIMGRID_MC_HASH_HPP - -#include "xbt/base.h" -#include "src/mc/mc_forward.hpp" - -namespace simgrid::mc { - -using hash_type = std::uint64_t; - -XBT_PRIVATE hash_type hash(simgrid::mc::Snapshot const& snapshot); - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/mc_ignore.hpp b/src/mc/mc_ignore.hpp deleted file mode 100644 index 55e725409d..0000000000 --- a/src/mc/mc_ignore.hpp +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_IGNORE_HPP -#define SIMGRID_MC_IGNORE_HPP - -#include "simgrid/forward.h" -#include "src/internal_config.h" - -#if HAVE_UCONTEXT_H -#include /* context relative declarations */ - -XBT_PUBLIC void MC_register_stack_area(void* stack, ucontext_t* context, size_t size); - -#endif - -#endif diff --git a/src/mc/mc_mmu.hpp b/src/mc/mc_mmu.hpp index d1c2e02bfd..bbeedf1e7d 100644 --- a/src/mc/mc_mmu.hpp +++ b/src/mc/mc_mmu.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,18 +6,10 @@ #ifndef SIMGRID_MC_MMU_HPP #define SIMGRID_MC_MMU_HPP +#include "xbt/misc.h" #include #include -#ifndef XBT_ALWAYS_INLINE -#define XBT_ALWAYS_INLINE inline __attribute__((always_inline)) -#endif - -/** Size of a memory page for the current system. */ -extern "C" int xbt_pagesize; -/** Number of bits of addresses inside a given page, log2(xbt_pagesize). */ -extern "C" int xbt_pagebits; - namespace simgrid::mc::mmu { // TODO, do not depend on xbt_pagesize/xbt_pagebits but our own chunk size diff --git a/src/mc/mc_pattern.hpp b/src/mc/mc_pattern.hpp deleted file mode 100644 index e29895cb9b..0000000000 --- a/src/mc/mc_pattern.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_PATTERN_H -#define SIMGRID_MC_PATTERN_H - -#include "src/kernel/activity/CommImpl.hpp" -#include "src/mc/remote/RemotePtr.hpp" - -namespace simgrid::mc { - -/* On every state, each actor has an entry of the following type. - * This represents both the actor and its transition because - * an actor cannot have more than one enabled transition at a given time. - */ -class ActorState { - /* Possible exploration status of an actor transition in a state. - * Either the checker did not consider the transition, or it was considered and still to do, or considered and done. - */ - enum class InterleavingType { - /** This actor transition is not considered by the checker (yet?) */ - disabled = 0, - /** The checker algorithm decided that this actor transitions should be done at some point */ - todo, - /** The checker algorithm decided that this should be done, but it was done in the meanwhile */ - done, - }; - - /** Exploration control information */ - InterleavingType state_ = InterleavingType::disabled; - - /** Number of times that the process was considered to be executed */ - unsigned int times_considered_ = 0; - -public: - unsigned int do_consider(unsigned int max_consider) - { - if (max_consider <= times_considered_ + 1) - set_done(); - return times_considered_++; - } - unsigned int get_times_considered() const { return times_considered_; } - - bool is_disabled() const { return this->state_ == InterleavingType::disabled; } - bool is_done() const { return this->state_ == InterleavingType::done; } - bool is_todo() const { return this->state_ == InterleavingType::todo; } - /** Mark that we should try executing this process at some point in the future of the checker algorithm */ - void mark_todo() - { - this->state_ = InterleavingType::todo; - this->times_considered_ = 0; - } - void set_done() { this->state_ = InterleavingType::done; } -}; - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/mc_private.hpp b/src/mc/mc_private.hpp index fc37957cce..d4185f0b0a 100644 --- a/src/mc/mc_private.hpp +++ b/src/mc/mc_private.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,29 +6,17 @@ #ifndef SIMGRID_MC_PRIVATE_HPP #define SIMGRID_MC_PRIVATE_HPP -#include "mc/mc.h" -#include "xbt/automaton.h" +#include "src/mc/mc.h" #include "src/mc/mc_forward.hpp" #include "src/xbt/memory_map.hpp" -/********************************* MC Global **********************************/ - -XBT_PRIVATE void MC_init_dot_output(); - -XBT_PRIVATE extern FILE* dot_output; - /********************************** Miscellaneous **********************************/ namespace simgrid::mc { XBT_PRIVATE void find_object_address(std::vector const& maps, simgrid::mc::ObjectInformation* result); -XBT_PRIVATE -bool snapshot_equal(const Snapshot* s1, const Snapshot* s2); - -// Move is somewhere else (in the LivenessChecker class, in the Session class?): -extern XBT_PRIVATE xbt_automaton_t property_automaton; } // namespace simgrid::mc #endif diff --git a/src/mc/mc_record.cpp b/src/mc/mc_record.cpp index 72483fe420..63d9fc0680 100644 --- a/src/mc/mc_record.cpp +++ b/src/mc/mc_record.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,12 +10,6 @@ #include "src/mc/mc_replay.hpp" #include "src/mc/transition/Transition.hpp" -#if SIMGRID_HAVE_MC -#include "src/mc/api/State.hpp" -#include "src/mc/explo/Exploration.hpp" -#include "src/mc/mc_private.hpp" -#endif - XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_record, mc, "Logging specific to MC record/replay facility"); namespace simgrid::mc { @@ -23,21 +17,47 @@ namespace simgrid::mc { void RecordTrace::replay() const { simgrid::mc::execute_actors(); + auto* engine = kernel::EngineImpl::get_instance(); - for (const simgrid::mc::Transition* transition : transitions_) { - XBT_DEBUG("Executing %ld$%i", transition->aid_, transition->times_considered_); + int frame_count = 1; + if (xbt_log_no_loc) + XBT_INFO("The backtrace of each transition will not be shown because of --log=no_loc"); + else + simgrid_mc_replay_show_backtraces = true; - // Choose a request: - kernel::actor::ActorImpl* actor = kernel::EngineImpl::get_instance()->get_actor_by_pid(transition->aid_); + for (const simgrid::mc::Transition* transition : transitions_) { + kernel::actor::ActorImpl* actor = engine->get_actor_by_pid(transition->aid_); xbt_assert(actor != nullptr, "Unexpected actor (id:%ld).", transition->aid_); const kernel::actor::Simcall* simcall = &(actor->simcall_); - xbt_assert(simcall->call_ != kernel::actor::Simcall::Type::NONE, "No simcall for process %ld.", transition->aid_); - xbt_assert(simgrid::mc::request_is_visible(simcall) && simgrid::mc::actor_is_enabled(actor), "Unexpected simcall."); + xbt_assert(simgrid::mc::request_is_visible(simcall), "Simcall %s of actor %s is not visible.", simcall->get_cname(), + actor->get_cname()); + + XBT_INFO("***********************************************************************************"); + XBT_INFO("* Path chunk #%d '%ld/%i' Actor %s(pid:%ld): %s", frame_count++, transition->aid_, + transition->times_considered_, simcall->issuer_->get_cname(), simcall->issuer_->get_pid(), + simcall->observer_->to_string().c_str()); + XBT_INFO("***********************************************************************************"); + if (not mc::actor_is_enabled(actor)) + simgrid::kernel::EngineImpl::get_instance()->display_all_actor_status(); + + xbt_assert(simgrid::mc::actor_is_enabled(actor), "Actor %s (simcall %s) is not enabled.", actor->get_cname(), + simcall->get_cname()); // Execute the request: simcall->issuer_->simcall_handle(transition->times_considered_); simgrid::mc::execute_actors(); } + + const auto& actor_list = engine->get_actor_list(); + if (actor_list.empty()) { + XBT_INFO("The replay of the trace is complete. The application is terminating."); + } else if (std::none_of(std::begin(actor_list), std::end(actor_list), + [](const auto& kv) { return mc::actor_is_enabled(kv.second); })) { + XBT_INFO("The replay of the trace is complete. DEADLOCK detected."); + engine->display_all_actor_status(); + } else { + XBT_INFO("The replay of the trace is complete. The application could run further."); + } } void simgrid::mc::RecordTrace::replay(const std::string& path_string) @@ -59,7 +79,7 @@ simgrid::mc::RecordTrace::RecordTrace(const char* data) const char* current = data; while (*current) { long aid; - int times_considered; + int times_considered = 0; if (int count = sscanf(current, "%ld/%d", &aid, ×_considered); count != 2 && count != 1) throw std::invalid_argument("Could not parse record path"); @@ -74,12 +94,12 @@ simgrid::mc::RecordTrace::RecordTrace(const char* data) } } -#if SIMGRID_HAVE_MC - std::string simgrid::mc::RecordTrace::to_string() const { std::ostringstream stream; for (auto i = transitions_.begin(); i != transitions_.end(); ++i) { + if (*i == nullptr) + continue; if (i != transitions_.begin()) stream << ';'; stream << (*i)->aid_; @@ -88,7 +108,4 @@ std::string simgrid::mc::RecordTrace::to_string() const } return stream.str(); } - -#endif - } // namespace simgrid::mc diff --git a/src/mc/mc_record.hpp b/src/mc/mc_record.hpp index d8cf3a346f..32f78efa11 100644 --- a/src/mc/mc_record.hpp +++ b/src/mc/mc_record.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,7 +9,7 @@ * The recorded path is written in the log output and can be replayed with MC disabled * (even with a non-MC build) using `--cfg=model-check/replay:$replayPath`. * - * The same version of Simgrid should be used and the same arguments should be + * The same version of SimGrid should be used and the same arguments should be * passed to the application (without the MC specific arguments). */ @@ -19,23 +19,30 @@ #include "src/mc/mc_forward.hpp" #include "xbt/base.h" +#include #include -#include namespace simgrid::mc { class RecordTrace { - std::vector transitions_; + std::deque transitions_; public: - RecordTrace() = default; + // Use rule-of-three, and implicitely disable the move constructor which cannot be 'noexcept' (as required by C++ Core + // Guidelines), due to the std::deque member. + RecordTrace() = default; + RecordTrace(const RecordTrace&) = default; + ~RecordTrace() = default; /** Build a trace that can be replayed from a string representation */ explicit RecordTrace(const char* data); /** Make a string representation that can later be used to create a new trace */ std::string to_string() const; + void push_front(Transition* t) { transitions_.push_front(t); } void push_back(Transition* t) { transitions_.push_back(t); } + std::deque::const_iterator begin() const { return transitions_.begin(); } + std::deque::const_iterator end() const { return transitions_.end(); } /** Replay all transitions of a trace */ void replay() const; diff --git a/src/mc/mc_replay.hpp b/src/mc/mc_replay.hpp index ae8cd4a06d..7c0ae437e1 100644 --- a/src/mc/mc_replay.hpp +++ b/src/mc/mc_replay.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -25,4 +25,7 @@ static inline int MC_record_replay_is_active() return not MC_record_path().empty(); } +/** Whether we should display extra information during this MC replay */ +extern bool simgrid_mc_replay_show_backtraces; + #endif diff --git a/src/mc/mc_safety.hpp b/src/mc/mc_safety.hpp deleted file mode 100644 index e16f12e025..0000000000 --- a/src/mc/mc_safety.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_SAFETY_HPP -#define SIMGRID_MC_SAFETY_HPP - -#include "xbt/base.h" - -namespace simgrid::mc { - -enum class ReductionMode { - unset, - none, - dpor, -}; - -extern XBT_PRIVATE simgrid::mc::ReductionMode reduction_mode; -} // namespace simgrid::mc - -#endif diff --git a/src/mc/mc_smx.cpp b/src/mc/mc_smx.cpp deleted file mode 100644 index 7593fc29f7..0000000000 --- a/src/mc/mc_smx.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/s4u/Host.hpp" - -#include "src/mc/ModelChecker.hpp" -#include "src/mc/remote/RemoteProcess.hpp" - -/** @file - * @brief (Cross-process, MCer/MCed) Access to SMX structures - * - * We copy some C data structure from the MCed process in the MCer process. - * This is implemented by: - * - * - `model_checker->process.smx_process_infos` - * (copy of `EngineImpl::actor_list_`); - * - * - `model_checker->hostnames`. - * - * The process lists are currently refreshed each time MCed code is executed. - * We don't try to give a persistent MCer address for a given MCed process. - * For this reason, a MCer simgrid::mc::Process* is currently not reusable after - * MCed code. - */ - -/** Load the remote list of processes into a vector - * - * @param process MCed process - * @param target Local vector (to be filled with `simgrid::mc::ActorInformation`) - * @param remote_dynar Address of the process dynar in the remote list - */ -static void MC_process_refresh_simix_actor_dynar(const simgrid::mc::RemoteProcess* process, - std::vector& target, - simgrid::mc::RemotePtr remote_dynar) -{ - target.clear(); - - s_xbt_dynar_t dynar; - process->read_bytes(&dynar, sizeof(dynar), remote_dynar); - - auto* data = static_cast(::operator new(dynar.elmsize * dynar.used)); - process->read_bytes(data, dynar.elmsize * dynar.used, simgrid::mc::RemotePtr(dynar.data)); - - // Load each element of the vector from the MCed process: - for (unsigned int i = 0; i < dynar.used; ++i) { - simgrid::mc::ActorInformation info; - - info.address = simgrid::mc::RemotePtr(data[i]); - process->read_bytes(&info.copy, sizeof(info.copy), simgrid::mc::remote(data[i])); - target.push_back(std::move(info)); - } - ::operator delete(data); -} -namespace simgrid::mc { - -void RemoteProcess::refresh_simix() -{ - if (this->cache_flags_ & RemoteProcess::cache_simix_processes) - return; - - MC_process_refresh_simix_actor_dynar(this, this->smx_actors_infos, actors_addr_); - - this->cache_flags_ |= RemoteProcess::cache_simix_processes; -} - -} // namespace simgrid::mc diff --git a/src/mc/remote/AppSide.cpp b/src/mc/remote/AppSide.cpp index 2d4dfbea70..aabac0027a 100644 --- a/src/mc/remote/AppSide.cpp +++ b/src/mc/remote/AppSide.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,40 +10,47 @@ #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" #include "src/mc/mc_base.hpp" -#include "src/mc/remote/RemoteProcess.hpp" +#include "src/mc/mc_config.hpp" +#include "src/mc/mc_environ.h" #if HAVE_SMPI #include "src/smpi/include/private.hpp" #endif -#include "xbt/coverage.h" +#include "src/sthread/sthread.h" +#include "src/xbt/coverage.h" #include "xbt/str.h" -#include "xbt/xbt_modinter.h" /* mmalloc_preinit to get the default mmalloc arena address */ #include #include +#include #include // setvbuf #include -#include #include +#include #include #include #include +#include +#include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_client, mc, "MC client logic"); +XBT_LOG_EXTERNAL_CATEGORY(mc_global); namespace simgrid::mc { std::unique_ptr AppSide::instance_; -AppSide* AppSide::initialize(xbt_dynar_t actors_addr) +AppSide* AppSide::get() { - if (not std::getenv(MC_ENV_SOCKET_FD)) // We are not in MC mode: don't initialize the MC world + // Only initialize the MC world once + if (instance_ != nullptr) + return instance_.get(); + + if (std::getenv(MC_ENV_SOCKET_FD) == nullptr) // We are not in MC mode: don't initialize the MC world return nullptr; - // Do not break if we are called multiple times: - if (instance_) - return instance_.get(); + XBT_DEBUG("Initialize the MC world."); - _sg_do_model_check = 1; + simgrid::mc::set_model_checking_mode(ModelCheckingMode::APP_SIDE); setvbuf(stdout, nullptr, _IOLBF, 0); @@ -52,60 +59,48 @@ AppSide* AppSide::initialize(xbt_dynar_t actors_addr) int fd = xbt_str_parse_int(fd_env, "Not a number in variable '" MC_ENV_SOCKET_FD "'"); XBT_DEBUG("Model-checked application found socket FD %i", fd); - // Check the socket type/validity: - int type; - socklen_t socklen = sizeof(type); - xbt_assert(getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &socklen) == 0, "Could not check socket type"); - xbt_assert(type == SOCK_SEQPACKET, "Unexpected socket type %i", type); - XBT_DEBUG("Model-checked application found expected socket type"); - instance_ = std::make_unique(fd); - // Wait for the model-checker: - errno = 0; -#if defined __linux__ - ptrace(PTRACE_TRACEME, 0, nullptr, nullptr); -#elif defined BSD - ptrace(PT_TRACE_ME, 0, nullptr, 0); -#else -#error "no ptrace equivalent coded for this platform" -#endif - xbt_assert(errno == 0 && raise(SIGSTOP) == 0, "Could not wait for the model-checker (errno = %d: %s)", errno, - strerror(errno)); - - s_mc_message_initial_addresses_t message{MessageType::INITIAL_ADDRESSES, mmalloc_preinit(), - kernel::actor::ActorImpl::get_maxpid_addr(), actors_addr}; - xbt_assert(instance_->channel_.send(message) == 0, "Could not send the initial message with addresses."); - instance_->handle_messages(); return instance_.get(); } void AppSide::handle_deadlock_check(const s_mc_message_t*) const { - const auto& actor_list = kernel::EngineImpl::get_instance()->get_actor_list(); + const auto* engine = kernel::EngineImpl::get_instance(); + const auto& actor_list = engine->get_actor_list(); bool deadlock = not actor_list.empty() && std::none_of(begin(actor_list), end(actor_list), [](const auto& kv) { return mc::actor_is_enabled(kv.second); }); + if (deadlock) { + XBT_CINFO(mc_global, "**************************"); + XBT_CINFO(mc_global, "*** DEADLOCK DETECTED ***"); + XBT_CINFO(mc_global, "**************************"); + engine->display_all_actor_status(); + } // Send result: - s_mc_message_int_t answer{MessageType::DEADLOCK_CHECK_REPLY, deadlock}; - xbt_assert(channel_.send(answer) == 0, "Could not send response"); + s_mc_message_int_t answer = {}; + answer.type = MessageType::DEADLOCK_CHECK_REPLY; + answer.value = deadlock; + xbt_assert(channel_.send(answer) == 0, "Could not send response: %s", strerror(errno)); } void AppSide::handle_simcall_execute(const s_mc_message_simcall_execute_t* message) const { kernel::actor::ActorImpl* actor = kernel::EngineImpl::get_instance()->get_actor_by_pid(message->aid_); xbt_assert(actor != nullptr, "Invalid pid %ld", message->aid_); + xbt_assert(actor->simcall_.observer_ == nullptr || actor->simcall_.observer_->is_enabled(), + "Please, model-checker, don't execute disabled transitions."); // The client may send some messages to the server while processing the transition actor->simcall_handle(message->times_considered_); // Say the server that the transition is over and that it should proceed - xbt_assert(channel_.send(MessageType::WAITING) == 0, "Could not send MESSAGE_WAITING to model-checker"); + xbt_assert(channel_.send(MessageType::WAITING) == 0, "Could not send MESSAGE_WAITING to model-checker: %s", + strerror(errno)); // Finish the RPC from the server: return a serialized observer, to build a Transition on Checker side - s_mc_message_simcall_execute_answer_t answer; - memset(&answer, 0, sizeof(answer)); - answer.type = MessageType::SIMCALL_EXECUTE_ANSWER; + s_mc_message_simcall_execute_answer_t answer = {}; + answer.type = MessageType::SIMCALL_EXECUTE_REPLY; std::stringstream stream; if (actor->simcall_.observer_ != nullptr) { actor->simcall_.observer_->serialize(stream); @@ -119,14 +114,7 @@ void AppSide::handle_simcall_execute(const s_mc_message_simcall_execute_t* messa answer.buffer.back() = '\0'; XBT_DEBUG("send SIMCALL_EXECUTE_ANSWER(%s) ~> '%s'", actor->get_cname(), str.c_str()); - xbt_assert(channel_.send(answer) == 0, "Could not send response"); -} - -void AppSide::handle_actor_enabled(const s_mc_message_actor_enabled_t* msg) const -{ - bool res = mc::actor_is_enabled(kernel::EngineImpl::get_instance()->get_actor_by_pid(msg->aid)); - s_mc_message_int_t answer{MessageType::ACTOR_ENABLED_REPLY, res}; - xbt_assert(channel_.send(answer) == 0, "Could not send ACTOR_ENABLED_REPLY"); + xbt_assert(channel_.send(answer) == 0, "Could not send response: %s", strerror(errno)); } void AppSide::handle_finalize(const s_mc_message_int_t* msg) const @@ -143,53 +131,196 @@ void AppSide::handle_finalize(const s_mc_message_int_t* msg) const #endif } coverage_checkpoint(); - xbt_assert(channel_.send(MessageType::DEADLOCK_CHECK_REPLY) == 0, // DEADLOCK_CHECK_REPLY, really? - "Could not answer to FINALIZE"); + xbt_assert(channel_.send(MessageType::FINALIZE_REPLY) == 0, "Could not answer to FINALIZE: %s", strerror(errno)); std::fflush(stdout); if (terminate_asap) ::_Exit(0); } +void AppSide::handle_fork(const s_mc_message_fork_t* msg) +{ + int status; + int pid; + /* Reap any zombie child, saving its status for later use in AppSide::handle_wait_child() */ + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + child_statuses_[pid] = status; + + pid = fork(); + xbt_assert(pid >= 0, "Could not fork application sub-process: %s.", strerror(errno)); + + if (pid == 0) { // Child + int sock = socket(AF_UNIX, +#ifdef __APPLE__ + SOCK_STREAM, /* Mac OSX does not have AF_UNIX + SOCK_SEQPACKET, even if that's faster*/ +#else + SOCK_SEQPACKET, +#endif + 0); + + struct sockaddr_un addr = {}; + addr.sun_family = AF_UNIX; + std::copy_n(begin(msg->socket_name), MC_SOCKET_NAME_LEN, addr.sun_path); + + xbt_assert(connect(sock, (struct sockaddr*)&addr, sizeof addr) >= 0, "Cannot connect to Checker on %c%s: %s.", + (addr.sun_path[0] ? addr.sun_path[0] : '@'), addr.sun_path + 1, strerror(errno)); + + channel_.reset_socket(sock); + + s_mc_message_int_t answer = {}; + answer.type = MessageType::FORK_REPLY; + answer.value = getpid(); + xbt_assert(channel_.send(answer) == 0, "Could not send response to WAIT_CHILD_REPLY: %s", strerror(errno)); + } else { + XBT_VERB("App %d forks subprocess %d.", getpid(), pid); + } +} +void AppSide::handle_wait_child(const s_mc_message_int_t* msg) +{ + int status; + errno = 0; + if (auto search = child_statuses_.find(msg->value); search != child_statuses_.end()) { + status = search->second; + child_statuses_.erase(search); // We only need this info once + } else { + waitpid(msg->value, &status, 0); + } + xbt_assert(errno == 0, "Cannot wait on behalf of the checker: %s.", strerror(errno)); + + s_mc_message_int_t answer = {}; + answer.type = MessageType::WAIT_CHILD_REPLY; + answer.value = status; + xbt_assert(channel_.send(answer) == 0, "Could not send response to WAIT_CHILD: %s", strerror(errno)); +} +void AppSide::handle_actors_status() const +{ + auto const& actor_list = kernel::EngineImpl::get_instance()->get_actor_list(); + XBT_DEBUG("Serialize the actors to answer ACTORS_STATUS from the checker. %zu actors to go.", actor_list.size()); + + std::vector status; + for (auto const& [aid, actor] : actor_list) { + xbt_assert(actor); + xbt_assert(actor->simcall_.observer_, "simcall %s in actor %s has no observer.", actor->simcall_.get_cname(), + actor->get_cname()); + s_mc_message_actors_status_one_t one = {}; + one.type = MessageType::ACTORS_STATUS_REPLY_TRANSITION; + one.aid = aid; + one.enabled = mc::actor_is_enabled(actor); + one.max_considered = actor->simcall_.observer_->get_max_consider(); + status.push_back(one); + } + + struct s_mc_message_actors_status_answer_t answer = {}; + answer.type = MessageType::ACTORS_STATUS_REPLY_COUNT; + answer.count = static_cast(status.size()); + + xbt_assert(channel_.send(answer) == 0, "Could not send ACTORS_STATUS_REPLY msg: %s", strerror(errno)); + if (answer.count > 0) { + size_t size = status.size() * sizeof(s_mc_message_actors_status_one_t); + xbt_assert(channel_.send(status.data(), size) == 0, "Could not send ACTORS_STATUS_REPLY data: %s", strerror(errno)); + } + + // Serialize each transition to describe what each actor is doing + XBT_DEBUG("Deliver ACTOR_TRANSITION_PROBE payload"); + for (const auto& actor_status : status) { + const auto& actor = actor_list.at(actor_status.aid); + const int max_considered = actor_status.max_considered; + + for (int times_considered = 0; times_considered < max_considered; times_considered++) { + std::stringstream stream; + s_mc_message_simcall_probe_one_t probe; + probe.type = MessageType::ACTORS_STATUS_REPLY_SIMCALL; + + if (actor->simcall_.observer_ != nullptr) { + actor->simcall_.observer_->prepare(times_considered); + actor->simcall_.observer_->serialize(stream); + } else { + stream << (short)mc::Transition::Type::UNKNOWN; + } + + std::string str = stream.str(); + xbt_assert(str.size() + 1 <= probe.buffer.size(), + "The serialized transition is too large for the buffer. Please fix the code."); + strncpy(probe.buffer.data(), str.c_str(), probe.buffer.size() - 1); + probe.buffer.back() = '\0'; + + XBT_DEBUG("send ACTOR_TRANSITION_PROBE(%s) ~> '%s'", actor->get_cname(), str.c_str()); + xbt_assert(channel_.send(probe) == 0, "Could not send ACTOR_TRANSITION_PROBE payload: %s", strerror(errno)); + } + // NOTE: We do NOT need to reset `times_considered` for each actor's + // simcall observer here to the "original" value (i.e. the value BEFORE + // multiple prepare() calls were made for serialization purposes) since + // each SIMCALL_EXECUTE provides a `times_considered` to be used to prepare + // the transition before execution. + } +} +void AppSide::handle_actors_maxpid() const +{ + s_mc_message_int_t answer = {}; + answer.type = MessageType::ACTORS_MAXPID_REPLY; + answer.value = kernel::actor::ActorImpl::get_maxpid(); + xbt_assert(channel_.send(answer) == 0, "Could not send response: %s", strerror(errno)); +} #define assert_msg_size(_name_, _type_) \ xbt_assert(received_size == sizeof(_type_), "Unexpected size for " _name_ " (%zd != %zu)", received_size, \ sizeof(_type_)) -void AppSide::handle_messages() const +void AppSide::handle_messages() { while (true) { // Until we get a CONTINUE message - XBT_DEBUG("Waiting messages from model-checker"); + XBT_DEBUG("Waiting messages from the model-checker"); std::array message_buffer; ssize_t received_size = channel_.receive(message_buffer.data(), message_buffer.size()); - xbt_assert(received_size >= 0, "Could not receive commands from the model-checker"); + if (received_size == 0) { + XBT_DEBUG("Socket closed on the Checker side, bailing out."); + ::_Exit(0); // Nobody's listening to that process anymore => exit as quickly as possible. + } + xbt_assert(received_size >= 0, "Could not receive commands from the model-checker: %s", strerror(errno)); + xbt_assert(static_cast(received_size) >= sizeof(s_mc_message_t), "Cannot handle short message (size=%zd)", + received_size); const s_mc_message_t* message = (s_mc_message_t*)message_buffer.data(); switch (message->type) { + case MessageType::CONTINUE: + assert_msg_size("MESSAGE_CONTINUE", s_mc_message_t); + return; + case MessageType::DEADLOCK_CHECK: assert_msg_size("DEADLOCK_CHECK", s_mc_message_t); handle_deadlock_check(message); break; - case MessageType::CONTINUE: - assert_msg_size("MESSAGE_CONTINUE", s_mc_message_t); - return; - case MessageType::SIMCALL_EXECUTE: assert_msg_size("SIMCALL_EXECUTE", s_mc_message_simcall_execute_t); handle_simcall_execute((s_mc_message_simcall_execute_t*)message_buffer.data()); break; - case MessageType::ACTOR_ENABLED: - assert_msg_size("ACTOR_ENABLED", s_mc_message_actor_enabled_t); - handle_actor_enabled((s_mc_message_actor_enabled_t*)message_buffer.data()); - break; - case MessageType::FINALIZE: assert_msg_size("FINALIZE", s_mc_message_int_t); handle_finalize((s_mc_message_int_t*)message_buffer.data()); break; + case MessageType::FORK: + assert_msg_size("FORK", s_mc_message_fork_t); + handle_fork((s_mc_message_fork_t*)message_buffer.data()); + break; + + case MessageType::WAIT_CHILD: + assert_msg_size("WAIT_CHILD", s_mc_message_int_t); + handle_wait_child((s_mc_message_int_t*)message_buffer.data()); + break; + + case MessageType::ACTORS_STATUS: + assert_msg_size("ACTORS_STATUS", s_mc_message_t); + handle_actors_status(); + break; + + case MessageType::ACTORS_MAXPID: + assert_msg_size("ACTORS_MAXPID", s_mc_message_t); + handle_actors_maxpid(); + break; + default: xbt_die("Received unexpected message %s (%i)", to_c_str(message->type), static_cast(message->type)); break; @@ -197,90 +328,26 @@ void AppSide::handle_messages() const } } -void AppSide::main_loop() const +void AppSide::main_loop() { simgrid::mc::processes_time.resize(simgrid::kernel::actor::ActorImpl::get_maxpid()); - MC_ignore_heap(simgrid::mc::processes_time.data(), - simgrid::mc::processes_time.size() * sizeof(simgrid::mc::processes_time[0])); + sthread_disable(); coverage_checkpoint(); + sthread_enable(); while (true) { simgrid::mc::execute_actors(); - xbt_assert(channel_.send(MessageType::WAITING) == 0, "Could not send WAITING message to model-checker"); + xbt_assert(channel_.send(MessageType::WAITING) == 0, "Could not send WAITING message to model-checker: %s", + strerror(errno)); this->handle_messages(); } } -void AppSide::report_assertion_failure() const +void AppSide::report_assertion_failure() { - xbt_assert(channel_.send(MessageType::ASSERTION_FAILED) == 0, "Could not send assertion to model-checker"); + xbt_assert(channel_.send(MessageType::ASSERTION_FAILED) == 0, "Could not send assertion to model-checker: %s", + strerror(errno)); this->handle_messages(); } -void AppSide::ignore_memory(void* addr, std::size_t size) const -{ - s_mc_message_ignore_memory_t message; - message.type = MessageType::IGNORE_MEMORY; - message.addr = (std::uintptr_t)addr; - message.size = size; - xbt_assert(channel_.send(message) == 0, "Could not send IGNORE_MEMORY message to model-checker"); -} - -void AppSide::ignore_heap(void* address, std::size_t size) const -{ - const s_xbt_mheap_t* heap = mmalloc_get_current_heap(); - - s_mc_message_ignore_heap_t message; - message.type = MessageType::IGNORE_HEAP; - message.address = address; - message.size = size; - message.block = ((char*)address - (char*)heap->heapbase) / BLOCKSIZE + 1; - if (heap->heapinfo[message.block].type == 0) { - message.fragment = -1; - heap->heapinfo[message.block].busy_block.ignore++; - } else { - message.fragment = (ADDR2UINT(address) % BLOCKSIZE) >> heap->heapinfo[message.block].type; - heap->heapinfo[message.block].busy_frag.ignore[message.fragment]++; - } - - xbt_assert(channel_.send(message) == 0, "Could not send ignored region to MCer"); -} - -void AppSide::unignore_heap(void* address, std::size_t size) const -{ - s_mc_message_ignore_memory_t message; - message.type = MessageType::UNIGNORE_HEAP; - message.addr = (std::uintptr_t)address; - message.size = size; - xbt_assert(channel_.send(message) == 0, "Could not send IGNORE_HEAP message to model-checker"); -} - -void AppSide::declare_symbol(const char* name, int* value) const -{ - s_mc_message_register_symbol_t message; - memset(&message, 0, sizeof(message)); - message.type = MessageType::REGISTER_SYMBOL; - xbt_assert(strlen(name) + 1 <= message.name.size(), "Symbol is too long"); - strncpy(message.name.data(), name, message.name.size()); - message.callback = nullptr; - message.data = value; - xbt_assert(channel_.send(message) == 0, "Could send REGISTER_SYMBOL message to model-checker"); -} - -void AppSide::declare_stack(void* stack, size_t size, ucontext_t* context) const -{ - const s_xbt_mheap_t* heap = mmalloc_get_current_heap(); - - s_stack_region_t region; - memset(®ion, 0, sizeof(region)); - region.address = stack; - region.context = context; - region.size = size; - region.block = ((char*)stack - (char*)heap->heapbase) / BLOCKSIZE + 1; - - s_mc_message_stack_region_t message; - message.type = MessageType::STACK_REGION; - message.stack_region = region; - xbt_assert(channel_.send(message) == 0, "Could not send STACK_REGION to model-checker"); -} } // namespace simgrid::mc diff --git a/src/mc/remote/AppSide.hpp b/src/mc/remote/AppSide.hpp index 393f1ea4d4..03250e901b 100644 --- a/src/mc/remote/AppSide.hpp +++ b/src/mc/remote/AppSide.hpp @@ -1,6 +1,6 @@ /* mc::remote::AppSide: the Application-side of the channel */ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,35 +22,30 @@ class XBT_PUBLIC AppSide { private: Channel channel_; static std::unique_ptr instance_; + std::unordered_map child_statuses_; public: AppSide(); explicit AppSide(int fd) : channel_(fd) {} - void handle_messages() const; + void handle_messages(); private: void handle_deadlock_check(const s_mc_message_t* msg) const; void handle_simcall_execute(const s_mc_message_simcall_execute_t* message) const; - void handle_actor_enabled(const s_mc_message_actor_enabled_t* msg) const; void handle_finalize(const s_mc_message_int_t* msg) const; + void handle_fork(const s_mc_message_fork_t* msg); + void handle_wait_child(const s_mc_message_int_t* msg); + void handle_actors_status() const; + void handle_actors_maxpid() const; public: Channel const& get_channel() const { return channel_; } Channel& get_channel() { return channel_; } - XBT_ATTRIB_NORETURN void main_loop() const; - void report_assertion_failure() const; - void ignore_memory(void* addr, std::size_t size) const; - void ignore_heap(void* addr, std::size_t size) const; - void unignore_heap(void* addr, std::size_t size) const; - void declare_symbol(const char* name, int* value) const; -#if HAVE_UCONTEXT_H - void declare_stack(void* stack, size_t size, ucontext_t* context) const; -#endif + XBT_ATTRIB_NORETURN void main_loop(); + void report_assertion_failure(); - // Singleton :/ // TODO, remove the singleton antipattern. - static AppSide* initialize(xbt_dynar_t actors_addr); - static AppSide* get() { return instance_.get(); } + static AppSide* get(); }; } // namespace simgrid::mc diff --git a/src/mc/remote/Channel.cpp b/src/mc/remote/Channel.cpp index 8155d847ee..7e3bfb9902 100644 --- a/src/mc/remote/Channel.cpp +++ b/src/mc/remote/Channel.cpp @@ -1,5 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,15 +6,20 @@ #include "src/mc/remote/Channel.hpp" #include +#include #include #include #include #include #include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_Channel, mc, "MC interprocess communication"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_channel, mc, "MC interprocess communication"); namespace simgrid::mc { +Channel::Channel(int sock, Channel const& other) : socket_(sock), buffer_(other.buffer_) +{ + XBT_DEBUG("Adopt %zu bytes buffered by father channel.", buffer_.size()); +} Channel::~Channel() { @@ -26,7 +30,14 @@ Channel::~Channel() /** @brief Send a message; returns 0 on success or errno on failure */ int Channel::send(const void* message, size_t size) const { - XBT_DEBUG("Send %s", to_c_str(*(MessageType*)message)); + if (size >= sizeof(int) && is_valid_MessageType(*static_cast(message))) { + XBT_DEBUG("Sending %s (%zu bytes sent)", to_c_str(*static_cast(message)), size); + } else { + XBT_DEBUG("Sending bytes directly (from address %p) (%zu bytes sent)", message, size); + if (size == 0) + XBT_WARN("Request to send a 0-sized message! Proceeding anyway."); + } + while (::send(this->socket_, message, size, 0) == -1) { if (errno != EINTR) { XBT_ERROR("Channel::send failure: %s", strerror(errno)); @@ -36,13 +47,44 @@ int Channel::send(const void* message, size_t size) const return 0; } -ssize_t Channel::receive(void* message, size_t size, bool block) const +ssize_t Channel::receive(void* message, size_t size, int flags) { - ssize_t res = recv(this->socket_, message, size, block ? 0 : MSG_DONTWAIT); - if (res != -1) - XBT_DEBUG("Receive %s", to_c_str(*(MessageType*)message)); - else - XBT_ERROR("Channel::receive failure: %s", strerror(errno)); + size_t bufsize = buffer_.size(); + ssize_t copied = 0; + auto* whereto = static_cast(message); + size_t todo = size; + if (bufsize > 0) { + XBT_DEBUG("%d %zu bytes (of %zu expected) are already in buffer", getpid(), bufsize, size); + copied = std::min(size, bufsize); + std::copy_n(begin(buffer_), copied, whereto); + buffer_.erase(begin(buffer_), begin(buffer_) + copied); + todo -= copied; + whereto += copied; + } + ssize_t res = 0; + if (todo > 0) { + errno = 0; + res = recv(this->socket_, whereto, todo, flags); + xbt_assert(res != -1 || errno == EAGAIN, "Channel::receive failure: %s", strerror(errno)); + if (res == -1) { + res = 0; + } + } + XBT_DEBUG("%d Wanted %zu; Got %zd from buffer and %zd from network", getpid(), size, copied, res); + res += copied; + if (static_cast(res) >= sizeof(int) && is_valid_MessageType(*static_cast(message))) { + XBT_DEBUG("%d Receive %s (requested %zu; received %zd at %p)", getpid(), + to_c_str(*static_cast(message)), size, res, message); + } else { + XBT_DEBUG("Receive %zd bytes", res); + } return res; } + +void Channel::reinject(const char* data, size_t size) +{ + xbt_assert(size > 0, "Cannot reinject less than one char (size: %lu)", size); + XBT_DEBUG("%d Reinject %zu bytes on top of %zu pre-existing bytes", getpid(), size, buffer_.size()); + buffer_.insert(end(buffer_), data, data + size); +} } // namespace simgrid::mc diff --git a/src/mc/remote/Channel.hpp b/src/mc/remote/Channel.hpp index 8dfef7ee12..06d22b1d89 100644 --- a/src/mc/remote/Channel.hpp +++ b/src/mc/remote/Channel.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -20,9 +20,12 @@ namespace simgrid::mc { class Channel { int socket_ = -1; template static constexpr bool messageType() { return std::is_class_v && std::is_trivial_v; } + std::vector buffer_; public: + Channel() = default; explicit Channel(int sock) : socket_(sock) {} + Channel(int sock, Channel const& other); ~Channel(); // No copy: @@ -43,13 +46,17 @@ public: } // Receive - ssize_t receive(void* message, size_t size, bool block = true) const; - template typename std::enable_if_t(), ssize_t> receive(M& m) const + ssize_t receive(void* message, size_t size, int flags = 0); + template typename std::enable_if_t(), ssize_t> receive(M& m) { - return this->receive(&m, sizeof(M)); + return this->receive(&m, sizeof(M), 0); } + void reinject(const char* data, size_t size); + bool has_pending_data() const { return not buffer_.empty(); } + // Socket handling int get_socket() const { return socket_; } + void reset_socket(int socket) { socket_ = socket; } }; } // namespace simgrid::mc diff --git a/src/mc/remote/CheckerSide.cpp b/src/mc/remote/CheckerSide.cpp index 06c489a113..2ad4f7ed08 100644 --- a/src/mc/remote/CheckerSide.cpp +++ b/src/mc/remote/CheckerSide.cpp @@ -1,29 +1,265 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/remote/CheckerSide.hpp" +#include "src/mc/explo/Exploration.hpp" +#include "src/mc/mc_environ.h" +#include "xbt/config.hpp" +#include "xbt/system_error.hpp" + +#ifdef __linux__ +#include +#endif + +#include #include +#include +#include #include +#ifdef __linux__ +#define WAITPID_CHECKED_FLAGS __WALL +#else +#define WAITPID_CHECKED_FLAGS 0 +#endif + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkerside, mc, "MC communication with the application"); + +static simgrid::config::Flag _sg_mc_setenv{ + "model-check/setenv", "Extra environment variables to pass to the child process (ex: 'AZE=aze;QWE=qwe').", "", + [](std::string_view value) { + xbt_assert(value.empty() || value.find('=', 0) != std::string_view::npos, + "The 'model-check/setenv' parameter must be like 'AZE=aze', but it does not contain an equal sign."); + }}; + namespace simgrid::mc { -void CheckerSide::start(void (*handler)(int, short, void*), ModelChecker* mc) +XBT_ATTRIB_NORETURN static void run_child_process(int socket, const std::vector& args) +{ + /* On startup, simix_global_init() calls simgrid::mc::Client::initialize(), which checks whether the MC_ENV_SOCKET_FD + * env variable is set. If so, MC mode is assumed, and the client is setup from its side + */ + +#ifdef __linux__ + // Make sure we do not outlive our parent + sigset_t mask; + sigemptyset(&mask); + xbt_assert(sigprocmask(SIG_SETMASK, &mask, nullptr) >= 0, "Could not unblock signals"); + xbt_assert(prctl(PR_SET_PDEATHSIG, SIGHUP) == 0, "Could not PR_SET_PDEATHSIG"); +#endif + + setenv(MC_ENV_SOCKET_FD, std::to_string(socket).c_str(), 1); + + /* Setup the tokenizer that parses the cfg:model-check/setenv parameter */ + using Tokenizer = boost::tokenizer>; + boost::char_separator semicol_sep(";"); + boost::char_separator equal_sep("="); + Tokenizer token_vars(_sg_mc_setenv.get(), semicol_sep); /* Iterate over all FOO=foo parts */ + for (const auto& token : token_vars) { + std::vector kv; + Tokenizer token_kv(token, equal_sep); + for (const auto& t : token_kv) /* Iterate over 'FOO' and then 'foo' in that 'FOO=foo' */ + kv.push_back(t); + xbt_assert(kv.size() == 2, "Parse error on 'model-check/setenv' value %s. Does it contain an equal sign?", + token.c_str()); + XBT_INFO("setenv '%s'='%s'", kv[0].c_str(), kv[1].c_str()); + setenv(kv[0].c_str(), kv[1].c_str(), 1); + } + + /* And now, exec the child process */ + int i = 1; + while (args[i] != nullptr && args[i][0] == '-') + i++; + + xbt_assert(args[i] != nullptr, + "Unable to find a binary to exec on the command line. Did you only pass config flags?"); + + execvp(args[i], args.data() + i); + XBT_CRITICAL("The model-checked process failed to exec(%s): %s.\n" + " Make sure that your binary exists on disk and is executable.", + args[i], strerror(errno)); + if (strchr(args[i], '=') != nullptr) + XBT_CRITICAL("If you want to pass environment variables to the application, please use --cfg=model-check/setenv:%s", + args[i]); + + xbt_die("Aborting now."); +} + +static void wait_application_process(pid_t pid) +{ + XBT_DEBUG("Waiting for the model-checked process"); + int status; + + // The model-checked process SIGSTOP itself to signal it's ready: + xbt_assert(waitpid(pid, &status, WAITPID_CHECKED_FLAGS) == pid && WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP, + "Could not wait model-checked process"); + + errno = 0; +#ifdef __linux__ + ptrace(PTRACE_SETOPTIONS, pid, nullptr, PTRACE_O_TRACEEXIT); + ptrace(PTRACE_CONT, pid, 0, 0); +#elif defined BSD + ptrace(PT_CONTINUE, pid, (caddr_t)1, 0); +#else + xbt_die("no ptrace equivalent coded for this platform, stateful model-checking is impossible."); +#endif + xbt_assert(errno == 0, + "Ptrace does not seem to be usable in your setup (errno: %d). " + "If you run from within a docker, adding `--cap-add SYS_PTRACE` to the docker line may help. " + "If it does not help, please report this bug.", + errno); + XBT_DEBUG("%d ptrace correctly setup.", getpid()); +} + +void CheckerSide::setup_events(bool socket_only) { auto* base = event_base_new(); base_.reset(base); - auto* socket_event = event_new(base, get_channel().get_socket(), EV_READ | EV_PERSIST, handler, mc); - event_add(socket_event, nullptr); - socket_event_.reset(socket_event); + socket_event_ = event_new( + base, get_channel().get_socket(), EV_READ | EV_PERSIST, + [](evutil_socket_t, short events, void* arg) { + auto* checker = static_cast(arg); + if (events == EV_READ) { + do { + std::array buffer; + ssize_t size = checker->get_channel().receive(buffer.data(), buffer.size(), MSG_DONTWAIT); + if (size == -1) { + XBT_ERROR("Channel::receive failure: %s", strerror(errno)); + if (errno != EAGAIN) + throw simgrid::xbt::errno_error(); + } + + if (size == 0) // The app closed the socket. It must be dead by now. + checker->handle_waitpid(); + else if (not checker->handle_message(buffer.data(), size)) { + checker->break_loop(); + break; + } + } while (checker->get_channel().has_pending_data()); + } else { + xbt_die("Unexpected event"); + } + }, + this); + event_add(socket_event_, nullptr); - auto* signal_event = event_new(base, SIGCHLD, EV_SIGNAL | EV_PERSIST, handler, mc); - event_add(signal_event, nullptr); - signal_event_.reset(signal_event); + if (socket_only) { + signal_event_ = nullptr; + } else { + signal_event_ = event_new( + base, SIGCHLD, EV_SIGNAL | EV_PERSIST, + [](evutil_socket_t sig, short events, void* arg) { + auto* checker = static_cast(arg); + if (events == EV_SIGNAL) { + if (sig == SIGCHLD) + checker->handle_waitpid(); + else + xbt_die("Unexpected signal: %d", sig); + } else { + xbt_die("Unexpected event"); + } + }, + this); + event_add(signal_event_, nullptr); + } } -void CheckerSide::dispatch() const +/* When this constructor is called, no other checkerside exists */ +CheckerSide::CheckerSide(const std::vector& args) : running_(true) +{ + XBT_DEBUG("Create a CheckerSide."); + + // Create an AF_UNIX socketpair used for exchanging messages between the model-checker process (ancestor) + // and the application process (child) + int sockets[2]; + xbt_assert(socketpair(AF_UNIX, +#ifdef __APPLE__ + SOCK_STREAM, /* Mac OSX does not have AF_UNIX + SOCK_SEQPACKET, even if that's faster */ +#else + SOCK_SEQPACKET, +#endif + 0, sockets) != -1, + "Could not create socketpair: %s", strerror(errno)); + + pid_ = fork(); + xbt_assert(pid_ >= 0, "Could not fork application process"); + + if (pid_ == 0) { // Child + ::close(sockets[1]); + run_child_process(sockets[0], args); + DIE_IMPOSSIBLE; + } + + // Parent (model-checker): + ::close(sockets[0]); + channel_.reset_socket(sockets[1]); + + setup_events(false); /* we need a signal handler too */ + wait_for_requests(); +} + +CheckerSide::~CheckerSide() +{ + event_del(socket_event_); + event_free(socket_event_); + if (signal_event_ != nullptr) { + event_del(signal_event_); + event_free(signal_event_); + } +} + +/* This constructor is called when cloning a checkerside to get its application to fork away */ +CheckerSide::CheckerSide(int socket, CheckerSide* child_checker) + : channel_(socket, child_checker->channel_), running_(true), child_checker_(child_checker) +{ + setup_events(true); // We already have a signal handled in that case + + s_mc_message_int_t answer; + ssize_t s = get_channel().receive(answer); + xbt_assert(s != -1, "Could not receive answer to FORK_REPLY"); + xbt_assert(s == sizeof answer, "Broken message (size=%zd; expected %zu)", s, sizeof answer); + xbt_assert(answer.type == MessageType::FORK_REPLY, + "Received unexpected message %s (%i); expected MessageType::FORK_REPLY (%i)", to_c_str(answer.type), + (int)answer.type, (int)MessageType::FORK_REPLY); + pid_ = answer.value; + + wait_for_requests(); +} + +std::unique_ptr CheckerSide::clone(int master_socket, const std::string& master_socket_name) +{ + s_mc_message_fork_t m = {}; + m.type = MessageType::FORK; + xbt_assert(master_socket_name.size() == MC_SOCKET_NAME_LEN); + std::copy_n(begin(master_socket_name), MC_SOCKET_NAME_LEN, begin(m.socket_name)); + xbt_assert(get_channel().send(m) == 0, "Could not ask the app to fork on need."); + + int sock = accept(master_socket, nullptr /* I know who's connecting*/, nullptr); + xbt_assert(sock > 0, "Cannot accept the incomming connection of the forked app: %s.", strerror(errno)); + + return std::make_unique(sock, this); +} + +void CheckerSide::finalize(bool terminate_asap) +{ + s_mc_message_int_t m = {}; + m.type = MessageType::FINALIZE; + m.value = terminate_asap; + xbt_assert(get_channel().send(m) == 0, "Could not ask the app to finalize on need"); + + s_mc_message_t answer; + ssize_t s = get_channel().receive(answer); + xbt_assert(s != -1, "Could not receive answer to FINALIZE"); + xbt_assert(s == sizeof answer, "Broken message (size=%zd; expected %zu)", s, sizeof answer); + xbt_assert(answer.type == MessageType::FINALIZE_REPLY, + "Received unexpected message %s (%i); expected MessageType::FINALIZE_REPLY (%i)", to_c_str(answer.type), + (int)answer.type, (int)MessageType::FINALIZE_REPLY); +} + +void CheckerSide::dispatch_events() const { event_base_dispatch(base_.get()); } @@ -33,4 +269,125 @@ void CheckerSide::break_loop() const event_base_loopbreak(base_.get()); } +bool CheckerSide::handle_message(const char* buffer, ssize_t size) +{ + s_mc_message_t base_message; + ssize_t consumed; + xbt_assert(size >= (ssize_t)sizeof(base_message), "Broken message. Got only %ld bytes.", size); + memcpy(&base_message, buffer, sizeof(base_message)); + + switch (base_message.type) { + + case MessageType::WAITING: + consumed = sizeof(s_mc_message_t); + if (size > consumed) { + XBT_DEBUG("%d reinject %d bytes after a %s message", getpid(), (int)(size - consumed), + to_c_str(base_message.type)); + channel_.reinject(&buffer[consumed], size - consumed); + } + + return false; + + case MessageType::ASSERTION_FAILED: + // report_assertion_failure() is NORETURN, but it may change when we report more than one error per run, + // so please keep the consumed computation even if clang-static detects it as a dead affectation. + consumed = sizeof(s_mc_message_t); + Exploration::get_instance()->report_assertion_failure(); + break; + + default: + xbt_die("Unexpected message from the application"); + } + if (size > consumed) { + XBT_DEBUG("%d reinject %d bytes after a %s message", getpid(), (int)(size - consumed), to_c_str(base_message.type)); + channel_.reinject(&buffer[consumed], size - consumed); + } + return true; +} + +void CheckerSide::wait_for_requests() +{ + XBT_DEBUG("Resume the application"); + if (get_channel().send(MessageType::CONTINUE) != 0) + throw xbt::errno_error(); + + if (running()) + dispatch_events(); +} + +void CheckerSide::handle_dead_child(int status) +{ + // From PTRACE_O_TRACEEXIT: +#ifdef __linux__ + if (status >> 8 == (SIGTRAP | (PTRACE_EVENT_EXIT << 8))) { + unsigned long eventmsg; + xbt_assert(ptrace(PTRACE_GETEVENTMSG, pid_, 0, &eventmsg) != -1, "Could not get exit status"); + status = static_cast(eventmsg); + if (WIFSIGNALED(status)) { + this->terminate(); + Exploration::get_instance()->report_crash(status); + } + } +#endif + + // We don't care about non-lethal signals, just reinject them: + if (WIFSTOPPED(status)) { + XBT_DEBUG("Stopped with signal %i", (int)WSTOPSIG(status)); + errno = 0; +#ifdef __linux__ + ptrace(PTRACE_CONT, pid_, 0, WSTOPSIG(status)); +#elif defined BSD + ptrace(PT_CONTINUE, pid_, (caddr_t)1, WSTOPSIG(status)); +#endif + xbt_assert(errno == 0, "Could not PTRACE_CONT: %s", strerror(errno)); + } + + else if (WIFSIGNALED(status)) { + this->terminate(); + Exploration::get_instance()->report_crash(status); + } else if (WIFEXITED(status)) { + XBT_DEBUG("Child process is over"); + this->terminate(); + } +} + +void CheckerSide::handle_waitpid() +{ + XBT_DEBUG("%d checks for wait event. %s", getpid(), + child_checker_ == nullptr ? "Wait directly." : "Ask our proxy to wait for its child."); + + if (child_checker_ == nullptr) { // Wait directly + int status; + pid_t pid; + while ((pid = waitpid(-1, &status, WNOHANG)) != 0) { + if (pid == -1) { + if (errno == ECHILD) { // No more children: + xbt_assert(not this->running(), "Inconsistent state"); + break; + } else { + xbt_die("Could not wait for pid: %s", strerror(errno)); + } + } + + if (pid == get_pid()) + handle_dead_child(status); + } + + } else { // Ask our proxy to wait for us + s_mc_message_int_t request = {}; + request.type = MessageType::WAIT_CHILD; + request.value = pid_; + xbt_assert(child_checker_->get_channel().send(request) == 0, + "Could not ask my child to waitpid its child for me: %s", strerror(errno)); + + s_mc_message_int_t answer; + ssize_t answer_size = child_checker_->get_channel().receive(answer); + xbt_assert(answer_size != -1, "Could not receive message"); + xbt_assert(answer.type == MessageType::WAIT_CHILD_REPLY, + "The received message is not the WAIT_CHILD_REPLY I was expecting but of type %s", + to_c_str(answer.type)); + xbt_assert(answer_size == sizeof answer, "Broken message (size=%zd; expected %zu)", answer_size, sizeof answer); + handle_dead_child(answer.value); + } +} } // namespace simgrid::mc diff --git a/src/mc/remote/CheckerSide.hpp b/src/mc/remote/CheckerSide.hpp index c4355cea17..f4605e4cd2 100644 --- a/src/mc/remote/CheckerSide.hpp +++ b/src/mc/remote/CheckerSide.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -15,27 +15,53 @@ namespace simgrid::mc { +/* CheckerSide: All what the checker needs to interact with a given application process */ + class CheckerSide { + event* socket_event_; + event* signal_event_; std::unique_ptr base_{nullptr, &event_base_free}; - std::unique_ptr socket_event_{nullptr, &event_free}; - std::unique_ptr signal_event_{nullptr, &event_free}; Channel channel_; + bool running_ = false; + pid_t pid_; + // When forking (no meminfo), the real app is our grandchild. In this case, + // child_checker_ is a CheckerSide to our child that can waitpid our grandchild on our behalf + CheckerSide* child_checker_ = nullptr; + + void setup_events(bool socket_only); // Part of the initialization + void handle_dead_child(int status); // Launched when the dying child is the PID we follow + void handle_waitpid(); // Launched when receiving a sigchild public: - explicit CheckerSide(int sockfd) : channel_(sockfd) {} + explicit CheckerSide(int socket, CheckerSide* child_checker); + explicit CheckerSide(const std::vector& args); + ~CheckerSide(); // No copy: CheckerSide(CheckerSide const&) = delete; CheckerSide& operator=(CheckerSide const&) = delete; CheckerSide& operator=(CheckerSide&&) = delete; + /* Communicating with the application */ Channel const& get_channel() const { return channel_; } Channel& get_channel() { return channel_; } - void start(void (*handler)(int, short, void*), ModelChecker* mc); - void dispatch() const; + bool handle_message(const char* buffer, ssize_t size); + void dispatch_events() const; void break_loop() const; + void wait_for_requests(); + + /* Create a new CheckerSide by forking the currently existing one, and connect it through the master_socket */ + std::unique_ptr clone(int master_socket, const std::string& master_socket_name); + + /** Ask the application to run post-mortem analysis, and maybe to stop ASAP */ + void finalize(bool terminate_asap = false); + + /* Interacting with the application process */ + pid_t get_pid() const { return pid_; } + bool running() const { return running_; } + void terminate() { running_ = false; } }; } // namespace simgrid::mc diff --git a/src/mc/remote/RemoteProcess.cpp b/src/mc/remote/RemoteProcess.cpp deleted file mode 100644 index 654717d3ff..0000000000 --- a/src/mc/remote/RemoteProcess.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#define _FILE_OFFSET_BITS 64 /* needed for pread_whole to work as expected on 32bits */ - -#include "src/mc/remote/RemoteProcess.hpp" - -#include "src/mc/sosp/Snapshot.hpp" -#include "xbt/file.hpp" -#include "xbt/log.h" - -#include -#include -#include // PROT_* - -#include -#include -#include -#include -#include -#include -#include - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information"); - -namespace simgrid::mc { - -// ***** Helper stuff - -static bool is_filtered_lib(std::string_view libname) -{ - return libname != "libsimgrid"; -} - -static std::string get_lib_name(const std::string& pathname) -{ - std::string map_basename = simgrid::xbt::Path(pathname).get_base_name(); - std::string libname; - - if (size_t pos = map_basename.rfind(".so"); pos != std::string::npos) { - // strip the extension (matching regex "\.so.*$") - libname.assign(map_basename, 0, pos); - - // strip the version suffix (matching regex "-[.0-9-]*$") - while (true) { - pos = libname.rfind('-'); - if (pos == std::string::npos || libname.find_first_not_of(".0123456789", pos + 1) != std::string::npos) - break; - libname.erase(pos); - } - } - - return libname; -} - -static ssize_t pread_whole(int fd, void* buf, size_t count, off_t offset) -{ - auto* buffer = static_cast(buf); - ssize_t real_count = count; - while (count) { - ssize_t res = pread(fd, buffer, count, offset); - if (res > 0) { - count -= res; - buffer += res; - offset += res; - } else if (res == 0) - return -1; - else if (errno != EINTR) { - XBT_ERROR("pread_whole: %s", strerror(errno)); - return -1; - } - } - return real_count; -} - -static ssize_t pwrite_whole(int fd, const void* buf, size_t count, off_t offset) -{ - const auto* buffer = static_cast(buf); - ssize_t real_count = count; - while (count) { - ssize_t res = pwrite(fd, buffer, count, offset); - if (res > 0) { - count -= res; - buffer += res; - offset += res; - } else if (res == 0) - return -1; - else if (errno != EINTR) { - XBT_ERROR("pwrite_whole: %s", strerror(errno)); - return -1; - } - } - return real_count; -} - -int open_vm(pid_t pid, int flags) -{ - std::string buffer = "/proc/" + std::to_string(pid) + "/mem"; - return open(buffer.c_str(), flags); -} - -// ***** RemoteProcess - -RemoteProcess::RemoteProcess(pid_t pid) : AddressSpace(this), pid_(pid), running_(true) {} - -void RemoteProcess::init(xbt_mheap_t mmalloc_default_mdp, unsigned long* maxpid, xbt_dynar_t actors) -{ - this->heap_address = remote(mmalloc_default_mdp); - this->maxpid_addr_ = remote(maxpid); - this->actors_addr_ = remote(actors); - - this->memory_map_ = simgrid::xbt::get_memory_map(this->pid_); - this->init_memory_map_info(); - - int fd = open_vm(this->pid_, O_RDWR); - xbt_assert(fd >= 0, "Could not open file for process virtual address space"); - this->memory_file = fd; - - this->smx_actors_infos.clear(); - this->unw_addr_space = simgrid::mc::UnwindContext::createUnwindAddressSpace(); - this->unw_underlying_addr_space = simgrid::unw::create_addr_space(); - this->unw_underlying_context = simgrid::unw::create_context(this->unw_underlying_addr_space, this->pid_); -} - -RemoteProcess::~RemoteProcess() -{ - if (this->memory_file >= 0) - close(this->memory_file); - - if (this->unw_underlying_addr_space != unw_local_addr_space) { - if (this->unw_underlying_addr_space) - unw_destroy_addr_space(this->unw_underlying_addr_space); - if (this->unw_underlying_context) - _UPT_destroy(this->unw_underlying_context); - } - - unw_destroy_addr_space(this->unw_addr_space); -} - -/** Refresh the information about the process - * - * Do not use directly, this is used by the getters when appropriate - * in order to have fresh data. - */ -void RemoteProcess::refresh_heap() -{ - // Read/dereference/refresh the std_heap pointer: - if (not this->heap) - this->heap = std::make_unique(); - this->read(this->heap.get(), this->heap_address); - this->cache_flags_ |= RemoteProcess::cache_heap; -} - -/** Refresh the information about the process - * - * Do not use directly, this is used by the getters when appropriate - * in order to have fresh data. - * */ -void RemoteProcess::refresh_malloc_info() -{ - // Refresh process->heapinfo: - if (this->cache_flags_ & RemoteProcess::cache_malloc) - return; - size_t count = this->heap->heaplimit + 1; - if (this->heap_info.size() < count) - this->heap_info.resize(count); - this->read_bytes(this->heap_info.data(), count * sizeof(malloc_info), remote(this->heap->heapinfo)); - this->cache_flags_ |= RemoteProcess::cache_malloc; -} - -/** @brief Finds the range of the different memory segments and binary paths */ -void RemoteProcess::init_memory_map_info() -{ - XBT_DEBUG("Get debug information ..."); - this->maestro_stack_start_ = nullptr; - this->maestro_stack_end_ = nullptr; - this->object_infos.clear(); - this->binary_info = nullptr; - - std::vector const& maps = this->memory_map_; - - const char* current_name = nullptr; - - for (size_t i = 0; i < maps.size(); i++) { - simgrid::xbt::VmMap const& reg = maps[i]; - const char* pathname = maps[i].pathname.c_str(); - - // Nothing to do - if (maps[i].pathname.empty()) { - current_name = nullptr; - continue; - } - - // [stack], [vvar], [vsyscall], [vdso] ... - if (pathname[0] == '[') { - if ((reg.prot & PROT_WRITE) && not memcmp(pathname, "[stack]", 7)) { - this->maestro_stack_start_ = remote(reg.start_addr); - this->maestro_stack_end_ = remote(reg.end_addr); - } - current_name = nullptr; - continue; - } - - if (current_name && strcmp(current_name, pathname) == 0) - continue; - - current_name = pathname; - if (not(reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)) - continue; - - const bool is_executable = not i; - std::string libname; - if (not is_executable) { - libname = get_lib_name(pathname); - if (is_filtered_lib(libname)) { - continue; - } - } - - std::shared_ptr info = - simgrid::mc::createObjectInformation(this->memory_map_, pathname); - this->object_infos.push_back(info); - if (is_executable) - this->binary_info = info; - } - - xbt_assert(this->maestro_stack_start_, "Did not find maestro_stack_start"); - xbt_assert(this->maestro_stack_end_, "Did not find maestro_stack_end"); - - XBT_DEBUG("Get debug information done !"); -} - -std::shared_ptr RemoteProcess::find_object_info(RemotePtr addr) const -{ - for (auto const& object_info : this->object_infos) - if (addr.address() >= (std::uint64_t)object_info->start && addr.address() <= (std::uint64_t)object_info->end) - return object_info; - return nullptr; -} - -std::shared_ptr RemoteProcess::find_object_info_exec(RemotePtr addr) const -{ - for (std::shared_ptr const& info : this->object_infos) - if (addr.address() >= (std::uint64_t)info->start_exec && addr.address() <= (std::uint64_t)info->end_exec) - return info; - return nullptr; -} - -std::shared_ptr RemoteProcess::find_object_info_rw(RemotePtr addr) const -{ - for (std::shared_ptr const& info : this->object_infos) - if (addr.address() >= (std::uint64_t)info->start_rw && addr.address() <= (std::uint64_t)info->end_rw) - return info; - return nullptr; -} - -simgrid::mc::Frame* RemoteProcess::find_function(RemotePtr ip) const -{ - std::shared_ptr info = this->find_object_info_exec(ip); - return info ? info->find_function((void*)ip.address()) : nullptr; -} - -/** Find (one occurrence of) the named variable definition - */ -const simgrid::mc::Variable* RemoteProcess::find_variable(const char* name) const -{ - // First lookup the variable in the executable shared object. - // A global variable used directly by the executable code from a library - // is reinstantiated in the executable memory .data/.bss. - // We need to look up the variable in the executable first. - if (this->binary_info) { - std::shared_ptr const& info = this->binary_info; - const simgrid::mc::Variable* var = info->find_variable(name); - if (var) - return var; - } - - for (std::shared_ptr const& info : this->object_infos) { - const simgrid::mc::Variable* var = info->find_variable(name); - if (var) - return var; - } - - return nullptr; -} - -void RemoteProcess::read_variable(const char* name, void* target, size_t size) const -{ - const simgrid::mc::Variable* var = this->find_variable(name); - xbt_assert(var, "Variable %s not found", name); - xbt_assert(var->address, "No simple location for this variable"); - - if (not var->type->full_type) // Try to resolve this type. The needed ObjectInfo was maybe (lazily) loaded recently - for (auto const& object_info : this->object_infos) - postProcessObjectInformation(this, object_info.get()); - xbt_assert(var->type->full_type, "Partial type for %s (even after re-resolving types), cannot retrieve its size.", - name); - xbt_assert((size_t)var->type->full_type->byte_size == size, "Unexpected size for %s (expected %zu, received %zu).", - name, size, (size_t)var->type->full_type->byte_size); - this->read_bytes(target, size, remote(var->address)); -} - -std::string RemoteProcess::read_string(RemotePtr address) const -{ - if (not address) - return {}; - - std::vector res(128); - off_t off = 0; - - while (true) { - ssize_t c = pread(this->memory_file, res.data() + off, res.size() - off, (off_t)address.address() + off); - if (c == -1 && errno == EINTR) - continue; - xbt_assert(c > 0, "Could not read string from remote process"); - - if (memchr(res.data() + off, '\0', c)) - return std::string(res.data()); - - off += c; - if (off == (off_t)res.size()) - res.resize(res.size() * 2); - } -} - -void* RemoteProcess::read_bytes(void* buffer, std::size_t size, RemotePtr address, ReadOptions /*options*/) const -{ - xbt_assert(pread_whole(this->memory_file, buffer, size, (size_t)address.address()) != -1, - "Read at %p from process %lli failed", (void*)address.address(), (long long)this->pid_); - return buffer; -} - -/** Write data to a process memory - * - * @param buffer local memory address (source) - * @param len data size - * @param address target process memory address (target) - */ -void RemoteProcess::write_bytes(const void* buffer, size_t len, RemotePtr address) const -{ - xbt_assert(pwrite_whole(this->memory_file, buffer, len, (size_t)address.address()) != -1, - "Write to process %lli failed", (long long)this->pid_); -} - -static void zero_buffer_init(const void** zero_buffer, size_t zero_buffer_size) -{ - int fd = open("/dev/zero", O_RDONLY); - xbt_assert(fd >= 0, "Could not open /dev/zero"); - *zero_buffer = mmap(nullptr, zero_buffer_size, PROT_READ, MAP_SHARED, fd, 0); - xbt_assert(*zero_buffer != MAP_FAILED, "Could not map the zero buffer"); - close(fd); -} - -void RemoteProcess::clear_bytes(RemotePtr address, size_t len) const -{ - static constexpr size_t zero_buffer_size = 10 * 4096; - static const void* zero_buffer; - static std::once_flag zero_buffer_flag; - - std::call_once(zero_buffer_flag, zero_buffer_init, &zero_buffer, zero_buffer_size); - while (len) { - size_t s = len > zero_buffer_size ? zero_buffer_size : len; - this->write_bytes(zero_buffer, s, address); - address = remote((char*)address.address() + s); - len -= s; - } -} - -void RemoteProcess::ignore_region(std::uint64_t addr, std::size_t size) -{ - IgnoredRegion region; - region.addr = addr; - region.size = size; - - auto pos = std::lower_bound(ignored_regions_.begin(), ignored_regions_.end(), region, - [](auto const& reg1, auto const& reg2) { - return reg1.addr < reg2.addr || (reg1.addr == reg2.addr && reg1.size < reg2.size); - }); - if (pos == ignored_regions_.end() || pos->addr != addr || pos->size != size) - ignored_regions_.insert(pos, region); -} - -void RemoteProcess::ignore_heap(IgnoredHeapRegion const& region) -{ - // Binary search the position of insertion: - auto pos = std::lower_bound(ignored_heap_.begin(), ignored_heap_.end(), region.address, - [](auto const& reg, auto const* addr) { return reg.address < addr; }); - if (pos == ignored_heap_.end() || pos->address != region.address) { - // Insert it: - ignored_heap_.insert(pos, region); - } -} - -void RemoteProcess::unignore_heap(void* address, size_t size) -{ - // Binary search: - auto pos = std::lower_bound(ignored_heap_.begin(), ignored_heap_.end(), address, - [](auto const& reg, auto const* addr) { return reg.address < addr; }); - if (pos != ignored_heap_.end() && static_cast(pos->address) <= static_cast(address) + size) - ignored_heap_.erase(pos); -} - -void RemoteProcess::ignore_local_variable(const char* var_name, const char* frame_name) const -{ - if (frame_name != nullptr && strcmp(frame_name, "*") == 0) - frame_name = nullptr; - for (std::shared_ptr const& info : this->object_infos) - info->remove_local_variable(var_name, frame_name); -} - -std::vector& RemoteProcess::actors() -{ - this->refresh_simix(); - return smx_actors_infos; -} - -void RemoteProcess::dump_stack() const -{ - unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, BYTE_ORDER); - if (as == nullptr) { - XBT_ERROR("Could not initialize ptrace address space"); - return; - } - - void* context = _UPT_create(this->pid_); - if (context == nullptr) { - unw_destroy_addr_space(as); - XBT_ERROR("Could not initialize ptrace context"); - return; - } - - unw_cursor_t cursor; - if (unw_init_remote(&cursor, as, context) != 0) { - _UPT_destroy(context); - unw_destroy_addr_space(as); - XBT_ERROR("Could not initialize ptrace cursor"); - return; - } - - simgrid::mc::dumpStack(stderr, &cursor); - - _UPT_destroy(context); - unw_destroy_addr_space(as); -} -} // namespace simgrid::mc diff --git a/src/mc/remote/RemoteProcess.hpp b/src/mc/remote/RemoteProcess.hpp deleted file mode 100644 index 47f6151fb0..0000000000 --- a/src/mc/remote/RemoteProcess.hpp +++ /dev/null @@ -1,257 +0,0 @@ -/* mc::RemoteClient: representative of the Client memory on the MC side */ - -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_PROCESS_H -#define SIMGRID_MC_PROCESS_H - -#include "mc/datatypes.h" -#include "src/mc/AddressSpace.hpp" -#include "src/mc/inspect/ObjectInformation.hpp" -#include "src/mc/remote/RemotePtr.hpp" -#include "src/xbt/memory_map.hpp" -#include "src/xbt/mmalloc/mmprivate.h" - -#include -#include - -namespace simgrid::mc { - -class ActorInformation { -public: - /** MCed address of the process */ - RemotePtr address{nullptr}; - Remote copy; - - /** Hostname (owned by `mc_model_checker->hostnames_`) */ - const xbt::string* hostname = nullptr; - xbt::string name; - - void clear() - { - name.clear(); - address = nullptr; - hostname = nullptr; - } -}; - -struct IgnoredRegion { - std::uint64_t addr; - std::size_t size; -}; - -struct IgnoredHeapRegion { - int block; - int fragment; - void* address; - std::size_t size; -}; - -/** The Application's process memory, seen from the MCer perspective - * - * This class is mixing a lot of different responsibilities and is tied - * to SIMIX. It should probably be split into different classes. - * - * Responsibilities: - * - * - reading from the process memory (`AddressSpace`); - * - accessing the system state of the process (heap, …); - * - storing the SIMIX state of the process; - * - privatization; - * - stack unwinding; - * - etc. - */ -class RemoteProcess final : public AddressSpace { -private: - // Those flags are used to track down which cached information - // is still up to date and which information needs to be updated. - static constexpr int cache_none = 0; - static constexpr int cache_heap = 1; - static constexpr int cache_malloc = 2; - static constexpr int cache_simix_processes = 4; - -public: - explicit RemoteProcess(pid_t pid); - ~RemoteProcess() override; - void init(xbt_mheap_t mmalloc_default_mdp, unsigned long* maxpid, xbt_dynar_t actors); - - RemoteProcess(RemoteProcess const&) = delete; - RemoteProcess(RemoteProcess&&) = delete; - RemoteProcess& operator=(RemoteProcess const&) = delete; - RemoteProcess& operator=(RemoteProcess&&) = delete; - - /* ************* */ - /* Low-level API */ - /* ************* */ - - // Read memory: - void* read_bytes(void* buffer, std::size_t size, RemotePtr address, - ReadOptions options = ReadOptions::none()) const override; - - void read_variable(const char* name, void* target, size_t size) const; - template void read_variable(const char* name, T* target) const - { - read_variable(name, target, sizeof(*target)); - } - template Remote read_variable(const char* name) const - { - Remote res; - read_variable(name, res.get_buffer(), sizeof(T)); - return res; - } - - std::string read_string(RemotePtr address) const; - using AddressSpace::read_string; - - // Write memory: - void write_bytes(const void* buffer, size_t len, RemotePtr address) const; - void clear_bytes(RemotePtr address, size_t len) const; - - // Debug information: - std::shared_ptr find_object_info(RemotePtr addr) const; - std::shared_ptr find_object_info_exec(RemotePtr addr) const; - std::shared_ptr find_object_info_rw(RemotePtr addr) const; - Frame* find_function(RemotePtr ip) const; - const Variable* find_variable(const char* name) const; - - // Heap access: - xbt_mheap_t get_heap() - { - if (not(this->cache_flags_ & RemoteProcess::cache_heap)) - this->refresh_heap(); - return this->heap.get(); - } - const malloc_info* get_malloc_info() - { - if (not(this->cache_flags_ & RemoteProcess::cache_malloc)) - this->refresh_malloc_info(); - return this->heap_info.data(); - } - - void clear_cache() { this->cache_flags_ = RemoteProcess::cache_none; } - - std::vector const& ignored_regions() const { return ignored_regions_; } - void ignore_region(std::uint64_t address, std::size_t size); - - pid_t pid() const { return pid_; } - - bool in_maestro_stack(RemotePtr p) const - { - return p >= this->maestro_stack_start_ && p < this->maestro_stack_end_; - } - - bool running() const { return running_; } - - void terminate() { running_ = false; } - - void ignore_global_variable(const char* name) const - { - for (std::shared_ptr const& info : this->object_infos) - info->remove_global_variable(name); - } - - std::vector& stack_areas() { return stack_areas_; } - std::vector const& stack_areas() const { return stack_areas_; } - - std::vector const& ignored_heap() const { return ignored_heap_; } - void ignore_heap(IgnoredHeapRegion const& region); - void unignore_heap(void* address, size_t size); - - void ignore_local_variable(const char* var_name, const char* frame_name) const; - - /* ***************** */ - /* SIMIX-related API */ - /* ***************** */ -private: - // Cache the address of the variables we read directly in the memory of remote - RemotePtr maxpid_addr_; - RemotePtr actors_addr_; - -public: - std::vector& actors(); - - unsigned long get_maxpid() const { return this->read(maxpid_addr_); } - - void dump_stack() const; - -private: - void init_memory_map_info(); - void refresh_heap(); - void refresh_malloc_info(); - void refresh_simix(); - - pid_t pid_ = -1; - bool running_ = false; - std::vector memory_map_; - RemotePtr maestro_stack_start_; - RemotePtr maestro_stack_end_; - int memory_file = -1; - std::vector ignored_regions_; - std::vector stack_areas_; - std::vector ignored_heap_; - - // Copies of MCed SMX data structures - /** Copy of `EngineImpl::actor_list_` - * - * See mc_smx.cpp. - */ - std::vector smx_actors_infos; - - /** State of the cache (which variables are up to date) */ - int cache_flags_ = RemoteProcess::cache_none; - -public: - // object info - // TODO, make private (first, objectify simgrid::mc::ObjectInformation*) - std::vector> object_infos; - std::shared_ptr binary_info; - - /** Address of the heap structure in the MCed process. */ - RemotePtr heap_address; - - /** Copy of the heap structure of the process - * - * This is refreshed with the `MC_process_refresh` call. - * This is not used if the process is the current one: - * use `get_heap_info()` in order to use it. - */ - std::unique_ptr heap; - - /** Copy of the allocation info structure - * - * This is refreshed with the `MC_process_refresh` call. - * This is not used if the process is the current one: - * use `get_malloc_info()` in order to use it. - */ - std::vector heap_info; - - // Libunwind-data - /** Full-featured MC-aware libunwind address space for the process - * - * This address space is using a simgrid::mc::UnwindContext* - * (with simgrid::mc::Process* / simgrid::mc::AddressSpace* - * and unw_context_t). - */ - unw_addr_space_t unw_addr_space = nullptr; - - /** Underlying libunwind address-space - * - * The `find_proc_info`, `put_unwind_info`, `get_dyn_info_list_addr` - * operations of the native MC address space is currently delegated - * to this address space (either the local or a ptrace unwinder). - */ - unw_addr_space_t unw_underlying_addr_space = nullptr; - - /** The corresponding context - */ - void* unw_underlying_context = nullptr; -}; - -/** Open a FD to a remote process memory (`/dev/$pid/mem`) */ -XBT_PRIVATE int open_vm(pid_t pid, int flags); -} // namespace simgrid::mc - -#endif diff --git a/src/mc/remote/RemotePtr.hpp b/src/mc/remote/RemotePtr.hpp index b8dc09a9d2..16efc9354b 100644 --- a/src/mc/remote/RemotePtr.hpp +++ b/src/mc/remote/RemotePtr.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -37,7 +37,7 @@ public: std::size_t get_buffer_size() const { return sizeof(T); } operator T() const { - static_assert(std::is_trivial::value, "Cannot convert non trivial type"); + static_assert(std::is_trivial_v, "Cannot convert non trivial type"); return *get_buffer(); } void clear() { std::memset(&buffer, 0, sizeof buffer); } diff --git a/src/mc/remote/mc_protocol.h b/src/mc/remote/mc_protocol.h index e83a281459..0c41b275ea 100644 --- a/src/mc/remote/mc_protocol.h +++ b/src/mc/remote/mc_protocol.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,39 +8,34 @@ // ***** Environment variables for passing context to the model-checked process -/** Environment variable name used to pass the communication socket. - * - * It is set by `simgrid-mc` to enable MC support in the children processes - */ -#define MC_ENV_SOCKET_FD "SIMGRID_MC_SOCKET_FD" - #ifdef __cplusplus #include "src/kernel/actor/SimcallObserver.hpp" -#include "mc/datatypes.h" #include "simgrid/forward.h" // aid_t +#include "src/mc/datatypes.h" +#include + #include #include -#include -#include -#include +#include // ***** Messages namespace simgrid::mc { -XBT_DECLARE_ENUM_CLASS(MessageType, NONE, INITIAL_ADDRESSES, CONTINUE, IGNORE_HEAP, UNIGNORE_HEAP, IGNORE_MEMORY, - STACK_REGION, REGISTER_SYMBOL, DEADLOCK_CHECK, DEADLOCK_CHECK_REPLY, WAITING, SIMCALL_EXECUTE, - SIMCALL_EXECUTE_ANSWER, ASSERTION_FAILED, ACTOR_ENABLED, ACTOR_ENABLED_REPLY, FINALIZE); - +XBT_DECLARE_ENUM_CLASS(MessageType, NONE, FORK, FORK_REPLY, WAIT_CHILD, WAIT_CHILD_REPLY, CONTINUE, DEADLOCK_CHECK, + DEADLOCK_CHECK_REPLY, WAITING, SIMCALL_EXECUTE, SIMCALL_EXECUTE_REPLY, ASSERTION_FAILED, + ACTORS_STATUS, ACTORS_STATUS_REPLY_COUNT, ACTORS_STATUS_REPLY_SIMCALL, + ACTORS_STATUS_REPLY_TRANSITION, ACTORS_MAXPID, ACTORS_MAXPID_REPLY, FINALIZE, FINALIZE_REPLY); } // namespace simgrid::mc -constexpr unsigned MC_MESSAGE_LENGTH = 512; +constexpr unsigned MC_MESSAGE_LENGTH = 512; +constexpr unsigned MC_SOCKET_NAME_LEN = sizeof(sockaddr_un::sun_path); constexpr unsigned SIMCALL_SERIALIZATION_BUFFER_SIZE = 2048; /** Basic structure for a MC message * - * The current version of the client/server protocol sends C structures over `AF_LOCAL` + * The current version of the client/server protocol sends C structures over `AF_UNIX` * `SOCK_SEQPACKET` sockets. This means that the protocol is ABI/architecture specific: * we currently can't model-check a x86 process from a x86_64 process. * @@ -59,40 +54,13 @@ struct s_mc_message_int_t { }; /* Client->Server */ -struct s_mc_message_initial_addresses_t { - simgrid::mc::MessageType type; - xbt_mheap_t mmalloc_default_mdp; - unsigned long* maxpid; - xbt_dynar_t actors; -}; - -struct s_mc_message_ignore_heap_t { - simgrid::mc::MessageType type; - int block; - int fragment; - void* address; - size_t size; -}; - -struct s_mc_message_ignore_memory_t { - simgrid::mc::MessageType type; - uint64_t addr; - size_t size; -}; -struct s_mc_message_stack_region_t { - simgrid::mc::MessageType type; - s_stack_region_t stack_region; -}; - -struct s_mc_message_register_symbol_t { +/* Server -> client */ +struct s_mc_message_fork_t { simgrid::mc::MessageType type; - std::array name; - int (*callback)(void*); - void* data; + std::array socket_name; }; -/* Server -> client */ struct s_mc_message_simcall_execute_t { simgrid::mc::MessageType type; aid_t aid_; @@ -108,9 +76,23 @@ struct s_mc_message_restore_t { int index; }; -struct s_mc_message_actor_enabled_t { +struct s_mc_message_actors_status_answer_t { simgrid::mc::MessageType type; - aid_t aid; // actor ID + int count; +}; +struct s_mc_message_actors_status_one_t { // an array of `s_mc_message_actors_status_one_t[count]` is sent right after + // after a `s_mc_message_actors_status_answer_t` + simgrid::mc::MessageType type; + aid_t aid; + bool enabled; + int max_considered; +}; + +// Answer from an actor to the question "what are you about to run?" +struct s_mc_message_simcall_probe_one_t { // a series of `s_mc_message_simcall_probe_one_t` + // is sent right after `s_mc_message_actors_status_one_t[]` + simgrid::mc::MessageType type; + std::array buffer; }; #endif // __cplusplus diff --git a/src/mc/sosp/ChunkedData.cpp b/src/mc/sosp/ChunkedData.cpp deleted file mode 100644 index b3c0cb83cc..0000000000 --- a/src/mc/sosp/ChunkedData.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/AddressSpace.hpp" -#include "src/mc/sosp/ChunkedData.hpp" - -namespace simgrid::mc { - -/** Take a per-page snapshot of a region - * - * @param addr The start of the region (must be at the beginning of a page) - * @param page_count Number of pages of the region - * @return Snapshot page numbers of this new snapshot - */ -ChunkedData::ChunkedData(PageStore& store, const AddressSpace& as, RemotePtr addr, std::size_t page_count) - : store_(&store) -{ - this->pagenos_.resize(page_count); - std::vector buffer(xbt_pagesize); - - for (size_t i = 0; i != page_count; ++i) { - RemotePtr page = remote((void*)simgrid::mc::mmu::join(i, addr.address())); - xbt_assert(simgrid::mc::mmu::split(page.address()).second == 0, "Not at the beginning of a page"); - - /* Adding another copy (and a syscall) will probably slow things a lot. - TODO, optimize this somehow (at least by grouping the syscalls) - if needed. Either: - - reduce the number of syscalls - - let the application snapshot itself - - move the segments in shared memory (this will break `fork` however) - */ - - as.read_bytes(buffer.data(), xbt_pagesize, page); - - pagenos_[i] = store_->store_page(buffer.data()); - } -} - -} // namespace simgrid::mc diff --git a/src/mc/sosp/ChunkedData.hpp b/src/mc/sosp/ChunkedData.hpp deleted file mode 100644 index 449873f6cc..0000000000 --- a/src/mc/sosp/ChunkedData.hpp +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_CHUNKED_DATA_HPP -#define SIMGRID_MC_CHUNKED_DATA_HPP - -#include - -#include "src/mc/mc_forward.hpp" -#include "src/mc/remote/RemotePtr.hpp" -#include "src/mc/sosp/PageStore.hpp" - -namespace simgrid::mc { - -/** A byte-string represented as a sequence of chunks from a PageStore - * - * In order to save memory when taking memory snapshots, a given byte-string - * is split in fixed-size chunks. Identical chunks (either from the same - * snapshot or more probably from different snapshots) share the same memory - * storage. - * - * Thus a chunked is represented as a sequence of indices of each chunk. - */ -class ChunkedData { - /** This is where we store the chunks */ - PageStore* store_ = nullptr; - /** Indices of the chunks in the `PageStore` */ - std::vector pagenos_; - -public: - ChunkedData() = default; - void clear() - { - for (std::size_t const& pageno : pagenos_) - store_->unref_page(pageno); - pagenos_.clear(); - } - ~ChunkedData() { clear(); } - - // Copy and move - ChunkedData(ChunkedData const& that) : store_(that.store_), pagenos_(that.pagenos_) - { - for (std::size_t const& pageno : pagenos_) - store_->ref_page(pageno); - } - ChunkedData(ChunkedData&& that) noexcept : pagenos_(std::move(that.pagenos_)) - { - std::swap(store_, that.store_); - that.pagenos_.clear(); - } - ChunkedData& operator=(ChunkedData const& that) - { - if (this != &that) { - this->clear(); - store_ = that.store_; - pagenos_ = that.pagenos_; - for (std::size_t const& pageno : pagenos_) - store_->ref_page(pageno); - } - return *this; - } - ChunkedData& operator=(ChunkedData&& that) noexcept - { - if (this != &that) { - this->clear(); - store_ = that.store_; - that.store_ = nullptr; - pagenos_ = std::move(that.pagenos_); - that.pagenos_.clear(); - } - return *this; - } - - /** How many pages are used */ - std::size_t page_count() const { return pagenos_.size(); } - - /** Get a chunk index */ - std::size_t pageno(std::size_t i) const { return pagenos_[i]; } - - /** Get a view of the chunk indices */ - const std::size_t* pagenos() const { return pagenos_.data(); } - - /** Get a pointer to a chunk */ - void* page(std::size_t i) const { return store_->get_page(pagenos_[i]); } - - ChunkedData(PageStore& store, const AddressSpace& as, RemotePtr addr, std::size_t page_count); -}; - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/sosp/PageStore.cpp b/src/mc/sosp/PageStore.cpp deleted file mode 100644 index 5944652646..0000000000 --- a/src/mc/sosp/PageStore.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#ifdef __FreeBSD__ -#define MAP_POPULATE MAP_PREFAULT_READ -#endif - -#include "src/internal_config.h" -#include "xbt/log.h" -#include "xbt/sysdep.h" - -#include "src/include/xxhash.hpp" -#include "src/mc/mc_mmu.hpp" -#include "src/mc/sosp/PageStore.hpp" - -#include // memcpy, memcmp -#include - -namespace simgrid::mc { - -/** @brief Compute a hash for the given memory page - * - * The page is used before inserting the page in the page store in order to find duplicate of this page in the page - * store. - * - * @param data Memory page - * @return hash off the page - */ -static XBT_ALWAYS_INLINE PageStore::hash_type mc_hash_page(const void* data) -{ - return xxh::xxhash<64>(data, xbt_pagesize); -} - -// ***** snapshot_page_manager - -PageStore::PageStore(std::size_t size) : capacity_(size) -{ - // Using mmap in order to be able to expand the region by relocating it somewhere else in the virtual memory space: - void* memory = - ::mmap(nullptr, size << xbt_pagebits, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); - xbt_assert(memory != MAP_FAILED, "Could not mmap initial snapshot pages."); - - this->top_index_ = 0; - this->memory_ = memory; - this->page_counts_.resize(size); -} - -PageStore::~PageStore() -{ - ::munmap(this->memory_, this->capacity_ << xbt_pagebits); -} - -void PageStore::resize(std::size_t size) -{ - size_t old_bytesize = this->capacity_ << xbt_pagebits; - size_t new_bytesize = size << xbt_pagebits; - void* new_memory; - - // Expand the memory region by moving it into another - // virtual memory address if necessary: -#if HAVE_MREMAP - new_memory = mremap(this->memory_, old_bytesize, new_bytesize, MREMAP_MAYMOVE); - xbt_assert(new_memory != MAP_FAILED, "Could not mremap snapshot pages."); -#else - if (new_bytesize > old_bytesize) { - // Grow: first try to add new space after current map - new_memory = mmap((char*)this->memory_ + old_bytesize, new_bytesize - old_bytesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); - xbt_assert(new_memory != MAP_FAILED, "Could not mremap snapshot pages."); - // Check if expanding worked - if (new_memory != (char*)this->memory_ + old_bytesize) { - // New memory segment could not be put at the end of this->memory_, - // so cancel this one and try to relocate everything and copy data - munmap(new_memory, new_bytesize - old_bytesize); - new_memory = - mmap(nullptr, new_bytesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); - xbt_assert(new_memory != MAP_FAILED, "Could not mremap snapshot pages."); - memcpy(new_memory, this->memory_, old_bytesize); - munmap(this->memory_, old_bytesize); - } - } else { - // We don't have functions to shrink a mapping, so leave memory as - // it is for now - new_memory = this->memory_; - } -#endif - - this->capacity_ = size; - this->memory_ = new_memory; - this->page_counts_.resize(size, 0); -} - -/** Allocate a free page - * - * @return index of the free page - */ -std::size_t PageStore::alloc_page() -{ - if (this->free_pages_.empty()) { - // Expand the region: - if (this->top_index_ == this->capacity_) - // All the pages are allocated, we need add more pages: - this->resize(2 * this->capacity_); - - // Use a page from the top: - return this->top_index_++; - } else { - // Use a page from free_pages_ (inside of the region): - size_t res = this->free_pages_[this->free_pages_.size() - 1]; - this->free_pages_.pop_back(); - return res; - } -} - -void PageStore::remove_page(std::size_t pageno) -{ - this->free_pages_.push_back(pageno); - const void* page = this->get_page(pageno); - hash_type hash = mc_hash_page(page); - this->hash_index_[hash].erase(pageno); -} - -/** Store a page in memory */ -std::size_t PageStore::store_page(const void* page) -{ - xbt_assert(top_index_ <= this->capacity_, "top_index is not consistent"); - - // First, we check if a page with the same content is already in the page store: - // 1. compute the hash of the page - // 2. find pages with the same hash using `hash_index_` - // 3. find a page with the same content - hash_type hash = mc_hash_page(page); - - // Try to find a duplicate in set of pages with the same hash: - page_set_type& page_set = this->hash_index_[hash]; - for (size_t const& pageno : page_set) { - const void* snapshot_page = this->get_page(pageno); - if (memcmp(page, snapshot_page, xbt_pagesize) == 0) { - // If a page with the same content is already in the page store it's reused and its refcount is incremented. - page_counts_[pageno]++; - return pageno; - } - } - - // Otherwise, a new page is allocated in the page store and the content of the page is `memcpy()`-ed to this new page. - std::size_t pageno = alloc_page(); - xbt_assert(this->page_counts_[pageno] == 0, "Allocated page is already used"); - void* snapshot_page = this->get_page(pageno); - memcpy(snapshot_page, page, xbt_pagesize); - page_set.insert(pageno); - page_counts_[pageno]++; - return pageno; -} - -} // namespace simgrid::mc diff --git a/src/mc/sosp/PageStore.hpp b/src/mc/sosp/PageStore.hpp deleted file mode 100644 index 6079621601..0000000000 --- a/src/mc/sosp/PageStore.hpp +++ /dev/null @@ -1,193 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_PAGESTORE_HPP -#define SIMGRID_MC_PAGESTORE_HPP - -#include "src/mc/mc_forward.hpp" -#include "src/mc/mc_mmu.hpp" - -#include -#include -#include - -#ifndef XBT_ALWAYS_INLINE -#define XBT_ALWAYS_INLINE inline __attribute__((always_inline)) -#endif - -namespace simgrid::mc { - -/** @brief Storage for snapshot memory pages - * - * The first (lower) layer of the per-page snapshot mechanism is a page store: - * its responsibility is to store immutable shareable reference-counted memory - * pages independently of the snapshotting logic. Snapshot management and - * representation is handled to an higher layer. READMORE - * - * Data structure: - * - * * A pointer (`memory_`) to a (currently anonymous) `mmap()`ed memory - * region holding the memory pages (the address of the first page). - * - * We want to keep this memory region aligned on the memory pages (so - * that we might be able to create non-linear memory mappings on those - * pages in the future) and be able to expand it without copying the - * data (there will be a lot of pages here): we will be able to - * efficiently expand the memory mapping using `mremap()`, moving it - * to another virtual address if necessary. - * - * Because we will move this memory mapping on the virtual address - * space, only the index of the page will be stored in the snapshots - * and the page will always be looked up by going through `memory`: - * - * void* page = (char*) page_store->memory + page_index << pagebits; - * - * * The number of pages mapped in virtual memory (`capacity_`). Once all - * those pages are used, we need to expand the page store with - * `mremap()`. - * - * * A reference count for each memory page `page_counts_`. Each time a - * snapshot references a page, the counter is incremented. If a - * snapshot is freed, the reference count is decremented. When the - * reference count, of a page reaches 0 it is added to a list of available - * pages (`free_pages_`). - * - * * A list of free pages `free_pages_` which can be reused. This avoids having - * to scan the reference count list to find a free page. - * - * * When we are expanding the memory map we do not want to add thousand of page - * to the `free_pages_` list and remove them just afterwards. The `top_index_` - * field is an index after which all pages are free and are not in the `free_pages_` - * list. - * - * * When we are adding a page, we need to check if a page with the same - * content is already in the page store in order to reuse it. For this - * reason, we maintain an index (`hash_index_`) mapping the hash of a - * page to the list of page indices with this hash. - * We use a fast (non cryptographic) hash so there may be conflicts: - * we must be able to store multiple indices for the same hash. - * - */ -class PageStore { -public: // Types - using hash_type = std::uint64_t; - -private: - // Types - // We are using a cheap hash to index a page. - // We should expect collision and we need to associate multiple page indices - // to the same hash. - using page_set_type = std::unordered_set; - using pages_map_type = std::unordered_map; - - // Fields: - /** First page */ - void* memory_; - /** Number of available pages in virtual memory */ - std::size_t capacity_; - /** Top of the used pages (index of the next available page) */ - std::size_t top_index_; - /** Page reference count */ - std::vector page_counts_; - /** Index of available pages before the top */ - std::vector free_pages_; - /** Index from page hash to page index */ - pages_map_type hash_index_; - - // Methods - void resize(std::size_t size); - std::size_t alloc_page(); - void remove_page(std::size_t pageno); - -public: - // Constructors - PageStore(PageStore const&) = delete; - PageStore& operator=(PageStore const&) = delete; - explicit PageStore(std::size_t size); - ~PageStore(); - - // Methods - - /** @brief Decrement the reference count for a given page - * - * Decrement the reference count of this page. Used when a snapshot is destroyed. - * - * If the reference count reaches zero, the page is recycled: - * it is added to the `free_pages_` list and removed from the `hash_index_`. - * - * */ - void unref_page(std::size_t pageno); - - /** @brief Increment the refcount for a given page - * - * This method used to increase a reference count of a page if we know - * that the content of a page is the same as a page already in the page - * store. - * - * This will be the case if a page if soft clean: we know that is has not - * changed since the previous snapshot/restoration and we can avoid - * hashing the page, comparing byte-per-byte to candidates. - * */ - void ref_page(size_t pageno); - - /** @brief Store a page in the page store */ - std::size_t store_page(const void* page); - - /** @brief Get a page from its page number - * - * @param pageno Number of the memory page in the store - * @return Start of the page - */ - void* get_page(std::size_t pageno) const; - - // Debug/test methods - - /** @brief Get the number of references for a page */ - std::size_t get_ref(std::size_t pageno) const; - - /** @brief Get the number of used pages */ - std::size_t size() const; - - /** @brief Get the capacity of the page store - * - * The capacity is expanded by a system call (mremap). - * */ - std::size_t capacity() const; -}; - -XBT_ALWAYS_INLINE void PageStore::unref_page(std::size_t pageno) -{ - if ((--this->page_counts_[pageno]) == 0) - this->remove_page(pageno); -} - -XBT_ALWAYS_INLINE void PageStore::ref_page(size_t pageno) -{ - ++this->page_counts_[pageno]; -} - -XBT_ALWAYS_INLINE void* PageStore::get_page(std::size_t pageno) const -{ - return (void*)simgrid::mc::mmu::join(pageno, (std::uintptr_t)this->memory_); -} - -XBT_ALWAYS_INLINE std::size_t PageStore::get_ref(std::size_t pageno) const -{ - return this->page_counts_[pageno]; -} - -XBT_ALWAYS_INLINE std::size_t PageStore::size() const -{ - return this->top_index_ - this->free_pages_.size(); -} - -XBT_ALWAYS_INLINE std::size_t PageStore::capacity() const -{ - return this->capacity_; -} - -} // namespace simgrid::mc - -#endif diff --git a/src/mc/sosp/PageStore_test.cpp b/src/mc/sosp/PageStore_test.cpp deleted file mode 100644 index 726a04c9f8..0000000000 --- a/src/mc/sosp/PageStore_test.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/include/catch.hpp" - -#include -#include -#include -#include - -#include -#include - -#include - -#include "src/mc/sosp/PageStore.hpp" - -using simgrid::mc::PageStore; - -/***********************************/ -// a class to hold the variable used in the test cases -class helper_tests { -public: - static std::size_t pagesize; - static std::unique_ptr store; - static void* data; - static std::array pageno; - static int value; - - // member functions used by the test suite(s) - static void Init(); - static void store_page_once(); - static void store_same_page(); - static void store_new_page(); - static void unref_pages(); - static void reallocate_page(); - - static void new_content(void* buf, std::size_t size); -}; - -// static member data initialization -std::size_t helper_tests::pagesize = 0; -std::unique_ptr helper_tests::store = nullptr; -void* helper_tests::data = nullptr; -std::array helper_tests::pageno = {{0, 0, 0, 0}}; -int helper_tests::value = 0; - -void helper_tests::Init() -{ - pagesize = (size_t)getpagesize(); - store = std::make_unique(50); - data = mmap(nullptr, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - REQUIRE(store->size() == 0); -} - -void helper_tests::store_page_once() -{ - new_content(data, pagesize); - pageno[0] = store->store_page(data); - REQUIRE(store->get_ref(pageno[0]) == 1); - const void* copy = store->get_page(pageno[0]); - REQUIRE(::memcmp(data, copy, pagesize) == 0); // The page data should be the same - REQUIRE(store->size() == 1); -} - -void helper_tests::store_same_page() -{ - pageno[1] = store->store_page(data); - REQUIRE(pageno[0] == pageno[1]); // Page should be the same - REQUIRE(store->get_ref(pageno[0]) == 2); - REQUIRE(store->size() == 1); -} - -void helper_tests::store_new_page() -{ - new_content(data, pagesize); - pageno[2] = store->store_page(data); - REQUIRE(pageno[0] != pageno[2]); // The new page should be different - REQUIRE(store->size() == 2); -} - -void helper_tests::unref_pages() -{ - store->unref_page(pageno[0]); - REQUIRE(store->get_ref(pageno[0]) == 1); - REQUIRE(store->size() == 2); - - store->unref_page(pageno[1]); - REQUIRE(store->size() == 1); -} - -void helper_tests::reallocate_page() -{ - new_content(data, pagesize); - pageno[3] = store->store_page(data); - REQUIRE(pageno[0] == pageno[3]); // The old page should be reused - REQUIRE(store->get_ref(pageno[3]) == 1); - REQUIRE(store->size() == 2); -} - -void helper_tests::new_content(void* buf, std::size_t size) -{ - value++; - ::memset(buf, value, size); -} - -TEST_CASE("MC page store, used during checkpoint", "MC::PageStore") -{ - helper_tests::Init(); - INFO("Store page once"); - helper_tests::store_page_once(); - - INFO("Store the same page"); - helper_tests::store_same_page(); - - INFO("Store a new page"); - helper_tests::store_new_page(); - - INFO("Unref pages"); - helper_tests::unref_pages(); - - INFO("Reallocate pages"); - helper_tests::reallocate_page(); -} diff --git a/src/mc/sosp/Region.cpp b/src/mc/sosp/Region.cpp deleted file mode 100644 index c11f7810f3..0000000000 --- a/src/mc/sosp/Region.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/sosp/Region.hpp" -#include "src/mc/ModelChecker.hpp" -#include "src/mc/mc_config.hpp" -#include "src/mc/mc_forward.hpp" -#include "src/mc/remote/RemoteProcess.hpp" - -#include -#include -#ifdef __FreeBSD__ -#define MAP_POPULATE MAP_PREFAULT_READ -#endif - -namespace simgrid::mc { - -Region::Region(RegionType region_type, void* start_addr, size_t size) - : region_type_(region_type), start_addr_(start_addr), size_(size) -{ - xbt_assert((((uintptr_t)start_addr) & (xbt_pagesize - 1)) == 0, "Start address not at the beginning of a page"); - - chunks_ = ChunkedData(mc_model_checker->page_store(), mc_model_checker->get_remote_process(), - RemotePtr(start_addr), mmu::chunk_count(size)); -} - -/** @brief Restore a region from a snapshot - * - * @param region Target region - */ -void Region::restore() const -{ - xbt_assert(((start().address()) & (xbt_pagesize - 1)) == 0, "Not at the beginning of a page"); - xbt_assert(simgrid::mc::mmu::chunk_count(size()) == get_chunks().page_count()); - - for (size_t i = 0; i != get_chunks().page_count(); ++i) { - auto* target_page = (void*)simgrid::mc::mmu::join(i, (std::uintptr_t)(void*)start().address()); - const void* source_page = get_chunks().page(i); - mc_model_checker->get_remote_process().write_bytes(source_page, xbt_pagesize, remote(target_page)); - } -} - -static XBT_ALWAYS_INLINE void* mc_translate_address_region(uintptr_t addr, const simgrid::mc::Region* region) -{ - auto [pageno, offset] = simgrid::mc::mmu::split(addr - region->start().address()); - void* snapshot_page = region->get_chunks().page(pageno); - return (char*)snapshot_page + offset; -} - -void* Region::read(void* target, const void* addr, std::size_t size) const -{ - xbt_assert(contain(simgrid::mc::remote(addr)), "Trying to read out of the region boundary."); - - // Last byte of the region: - const void* end_addr = (const char*)addr + size - 1; - if (simgrid::mc::mmu::same_chunk((std::uintptr_t)addr, (std::uintptr_t)end_addr)) { - // The memory is contained in a single page: - return mc_translate_address_region((uintptr_t)addr, this); - } - // Otherwise, the memory spans several pages. Let's copy it all into the provided buffer - xbt_assert(target != nullptr, "Missing destination buffer for fragmented memory access"); - - // TODO, we assume the chunks are aligned to natural chunk boundaries. - // We should remove this assumption. - - // Page of the last byte of the memory area: - size_t page_end = simgrid::mc::mmu::split((std::uintptr_t)end_addr).first; - - void* dest = target; // iterator in the buffer to where we should copy next - - // Read each page: - while (simgrid::mc::mmu::split((std::uintptr_t)addr).first != page_end) { - const void* snapshot_addr = mc_translate_address_region((uintptr_t)addr, this); - auto* next_page = (void*)simgrid::mc::mmu::join(simgrid::mc::mmu::split((std::uintptr_t)addr).first + 1, 0); - size_t readable = (char*)next_page - (const char*)addr; - memcpy(dest, snapshot_addr, readable); - addr = (const char*)addr + readable; - dest = (char*)dest + readable; - size -= readable; - } - - // Read the end: - const void* snapshot_addr = mc_translate_address_region((uintptr_t)addr, this); - memcpy(dest, snapshot_addr, size); - - return target; -} - -} // namespace simgrid::mc - -/** Compare memory between snapshots (with known regions) - * - * @param addr1 Address in the first snapshot - * @param region1 Region of the address in the first snapshot - * @param addr2 Address in the second snapshot - * @param region2 Region of the address in the second snapshot - * @return same semantic as memcmp - */ -int MC_snapshot_region_memcmp(const void* addr1, const simgrid::mc::Region* region1, const void* addr2, - const simgrid::mc::Region* region2, size_t size) -{ - // Using alloca() for large allocations may trigger stack overflow: - // use malloc if the buffer is too big. - bool stack_alloc = size < 64; - void* buffer1a = stack_alloc ? alloca(size) : ::operator new(size); - void* buffer2a = stack_alloc ? alloca(size) : ::operator new(size); - const void* buffer1 = region1->read(buffer1a, addr1, size); - const void* buffer2 = region2->read(buffer2a, addr2, size); - int res; - if (buffer1 == buffer2) - res = 0; - else - res = memcmp(buffer1, buffer2, size); - if (not stack_alloc) { - ::operator delete(buffer1a); - ::operator delete(buffer2a); - } - return res; -} diff --git a/src/mc/sosp/Region.hpp b/src/mc/sosp/Region.hpp deleted file mode 100644 index e1685d1afa..0000000000 --- a/src/mc/sosp/Region.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_SOSP_REGION_HPP -#define SIMGRID_MC_SOSP_REGION_HPP - -#include "src/mc/remote/RemotePtr.hpp" -#include "src/mc/sosp/ChunkedData.hpp" - -#include -#include - -namespace simgrid::mc { - -enum class RegionType { Heap = 1, Data = 2 }; - -/** A copy/snapshot of a given memory region, where identical pages are stored only once */ -class Region { -public: - static const RegionType HeapRegion = RegionType::Heap; - static const RegionType DataRegion = RegionType::Data; - -private: - RegionType region_type_; - simgrid::mc::ObjectInformation* object_info_ = nullptr; - - /** @brief Virtual address of the region in the simulated process */ - void* start_addr_ = nullptr; - - /** @brief Size of the data region in bytes */ - std::size_t size_ = 0; - - ChunkedData chunks_; - -public: - Region(RegionType type, void* start_addr, size_t size); - Region(Region const&) = delete; - Region& operator=(Region const&) = delete; - Region(Region&& that) = delete; - Region& operator=(Region&& that) = delete; - - // Data - - ChunkedData const& get_chunks() const { return chunks_; } - - simgrid::mc::ObjectInformation* object_info() const { return object_info_; } - void object_info(simgrid::mc::ObjectInformation* info) { object_info_ = info; } - - // Other getters - - RemotePtr start() const { return remote(start_addr_); } - RemotePtr end() const { return remote((char*)start_addr_ + size_); } - std::size_t size() const { return size_; } - RegionType region_type() const { return region_type_; } - - bool contain(RemotePtr p) const { return p >= start() && p < end(); } - - /** @brief Restore a region from a snapshot */ - void restore() const; - - /** @brief Read memory that was snapshotted in this region - * - * @param target Buffer to store contiguously the value if it spans over several pages - * @param addr Process (non-snapshot) address of the data - * @param size Size of the data to read in bytes - * @return Pointer where the data is located (either target buffer or original location) - */ - void* read(void* target, const void* addr, std::size_t size) const; -}; - -} // namespace simgrid::mc - -int MC_snapshot_region_memcmp(const void* addr1, const simgrid::mc::Region* region1, const void* addr2, - const simgrid::mc::Region* region2, std::size_t size); - -static XBT_ALWAYS_INLINE void* MC_region_read_pointer(const simgrid::mc::Region* region, const void* addr) -{ - void* res; - return *(void**)region->read(&res, addr, sizeof(void*)); -} - -#endif diff --git a/src/mc/sosp/Snapshot.cpp b/src/mc/sosp/Snapshot.cpp deleted file mode 100644 index 6b07c1f544..0000000000 --- a/src/mc/sosp/Snapshot.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/mc/sosp/Snapshot.hpp" -#include "src/mc/mc_config.hpp" -#include "src/mc/mc_hash.hpp" - -#include /* std::size_t */ - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_snapshot, mc, "Taking and restoring snapshots"); -namespace simgrid::mc { -/************************************* Take Snapshot ************************************/ -/****************************************************************************************/ - -void Snapshot::snapshot_regions(RemoteProcess* process) -{ - snapshot_regions_.clear(); - - for (auto const& object_info : process->object_infos) - add_region(RegionType::Data, object_info.get(), object_info->start_rw, object_info->end_rw - object_info->start_rw); - - const s_xbt_mheap_t* heap = process->get_heap(); - void* start_heap = heap->base; - void* end_heap = heap->breakval; - - add_region(RegionType::Heap, nullptr, start_heap, (char*)end_heap - (char*)start_heap); - heap_bytes_used_ = mmalloc_get_bytes_used_remote(heap->heaplimit, process->get_malloc_info()); -} - -/** @brief Checks whether the variable is in scope for a given IP. - * - * A variable may be defined only from a given value of IP. - * - * @param var Variable description - * @param scope Scope description - * @param ip Instruction pointer - * @return true if the variable is valid - * */ -static bool valid_variable(const simgrid::mc::Variable* var, simgrid::mc::Frame* scope, const void* ip) -{ - // The variable is not yet valid: - if (scope->range.begin() + var->start_scope > (std::uint64_t)ip) - return false; - else - return true; -} - -static void fill_local_variables_values(mc_stack_frame_t stack_frame, Frame* scope, - std::vector& result) -{ - if (not scope || not scope->range.contain(stack_frame->ip)) - return; - - for (const Variable& current_variable : scope->variables) { - if (not valid_variable(¤t_variable, scope, (void*)stack_frame->ip)) - continue; - - if (not current_variable.type) { - XBT_VERB("Ignore local variable without type: '%s' [%s]", current_variable.name.c_str(), - stack_frame->frame->name.c_str()); - continue; - } - - s_local_variable_t new_var; - new_var.subprogram = stack_frame->frame; - new_var.ip = stack_frame->ip; - new_var.name = current_variable.name; - new_var.type = current_variable.type; - new_var.address = nullptr; - - if (current_variable.address != nullptr) - new_var.address = current_variable.address; - else if (not current_variable.location_list.empty()) { - dwarf::Location location = simgrid::dwarf::resolve(current_variable.location_list, current_variable.object_info, - &(stack_frame->unw_cursor), (void*)stack_frame->frame_base, - &mc_model_checker->get_remote_process()); - - xbt_assert(location.in_memory(), "Cannot handle non-address variable"); - new_var.address = location.address(); - } else - xbt_die("No address"); - - result.push_back(std::move(new_var)); - } - - // Recursive processing of nested scopes: - for (Frame& nested_scope : scope->scopes) - fill_local_variables_values(stack_frame, &nested_scope, result); -} - -static std::vector get_local_variables_values(std::vector& stack_frames) -{ - std::vector variables; - for (s_mc_stack_frame_t& stack_frame : stack_frames) - fill_local_variables_values(&stack_frame, stack_frame.frame, variables); - return variables; -} - -static std::vector unwind_stack_frames(UnwindContext* stack_context) -{ - const RemoteProcess* process = &mc_model_checker->get_remote_process(); - std::vector result; - - unw_cursor_t c = stack_context->cursor(); - - // TODO, check condition check (unw_init_local==0 means end of frame) - - while (true) { - s_mc_stack_frame_t stack_frame; - - stack_frame.unw_cursor = c; - - unw_word_t ip; - unw_word_t sp; - - unw_get_reg(&c, UNW_REG_IP, &ip); - unw_get_reg(&c, UNW_REG_SP, &sp); - - stack_frame.ip = ip; - stack_frame.sp = sp; - - // TODO, use real addresses in frame_t instead of fixing it here - - Frame* frame = process->find_function(remote(ip)); - stack_frame.frame = frame; - - if (frame) { - stack_frame.frame_name = frame->name; - stack_frame.frame_base = (unw_word_t)frame->frame_base(c); - } else { - stack_frame.frame_base = 0; - stack_frame.frame_name = std::string(); - } - - result.push_back(std::move(stack_frame)); - - /* Stop before context switch with maestro */ - if (frame != nullptr && frame->name == "smx_ctx_wrapper") - break; - - int ret = unw_step(&c); - xbt_assert(ret >= 0, "Error while unwinding stack"); - xbt_assert(ret != 0, "Unexpected end of stack."); - } - - xbt_assert(not result.empty(), "unw_init_local failed"); - - return result; -} - -void Snapshot::snapshot_stacks(RemoteProcess* process) -{ - for (auto const& stack : process->stack_areas()) { - s_mc_snapshot_stack_t st; - - // Read the context from remote process: - unw_context_t context; - process->read_bytes(&context, sizeof(context), remote(stack.context)); - - st.context.initialize(process, &context); - - st.stack_frames = unwind_stack_frames(&st.context); - st.local_variables = get_local_variables_values(st.stack_frames); - - unw_word_t sp = st.stack_frames[0].sp; - - stacks_.push_back(std::move(st)); - - size_t stack_size = (char*)stack.address + stack.size - (char*)sp; - stack_sizes_.push_back(stack_size); - } -} - -static void snapshot_handle_ignore(Snapshot* snapshot) -{ - xbt_assert(snapshot->get_remote_process()); - - // Copy the memory: - for (auto const& region : snapshot->get_remote_process()->ignored_regions()) { - s_mc_snapshot_ignored_data_t ignored_data; - ignored_data.start = (void*)region.addr; - ignored_data.data.resize(region.size); - // TODO, we should do this once per privatization segment: - snapshot->get_remote_process()->read_bytes(ignored_data.data.data(), region.size, remote(region.addr)); - snapshot->ignored_data_.push_back(std::move(ignored_data)); - } - - // Zero the memory: - for (auto const& region : snapshot->get_remote_process()->ignored_regions()) - snapshot->get_remote_process()->clear_bytes(remote(region.addr), region.size); -} - -static void snapshot_ignore_restore(const simgrid::mc::Snapshot* snapshot) -{ - for (auto const& ignored_data : snapshot->ignored_data_) - snapshot->get_remote_process()->write_bytes(ignored_data.data.data(), ignored_data.data.size(), - remote(ignored_data.start)); -} - -Snapshot::Snapshot(long num_state, RemoteProcess* process) : AddressSpace(process), num_state_(num_state) -{ - XBT_DEBUG("Taking snapshot %ld", num_state); - - for (auto const& p : process->actors()) - enabled_processes_.insert(p.copy.get_buffer()->get_pid()); - - snapshot_handle_ignore(this); - - /* Save the std heap and the writable mapped pages of libsimgrid and binary */ - snapshot_regions(process); - - to_ignore_ = process->ignored_heap(); - - if (_sg_mc_max_visited_states > 0 || not _sg_mc_property_file.get().empty()) { - snapshot_stacks(process); - hash_ = simgrid::mc::hash(*this); - } - - snapshot_ignore_restore(this); -} - -void Snapshot::add_region(RegionType type, ObjectInformation* object_info, void* start_addr, std::size_t size) -{ - if (type == RegionType::Data) - xbt_assert(object_info, "Missing object info for object."); - else if (type == RegionType::Heap) - xbt_assert(not object_info, "Unexpected object info for heap region."); - - auto* region = new Region(type, start_addr, size); - region->object_info(object_info); - snapshot_regions_.push_back(std::unique_ptr(region)); -} - -void* Snapshot::read_bytes(void* buffer, std::size_t size, RemotePtr address, ReadOptions options) const -{ - const Region* region = this->get_region((void*)address.address()); - if (region) { - void* res = region->read(buffer, (void*)address.address(), size); - if (buffer == res || options & ReadOptions::lazy()) - return res; - else { - memcpy(buffer, res, size); - return buffer; - } - } else - return this->get_remote_process()->read_bytes(buffer, size, address, options); -} -/** @brief Find the snapshotted region from a pointer - * - * @param addr Pointer - * */ -Region* Snapshot::get_region(const void* addr) const -{ - size_t n = snapshot_regions_.size(); - for (size_t i = 0; i != n; ++i) { - Region* region = snapshot_regions_[i].get(); - if (not(region && region->contain(simgrid::mc::remote(addr)))) - continue; - - return region; - } - - return nullptr; -} - -/** @brief Find the snapshotted region from a pointer, with a hinted_region */ -Region* Snapshot::get_region(const void* addr, Region* hinted_region) const -{ - if (hinted_region->contain(simgrid::mc::remote(addr))) - return hinted_region; - else - return get_region(addr); -} - -void Snapshot::restore(RemoteProcess* process) const -{ - XBT_DEBUG("Restore snapshot %ld", num_state_); - - // Restore regions - for (std::unique_ptr const& region : snapshot_regions_) { - if (region) // privatized variables are not snapshotted - region.get()->restore(); - } - - snapshot_ignore_restore(this); - process->clear_cache(); -} - -} // namespace simgrid::mc diff --git a/src/mc/sosp/Snapshot.hpp b/src/mc/sosp/Snapshot.hpp deleted file mode 100644 index 412c7b998c..0000000000 --- a/src/mc/sosp/Snapshot.hpp +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_SNAPSHOT_HPP -#define SIMGRID_MC_SNAPSHOT_HPP - -#include "src/mc/ModelChecker.hpp" -#include "src/mc/inspect/mc_unw.hpp" -#include "src/mc/remote/RemoteProcess.hpp" -#include "src/mc/sosp/Region.hpp" - -// ***** MC Snapshot - -/** Ignored data - * - * Some parts of the snapshot are ignored by zeroing them out: the real - * values is stored here. - * */ -struct s_mc_snapshot_ignored_data_t { - void* start; - std::vector data; -}; - -/** Information about a given stack frame */ -struct s_mc_stack_frame_t { - /** Instruction pointer */ - unw_word_t ip; - /** Stack pointer */ - unw_word_t sp; - unw_word_t frame_base; - simgrid::mc::Frame* frame; - std::string frame_name; - unw_cursor_t unw_cursor; -}; -using mc_stack_frame_t = s_mc_stack_frame_t*; - -struct s_local_variable_t { - simgrid::mc::Frame* subprogram; - unsigned long ip; - std::string name; - simgrid::mc::Type* type; - void* address; -}; -using local_variable_t = s_local_variable_t*; -using const_local_variable_t = const s_local_variable_t*; - -struct XBT_PRIVATE s_mc_snapshot_stack_t { - std::vector local_variables; - simgrid::mc::UnwindContext context; - std::vector stack_frames; -}; -using mc_snapshot_stack_t = s_mc_snapshot_stack_t*; -using const_mc_snapshot_stack_t = const s_mc_snapshot_stack_t*; - -namespace simgrid::mc { - -class XBT_PRIVATE Snapshot final : public AddressSpace { -public: - /* Initialization */ - Snapshot(long num_state, RemoteProcess* process = &mc_model_checker->get_remote_process()); - - /* Regular use */ - bool on_heap(const void* address) const - { - const s_xbt_mheap_t* heap = get_remote_process()->get_heap(); - return address >= heap->heapbase && address < heap->breakval; - } - - void* read_bytes(void* buffer, std::size_t size, RemotePtr address, - ReadOptions options = ReadOptions::none()) const override; - Region* get_region(const void* addr) const; - Region* get_region(const void* addr, Region* hinted_region) const; - void restore(RemoteProcess* process) const; - - // To be private - long num_state_; - std::size_t heap_bytes_used_ = 0; - std::vector> snapshot_regions_; - std::set enabled_processes_; - std::vector stack_sizes_; - std::vector stacks_; - std::vector to_ignore_; - std::uint64_t hash_ = 0; - std::vector ignored_data_; - -private: - void add_region(RegionType type, ObjectInformation* object_info, void* start_addr, std::size_t size); - void snapshot_regions(RemoteProcess* process); - void snapshot_stacks(RemoteProcess* process); -}; -} // namespace simgrid::mc - -#endif diff --git a/src/mc/sosp/Snapshot_test.cpp b/src/mc/sosp/Snapshot_test.cpp deleted file mode 100644 index 3d9bb72480..0000000000 --- a/src/mc/sosp/Snapshot_test.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/include/catch.hpp" -#include "src/mc/mc_config.hpp" -#include "src/mc/sosp/Snapshot.hpp" - -#include -#include -#include -#include - -/**************** Class BOOST_tests *************************/ -using simgrid::mc::Region; -class snap_test_helper { -public: - static void init_memory(void* mem, size_t size); - static void Init(); - struct prologue_return { - size_t size; - void* src; - void* dstn; - Region* region0; - Region* region; - }; - static prologue_return prologue(int n); // common to the below 5 fxs - static void read_whole_region(); - static void read_region_parts(); - static void compare_whole_region(); - static void compare_region_parts(); - static void read_pointer(); - - static void cleanup() - { - delete mc_model_checker; - mc_model_checker = nullptr; - } - - static std::unique_ptr process; -}; - -// static member variables init. -std::unique_ptr snap_test_helper::process = nullptr; - -void snap_test_helper::init_memory(void* mem, size_t size) -{ - auto* dest = static_cast(mem); - for (size_t i = 0; i < size; ++i) { - dest[i] = simgrid::xbt::random::uniform_int(0, 0xff); - } -} - -void snap_test_helper::Init() -{ - REQUIRE(xbt_pagesize == getpagesize()); - REQUIRE(1 << xbt_pagebits == xbt_pagesize); - - process = std::make_unique(getpid()); - process->init(nullptr, nullptr, nullptr); - mc_model_checker = new ::simgrid::mc::ModelChecker(std::move(process), -1); -} - -snap_test_helper::prologue_return snap_test_helper::prologue(int n) -{ - // Store region page(s): - size_t byte_size = n * xbt_pagesize; - void* source = mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - INFO("Could not allocate source memory"); - REQUIRE(source != MAP_FAILED); - - // Init memory and take snapshots: - init_memory(source, byte_size); - auto* region0 = new simgrid::mc::Region(simgrid::mc::RegionType::Data, source, byte_size); - for (int i = 0; i < n; i += 2) { - init_memory((char*)source + i * xbt_pagesize, xbt_pagesize); - } - auto* region = new simgrid::mc::Region(simgrid::mc::RegionType::Data, source, byte_size); - - void* destination = mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - INFO("Could not allocate destination memory"); - REQUIRE(destination != MAP_FAILED); - - return {.size = byte_size, .src = source, .dstn = destination, .region0 = region0, .region = region}; -} - -void snap_test_helper::read_whole_region() -{ - for (int n = 1; n != 32; ++n) { - prologue_return ret = prologue(n); - const void* read = ret.region->read(ret.dstn, ret.src, ret.size); - INFO("Mismatch in MC_region_read()"); - REQUIRE(not memcmp(ret.src, read, ret.size)); - - munmap(ret.dstn, ret.size); - munmap(ret.src, ret.size); - delete ret.region0; - delete ret.region; - } -} - -void snap_test_helper::read_region_parts() -{ - for (int n = 1; n != 32; ++n) { - prologue_return ret = prologue(n); - - for (int j = 0; j != 100; ++j) { - size_t offset = simgrid::xbt::random::uniform_int(0, ret.size - 1); - size_t size = simgrid::xbt::random::uniform_int(0, ret.size - offset - 1); - const void* read = ret.region->read(ret.dstn, (const char*)ret.src + offset, size); - INFO("Mismatch in MC_region_read()"); - REQUIRE(not memcmp((char*)ret.src + offset, read, size)); - } - munmap(ret.dstn, ret.size); - munmap(ret.src, ret.size); - delete ret.region0; - delete ret.region; - } -} - -void snap_test_helper::compare_whole_region() -{ - for (int n = 1; n != 32; ++n) { - prologue_return ret = prologue(n); - - INFO("Unexpected match in MC_snapshot_region_memcmp() with previous snapshot"); - REQUIRE(MC_snapshot_region_memcmp(ret.src, ret.region0, ret.src, ret.region, ret.size)); - - munmap(ret.dstn, ret.size); - munmap(ret.src, ret.size); - delete ret.region0; - delete ret.region; - } -} - -void snap_test_helper::compare_region_parts() -{ - for (int n = 1; n != 32; ++n) { - prologue_return ret = prologue(n); - - for (int j = 0; j != 100; ++j) { - size_t offset = simgrid::xbt::random::uniform_int(0, ret.size - 1); - size_t size = simgrid::xbt::random::uniform_int(0, ret.size - offset - 1); - - INFO("Mismatch in MC_snapshot_region_memcmp()"); - REQUIRE(not MC_snapshot_region_memcmp((char*)ret.src + offset, ret.region, (char*)ret.src + offset, ret.region, - size)); - } - munmap(ret.dstn, ret.size); - munmap(ret.src, ret.size); - delete ret.region0; - delete ret.region; - } -} - -void snap_test_helper::read_pointer() -{ - prologue_return ret = prologue(1); - memcpy(ret.src, &mc_model_checker, sizeof(void*)); - const simgrid::mc::Region region2(simgrid::mc::RegionType::Data, ret.src, ret.size); - INFO("Mismtach in MC_region_read_pointer()"); - REQUIRE(MC_region_read_pointer(®ion2, ret.src) == mc_model_checker); - - munmap(ret.dstn, ret.size); - munmap(ret.src, ret.size); - delete ret.region0; - delete ret.region; -} - -/*************** End: class snap_test_helper *****************************/ - -TEST_CASE("MC::Snapshot: A copy/snapshot of a given memory region", "MC::Snapshot") -{ - INFO("Sparse snapshot (using pages)"); - - snap_test_helper::Init(); - - INFO("Read whole region"); - snap_test_helper::read_whole_region(); - - INFO("Read region parts"); - snap_test_helper::read_region_parts(); - - INFO("Compare whole region"); - snap_test_helper::compare_whole_region(); - - INFO("Compare region parts"); - snap_test_helper::compare_region_parts(); - - INFO("Read pointer"); - snap_test_helper::read_pointer(); - - snap_test_helper::cleanup(); -} diff --git a/src/mc/transition/Transition.cpp b/src/mc/transition/Transition.cpp index 3fb8ced4ac..fc3a5e2309 100644 --- a/src/mc/transition/Transition.cpp +++ b/src/mc/transition/Transition.cpp @@ -1,17 +1,20 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/transition/Transition.hpp" +#include "src/kernel/actor/Simcall.hpp" #include "xbt/asserts.h" #include "xbt/string.hpp" #include #if SIMGRID_HAVE_MC -#include "src/mc/ModelChecker.hpp" +#include "src/mc/explo/Exploration.hpp" +#include "src/mc/transition/TransitionActor.hpp" #include "src/mc/transition/TransitionAny.hpp" #include "src/mc/transition/TransitionComm.hpp" +#include "src/mc/transition/TransitionObjectAccess.hpp" #include "src/mc/transition/TransitionRandom.hpp" #include "src/mc/transition/TransitionSynchro.hpp" #endif @@ -41,13 +44,12 @@ std::string Transition::dot_string() const return xbt::string_printf("label = \"[(%ld)] %s\", color = %s, fontcolor = %s", aid_, Transition::to_c_str(type_), color, color); } -void Transition::replay() const +void Transition::replay(RemoteApp& app) const { replayed_transitions_++; - #if SIMGRID_HAVE_MC - mc_model_checker->handle_simcall(aid_, times_considered_, false); - mc_model_checker->wait_for_requests(); + app.handle_simcall(aid_, times_considered_, false); + app.wait_for_requests(); #endif } @@ -58,13 +60,13 @@ Transition* deserialize_transition(aid_t issuer, int times_considered, std::stri xbt_assert(stream >> type); switch (auto simcall = static_cast(type)) { - case Transition::Type::BARRIER_LOCK: + case Transition::Type::BARRIER_ASYNC_LOCK: case Transition::Type::BARRIER_WAIT: return new BarrierTransition(issuer, times_considered, simcall, stream); - case Transition::Type::COMM_RECV: + case Transition::Type::COMM_ASYNC_RECV: return new CommRecvTransition(issuer, times_considered, stream); - case Transition::Type::COMM_SEND: + case Transition::Type::COMM_ASYNC_SEND: return new CommSendTransition(issuer, times_considered, stream); case Transition::Type::COMM_TEST: return new CommTestTransition(issuer, times_considered, stream); @@ -80,24 +82,34 @@ Transition* deserialize_transition(aid_t issuer, int times_considered, std::stri return new RandomTransition(issuer, times_considered, stream); case Transition::Type::MUTEX_TRYLOCK: - case Transition::Type::MUTEX_LOCK: + case Transition::Type::MUTEX_ASYNC_LOCK: case Transition::Type::MUTEX_TEST: case Transition::Type::MUTEX_WAIT: case Transition::Type::MUTEX_UNLOCK: return new MutexTransition(issuer, times_considered, simcall, stream); - case Transition::Type::SEM_LOCK: + case Transition::Type::SEM_ASYNC_LOCK: case Transition::Type::SEM_UNLOCK: case Transition::Type::SEM_WAIT: return new SemaphoreTransition(issuer, times_considered, simcall, stream); + case Transition::Type::ACTOR_JOIN: + return new ActorJoinTransition(issuer, times_considered, stream); + case Transition::Type::ACTOR_SLEEP: + return new ActorSleepTransition(issuer, times_considered, stream); + + case Transition::Type::OBJECT_ACCESS: + return new ObjectAccessTransition(issuer, times_considered, stream); + case Transition::Type::UNKNOWN: return new Transition(Transition::Type::UNKNOWN, issuer, times_considered); default: break; } - xbt_die("Invalid transition type %d received", type); + xbt_die("Invalid transition type %d received. Did you implement a new observer in the app without implementing the " + "corresponding transition in the checker?", + type); #else xbt_die("Deserializing transitions is only interesting in MC mode."); #endif diff --git a/src/mc/transition/Transition.hpp b/src/mc/transition/Transition.hpp index 19e30b9051..246b3f0ba2 100644 --- a/src/mc/transition/Transition.hpp +++ b/src/mc/transition/Transition.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,6 +7,7 @@ #define SIMGRID_MC_TRANSITION_HPP #include "simgrid/forward.h" // aid_t +#include "xbt/ex.h" #include "xbt/utility.hpp" // XBT_DECLARE_ENUM_CLASS #include @@ -23,7 +24,7 @@ namespace simgrid::mc { * calls. */ class Transition { - /* Textual representation of the transition, to display backtraces */ + /* Global statistics */ static unsigned long executed_transitions_; static unsigned long replayed_transitions_; @@ -31,17 +32,30 @@ class Transition { public: /* Ordering is important here. depends() implementations only consider subsequent types in this ordering */ - XBT_DECLARE_ENUM_CLASS(Type, RANDOM, /* First because indep with anybody */ - TESTANY, WAITANY, /* high priority because they can rewrite themselves to *_WAIT */ - BARRIER_LOCK, BARRIER_WAIT, /* BARRIER transitions sorted alphabetically */ - COMM_RECV, COMM_SEND, COMM_TEST, COMM_WAIT, /* Alphabetical ordering of COMM_* */ - MUTEX_LOCK, MUTEX_TEST, MUTEX_TRYLOCK, MUTEX_UNLOCK, MUTEX_WAIT, /* alphabetical */ - SEM_LOCK, SEM_UNLOCK, SEM_WAIT, /* alphabetical ordering of SEM transitions */ - /* UNKNOWN must be last */ UNKNOWN); + XBT_DECLARE_ENUM_CLASS(Type, + /* First because indep with anybody including themselves */ + RANDOM, ACTOR_JOIN, ACTOR_SLEEP, + /* high priority because indep with almost everybody */ + OBJECT_ACCESS, + /* high priority because they can rewrite themselves to *_WAIT */ + TESTANY, WAITANY, + /* BARRIER transitions sorted alphabetically */ + BARRIER_ASYNC_LOCK, BARRIER_WAIT, + /* Alphabetical ordering of COMM_* */ + COMM_ASYNC_RECV, COMM_ASYNC_SEND, COMM_TEST, COMM_WAIT, + /* alphabetical */ + MUTEX_ASYNC_LOCK, MUTEX_TEST, MUTEX_TRYLOCK, MUTEX_UNLOCK, MUTEX_WAIT, + /* alphabetical ordering of SEM transitions */ + SEM_ASYNC_LOCK, SEM_UNLOCK, SEM_WAIT, + /* UNKNOWN must be last */ + UNKNOWN); Type type_ = Type::UNKNOWN; aid_t aid_ = 0; + /** The user function call that caused this transition to exist. Format: >>filename:line:function()<< */ + std::string call_location_ = ""; + /* Which transition was executed for this simcall * * Some simcalls can lead to different transitions: @@ -64,11 +78,28 @@ public: /** Returns something like >>label = "desc", color = c<< to describe the transition in dot format */ virtual std::string dot_string() const; + std::string const& get_call_location() const { return call_location_; } + /* Moves the application toward a path that was already explored, but don't change the current transition */ - void replay() const; + void replay(RemoteApp& app) const; virtual bool depends(const Transition* other) const { return true; } + /** + The reversible race detector should only be used if we already have the assumption + this <* other (see Source set: a foundation for ODPOR). In particular this means that : + - this -->_E other + - proc(this) != proc(other) + - there is no event e s.t. this --> e --> other + + @note: It is safe to assume that there is indeed a race between the two events in the execution; + indeed, the question the method answers is only sensible in the context of a race + */ + virtual bool reversible_race(const Transition* other) const + { + xbt_die("%s unimplemented for %s", __func__, to_c_str(type_)); + } + /* Returns the total amount of transitions executed so far (for statistics) */ static unsigned long get_executed_transitions() { return executed_transitions_; } /* Returns the total amount of transitions replayed so far while backtracing (for statistics) */ diff --git a/src/mc/transition/TransitionActor.cpp b/src/mc/transition/TransitionActor.cpp new file mode 100644 index 0000000000..3e1027b576 --- /dev/null +++ b/src/mc/transition/TransitionActor.cpp @@ -0,0 +1,85 @@ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/transition/TransitionActor.hpp" +#include "simgrid/config.h" +#include "xbt/asserts.h" +#include "xbt/string.hpp" + +#include + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_trans_actorlifecycle, mc_transition, + "Logging specific to MC transitions about actors' lifecycle: joining, ending"); + +namespace simgrid::mc { + +ActorJoinTransition::ActorJoinTransition(aid_t issuer, int times_considered, std::stringstream& stream) + : Transition(Type::ACTOR_JOIN, issuer, times_considered) +{ + xbt_assert(stream >> target_ >> timeout_); + XBT_DEBUG("ActorJoinTransition target:%ld, %s ", target_, (timeout_ ? "timeout" : "no-timeout")); +} +std::string ActorJoinTransition::to_string(bool verbose) const +{ + return xbt::string_printf("ActorJoin(target %ld, %s)", target_, (timeout_ ? "timeout" : "no timeout")); +} +bool ActorJoinTransition::depends(const Transition* other) const +{ + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + + // Joining is dependent with any transition whose + // actor is that of the `other` action. , Join i + if (other->aid_ == target_) { + return true; + } + + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + + // Otherwise, joining is indep with any other transitions: + // - It is only enabled once the target ends, and after this point it's enabled no matter what + // - Other joins don't affect it, and it does not impact on the enabledness of any other transition + return false; +} + +bool ActorJoinTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::ACTOR_JOIN, "Unexpected transition type %s", to_c_str(type_)); + + // ActorJoin races with another event iff its target `T` is the same as the actor executing the other transition. + // Clearly, then, we could not join on that actor `T` and then run a transition by `T`, so no race is reversible + return false; +} + +ActorSleepTransition::ActorSleepTransition(aid_t issuer, int times_considered, std::stringstream&) + : Transition(Type::ACTOR_SLEEP, issuer, times_considered) +{ + XBT_DEBUG("ActorSleepTransition()"); +} +std::string ActorSleepTransition::to_string(bool verbose) const +{ + return xbt::string_printf("ActorSleep()"); +} +bool ActorSleepTransition::depends(const Transition* other) const +{ + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + + // Sleeping is indep with any other transitions: always enabled, not impacted by any transition + return false; +} + +bool ActorSleepTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::ACTOR_SLEEP, "Unexpected transition type %s", to_c_str(type_)); + + return true; // Always enabled +} + +} // namespace simgrid::mc diff --git a/src/mc/transition/TransitionActor.hpp b/src/mc/transition/TransitionActor.hpp new file mode 100644 index 0000000000..68cc89f502 --- /dev/null +++ b/src/mc/transition/TransitionActor.hpp @@ -0,0 +1,44 @@ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_TRANSITION_ACTOR_HPP +#define SIMGRID_MC_TRANSITION_ACTOR_HPP + +#include "src/kernel/actor/SimcallObserver.hpp" +#include "src/mc/transition/Transition.hpp" + +#include +#include +#include + +namespace simgrid::mc { + +class ActorJoinTransition : public Transition { + bool timeout_; + aid_t target_; + +public: + ActorJoinTransition(aid_t issuer, int times_considered, std::stringstream& stream); + std::string to_string(bool verbose) const override; + bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; + + bool get_timeout() const { return timeout_; } + /** Target ID */ + aid_t get_target() const { return target_; } +}; + +class ActorSleepTransition : public Transition { + +public: + ActorSleepTransition(aid_t issuer, int times_considered, std::stringstream& stream); + std::string to_string(bool verbose) const override; + bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; +}; + +} // namespace simgrid::mc + +#endif diff --git a/src/mc/transition/TransitionAny.cpp b/src/mc/transition/TransitionAny.cpp index d590c5f5a1..b3c7b63cb3 100644 --- a/src/mc/transition/TransitionAny.cpp +++ b/src/mc/transition/TransitionAny.cpp @@ -1,16 +1,12 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/transition/TransitionAny.hpp" +#include "simgrid/config.h" #include "xbt/asserts.h" -#include -#if SIMGRID_HAVE_MC -#include "src/mc/ModelChecker.hpp" -#include "src/mc/Session.hpp" -#include "src/mc/api/State.hpp" -#endif +#include "xbt/string.hpp" #include @@ -25,22 +21,35 @@ TestAnyTransition::TestAnyTransition(aid_t issuer, int times_considered, std::st xbt_assert(stream >> size); for (int i = 0; i < size; i++) { Transition* t = deserialize_transition(issuer, 0, stream); - XBT_DEBUG("TestAny received a transition %s", t->to_string(true).c_str()); + XBT_INFO("TestAny received a transition %s", t->to_string(true).c_str()); transitions_.push_back(t); } } std::string TestAnyTransition::to_string(bool verbose) const { - auto res = xbt::string_printf("TestAny{ "); - for (auto const* t : transitions_) + auto res = xbt::string_printf("TestAny(%s){ ", this->result() ? "TRUE" : "FALSE"); + for (auto const* t : transitions_) { res += t->to_string(verbose); + res += "; "; + } res += " }"; return res; } bool TestAnyTransition::depends(const Transition* other) const { + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + return transitions_[times_considered_]->depends(other); } +bool TestAnyTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::TESTANY, "Unexpected transition type %s", to_c_str(type_)); + + return true; // TestAny is always enabled +} + WaitAnyTransition::WaitAnyTransition(aid_t issuer, int times_considered, std::stringstream& stream) : Transition(Type::WAITANY, issuer, times_considered) { @@ -48,6 +57,7 @@ WaitAnyTransition::WaitAnyTransition(aid_t issuer, int times_considered, std::st xbt_assert(stream >> size); for (int i = 0; i < size; i++) { Transition* t = deserialize_transition(issuer, 0, stream); + XBT_INFO("WaitAny received transition %d/%d %s", (i + 1), size, t->to_string(true).c_str()); transitions_.push_back(t); } } @@ -56,12 +66,22 @@ std::string WaitAnyTransition::to_string(bool verbose) const auto res = xbt::string_printf("WaitAny{ "); for (auto const* t : transitions_) res += t->to_string(verbose); - res += " }"; + res += " } (times considered = " + std::to_string(times_considered_) + ")"; return res; } bool WaitAnyTransition::depends(const Transition* other) const { + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; return transitions_[times_considered_]->depends(other); } +bool WaitAnyTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::WAITANY, "Unexpected transition type %s", to_c_str(type_)); + + // TODO: We need to check if any of the transitions waited on occurred before `e1` + return true; // Let's overapproximate to not miss branches +} } // namespace simgrid::mc diff --git a/src/mc/transition/TransitionAny.hpp b/src/mc/transition/TransitionAny.hpp index 2774d28327..35cbf4e391 100644 --- a/src/mc/transition/TransitionAny.hpp +++ b/src/mc/transition/TransitionAny.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,7 +8,9 @@ #include "src/kernel/actor/SimcallObserver.hpp" #include "src/mc/transition/Transition.hpp" +#include "src/mc/transition/TransitionComm.hpp" +#include #include #include @@ -21,8 +23,16 @@ public: TestAnyTransition(aid_t issuer, int times_considered, std::stringstream& stream); std::string to_string(bool verbose) const override; bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; Transition* get_current_transition() const { return transitions_.at(times_considered_); } + bool result() const + { + return std::any_of(begin(transitions_), end(transitions_), [](const Transition* transition) { + const auto* tested_transition = static_cast(transition); + return (tested_transition->get_sender() != -1 && tested_transition->get_receiver() != -1); + }); + } }; class WaitAnyTransition : public Transition { @@ -32,6 +42,7 @@ public: WaitAnyTransition(aid_t issuer, int times_considered, std::stringstream& stream); std::string to_string(bool verbose) const override; bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; Transition* get_current_transition() const { return transitions_.at(times_considered_); } }; diff --git a/src/mc/transition/TransitionComm.cpp b/src/mc/transition/TransitionComm.cpp index 916dd8ba85..d23cd86fb8 100644 --- a/src/mc/transition/TransitionComm.cpp +++ b/src/mc/transition/TransitionComm.cpp @@ -1,17 +1,16 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/transition/TransitionComm.hpp" -#include "xbt/asserts.h" -#include -#if SIMGRID_HAVE_MC -#include "src/mc/ModelChecker.hpp" -#include "src/mc/Session.hpp" +#include "simgrid/config.h" +#include "src/mc/api/RemoteApp.hpp" #include "src/mc/api/State.hpp" -#endif +#include "xbt/asserts.h" +#include "xbt/string.hpp" +#include #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_trans_comm, mc_transition, @@ -19,74 +18,83 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_trans_comm, mc_transition, namespace simgrid::mc { +CommWaitTransition::CommWaitTransition(aid_t issuer, int times_considered, bool timeout_, unsigned comm_, aid_t sender_, + aid_t receiver_, unsigned mbox_) + : Transition(Type::COMM_WAIT, issuer, times_considered) + , timeout_(timeout_) + , comm_(comm_) + , mbox_(mbox_) + , sender_(sender_) + , receiver_(receiver_) +{ +} CommWaitTransition::CommWaitTransition(aid_t issuer, int times_considered, std::stringstream& stream) : Transition(Type::COMM_WAIT, issuer, times_considered) { - xbt_assert(stream >> timeout_ >> comm_ >> sender_ >> receiver_ >> mbox_ >> sbuff_ >> rbuff_ >> size_); - XBT_DEBUG("CommWaitTransition %s comm:%" PRIxPTR ", sender:%ld receiver:%ld mbox:%u sbuff:%" PRIxPTR - " rbuff:%" PRIxPTR " size:%zu", - (timeout_ ? "timeout" : "no-timeout"), comm_, sender_, receiver_, mbox_, sbuff_, rbuff_, size_); + xbt_assert(stream >> timeout_ >> comm_ >> sender_ >> receiver_ >> mbox_ >> call_location_); + XBT_DEBUG("CommWaitTransition %s comm:%u, sender:%ld receiver:%ld mbox:%u call_loc:%s", + (timeout_ ? "timeout" : "no-timeout"), comm_, sender_, receiver_, mbox_, call_location_.c_str()); } std::string CommWaitTransition::to_string(bool verbose) const { - auto res = xbt::string_printf("WaitComm(from %ld to %ld, mbox=%u, %s", sender_, receiver_, mbox_, - (timeout_ ? "timeout" : "no timeout")); - if (verbose) { - res += ", sbuff=" + xbt::string_printf("%" PRIxPTR, sbuff_) + ", size=" + std::to_string(size_); - res += ", rbuff=" + xbt::string_printf("%" PRIxPTR, rbuff_); - } - res += ")"; - return res; + return xbt::string_printf("WaitComm(from %ld to %ld, mbox=%u, %s)", sender_, receiver_, mbox_, + (timeout_ ? "timeout" : "no timeout")); } bool CommWaitTransition::depends(const Transition* other) const { - if (aid_ == other->aid_) - return false; - if (other->type_ < type_) return other->depends(this); + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + if (const auto* wait = dynamic_cast(other)) { if (timeout_ || wait->timeout_) return true; // Timeouts are not considered by the independence theorem, thus assumed dependent - - if (sbuff_ == wait->sbuff_ && rbuff_ == wait->rbuff_) - return false; - if (sbuff_ != 0 && rbuff_ != 0 && wait->sbuff_ != 0 && wait->rbuff_ != 0 && rbuff_ != wait->sbuff_ && - rbuff_ != wait->rbuff_ && rbuff_ != sbuff_) - return false; - - return true; } return false; // Comm transitions are INDEP with non-comm transitions } + +bool CommWaitTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::COMM_WAIT, "Unexpected transition type %s", to_c_str(type_)); + + // If the other event is a communication event, then we are not reversible; otherwise we are reversible. + return other->type_ != Transition::Type::COMM_ASYNC_SEND && other->type_ != Transition::Type::COMM_ASYNC_RECV; +} + +CommTestTransition::CommTestTransition(aid_t issuer, int times_considered, unsigned comm_, aid_t sender_, + aid_t receiver_, unsigned mbox_) + : Transition(Type::COMM_TEST, issuer, times_considered) + , comm_(comm_) + , mbox_(mbox_) + , sender_(sender_) + , receiver_(receiver_) +{ +} CommTestTransition::CommTestTransition(aid_t issuer, int times_considered, std::stringstream& stream) : Transition(Type::COMM_TEST, issuer, times_considered) { - xbt_assert(stream >> comm_ >> sender_ >> receiver_ >> mbox_ >> sbuff_ >> rbuff_ >> size_); - XBT_DEBUG("CommTestTransition comm:%" PRIxPTR ", sender:%ld receiver:%ld mbox:%u sbuff:%" PRIxPTR " rbuff:%" PRIxPTR - " size:%zu", - comm_, sender_, receiver_, mbox_, sbuff_, rbuff_, size_); + xbt_assert(stream >> comm_ >> sender_ >> receiver_ >> mbox_ >> call_location_); + XBT_DEBUG("CommTestTransition comm:%u, sender:%ld receiver:%ld mbox:%u call_loc:%s", comm_, sender_, receiver_, mbox_, + call_location_.c_str()); } std::string CommTestTransition::to_string(bool verbose) const { - auto res = xbt::string_printf("TestComm(from %ld to %ld, mbox=%u", sender_, receiver_, mbox_); - if (verbose) { - res += ", sbuff=" + xbt::string_printf("%" PRIxPTR, sbuff_) + ", size=" + std::to_string(size_); - res += ", rbuff=" + xbt::string_printf("%" PRIxPTR, rbuff_); - } - res += ")"; - return res; + return xbt::string_printf("TestComm(from %ld to %ld, mbox=%u)", sender_, receiver_, mbox_); } + bool CommTestTransition::depends(const Transition* other) const { - if (aid_ == other->aid_) - return false; - if (other->type_ < type_) return other->depends(this); + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + if (dynamic_cast(other) != nullptr) return false; // Test & Test are independent @@ -101,27 +109,35 @@ bool CommTestTransition::depends(const Transition* other) const return false; // Comm transitions are INDEP with non-comm transitions } +bool CommTestTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::COMM_TEST, "Unexpected transition type %s", to_c_str(type_)); + return true; // CommTest is always enabled +} + +CommRecvTransition::CommRecvTransition(aid_t issuer, int times_considered, unsigned comm_, unsigned mbox_, int tag_) + : Transition(Type::COMM_ASYNC_RECV, issuer, times_considered), comm_(comm_), mbox_(mbox_), tag_(tag_) +{ +} CommRecvTransition::CommRecvTransition(aid_t issuer, int times_considered, std::stringstream& stream) - : Transition(Type::COMM_RECV, issuer, times_considered) + : Transition(Type::COMM_ASYNC_RECV, issuer, times_considered) { - xbt_assert(stream >> comm_ >> mbox_ >> rbuff_ >> tag_); + xbt_assert(stream >> comm_ >> mbox_ >> tag_ >> call_location_); + XBT_DEBUG("CommRecvTransition comm:%u, mbox:%u tag:%d call_loc:%s", comm_, mbox_, tag_, call_location_.c_str()); } std::string CommRecvTransition::to_string(bool verbose) const { - auto res = xbt::string_printf("iRecv(mbox=%u", mbox_); - if (verbose) - res += ", rbuff=" + xbt::string_printf("%" PRIxPTR, rbuff_); - res += ")"; - return res; + return xbt::string_printf("iRecv(mbox=%u)", mbox_); } bool CommRecvTransition::depends(const Transition* other) const { - if (aid_ == other->aid_) - return false; - if (other->type_ < type_) return other->depends(this); + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + if (const auto* recv = dynamic_cast(other)) return mbox_ == recv->mbox_; @@ -132,20 +148,30 @@ bool CommRecvTransition::depends(const Transition* other) const if (mbox_ != test->mbox_) return false; - if ((aid_ != test->sender_) && (aid_ != test->receiver_) && (test->rbuff_ != rbuff_)) + if ((aid_ != test->sender_) && (aid_ != test->receiver_)) + return false; + + // If the test is checking a paired comm already, we're independent! + // If we happen to make up that pair, then we're dependent... + if (test->comm_ != comm_) return false; return true; // DEP with other send transitions } - if (auto* wait = dynamic_cast(other)) { + if (const auto* wait = dynamic_cast(other)) { if (wait->timeout_) return true; if (mbox_ != wait->mbox_) return false; - if ((aid_ != wait->sender_) && (aid_ != wait->receiver_) && (wait->rbuff_ != rbuff_)) + if ((aid_ != wait->sender_) && (aid_ != wait->receiver_)) + return false; + + // If the wait is waiting on a paired comm already, we're independent! + // If we happen to make up that pair, then we're dependent... + if ((aid_ != wait->aid_) && wait->comm_ != comm_) return false; return true; // DEP with other wait transitions @@ -154,29 +180,37 @@ bool CommRecvTransition::depends(const Transition* other) const return false; // Comm transitions are INDEP with non-comm transitions } +bool CommRecvTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::COMM_ASYNC_RECV, "Unexpected transition type %s", to_c_str(type_)); + + return true; // CommRecv is always enabled +} + +CommSendTransition::CommSendTransition(aid_t issuer, int times_considered, unsigned comm_, unsigned mbox_, int tag_) + : Transition(Type::COMM_ASYNC_SEND, issuer, times_considered), comm_(comm_), mbox_(mbox_), tag_(tag_) +{ +} CommSendTransition::CommSendTransition(aid_t issuer, int times_considered, std::stringstream& stream) - : Transition(Type::COMM_SEND, issuer, times_considered) + : Transition(Type::COMM_ASYNC_SEND, issuer, times_considered) { - xbt_assert(stream >> comm_ >> mbox_ >> sbuff_ >> size_ >> tag_); - XBT_DEBUG("SendTransition comm:%" PRIxPTR " mbox:%u sbuff:%" PRIxPTR " size:%zu", comm_, mbox_, sbuff_, size_); + xbt_assert(stream >> comm_ >> mbox_ >> tag_ >> call_location_); + XBT_DEBUG("SendTransition comm:%u mbox:%u tag:%d call_loc:%s", comm_, mbox_, tag_, call_location_.c_str()); } std::string CommSendTransition::to_string(bool verbose = false) const { - auto res = xbt::string_printf("iSend(mbox=%u", mbox_); - if (verbose) - res += ", sbuff=" + xbt::string_printf("%" PRIxPTR, sbuff_) + ", size=" + std::to_string(size_); - res += ")"; - return res; + return xbt::string_printf("iSend(mbox=%u)", mbox_); } bool CommSendTransition::depends(const Transition* other) const { - if (aid_ == other->aid_) - return false; - if (other->type_ < type_) return other->depends(this); + // Actions executed by the same actor are always dependent + if (other->aid_ == aid_) + return true; + if (const auto* other_isend = dynamic_cast(other)) return mbox_ == other_isend->mbox_; @@ -187,7 +221,12 @@ bool CommSendTransition::depends(const Transition* other) const if (mbox_ != test->mbox_) return false; - if ((aid_ != test->sender_) && (aid_ != test->receiver_) && (test->sbuff_ != sbuff_)) + if ((aid_ != test->sender_) && (aid_ != test->receiver_)) + return false; + + // If the test is checking a paired comm already, we're independent! + // If we happen to make up that pair, then we're dependent... + if (test->comm_ != comm_) return false; return true; // DEP with other test transitions @@ -200,7 +239,12 @@ bool CommSendTransition::depends(const Transition* other) const if (mbox_ != wait->mbox_) return false; - if ((aid_ != wait->sender_) && (aid_ != wait->receiver_) && (wait->sbuff_ != sbuff_)) + if ((aid_ != wait->sender_) && (aid_ != wait->receiver_)) + return false; + + // If the wait is waiting on a paired comm already, we're independent! + // If we happen to make up that pair, then we're dependent... + if ((aid_ != wait->aid_) && wait->comm_ != comm_) return false; return true; // DEP with other wait transitions @@ -209,4 +253,11 @@ bool CommSendTransition::depends(const Transition* other) const return false; // Comm transitions are INDEP with non-comm transitions } +bool CommSendTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::COMM_ASYNC_SEND, "Unexpected transition type %s", to_c_str(type_)); + + return true; // CommSend is always enabled +} + } // namespace simgrid::mc diff --git a/src/mc/transition/TransitionComm.hpp b/src/mc/transition/TransitionComm.hpp index 5a8a1e6488..1e9d0748cf 100644 --- a/src/mc/transition/TransitionComm.hpp +++ b/src/mc/transition/TransitionComm.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -21,111 +21,94 @@ class CommTestTransition; class CommWaitTransition : public Transition { bool timeout_; - uintptr_t comm_; + unsigned comm_; + unsigned mbox_; aid_t sender_; aid_t receiver_; - unsigned mbox_; - uintptr_t sbuff_; - uintptr_t rbuff_; - size_t size_; friend CommRecvTransition; friend CommSendTransition; friend CommTestTransition; public: + CommWaitTransition(aid_t issuer, int times_considered, bool timeout_, unsigned comm_, aid_t sender_, aid_t receiver_, + unsigned mbox_); CommWaitTransition(aid_t issuer, int times_considered, std::stringstream& stream); std::string to_string(bool verbose) const override; bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; bool get_timeout() const { return timeout_; } - /** Address of the corresponding Communication object in the application */ - uintptr_t get_comm() const { return comm_; } + /** ID of the corresponding Communication object in the application, or 0 if unknown */ + unsigned get_comm() const { return comm_; } /** Sender ID */ aid_t get_sender() const { return sender_; } /** Receiver ID */ aid_t get_receiver() const { return receiver_; } /** Mailbox ID */ unsigned get_mailbox() const { return mbox_; } - /** Sender buffer */ - uintptr_t get_sbuff() const { return sbuff_; } - /** Receiver buffer */ - uintptr_t get_rbuff() const { return rbuff_; } - /** data size */ - size_t get_size() const { return size_; } }; class CommTestTransition : public Transition { - uintptr_t comm_; + unsigned comm_; + unsigned mbox_; aid_t sender_; aid_t receiver_; - unsigned mbox_; - uintptr_t sbuff_; - uintptr_t rbuff_; - size_t size_; friend CommSendTransition; friend CommRecvTransition; public: + CommTestTransition(aid_t issuer, int times_considered, unsigned comm_, aid_t sender_, aid_t receiver_, + unsigned mbox_); CommTestTransition(aid_t issuer, int times_considered, std::stringstream& stream); std::string to_string(bool verbose) const override; bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; - /** Address of the corresponding Communication object in the application */ - uintptr_t get_comm() const { return comm_; } + /** ID of the corresponding Communication object in the application, or 0 if unknown */ + unsigned get_comm() const { return comm_; } /** Sender ID */ aid_t get_sender() const { return sender_; } /** Receiver ID */ aid_t get_receiver() const { return receiver_; } /** Mailbox ID */ unsigned get_mailbox() const { return mbox_; } - /** Sender buffer */ - uintptr_t get_sbuff() const { return sbuff_; } - /** Receiver buffer */ - uintptr_t get_rbuff() const { return rbuff_; } - /** data size */ - size_t get_size() const { return size_; } }; class CommRecvTransition : public Transition { - uintptr_t comm_; /* Addr of the CommImpl */ + unsigned comm_; /* ID of the CommImpl or 0 if not known */ unsigned mbox_; - uintptr_t rbuff_; int tag_; public: + CommRecvTransition(aid_t issuer, int times_considered, unsigned comm_, unsigned mbox_, int tag_); CommRecvTransition(aid_t issuer, int times_considered, std::stringstream& stream); std::string to_string(bool verbose) const override; bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; - /** Address of the corresponding Communication object in the application */ - uintptr_t get_comm() const { return comm_; } + /** ID of the corresponding Communication object in the application (or 0 if unknown)*/ + unsigned get_comm() const { return comm_; } /** Mailbox ID */ unsigned get_mailbox() const { return mbox_; } - /** Receiver buffer */ - uintptr_t get_rbuff() const { return rbuff_; } /** If using SMPI, the tag */ int get_tag() const { return tag_; } }; class CommSendTransition : public Transition { - uintptr_t comm_; /* Addr of the CommImpl */ + unsigned comm_; unsigned mbox_; - uintptr_t sbuff_; - size_t size_; int tag_; public: + CommSendTransition(aid_t issuer, int times_considered, unsigned comm_, unsigned mbox_, int tag_); CommSendTransition(aid_t issuer, int times_considered, std::stringstream& stream); std::string to_string(bool verbose) const override; bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; - /** Address of the corresponding Communication object in the application */ - uintptr_t get_comm() const { return comm_; } + /** ID of the corresponding Communication object in the application, or 0 if unknown */ + unsigned get_comm() const { return comm_; } /** Mailbox ID */ unsigned get_mailbox() const { return mbox_; } - /** Sender buffer */ - uintptr_t get_sbuff() const { return sbuff_; } - /** data size */ - size_t get_size() const { return size_; } /** If using SMPI, the tag */ int get_tag() const { return tag_; } }; diff --git a/src/mc/transition/TransitionObjectAccess.cpp b/src/mc/transition/TransitionObjectAccess.cpp new file mode 100644 index 0000000000..f32e459008 --- /dev/null +++ b/src/mc/transition/TransitionObjectAccess.cpp @@ -0,0 +1,56 @@ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/mc/transition/TransitionObjectAccess.hpp" +#include "xbt/asserts.h" +#include "xbt/log.h" +#include + +namespace simgrid::mc { + +ObjectAccessTransition::ObjectAccessTransition(aid_t issuer, int times_considered, std::stringstream& stream) + : Transition(Type::OBJECT_ACCESS, issuer, times_considered) +{ + short s; + xbt_assert(stream >> s >> objaddr_ >> objname_ >> file_ >> line_); + access_type_ = static_cast(s); +} +std::string ObjectAccessTransition::to_string(bool verbose) const +{ + std::string res; + if (access_type_ == ObjectAccessType::ENTER) + res = std::string("BeginObjectAccess("); + else if (access_type_ == ObjectAccessType::EXIT) + res = std::string("EndObjectAccess("); + else + res = std::string("ObjectAccess("); + res += objname_; + if (not xbt_log_no_loc) + res += std::string(" @ ") + file_ + ":" + std::to_string(line_); + res += std::string(")"); + return res; +} +bool ObjectAccessTransition::depends(const Transition* o) const +{ + if (o->type_ < type_) + return o->depends(this); + + // Actions executed by the same actor are always dependent + if (o->aid_ == aid_) + return true; + + if (const auto* other = dynamic_cast(o)) + return objaddr_ == other->objaddr_; // dependent only if it's an access to the same object + return false; +} + +bool ObjectAccessTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::OBJECT_ACCESS, "Unexpected transition type %s", to_c_str(type_)); + + return true; // Object access is always enabled +} + +} // namespace simgrid::mc diff --git a/src/mc/transition/TransitionObjectAccess.hpp b/src/mc/transition/TransitionObjectAccess.hpp new file mode 100644 index 0000000000..f9d7bc299e --- /dev/null +++ b/src/mc/transition/TransitionObjectAccess.hpp @@ -0,0 +1,30 @@ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MC_TRANSITION_OBJECT_ACCESS_HPP +#define SIMGRID_MC_TRANSITION_OBJECT_ACCESS_HPP + +#include "src/mc/transition/Transition.hpp" + +namespace simgrid::mc { +XBT_DECLARE_ENUM_CLASS(ObjectAccessType, ENTER, EXIT, BOTH); + +class ObjectAccessTransition : public Transition { + ObjectAccessType access_type_; + void* objaddr_; + std::string objname_; + std::string file_; + int line_; + +public: + ObjectAccessTransition(aid_t issuer, int times_considered, std::stringstream& stream); + std::string to_string(bool verbose) const override; + bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; +}; + +} // namespace simgrid::mc + +#endif \ No newline at end of file diff --git a/src/mc/transition/TransitionRandom.cpp b/src/mc/transition/TransitionRandom.cpp index aa01c70536..7470be286d 100644 --- a/src/mc/transition/TransitionRandom.cpp +++ b/src/mc/transition/TransitionRandom.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -23,4 +23,11 @@ RandomTransition::RandomTransition(aid_t issuer, int times_considered, std::stri xbt_assert(stream >> min_ >> max_); } +bool RandomTransition::reversible_race(const Transition* other) const +{ + xbt_assert(type_ == Type::RANDOM, "Unexpected transition type %s", to_c_str(type_)); + + return true; // Random is always enabled +} + } // namespace simgrid::mc diff --git a/src/mc/transition/TransitionRandom.hpp b/src/mc/transition/TransitionRandom.hpp index 8c53c3b0eb..27d9757a27 100644 --- a/src/mc/transition/TransitionRandom.hpp +++ b/src/mc/transition/TransitionRandom.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -17,7 +17,14 @@ class RandomTransition : public Transition { public: std::string to_string(bool verbose) const override; RandomTransition(aid_t issuer, int times_considered, std::stringstream& stream); - bool depends(const Transition* other) const override { return false; } // Independent with any other transition + bool depends(const Transition* other) const override + { + if (other->type_ < type_) + return other->depends(this); + + return aid_ == other->aid_; + } // Independent with any other transition + bool reversible_race(const Transition* other) const override; }; } // namespace simgrid::mc diff --git a/src/mc/transition/TransitionSynchro.cpp b/src/mc/transition/TransitionSynchro.cpp index 99aa4c2028..3d0e0cd794 100644 --- a/src/mc/transition/TransitionSynchro.cpp +++ b/src/mc/transition/TransitionSynchro.cpp @@ -1,9 +1,11 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/mc/transition/TransitionSynchro.hpp" +#include "src/mc/mc_forward.hpp" +#include "src/mc/transition/TransitionObjectAccess.hpp" #include "xbt/asserts.h" #include "xbt/ex.h" #include "xbt/string.hpp" @@ -29,12 +31,16 @@ bool BarrierTransition::depends(const Transition* o) const if (o->type_ < type_) return o->depends(this); - if (auto* other = dynamic_cast(o)) { + // Actions executed by the same actor are always dependent + if (o->aid_ == aid_) + return true; + + if (const auto* other = dynamic_cast(o)) { if (bar_ != other->bar_) return false; // LOCK indep LOCK: requests are not ordered in a barrier - if (type_ == Type::BARRIER_LOCK && other->type_ == Type::BARRIER_LOCK) + if (type_ == Type::BARRIER_ASYNC_LOCK && other->type_ == Type::BARRIER_ASYNC_LOCK) return false; // WAIT indep WAIT: requests are not ordered @@ -46,10 +52,23 @@ bool BarrierTransition::depends(const Transition* o) const return false; // barriers are INDEP with non-barrier transitions } +bool BarrierTransition::reversible_race(const Transition* other) const +{ + switch (type_) { + case Type::BARRIER_ASYNC_LOCK: + return true; // BarrierAsyncLock is always enabled + case Type::BARRIER_WAIT: + // If the other event is a barrier lock event, then we are not reversible; + // otherwise we are reversible. + return other->type_ != Transition::Type::BARRIER_ASYNC_LOCK; + default: + xbt_die("Unexpected transition type %s", to_c_str(type_)); + } +} std::string MutexTransition::to_string(bool verbose) const { - return xbt::string_printf("%s(mutex: %" PRIxPTR ", owner:%ld)", Transition::to_c_str(type_), mutex_, owner_); + return xbt::string_printf("%s(mutex: %" PRIxPTR ", owner: %ld)", Transition::to_c_str(type_), mutex_, owner_); } MutexTransition::MutexTransition(aid_t issuer, int times_considered, Type type, std::stringstream& stream) @@ -63,21 +82,31 @@ bool MutexTransition::depends(const Transition* o) const if (o->type_ < type_) return o->depends(this); + // Actions executed by the same actor are always dependent + if (o->aid_ == aid_) + return true; + // type_ <= other->type_ in MUTEX_LOCK, MUTEX_TEST, MUTEX_TRYLOCK, MUTEX_UNLOCK, MUTEX_WAIT, - if (auto* other = dynamic_cast(o)) { + if (const auto* other = dynamic_cast(o)) { // Theorem 4.4.7: Any pair of synchronization actions of distinct actors concerning distinct mutexes are independent if (mutex_ != other->mutex_) return false; // Theorem 4.4.11: LOCK indep TEST/WAIT. // If both enabled, the result does not depend on their order. If WAIT is not enabled, LOCK won't enable it. - if (type_ == Type::MUTEX_LOCK && (other->type_ == Type::MUTEX_TEST || other->type_ == Type::MUTEX_WAIT)) + if (type_ == Type::MUTEX_ASYNC_LOCK && (other->type_ == Type::MUTEX_TEST || other->type_ == Type::MUTEX_WAIT)) return false; // Theorem 4.4.8: LOCK indep UNLOCK. // pop_front and push_back are independent. - if (type_ == Type::MUTEX_LOCK && other->type_ == Type::MUTEX_UNLOCK) + if (type_ == Type::MUTEX_ASYNC_LOCK && other->type_ == Type::MUTEX_UNLOCK) + return false; + + // Theorem 4.4.9: LOCK indep UNLOCK. + // any combination of wait and test is indenpendent. + if ((type_ == Type::MUTEX_WAIT || type_ == Type::MUTEX_TEST) && + (other->type_ == Type::MUTEX_WAIT || other->type_ == Type::MUTEX_TEST)) return false; // TEST is a pure function; TEST/WAIT won't change the owner; TRYLOCK will always fail if TEST is enabled (because a @@ -98,42 +127,69 @@ bool MutexTransition::depends(const Transition* o) const return false; // mutexes are INDEP with non-mutex transitions } +bool SemaphoreTransition::reversible_race(const Transition* other) const +{ + switch (type_) { + case Type::SEM_ASYNC_LOCK: + return true; // SemAsyncLock is always enabled + case Type::SEM_UNLOCK: + return true; // SemUnlock is always enabled + case Type::SEM_WAIT: + if (other->type_ == Transition::Type::SEM_UNLOCK && + static_cast(other)->get_capacity() <= 1) { + return false; + } + xbt_die("SEM_WAIT that is dependent with a SEM_UNLOCK should not be reversible. FixMe"); + return true; + default: + xbt_die("Unexpected transition type %s", to_c_str(type_)); + } +} + std::string SemaphoreTransition::to_string(bool verbose) const { - if (type_ == Type::SEM_LOCK || type_ == Type::SEM_UNLOCK) - return xbt::string_printf("%s(semaphore: %" PRIxPTR ")", Transition::to_c_str(type_), sem_); + if (type_ == Type::SEM_ASYNC_LOCK || type_ == Type::SEM_UNLOCK) + return xbt::string_printf("%s(semaphore: %u, capacity: %u)", Transition::to_c_str(type_), sem_, capacity_); if (type_ == Type::SEM_WAIT) - return xbt::string_printf("%s(semaphore: %" PRIxPTR ", granted: %s)", Transition::to_c_str(type_), sem_, - granted_ ? "yes" : "no"); + return xbt::string_printf("%s(semaphore: %u, capacity: %u, granted: %s)", Transition::to_c_str(type_), sem_, + capacity_, granted_ ? "yes" : "no"); THROW_IMPOSSIBLE; } SemaphoreTransition::SemaphoreTransition(aid_t issuer, int times_considered, Type type, std::stringstream& stream) : Transition(type, issuer, times_considered) { - xbt_assert(stream >> sem_ >> granted_); + xbt_assert(stream >> sem_ >> granted_ >> capacity_); } bool SemaphoreTransition::depends(const Transition* o) const { if (o->type_ < type_) return o->depends(this); - if (auto* other = dynamic_cast(o)) { + // Actions executed by the same actor are always dependent + if (o->aid_ == aid_) + return true; + + if (const auto* other = dynamic_cast(o)) { if (sem_ != other->sem_) return false; // LOCK indep UNLOCK: pop_front and push_back are independent. - if (type_ == Type::SEM_LOCK && other->type_ == Type::SEM_UNLOCK) + if (type_ == Type::SEM_ASYNC_LOCK && other->type_ == Type::SEM_UNLOCK) return false; // LOCK indep WAIT: If both enabled, ordering has no impact on the result. If WAIT is not enabled, LOCK won't enable // it. - if (type_ == Type::SEM_LOCK && other->type_ == Type::SEM_WAIT) + if (type_ == Type::SEM_ASYNC_LOCK && other->type_ == Type::SEM_WAIT) return false; // UNLOCK indep UNLOCK: ordering of two pop_front has no impact if (type_ == Type::SEM_UNLOCK && other->type_ == Type::SEM_UNLOCK) return false; + // UNLOCK indep with a WAIT if the semaphore had enought capacity anyway + if (type_ == Type::SEM_UNLOCK && capacity_ > 1 && other->type_ == Type::SEM_WAIT) + return false; + // WAIT indep WAIT: // if both enabled (may happen in the initial value is sufficient), the ordering has no impact on the result. // If only one enabled, the other won't be enabled by the first one. @@ -147,4 +203,26 @@ bool SemaphoreTransition::depends(const Transition* o) const return false; // semaphores are INDEP with non-semaphore transitions } +bool MutexTransition::reversible_race(const Transition* other) const +{ + switch (type_) { + case Type::MUTEX_ASYNC_LOCK: + return true; // MutexAsyncLock is always enabled + case Type::MUTEX_TEST: + return true; // MutexTest is always enabled + case Type::MUTEX_TRYLOCK: + return true; // MutexTrylock is always enabled + case Type::MUTEX_UNLOCK: + return true; // MutexUnlock is always enabled + + case Type::MUTEX_WAIT: + // Only an Unlock can be dependent with a Wait + // and in this case, that Unlock enabled the wait + // Not reversible + return false; + default: + xbt_die("Unexpected transition type %s", to_c_str(type_)); + } +} + } // namespace simgrid::mc diff --git a/src/mc/transition/TransitionSynchro.hpp b/src/mc/transition/TransitionSynchro.hpp index 6a4d51ea6a..d8b7d030eb 100644 --- a/src/mc/transition/TransitionSynchro.hpp +++ b/src/mc/transition/TransitionSynchro.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -19,6 +19,7 @@ public: std::string to_string(bool verbose) const override; BarrierTransition(aid_t issuer, int times_considered, Type type, std::stringstream& stream); bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; }; class MutexTransition : public Transition { @@ -29,16 +30,24 @@ public: std::string to_string(bool verbose) const override; MutexTransition(aid_t issuer, int times_considered, Type type, std::stringstream& stream); bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; + + uintptr_t get_mutex() const { return this->mutex_; } + aid_t get_owner() const { return this->owner_; } }; class SemaphoreTransition : public Transition { - uintptr_t sem_; + unsigned int sem_; // ID bool granted_; + unsigned capacity_; public: std::string to_string(bool verbose) const override; SemaphoreTransition(aid_t issuer, int times_considered, Type type, std::stringstream& stream); bool depends(const Transition* other) const override; + bool reversible_race(const Transition* other) const override; + + int get_capacity() const { return capacity_; } }; } // namespace simgrid::mc diff --git a/src/mc/udpor_global.cpp b/src/mc/udpor_global.cpp deleted file mode 100644 index b3815246cc..0000000000 --- a/src/mc/udpor_global.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "udpor_global.hpp" -#include "xbt/log.h" -#include - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_udpor_global, mc, "udpor_global"); - -namespace simgrid::mc { - -EventSet EvtSetTools::makeUnion(const EventSet& s1, const EventSet& s2) -{ - EventSet res = s1; - for (auto evt : s2) - EvtSetTools::pushBack(res, evt); - return res; -} - -void EvtSetTools::pushBack(EventSet& events, UnfoldingEvent* e) -{ - if (not EvtSetTools::contains(events, e)) - events.push_back(e); -} - -bool EvtSetTools::contains(const EventSet& events, const UnfoldingEvent* e) -{ - return std::any_of(events.begin(), events.end(), [e](const UnfoldingEvent* evt) { return *evt == *e; }); -} - -} // namespace simgrid::mc diff --git a/src/mc/udpor_global.hpp b/src/mc/udpor_global.hpp deleted file mode 100644 index 60a6eb0947..0000000000 --- a/src/mc/udpor_global.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_MC_UDPOR_GLOBAL_HPP -#define SIMGRID_MC_UDPOR_GLOBAL_HPP - -#include -#include -#include - -namespace simgrid::mc { - -class UnfoldingEvent; -using EventSet = std::deque; - -class EvtSetTools { -public: - static bool contains(const EventSet& events, const UnfoldingEvent* e); - static UnfoldingEvent* find(const EventSet& events, const UnfoldingEvent* e); - static void subtract(EventSet& events, EventSet const& otherSet); - static bool depends(const EventSet& events, const EventSet& otherSet); - static bool isEmptyIntersection(EventSet evtS1, EventSet evtS2); - static EventSet makeUnion(const EventSet& s1, const EventSet& s2); - static void pushBack(EventSet& events, UnfoldingEvent* e); - static void remove(EventSet& events, UnfoldingEvent* e); - static EventSet minus(EventSet events, UnfoldingEvent* e); - static EventSet plus(EventSet events, UnfoldingEvent* e); -}; - -struct s_evset_in_t { - EventSet causuality_events; - EventSet cause; - EventSet ancestorSet; -}; - -class Configuration { -public: - EventSet events_; - EventSet maxEvent; // Events recently added to events_ - EventSet actorMaxEvent; // maximal events of the actors in current configuration - UnfoldingEvent* lastEvent; // The last added event - - Configuration plus_config(UnfoldingEvent*) const; - void createEvts(Configuration C, EventSet& result, const std::string& trans_tag, s_evset_in_t ev_sets, bool chk, - UnfoldingEvent* immPreEvt); - void updateMaxEvent(UnfoldingEvent*); // update maximal events of the configuration and actors - UnfoldingEvent* findActorMaxEvt(int actorId); // find maximal event of a Actor whose id = actorId - - UnfoldingEvent* findTestedComm(const UnfoldingEvent* testEvt); // find comm tested by action testTrans - - Configuration() = default; - Configuration(const Configuration&) = default; - Configuration& operator=(Configuration const&) = default; - Configuration(Configuration&&) = default; -}; - -class UnfoldingEvent { -public: - UnfoldingEvent(unsigned int nb_events, std::string const& trans_tag, EventSet const& causes, int sid = -1); - UnfoldingEvent(const UnfoldingEvent&) = default; - UnfoldingEvent& operator=(UnfoldingEvent const&) = default; - UnfoldingEvent(UnfoldingEvent&&) = default; - - EventSet getHistory() const; - - bool isConflict(UnfoldingEvent* event, UnfoldingEvent* otherEvent) const; - bool concernSameComm(const UnfoldingEvent* event, const UnfoldingEvent* otherEvent) const; - - // check otherEvent is in my history ? - bool inHistory(UnfoldingEvent* otherEvent) const; - - bool isImmediateConflict1(UnfoldingEvent* evt, UnfoldingEvent* otherEvt) const; - - bool conflictWithConfig(UnfoldingEvent* event, Configuration const& config) const; - /* TODO: implement */ - bool operator==(const UnfoldingEvent&) const { return false; }; - void print() const; - - inline int get_state_id() const { return state_id; } - inline void set_state_id(int sid) { state_id = sid; } - - inline std::string get_transition_tag() const { return transition_tag; } - inline void set_transition_tag(std::string_view tr_tag) { transition_tag = tr_tag; } - -private: - EventSet causes; // used to store directed ancestors of event e - int id = -1; - int state_id{-1}; - std::string transition_tag{""}; // The tag of the last transition that lead to creating the event - bool transition_is_IReceive(const UnfoldingEvent* testedEvt, const UnfoldingEvent* SdRcEvt) const; - bool transition_is_ISend(const UnfoldingEvent* testedEvt, const UnfoldingEvent* SdRcEvt) const; - bool check_tr_concern_same_comm(bool& chk1, bool& chk2, UnfoldingEvent* evt1, UnfoldingEvent* evt2) const; -}; -} // namespace simgrid::mc -#endif diff --git a/src/msg/msg_comm.cpp b/src/msg/msg_comm.cpp deleted file mode 100644 index 049c669ff7..0000000000 --- a/src/msg/msg_comm.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include - -#include "simgrid/Exception.hpp" -#include "simgrid/s4u/Actor.hpp" -#include "simgrid/s4u/Comm.hpp" -#include "simgrid/s4u/Exec.hpp" -#include "simgrid/s4u/Mailbox.hpp" -#include "src/instr/instr_private.hpp" -#include "src/msg/msg_private.hpp" - -namespace simgrid::msg { - -bool Comm::test() -{ - bool finished = false; - - try { - finished = s_comm->test(); - if (finished && task_received != nullptr) { - /* I am the receiver */ - (*task_received)->set_not_used(); - } - } catch (const simgrid::TimeoutException&) { - status_ = MSG_TIMEOUT; - finished = true; - } catch (const simgrid::CancelException&) { - status_ = MSG_TASK_CANCELED; - finished = true; - } catch (const simgrid::NetworkFailureException&) { - status_ = MSG_TRANSFER_FAILURE; - finished = true; - } - - return finished; -} -msg_error_t Comm::wait_for(double timeout) -{ - try { - s_comm->wait_for(timeout); - - if (task_received != nullptr) { - /* I am the receiver */ - (*task_received)->set_not_used(); - } - - /* FIXME: these functions are not traceable */ - } catch (const simgrid::TimeoutException&) { - status_ = MSG_TIMEOUT; - } catch (const simgrid::CancelException&) { - status_ = MSG_TASK_CANCELED; - } catch (const simgrid::NetworkFailureException&) { - status_ = MSG_TRANSFER_FAILURE; - } - - return status_; -} -} // namespace simgrid::msg - -/** - * @brief Checks whether a communication is done, and if yes, finalizes it. - * @param comm the communication to test - * @return 'true' if the communication is finished - * (but it may have failed, use MSG_comm_get_status() to know its status) - * or 'false' if the communication is not finished yet - * If the status is 'false', don't forget to use MSG_process_sleep() after the test. - */ -int MSG_comm_test(msg_comm_t comm) -{ - return comm->test(); -} - -/** - * @brief This function checks if a communication is finished. - * @param comms a vector of communications - * @return the position of the finished communication if any - * (but it may have failed, use MSG_comm_get_status() to know its status), or -1 if none is finished - */ -int MSG_comm_testany(const_xbt_dynar_t comms) -{ - ssize_t finished_index = -1; - - /* Create the equivalent array with SIMIX objects: */ - std::vector s_comms; - s_comms.reserve(xbt_dynar_length(comms)); - msg_comm_t comm; - unsigned int cursor; - xbt_dynar_foreach (comms, cursor, comm) - s_comms.push_back(comm->s_comm); - - msg_error_t status = MSG_OK; - try { - finished_index = simgrid::s4u::Comm::test_any(s_comms); - } catch (const simgrid::TimeoutException& e) { - finished_index = e.get_value(); - status = MSG_TIMEOUT; - } catch (const simgrid::CancelException& e) { - finished_index = e.get_value(); - status = MSG_TASK_CANCELED; - } catch (const simgrid::NetworkFailureException& e) { - finished_index = e.get_value(); - status = MSG_TRANSFER_FAILURE; - } - - if (finished_index != -1) { - comm = xbt_dynar_get_as(comms, finished_index, msg_comm_t); - /* the communication is finished */ - comm->set_status(status); - - if (status == MSG_OK && comm->task_received != nullptr) { - /* I am the receiver */ - (*comm->task_received)->set_not_used(); - } - } - - return static_cast(finished_index); -} - -/** @brief Destroys the provided communication. */ -void MSG_comm_destroy(const_msg_comm_t comm) -{ - delete comm; -} - -/** @brief Wait for the completion of a communication. - * - * It takes two parameters. - * @param comm the communication to wait. - * @param timeout Wait until the communication terminates or the timeout occurs. - * You can provide a -1 timeout to obtain an infinite timeout. - * @return msg_error_t - */ -msg_error_t MSG_comm_wait(msg_comm_t comm, double timeout) -{ - return comm->wait_for(timeout); -} - -/** @brief This function is called by a sender and permits waiting for each communication - * - * @param comm a vector of communication - * @param nb_elem is the size of the comm vector - * @param timeout for each call of MSG_comm_wait - */ -void MSG_comm_waitall(msg_comm_t* comm, int nb_elem, double timeout) -{ - for (int i = 0; i < nb_elem; i++) - comm[i]->wait_for(timeout); -} - -/** @brief This function waits for the first communication finished in a list. - * @param comms a vector of communications - * @return the position of the first finished communication - * (but it may have failed, use MSG_comm_get_status() to know its status) - */ -int MSG_comm_waitany(const_xbt_dynar_t comms) -{ - ssize_t finished_index = -1; - - /* Create the equivalent array with SIMIX objects: */ - std::vector s_comms; - s_comms.reserve(xbt_dynar_length(comms)); - msg_comm_t comm; - unsigned int cursor; - xbt_dynar_foreach (comms, cursor, comm) { - s_comms.push_back(comm->s_comm); - } - - msg_error_t status = MSG_OK; - try { - finished_index = simgrid::s4u::Comm::wait_any_for(s_comms, -1); - } catch (const simgrid::TimeoutException& e) { - finished_index = e.get_value(); - status = MSG_TIMEOUT; - } catch (const simgrid::CancelException& e) { - finished_index = e.get_value(); - status = MSG_TASK_CANCELED; - } catch (const simgrid::NetworkFailureException& e) { - finished_index = e.get_value(); - status = MSG_TRANSFER_FAILURE; - } - - xbt_assert(finished_index != -1, "WaitAny returned -1"); - - comm = xbt_dynar_get_as(comms, finished_index, msg_comm_t); - /* the communication is finished */ - comm->set_status(status); - - if (comm->task_received != nullptr) { - /* I am the receiver */ - (*comm->task_received)->set_not_used(); - } - - return static_cast(finished_index); -} - -/** - * @brief Returns the error (if any) that occurred during a finished communication. - * @param comm a finished communication - * @return the status of the communication, or #MSG_OK if no error occurred during the communication - */ -msg_error_t MSG_comm_get_status(const_msg_comm_t comm) -{ - return comm->get_status(); -} - -/** @brief Get a task (#msg_task_t) from a communication - * - * @param comm the communication where to get the task - * @return the task from the communication - */ -msg_task_t MSG_comm_get_task(const_msg_comm_t comm) -{ - xbt_assert(comm, "Invalid parameter"); - - return comm->task_received ? *comm->task_received : comm->task_sent; -} diff --git a/src/msg/msg_global.cpp b/src/msg/msg_global.cpp deleted file mode 100644 index a1d475bd28..0000000000 --- a/src/msg/msg_global.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "mc/mc.h" -#include "simgrid/s4u/Engine.hpp" -#include "simgrid/s4u/Host.hpp" -#include "src/instr/instr_private.hpp" -#include "src/kernel/EngineImpl.hpp" -#include "src/msg/msg_private.hpp" -#include - -XBT_LOG_NEW_CATEGORY(msg, "All MSG categories"); - -bool MSG_Global_t::debug_multiple_use = false; - -MSG_Global_t* msg_global = nullptr; - -static void MSG_exit(); - -/********************************* MSG **************************************/ - -/** - * @ingroup msg_simulation - * @brief Initialize MSG with less verifications - * You should use the MSG_init() function instead. Failing to do so may turn into PEBKAC some day. You've been warned. - */ -void MSG_init_nocheck(int* argc, char** argv) -{ - simgrid::instr::init(); - - if (not msg_global) { - simgrid::config::bind_flag(MSG_Global_t::debug_multiple_use, "msg/debug-multiple-use", - "Print backtraces of both processes when there is a conflict of multiple use of a task"); - - simgrid::kernel::EngineImpl::get_instance(argc, argv); - - msg_global = new MSG_Global_t(); - - msg_global->sent_msg = 0; - msg_global->task_copy_callback = nullptr; - msg_global->process_data_cleanup = nullptr; - simgrid::s4u::Actor::on_termination_cb([](simgrid::s4u::Actor const& actor) { - // free the data if a function was provided - void* userdata = sg_actor_get_data(&actor); - if (userdata && msg_global->process_data_cleanup) - msg_global->process_data_cleanup(userdata); - }); - } - - if(MC_is_active()){ - /* Ignore total amount of messages sent during the simulation for heap comparison */ - MC_ignore_heap(&msg_global->sent_msg, sizeof msg_global->sent_msg); - } - - if (simgrid::config::get_value("debug/clean-atexit")) - atexit(MSG_exit); -} - -void MSG_config(const char* key, const char* value) -{ - xbt_assert(msg_global,"ERROR: Please call MSG_init() before using MSG_config()"); - simgrid::config::set_as_string(key, value); -} - -static void MSG_exit() -{ - delete msg_global; - msg_global = nullptr; -} - -unsigned long int MSG_get_sent_msg() -{ - return msg_global->sent_msg; -} diff --git a/src/msg/msg_legacy.cpp b/src/msg/msg_legacy.cpp deleted file mode 100644 index 54afa6f647..0000000000 --- a/src/msg/msg_legacy.cpp +++ /dev/null @@ -1,443 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/Exception.hpp" -#include "simgrid/s4u/Engine.hpp" -#include "src/msg/msg_private.hpp" -#include "xbt/functional.hpp" - -#define MSG_CALL(type, oldname, args) - -/* ************************** Engine *************************** */ -void MSG_create_environment(const char* filename) -{ - simgrid_load_platform(filename); -} - -void MSG_launch_application(const char* filename) -{ - simgrid_load_deployment(filename); -} -msg_error_t MSG_main() -{ - simgrid_run(); - return MSG_OK; -} -void MSG_function_register(const char* name, int (*code)(int, char**)) -{ - simgrid::kernel::actor::ActorCodeFactory code_factory = [code](std::vector args) { - return simgrid::xbt::wrap_main(code, std::move(args)); - }; - simgrid::s4u::Engine::get_instance()->register_function(name, code_factory); -} -void MSG_function_register_default(int (*code)(int, char**)) -{ - simgrid::s4u::Engine::get_instance()->register_default( - [code](std::vector args) { return simgrid::xbt::wrap_main(code, std::move(args)); }); -} -double MSG_get_clock() -{ - return simgrid_get_clock(); -} - -/* ************************** Mailboxes ************************ */ -void MSG_mailbox_set_async(const char* alias) -{ - sg_mailbox_set_receiver(alias); -} -int MSG_task_listen(const char* alias) -{ - return sg_mailbox_listen(alias); -} - -/* ************************** Actors *************************** */ -void MSG_process_on_exit(int_f_int_pvoid_t fun, void* data) -{ - /* We can't use the sg_actor_on_exit, as the return type of the callback changed: the int in MSG is ignored and was - * removed in sg */ - simgrid::s4u::this_actor::on_exit([fun, data](bool failed) { fun(failed ? 1 /*FAILURE*/ : 0 /*SUCCESS*/, data); }); -} - -int MSG_process_get_PID(const_sg_actor_t actor) -{ - return sg_actor_get_pid(actor); -} -int MSG_process_get_PPID(const_sg_actor_t actor) -{ - return sg_actor_get_ppid(actor); -} -msg_process_t MSG_process_from_PID(int pid) -{ - return sg_actor_by_pid(pid); -} -const char* MSG_process_get_name(const_sg_actor_t actor) -{ - return sg_actor_get_name(actor); -} -sg_host_t MSG_process_get_host(const_sg_actor_t actor) -{ - return sg_actor_get_host(actor); -} -xbt_dict_t MSG_process_get_properties(const_sg_actor_t actor) -{ - return sg_actor_get_properties(actor); -} -const char* MSG_process_get_property_value(const_sg_actor_t actor, const char* name) -{ - return sg_actor_get_property_value(actor, name); -} -void MSG_process_suspend(sg_actor_t actor) -{ - sg_actor_suspend(actor); -} -void MSG_process_resume(sg_actor_t actor) -{ - sg_actor_resume(actor); -} -int MSG_process_is_suspended(const_sg_actor_t actor) -{ - return sg_actor_is_suspended(actor); -} -void MSG_process_restart(sg_actor_t actor) -{ - sg_actor_restart(actor); -} -void MSG_process_auto_restart_set(sg_actor_t actor, int auto_restart) -{ - sg_actor_set_auto_restart(actor, auto_restart); -} - -void MSG_process_daemonize(sg_actor_t actor) -{ - sg_actor_daemonize(actor); -} -void MSG_process_migrate(sg_actor_t actor, sg_host_t host) -{ - sg_actor_set_host(actor, host); -} -void MSG_process_join(const_sg_actor_t actor, double timeout) -{ - sg_actor_join(actor, timeout); -} -void MSG_process_kill(sg_actor_t actor) -{ - sg_actor_kill(actor); -} -void MSG_process_killall() -{ - sg_actor_kill_all(); -} -void MSG_process_set_kill_time(sg_actor_t actor, double kill_time) -{ - sg_actor_set_kill_time(actor, kill_time); -} -void MSG_process_yield() -{ - sg_actor_yield(); -} - -msg_error_t MSG_process_sleep(double duration) -{ - try { - sg_actor_sleep_for(duration); - return MSG_OK; - } catch (const simgrid::HostFailureException&) { - return MSG_HOST_FAILURE; - } -} - -/** @brief Returns the user data of a process. - * - * This function checks whether @a process is a valid pointer and returns the user data associated to this process. - */ -void* MSG_process_get_data(const_sg_actor_t process) -{ - xbt_assert(process != nullptr, "Invalid parameter: first parameter must not be nullptr!"); - - /* get from SIMIX the MSG process data, and then the user data */ - return sg_actor_get_data(process); -} - -/** @brief Sets the user data of a process. - * - * This function checks whether @a process is a valid pointer and sets the user data associated to this process. - */ -msg_error_t MSG_process_set_data(msg_process_t process, void* data) -{ - xbt_assert(process != nullptr, "Invalid parameter: first parameter must not be nullptr!"); - sg_actor_set_data(process, data); - - return MSG_OK; -} - -msg_process_t MSG_process_attach(const char* name, void* data, msg_host_t host, xbt_dict_t properties) -{ - return sg_actor_attach(name, data, host, properties); -} - -void MSG_process_detach() -{ - sg_actor_detach(); -} -aid_t MSG_process_self_PID() -{ - return sg_actor_self_get_pid(); -} - -/** @brief Return the PPID of the current process. - * - * This function returns the PID of the parent of the currently running #msg_process_t. - */ -aid_t MSG_process_self_PPID() -{ - return sg_actor_self_get_ppid(); -} - -/** @brief Return the name of the current process. */ -const char* MSG_process_self_name() -{ - return sg_actor_self_get_name(); -} -/** @brief Return the current process. - * - * This function returns the currently running #msg_process_t. - */ -msg_process_t MSG_process_self() -{ - return sg_actor_self(); -} - -/** @brief Take an extra reference on that process to prevent it to be garbage-collected */ -void MSG_process_ref(const_sg_actor_t process) -{ - sg_actor_ref(process); -} -/** @brief Release a reference on that process so that it can get be garbage-collected */ -void MSG_process_unref(const_sg_actor_t process) -{ - sg_actor_unref(process); -} - -/* ************************** NetZones *************************** */ -sg_netzone_t MSG_zone_get_root() -{ - return sg_zone_get_root(); -} -const char* MSG_zone_get_name(const_sg_netzone_t zone) -{ - return sg_zone_get_name(zone); -} -sg_netzone_t MSG_zone_get_by_name(const char* name) -{ - return sg_zone_get_by_name(name); -} -void MSG_zone_get_sons(const_sg_netzone_t zone, xbt_dict_t whereto) -{ - return sg_zone_get_sons(zone, whereto); -} -const char* MSG_zone_get_property_value(const_sg_netzone_t zone, const char* name) -{ - return sg_zone_get_property_value(zone, name); -} -void MSG_zone_set_property_value(sg_netzone_t zone, const char* name, const char* value) -{ - sg_zone_set_property_value(zone, name, value); -} -void MSG_zone_get_hosts(const_sg_netzone_t zone, xbt_dynar_t whereto) -{ - sg_zone_get_hosts(zone, whereto); -} - -/* ************************** hosts *************************** */ -size_t MSG_get_host_number() -{ - return sg_host_count(); -} -sg_host_t MSG_get_host_by_name(const char* name) -{ - return sg_host_by_name(name); -} -sg_host_t MSG_host_by_name(const char* name) -{ - return sg_host_by_name(name); -} -const char* MSG_host_get_name(const_sg_host_t host) -{ - return sg_host_get_name(host); -} -void* MSG_host_get_data(const_sg_host_t host) -{ - return sg_host_get_data(host); -} -void MSG_host_set_data(sg_host_t host, void* data) -{ - return sg_host_set_data(host, data); -} -double MSG_host_get_speed(const_sg_host_t host) -{ - return sg_host_get_speed(host); -} -double MSG_host_get_power_peak_at(const_sg_host_t host, int pstate_index) -{ - return sg_host_get_pstate_speed(host, pstate_index); -} -int MSG_host_get_core_number(const_sg_host_t host) -{ - return sg_host_core_count(host); -} -int MSG_host_get_nb_pstates(const_sg_host_t host) -{ - return sg_host_get_nb_pstates(host); -} -int MSG_host_get_pstate(const_sg_host_t host) -{ - return sg_host_get_pstate(host); -} -void MSG_host_set_pstate(sg_host_t host, int pstate) -{ - sg_host_set_pstate(host, pstate); -} -void MSG_host_on(sg_host_t h) -{ - sg_host_turn_on(h); -} -void MSG_host_off(sg_host_t h) -{ - sg_host_turn_off(h); -} -int MSG_host_is_on(const_sg_host_t h) -{ - return sg_host_is_on(h); -} -xbt_dict_t MSG_host_get_properties(const_sg_host_t host) -{ - return sg_host_get_properties(host); -} -const char* MSG_host_get_property_value(const_sg_host_t host, const char* name) -{ - return sg_host_get_property_value(host, name); -} -void MSG_host_set_property_value(sg_host_t host, const char* name, const char* value) -{ - sg_host_set_property_value(host, name, value); -} -void MSG_host_get_process_list(const_sg_host_t host, xbt_dynar_t whereto) -{ - sg_host_get_actor_list(host, whereto); -} -sg_host_t MSG_host_self() -{ - return sg_host_self(); -} - -double MSG_host_get_load(const_sg_host_t host) -{ - return sg_host_get_load(host); -} -/* ************************** Virtual Machines *************************** */ -sg_vm_t MSG_vm_create_core(sg_host_t pm, const char* name) -{ - return sg_vm_create_core(pm, name); -} -sg_vm_t MSG_vm_create_multicore(sg_host_t pm, const char* name, int coreAmount) -{ - return sg_vm_create_multicore(pm, name, coreAmount); -} -int MSG_vm_is_created(const_sg_vm_t vm) -{ - return sg_vm_is_created(vm); -} -int MSG_vm_is_running(const_sg_vm_t vm) -{ - return sg_vm_is_running(vm); -} -int MSG_vm_is_suspended(const_sg_vm_t vm) -{ - return sg_vm_is_suspended(vm); -} -const char* MSG_vm_get_name(const_sg_vm_t vm) -{ - return sg_vm_get_name(vm); -} -void MSG_vm_set_ramsize(sg_vm_t vm, size_t size) -{ - sg_vm_set_ramsize(vm, size); -} -size_t MSG_vm_get_ramsize(const_sg_vm_t vm) -{ - return sg_vm_get_ramsize(vm); -} -sg_host_t MSG_vm_get_pm(const_sg_vm_t vm) -{ - return sg_vm_get_pm(vm); -} -void MSG_vm_set_bound(sg_vm_t vm, double bound) -{ - sg_vm_set_bound(vm, bound); -} -void MSG_vm_start(sg_vm_t vm) -{ - sg_vm_start(vm); -} -void MSG_vm_suspend(sg_vm_t vm) -{ - sg_vm_suspend(vm); -} -void MSG_vm_resume(sg_vm_t vm) -{ - sg_vm_resume(vm); -} -void MSG_vm_shutdown(sg_vm_t vm) -{ - sg_vm_shutdown(vm); -} -void MSG_vm_destroy(sg_vm_t vm) -{ - sg_vm_destroy(vm); -} -/********* barriers ************/ -sg_bar_t MSG_barrier_init(unsigned int count) -{ - return sg_barrier_init(count); -} - -void MSG_barrier_destroy(sg_bar_t bar) -{ - sg_barrier_destroy(bar); -} - -int MSG_barrier_wait(sg_bar_t bar) -{ - return sg_barrier_wait(bar); -} - -sg_sem_t MSG_sem_init(int initial_value) -{ - return sg_sem_init(initial_value); -} -void MSG_sem_acquire(sg_sem_t sem) -{ - sg_sem_acquire(sem); -} -int MSG_sem_acquire_timeout(sg_sem_t sem, double timeout) -{ - return sg_sem_acquire_timeout(sem, timeout); -} -void MSG_sem_release(sg_sem_t sem) -{ - sg_sem_release(sem); -} -int MSG_sem_get_capacity(const_sg_sem_t sem) -{ - return sg_sem_get_capacity(sem); -} -void MSG_sem_destroy(const_sg_sem_t sem) -{ - sg_sem_destroy(sem); -} -int MSG_sem_would_block(const_sg_sem_t sem) -{ - return sg_sem_would_block(sem); -} diff --git a/src/msg/msg_private.hpp b/src/msg/msg_private.hpp deleted file mode 100644 index 2579f3b793..0000000000 --- a/src/msg/msg_private.hpp +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef MSG_PRIVATE_HPP -#define MSG_PRIVATE_HPP - -#include "simgrid/Exception.hpp" -#include "simgrid/msg.h" -#include "src/kernel/activity/CommImpl.hpp" -#include -#include - -#include - -/**************** datatypes **********************************/ -namespace simgrid { - -extern template class XBT_PUBLIC xbt::Extendable; - -namespace msg { -class Task : public xbt::Extendable { - std::string name_ = ""; - std::string tracing_category_ = ""; - long long int id_; - - double timeout_ = -1; /* Default timeout is infinite */ - double priority_ = 1.0; - double bound_ = 0.0; /* Capping for CPU resource, or 0 for no capping */ - double rate_ = -1; /* Capping for network resource, or -1 for no capping*/ - bool is_used_ = false; /* Indicates whether the task is used in SIMIX currently */ - - explicit Task(const std::string& name, double flops_amount, double bytes_amount, void* data); - explicit Task(const std::string& name, std::vector&& hosts, std::vector&& flops_amount, - std::vector&& bytes_amount, void* data); - - void report_multiple_use() const; - -public: - static Task* create(const std::string& name, double flops_amount, double bytes_amount, void* data); - static Task* create_parallel(const std::string& name, int host_nb, const msg_host_t* host_list, double* flops_amount, - double* bytes_amount, void* data); - msg_error_t execute(); - msg_error_t send(const std::string& alias, double timeout); - s4u::CommPtr send_async(const std::string& alias, void_f_pvoid_t cleanup, bool detached); - - void cancel(); - - Task(const Task&) = delete; - Task& operator=(const Task&) = delete; - - bool is_used() const { return is_used_; } - bool is_parallel() const { return parallel_; } - - void set_used(); - void set_not_used() { this->is_used_ = false; } - const std::string& get_name() const { return name_; } - const char* get_cname() const { return name_.c_str(); } - void set_name(const char* new_name) { name_ = std::string(new_name); } - void set_tracing_category(const char* category) { tracing_category_ = category ? category : ""; } - const std::string& get_tracing_category() const { return tracing_category_; } - bool has_tracing_category() { return not tracing_category_.empty(); } - long long int get_id() const { return id_; } - double get_priority() const { return priority_; } - void set_priority(double priority); - void set_bound(double bound) { bound_ = bound; } - double get_bound() const { return bound_; } - void set_rate(double rate) { rate_ = rate; } - double get_rate() const { return rate_; } - void set_timeout(double timeout) { timeout_ = timeout; } - - s4u::Actor* get_sender() const; - s4u::Host* get_source() const; - - s4u::ExecPtr compute = nullptr; /* S4U modeling of computation */ - s4u::CommPtr comm = nullptr; /* S4U modeling of communication */ - double flops_amount = 0.0; /* Computation size */ - double bytes_amount = 0.0; /* Data size */ - - /******* Parallel Tasks Only !!!! *******/ - bool parallel_ = false; - std::vector hosts_; - std::vector flops_parallel_amount; - std::vector bytes_parallel_amount; -}; - -class Comm { - msg_error_t status_ = MSG_OK; /* status of the communication once finished */ -public: - Task* task_sent; /* task sent (NULL for the receiver) */ - Task** task_received; /* where the task will be received (NULL for the sender) */ - s4u::CommPtr s_comm; /* SIMIX communication object encapsulated (the same for both processes) */ - Comm(msg_task_t sent, msg_task_t* received, s4u::CommPtr comm) - : task_sent(sent), task_received(received), s_comm(std::move(comm)) - { - } - bool test(); - msg_error_t wait_for(double timeout); - void set_status(msg_error_t status) { status_ = status; } - msg_error_t get_status() const { return status_; } -}; - -} // namespace msg -} // namespace simgrid - -/************************** Global variables ********************************/ -struct MSG_Global_t { - static bool debug_multiple_use; /* whether we want an error message when reusing the same Task for 2 things */ - std::atomic_int_fast32_t sent_msg; /* Total amount of messages sent during the simulation */ - void (*task_copy_callback)(msg_task_t task, msg_process_t src, msg_process_t dst); - void_f_pvoid_t process_data_cleanup; -}; - -XBT_PUBLIC_DATA MSG_Global_t* msg_global; - -/*************************************************************/ - -#endif diff --git a/src/msg/msg_process.cpp b/src/msg/msg_process.cpp deleted file mode 100644 index 7a0e6a0be8..0000000000 --- a/src/msg/msg_process.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "msg_private.hpp" -#include "simgrid/Exception.hpp" -#include "simgrid/s4u/Host.hpp" -#include "src/kernel/EngineImpl.hpp" - -/******************************** Process ************************************/ -/** @brief Creates and runs a new #msg_process_t. - * - * Does exactly the same as #MSG_process_create_with_arguments but without providing standard arguments - * (@a argc, @a argv, @a start_time, @a kill_time). - */ -msg_process_t MSG_process_create(const char* name, int (*code)(int, char**), void* data, msg_host_t host) -{ - return MSG_process_create_with_environment(name == nullptr ? "" : name, code, data, host, 0, nullptr, nullptr); -} - -/** @brief Creates and runs a new process. - - * A constructor for #msg_process_t taking four arguments and returning the corresponding object. The structure (and - * the corresponding thread) is created, and put in the list of ready process. - * @param name a name for the object. It is for user-level information and can be nullptr. - * @param code is a function describing the behavior of the process. - * @param data a pointer to any data one may want to attach to the new object. It is for user-level information and - * can be nullptr. It can be retrieved with the function MSG_process_get_data(). - * @param host the location where the new process is executed. - * @param argc first argument passed to @a code - * @param argv second argument passed to @a code - */ - -msg_process_t MSG_process_create_with_arguments(const char* name, int (*code)(int, char**), void* data, msg_host_t host, - int argc, char** argv) -{ - return MSG_process_create_with_environment(name, code, data, host, argc, argv, nullptr); -} - -/** - * @brief Creates and runs a new #msg_process_t. - - * A constructor for #msg_process_t taking four arguments and returning the corresponding object. The structure (and - * the corresponding thread) is created, and put in the list of ready process. - * @param name a name for the object. It is for user-level information and can be nullptr. - * @param code is a function describing the behavior of the process. - * @param data a pointer to any data one may want to attach to the new object. It is for user-level information and - * can be nullptr. It can be retrieved with the function MSG_process_get_data(). - * @param host the location where the new process is executed. - * @param argc first argument passed to @a code - * @param argv second argument passed to @a code. WARNING, these strings are freed by the SimGrid kernel when the - * process exits, so they cannot be static nor shared between several processes. - * @param properties list a properties defined for this process - * @see msg_process_t - * @return The new corresponding object. - */ -msg_process_t MSG_process_create_with_environment(const char* name, int (*code)(int, char**), void* data, - msg_host_t host, int argc, char** argv, xbt_dict_t properties) -{ - xbt_assert(host != nullptr, "Invalid parameters: host param must not be nullptr"); - sg_actor_t actor = sg_actor_init(std::move(name), host); - - try { - if (data != nullptr) { - sg_actor_set_data(actor, data); - xbt_dict_cursor_t cursor = nullptr; - char* key; - char* value; - xbt_dict_foreach (properties, cursor, key, value) - actor->set_property(key, value); - } - actor->start(std::move(simgrid::xbt::wrap_main(code, argc, argv))); - } catch (simgrid::HostFailureException const&) { - xbt_die("Could not launch a new process on failed host %s.", host->get_cname()); - } - - xbt_dict_free(&properties); - for (int i = 0; i != argc; ++i) - xbt_free(argv[i]); - xbt_free(argv); - - simgrid::s4u::this_actor::yield(); - return actor; -} - -/** @brief Sets a cleanup function to be called to free the userdata of a process when a process is destroyed. - * @param data_cleanup a cleanup function for the userdata of a process, or nullptr to call no function - */ -XBT_PUBLIC void MSG_process_set_data_cleanup(void_f_pvoid_t data_cleanup) -{ - msg_global->process_data_cleanup = data_cleanup; -} diff --git a/src/msg/msg_task.cpp b/src/msg/msg_task.cpp deleted file mode 100644 index fc934d2abb..0000000000 --- a/src/msg/msg_task.cpp +++ /dev/null @@ -1,811 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "msg_private.hpp" -#include "src/instr/instr_private.hpp" -#include -#include -#include -#include - -#include -#include - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_task, msg, "Logging specific to MSG (task)"); - -namespace simgrid { - -template class xbt::Extendable; - -namespace msg { - -Task::Task(const std::string& name, double flops_amount, double bytes_amount, void* data) - : name_(name), flops_amount(flops_amount), bytes_amount(bytes_amount) -{ - static std::atomic_ullong counter{0}; - id_ = counter++; - set_data(data); - if (MC_is_active()) - MC_ignore_heap(&id_, sizeof id_); -} - -Task::Task(const std::string& name, std::vector&& hosts, std::vector&& flops_amount, - std::vector&& bytes_amount, void* data) - : Task(name, 1.0, 0, data) -{ - parallel_ = true; - hosts_ = std::move(hosts); - flops_parallel_amount = std::move(flops_amount); - bytes_parallel_amount = std::move(bytes_amount); -} - -Task* Task::create(const std::string& name, double flops_amount, double bytes_amount, void* data) -{ - return new Task(name, flops_amount, bytes_amount, data); -} - -Task* Task::create_parallel(const std::string& name, int host_nb, const msg_host_t* host_list, double* flops_amount, - double* bytes_amount, void* data) -{ - std::vector hosts(host_list, host_list + host_nb); - std::vector flops; - std::vector bytes; - if (flops_amount != nullptr) - flops = std::vector(flops_amount, flops_amount + host_nb); - if (bytes_amount != nullptr) - bytes = std::vector(bytes_amount, bytes_amount + host_nb * host_nb); - - return new Task(name, std::move(hosts), std::move(flops), std::move(bytes), data); -} - -msg_error_t Task::execute() -{ - /* checking for infinite values */ - xbt_assert(std::isfinite(flops_amount), "flops_amount is not finite!"); - - msg_error_t status = MSG_OK; - if (flops_amount <= 0.0) - return MSG_OK; - - try { - set_used(); - if (parallel_) - compute = s4u::this_actor::exec_init(hosts_, flops_parallel_amount, bytes_parallel_amount); - else - compute = s4u::this_actor::exec_init(flops_amount); - - compute->set_name(name_) - ->set_tracing_category(tracing_category_) - ->set_priority(1 / priority_) - ->set_bound(bound_) - ->wait_for(timeout_); - - set_not_used(); - XBT_DEBUG("Execution task '%s' finished", get_cname()); - } catch (const HostFailureException&) { - status = MSG_HOST_FAILURE; - } catch (const TimeoutException&) { - status = MSG_TIMEOUT; - } catch (const CancelException&) { - status = MSG_TASK_CANCELED; - } - - /* action ended, set comm and compute = nullptr, the actions is already destroyed in the main function */ - flops_amount = 0.0; - comm = nullptr; - compute = nullptr; - - return status; -} - -s4u::CommPtr Task::send_async(const std::string& alias, void_f_pvoid_t cleanup, bool detached) -{ - if (TRACE_actor_is_enabled()) { - auto* process_container = instr::Container::by_name(instr_pid(*MSG_process_self())); - std::string key = std::string("p") + std::to_string(get_id()); - instr::Container::get_root()->get_link("ACTOR_LINK")->start_event(process_container, "SR", key); - } - - /* Prepare the task to send */ - set_used(); - this->comm = nullptr; - msg_global->sent_msg++; - - s4u::CommPtr s4u_comm = s4u::Mailbox::by_name(alias)->put_init(this, bytes_amount)->set_rate(get_rate()); - if (TRACE_is_enabled() && has_tracing_category()) - s4u_comm->set_tracing_category(tracing_category_); - - comm = s4u_comm; - - if (detached) - comm->detach(cleanup); - else - comm->start(); - - return comm; -} - -msg_error_t Task::send(const std::string& alias, double timeout) -{ - msg_error_t ret = MSG_OK; - /* Try to send it */ - try { - comm = nullptr; // needed, otherwise MC gets confused. - s4u::CommPtr s4u_comm = send_async(alias, nullptr, false); - comm = s4u_comm; - comm->wait_for(timeout); - } catch (const TimeoutException&) { - ret = MSG_TIMEOUT; - } catch (const CancelException&) { - ret = MSG_HOST_FAILURE; - } catch (const NetworkFailureException&) { - ret = MSG_TRANSFER_FAILURE; - /* If the send failed, it is not used anymore */ - set_not_used(); - } - - return ret; -} -void Task::cancel() -{ - if (compute) { - compute->cancel(); - } else if (comm) { - comm->cancel(); - } - set_not_used(); -} - -void Task::set_priority(double priority) -{ - xbt_assert(std::isfinite(1.0 / priority), "priority is not finite!"); - priority_ = 1.0 / priority; -} - -s4u::Actor* Task::get_sender() const -{ - return comm ? comm->get_sender() : nullptr; -} - -s4u::Host* Task::get_source() const -{ - return comm ? comm->get_sender()->get_host() : nullptr; -} - -void Task::set_used() -{ - if (is_used_) - report_multiple_use(); - is_used_ = true; -} - -void Task::report_multiple_use() const -{ - if (MSG_Global_t::debug_multiple_use) { - XBT_ERROR("This task is already used in there:"); - // TODO, backtrace - XBT_ERROR(""); - XBT_ERROR("And you try to reuse it from here:"); - xbt_backtrace_display_current(); - } else { - xbt_die("This task is still being used somewhere else. You cannot send it now. Go fix your code!" - "(use --cfg=msg/debug-multiple-use:on to get the backtrace of the other process)"); - } -} -} // namespace msg -} // namespace simgrid - -/********************************* Task **************************************/ -/** @brief Creates a new task - * - * A constructor for msg_task_t taking four arguments. - * - * @param name a name for the object. It is for user-level information and can be nullptr. - * @param flop_amount a value of the processing amount (in flop) needed to process this new task. - * If 0, then it cannot be executed with MSG_task_execute(). This value has to be >=0. - * @param message_size a value of the amount of data (in bytes) needed to transfer this new task. If 0, then it cannot - * be transferred with MSG_task_send() and MSG_task_recv(). This value has to be >=0. - * @param data a pointer to any data may want to attach to the new object. It is for user-level information and can - * be nullptr. It can be retrieved with the function MSG_task_get_data(). - * @return The new corresponding object. - */ -msg_task_t MSG_task_create(const char *name, double flop_amount, double message_size, void *data) -{ - return simgrid::msg::Task::create(name ? name : "", flop_amount, message_size, data); -} - -/** @brief Creates a new parallel task - * - * A constructor for #msg_task_t taking six arguments. - * - * @beginrst - * See :ref:`simgrid::s4u::this_actor::parallel_execute() ` for - * the exact semantic of the parameters. - * @endrst - * - * @param name a name for the object. It is for user-level information and can be nullptr. - * @param host_nb the number of hosts implied in the parallel task. - * @param host_list an array of @p host_nb msg_host_t. - * @param flops_amount an array of @p host_nb doubles. - * flops_amount[i] is the total number of operations that have to be performed on host_list[i]. - * @param bytes_amount an array of @p host_nb* @p host_nb doubles. - * @param data a pointer to any data may want to attach to the new object. - * It is for user-level information and can be nullptr. - * It can be retrieved with the function MSG_task_get_data(). - */ -msg_task_t MSG_parallel_task_create(const char *name, int host_nb, const msg_host_t * host_list, - double *flops_amount, double *bytes_amount, void *data) -{ - // Task's flops amount is set to an arbitrary value > 0.0 to be able to distinguish, in - // MSG_task_get_remaining_work_ratio(), a finished task and a task that has not started yet. - return simgrid::msg::Task::create_parallel(name ? name : "", host_nb, host_list, flops_amount, bytes_amount, data); -} - -/** @brief Return the user data of the given task */ -void* MSG_task_get_data(const_msg_task_t task) -{ - return task->get_data(); -} - -/** @brief Sets the user data of a given task */ -void MSG_task_set_data(msg_task_t task, void *data) -{ - task->set_data(data); -} - -/** @brief Returns the sender of the given task */ -msg_process_t MSG_task_get_sender(const_msg_task_t task) -{ - return task->get_sender(); -} - -/** @brief Returns the source (the sender's host) of the given task */ -msg_host_t MSG_task_get_source(const_msg_task_t task) -{ - return task->get_source(); -} - -/** @brief Returns the name of the given task. */ -const char* MSG_task_get_name(const_msg_task_t task) -{ - return task->get_cname(); -} - -/** @brief Sets the name of the given task. */ -void MSG_task_set_name(msg_task_t task, const char *name) -{ - task->set_name(name); -} - -/** - * @brief Executes a task and waits for its termination. - * - * This function is used for describing the behavior of a process. It takes only one parameter. - * @param task a #msg_task_t to execute on the location on which the process is running. - * @return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED or #MSG_HOST_FAILURE otherwise - */ -msg_error_t MSG_task_execute(msg_task_t task) -{ - return task->execute(); -} - -/** - * @brief Executes a parallel task and waits for its termination. - * - * @param task a #msg_task_t to execute on the location on which the process is running. - * - * @return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED or #MSG_HOST_FAILURE otherwise - */ -msg_error_t MSG_parallel_task_execute(msg_task_t task) -{ - return task->execute(); -} - -msg_error_t MSG_parallel_task_execute_with_timeout(msg_task_t task, double timeout) -{ - task->set_timeout(timeout); - return task->execute(); -} - -/** - * @brief Sends a task on a mailbox. - * - * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test() to end the communication. - * - * @param task a #msg_task_t to send on another location. - * @param alias name of the mailbox to sent the task to - * @return the msg_comm_t communication created - */ -msg_comm_t MSG_task_isend(msg_task_t task, const char* alias) -{ - return new simgrid::msg::Comm(task, nullptr, task->send_async(alias, nullptr, false)); -} - -/** - * @brief Sends a task on a mailbox with a maximum rate - * - * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test() to end the communication. The maxrate - * parameter allows the application to limit the bandwidth utilization of network links when sending the task. - * - * @param task a #msg_task_t to send on another location. - * @param alias name of the mailbox to sent the task to - * @param maxrate the maximum communication rate for sending this task (byte/sec). - * @return the msg_comm_t communication created - */ -msg_comm_t MSG_task_isend_bounded(msg_task_t task, const char* alias, double maxrate) -{ - task->set_rate(maxrate); - return new simgrid::msg::Comm(task, nullptr, task->send_async(alias, nullptr, false)); -} - -/** - * @brief Sends a task on a mailbox. - * - * This is a non blocking detached send function. - * Think of it as a best effort send. Keep in mind that the third parameter is only called if the communication fails. - * If the communication does work, it is responsibility of the receiver code to free anything related to the task, as - * usual. More details on this can be obtained on - * this thread - * in the SimGrid-user mailing list archive. - * - * @param task a #msg_task_t to send on another location. - * @param alias name of the mailbox to sent the task to - * @param cleanup a function to destroy the task if the communication fails, e.g. MSG_task_destroy - * (if nullptr, no function will be called) - */ -void MSG_task_dsend(msg_task_t task, const char* alias, void_f_pvoid_t cleanup) -{ - task->send_async(alias, cleanup, true); -} - -/** - * @brief Sends a task on a mailbox with a maximal rate. - * - * This is a non blocking detached send function. - * Think of it as a best effort send. Keep in mind that the third parameter is only called if the communication fails. - * If the communication does work, it is responsibility of the receiver code to free anything related to the task, as - * usual. More details on this can be obtained on - * this thread - * in the SimGrid-user mailing list archive. - * - * The rate parameter can be used to send a task with a limited bandwidth (smaller than the physical available value). - * Use MSG_task_dsend() if you don't limit the rate (or pass -1 as a rate value do disable this feature). - * - * @param task a #msg_task_t to send on another location. - * @param alias name of the mailbox to sent the task to - * @param cleanup a function to destroy the task if the communication fails, e.g. MSG_task_destroy (if nullptr, no - * function will be called) - * @param maxrate the maximum communication rate for sending this task (byte/sec) - * - */ -void MSG_task_dsend_bounded(msg_task_t task, const char* alias, void_f_pvoid_t cleanup, double maxrate) -{ - task->set_rate(maxrate); - task->send_async(alias, cleanup, true); -} -/** - * @brief Sends a task to a mailbox - * - * This is a blocking function, the execution flow will be blocked until the task is sent (and received on the other - * side if #MSG_task_receive is used). - * See #MSG_task_isend for sending tasks asynchronously. - * - * @param task the task to be sent - * @param alias the mailbox name to where the task is sent - * - * @return Returns #MSG_OK if the task was successfully sent, - * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise. - */ -msg_error_t MSG_task_send(msg_task_t task, const char* alias) -{ - XBT_DEBUG("MSG_task_send: Trying to send a message on mailbox '%s'", alias); - return task->send(alias, -1); -} - -/** - * @brief Sends a task to a mailbox with a maximum rate - * - * This is a blocking function, the execution flow will be blocked until the task is sent. The maxrate parameter allows - * the application to limit the bandwidth utilization of network links when sending the task. - * - * The maxrate parameter can be used to send a task with a limited bandwidth (smaller than the physical available - * value). Use MSG_task_send() if you don't limit the rate (or pass -1 as a rate value do disable this feature). - * - * @param task the task to be sent - * @param alias the mailbox name to where the task is sent - * @param maxrate the maximum communication rate for sending this task (byte/sec) - * - * @return Returns #MSG_OK if the task was successfully sent, - * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise. - */ -msg_error_t MSG_task_send_bounded(msg_task_t task, const char* alias, double maxrate) -{ - task->set_rate(maxrate); - return task->send(alias, -1); -} - -/** - * @brief Sends a task to a mailbox with a timeout - * - * This is a blocking function, the execution flow will be blocked until the task is sent or the timeout is achieved. - * - * @param task the task to be sent - * @param alias the mailbox name to where the task is sent - * @param timeout is the maximum wait time for completion (if -1, this call is the same as #MSG_task_send) - * - * @return Returns #MSG_OK if the task was successfully sent, - * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise. - */ -msg_error_t MSG_task_send_with_timeout(msg_task_t task, const char* alias, double timeout) -{ - return task->send(alias, timeout); -} - -/** - * @brief Sends a task to a mailbox with a timeout and with a maximum rate - * - * This is a blocking function, the execution flow will be blocked until the task is sent or the timeout is achieved. - * - * The maxrate parameter can be used to send a task with a limited bandwidth (smaller than the physical available - * value). Use MSG_task_send_with_timeout() if you don't limit the rate (or pass -1 as a rate value do disable this - * feature). - * - * @param task the task to be sent - * @param alias the mailbox name to where the task is sent - * @param timeout is the maximum wait time for completion (if -1, this call is the same as #MSG_task_send) - * @param maxrate the maximum communication rate for sending this task (byte/sec) - * - * @return Returns #MSG_OK if the task was successfully sent, - * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise. - */ -msg_error_t MSG_task_send_with_timeout_bounded(msg_task_t task, const char* alias, double timeout, double maxrate) -{ - task->set_rate(maxrate); - return task->send(alias, timeout); -} - -/** - * @brief Receives a task from a mailbox. - * - * This is a blocking function, the execution flow will be blocked until the task is received. See #MSG_task_irecv - * for receiving tasks asynchronously. - * - * @param task a memory location for storing a #msg_task_t. - * @param alias name of the mailbox to receive the task from - * - * @return Returns - * #MSG_OK if the task was successfully received, - * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise. - */ -msg_error_t MSG_task_receive(msg_task_t * task, const char *alias) -{ - return MSG_task_receive_with_timeout(task, alias, -1); -} - -/** - * @brief Receives a task from a mailbox at a given rate. - * - * @param task a memory location for storing a #msg_task_t. - * @param alias name of the mailbox to receive the task from - * @param rate limit the reception to rate bandwidth (byte/sec) - * - * The rate parameter can be used to receive a task with a limited bandwidth (smaller than the physical available - * value). Use MSG_task_receive() if you don't limit the rate (or pass -1 as a rate value do disable this feature). - * - * @return Returns - * #MSG_OK if the task was successfully received, - * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise. - */ -msg_error_t MSG_task_receive_bounded(msg_task_t* task, const char* alias, double rate) -{ - return MSG_task_receive_with_timeout_bounded(task, alias, -1, rate); -} - -/** - * @brief Receives a task from a mailbox with a given timeout. - * - * This is a blocking function with a timeout, the execution flow will be blocked until the task is received or the - * timeout is achieved. See #MSG_task_irecv for receiving tasks asynchronously. You can provide a -1 timeout - * to obtain an infinite timeout. - * - * @param task a memory location for storing a #msg_task_t. - * @param alias name of the mailbox to receive the task from - * @param timeout is the maximum wait time for completion (if -1, this call is the same as #MSG_task_receive) - * - * @return Returns - * #MSG_OK if the task was successfully received, - * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise. - */ -msg_error_t MSG_task_receive_with_timeout(msg_task_t* task, const char* alias, double timeout) -{ - return MSG_task_receive_with_timeout_bounded(task, alias, timeout, -1); -} - -/** - * @brief Receives a task from a mailbox with a given timeout and at a given rate. - * - * @param task a memory location for storing a #msg_task_t. - * @param alias name of the mailbox to receive the task from - * @param timeout is the maximum wait time for completion (if -1, this call is the same as #MSG_task_receive) - * @param rate limit the reception to rate bandwidth (byte/sec) - * - * The rate parameter can be used to send a task with a limited - * bandwidth (smaller than the physical available value). Use - * MSG_task_receive() if you don't limit the rate (or pass -1 as a - * rate value do disable this feature). - * - * @return Returns - * #MSG_OK if the task was successfully received, - * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise. - */ -msg_error_t MSG_task_receive_with_timeout_bounded(msg_task_t* task, const char* alias, double timeout, double rate) -{ - XBT_DEBUG("MSG_task_receive_with_timeout_bounded: Trying to receive a message on mailbox '%s'", alias); - msg_error_t ret = MSG_OK; - - /* Sanity check */ - xbt_assert(task, "Null pointer for the task storage"); - - if (*task) - XBT_WARN("Asked to write the received task in a non empty struct -- proceeding."); - - /* Try to receive it by calling SIMIX network layer */ - try { - void* payload; - simgrid::s4u::Mailbox::by_name(alias) - ->get_init() - ->set_dst_data(&payload, sizeof(msg_task_t*)) - ->set_rate(rate) - ->wait_for(timeout); - *task = static_cast(payload); - XBT_DEBUG("Got task %s from %s", (*task)->get_cname(), alias); - (*task)->set_not_used(); - } catch (const simgrid::HostFailureException&) { - ret = MSG_HOST_FAILURE; - } catch (const simgrid::TimeoutException&) { - ret = MSG_TIMEOUT; - } catch (const simgrid::CancelException&) { - ret = MSG_TASK_CANCELED; - } catch (const simgrid::NetworkFailureException&) { - ret = MSG_TRANSFER_FAILURE; - } - - if (TRACE_actor_is_enabled() && ret != MSG_HOST_FAILURE && ret != MSG_TRANSFER_FAILURE && ret != MSG_TIMEOUT) { - auto* process_container = simgrid::instr::Container::by_name(instr_pid(*MSG_process_self())); - - std::string key = std::string("p") + std::to_string((*task)->get_id()); - simgrid::instr::Container::get_root()->get_link("ACTOR_LINK")->end_event(process_container, "SR", key); - } - return ret; -} - -/** - * @brief Starts listening for receiving a task from an asynchronous communication. - * - * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test() to end the communication. - * - * @param task a memory location for storing a #msg_task_t. has to be valid until the end of the communication. - * @param name of the mailbox to receive the task on - * @return the msg_comm_t communication created - */ -msg_comm_t MSG_task_irecv(msg_task_t* task, const char* name) -{ - return MSG_task_irecv_bounded(task, name, -1.0); -} - -/** - * @brief Starts listening for receiving a task from an asynchronous communication at a given rate. - * - * The rate parameter can be used to receive a task with a limited - * bandwidth (smaller than the physical available value). Use - * MSG_task_irecv() if you don't limit the rate (or pass -1 as a rate - * value do disable this feature). - * - * @param task a memory location for storing a #msg_task_t. has to be valid until the end of the communication. - * @param name of the mailbox to receive the task on - * @param rate limit the bandwidth to the given rate (byte/sec) - * @return the msg_comm_t communication created - */ -msg_comm_t MSG_task_irecv_bounded(msg_task_t* task, const char* name, double rate) -{ - /* FIXME: these functions are not traceable */ - /* Sanity check */ - xbt_assert(task, "Null pointer for the task storage"); - - if (*task) - XBT_CRITICAL("MSG_task_irecv() was asked to write in a non empty task struct."); - - /* Try to receive it by calling SIMIX network layer */ - simgrid::s4u::CommPtr comm = simgrid::s4u::Mailbox::by_name(name) - ->get_init() - ->set_dst_data((void**)task, sizeof(msg_task_t*)) - ->set_rate(rate) - ->start(); - - return new simgrid::msg::Comm(nullptr, task, comm); -} - -/** - * @brief Look if there is a communication on a mailbox and return the PID of the sender process. - * - * @param alias the name of the mailbox to be considered - * - * @return Returns the PID of sender process (or -1 if there is no communication in the mailbox) - * - */ -int MSG_task_listen_from(const char* alias) -{ - return simgrid::s4u::Mailbox::by_name(alias)->listen_from(); -} - -/** @brief Destroys the given task. - * - * You should free user data, if any, @b before calling this destructor. - * - * Only the process that owns the task can destroy it. - * The owner changes after a successful send. - * If a task is successfully sent, the receiver becomes the owner and is supposed to destroy it. The sender should not - * use it anymore. - * If the task failed to be sent, the sender remains the owner of the task. - */ -msg_error_t MSG_task_destroy(msg_task_t task) -{ - if (task->is_used()) { - /* the task is being sent or executed: cancel it first */ - task->cancel(); - } - - /* free main structures */ - delete task; - - return MSG_OK; -} - -/** @brief Cancel the given task - * - * If it was currently executed or transferred, the working process is stopped. - */ -msg_error_t MSG_task_cancel(msg_task_t task) -{ - xbt_assert((task != nullptr), "Cannot cancel a nullptr task"); - task->cancel(); - return MSG_OK; -} - -/** @brief Returns a value in ]0,1[ that represent the task remaining work - * to do: starts at 1 and goes to 0. Returns 0 if not started or finished. - * - * It works for either parallel or sequential tasks. - */ -double MSG_task_get_remaining_work_ratio(const_msg_task_t task) -{ - xbt_assert((task != nullptr), "Cannot get information from a nullptr task"); - if (task->compute) { - // Task in progress - return task->compute->get_remaining_ratio(); - } else { - // Task not started (flops_amount is > 0.0) or finished (flops_amount is set to 0.0) - return task->flops_amount > 0.0 ? 1.0 : 0.0; - } -} - -/** @brief Returns the amount of flops that remain to be computed - * - * The returned value is initially the cost that you defined for the task, then it decreases until it reaches 0 - * - * It works for sequential tasks, but the remaining amount of work is not a scalar value for parallel tasks. - * So you will get an exception if you call this function on parallel tasks. Just don't do it. - */ -double MSG_task_get_flops_amount(const_msg_task_t task) -{ - if (task->compute != nullptr && task->compute->get_state() == simgrid::s4u::Activity::State::STARTED) { - return task->compute->get_remaining(); - } else { - // Not started or already done. - // - Before starting, flops_amount is initially the task cost - // - After execution, flops_amount is set to 0 (until someone uses MSG_task_set_flops_amount, if any) - return task->flops_amount; - } -} - -/** @brief set the computation amount needed to process the given task. - * - * @warning If the computation is ongoing (already started and not finished), - * it is not modified by this call. Moreover, after its completion, the ongoing execution with set the flops_amount to - * zero, overriding any value set during the execution. - */ -void MSG_task_set_flops_amount(msg_task_t task, double flops_amount) -{ - task->flops_amount = flops_amount; -} - -/** @brief set the amount data attached with the given task. - * - * @warning If the transfer is ongoing (already started and not finished), it is not modified by this call. - */ -void MSG_task_set_bytes_amount(msg_task_t task, double data_size) -{ - task->bytes_amount = data_size; -} - -/** @brief Returns the total amount received by the given task - * - * If the communication does not exist it will return 0. - * So, if the communication has FINISHED or FAILED it returns zero. - */ -double MSG_task_get_remaining_communication(const_msg_task_t task) -{ - XBT_DEBUG("calling s4u::Comm::get_remaining (%p)", task->comm.get()); - return task->comm->get_remaining(); -} - -/** @brief Returns the size of the data attached to the given task. */ -double MSG_task_get_bytes_amount(const_msg_task_t task) -{ - xbt_assert(task != nullptr, "Invalid parameter"); - return task->bytes_amount; -} - -/** @brief Changes the priority of a computation task. - * - * This priority doesn't affect the transfer rate. A priority of 2 - * will make a task receive two times more cpu power than regular tasks. - */ -void MSG_task_set_priority(msg_task_t task, double priority) -{ - task->set_priority(priority); -} - -/** @brief Changes the maximum CPU utilization of a computation task (in flops/s). - * - * For VMs, there is a pitfall. Please see MSG_vm_set_bound(). - */ -void MSG_task_set_bound(msg_task_t task, double bound) -{ - if (bound < 1e-12) /* close enough to 0 without any floating precision surprise */ - XBT_INFO("bound == 0 means no capping (i.e., unlimited)."); - task->set_bound(bound); -} - -/** - * @brief Sets the tracing category of a task. - * - * This function should be called after the creation of a MSG task, to define the category of that task. The - * first parameter task must contain a task that was =created with the function MSG_task_create(). The second - * parameter category must contain a category that was previously declared with the function #TRACE_category - * (or with #TRACE_category_with_color). - * - * @beginrst - * See :ref:`outcome_vizu` for details on how to trace the (categorized) resource utilization. - * @endrst - * - * @param task the task that is going to be categorized - * @param category the name of the category to be associated to the task - */ -void MSG_task_set_category(msg_task_t task, const char* category) -{ - xbt_assert(not task->has_tracing_category(), "Task %p(%s) already has a category (%s).", task, task->get_cname(), - task->get_tracing_category().c_str()); - - // if user provides a nullptr category, task is no longer traced - if (category == nullptr) { - task->set_tracing_category(""); - XBT_DEBUG("MSG task %p(%s), category removed", task, task->get_cname()); - } else { - // set task category - task->set_tracing_category(category); - XBT_DEBUG("MSG task %p(%s), category %s", task, task->get_cname(), task->get_tracing_category().c_str()); - } -} - -/** - * @brief Gets the current tracing category of a task. (@see MSG_task_set_category) - * @param task the task to be considered - * @return Returns the name of the tracing category of the given task, "" otherwise - */ -const char* MSG_task_get_category(const_msg_task_t task) -{ - return task->get_tracing_category().c_str(); -} diff --git a/src/plugins/ProducerConsumer.cpp b/src/plugins/ProducerConsumer.cpp index 521bf6652f..2614a1b580 100644 --- a/src/plugins/ProducerConsumer.cpp +++ b/src/plugins/ProducerConsumer.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2021-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,5 +8,5 @@ XBT_LOG_NEW_CATEGORY(producer_consumer, "Producer-Consumer plugin logging category"); namespace simgrid::plugin { -unsigned long pc_id = 0; +unsigned long ProducerConsumerId::pc_id = 0; } diff --git a/src/plugins/battery.cpp b/src/plugins/battery.cpp new file mode 100644 index 0000000000..0cbfdbc8c5 --- /dev/null +++ b/src/plugins/battery.cpp @@ -0,0 +1,472 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ +#include +#include +#include +#include +#include + +#include "src/kernel/resource/CpuImpl.hpp" +#include "src/simgrid/module.hpp" + +SIMGRID_REGISTER_PLUGIN(battery, "Battery management", nullptr) +/** @defgroup plugin_battery plugin_battery Plugin Battery + + @beginrst + +This is the battery plugin, enabling management of batteries. + +Batteries +......... + +A battery has an initial State of Charge :math:`SoC`, a nominal charge power, a nominal discharge power, a charge +efficiency :math:`\eta_{charge}`, a discharge efficiency :math:`\eta_{discharge}`, an initial capacity +:math:`C_{initial}` and a number of cycle :math:`N`. + +The nominal charge(discharge) power is the maximum power the Battery can consume(provide), before application of the +charge(discharge) efficiency factor. For instance, if a load provides(consumes) 100W to(from) the Battery with a nominal +charge(discharge) power of 50W and a charge(discharge) efficiency of 0.9, the Battery will only gain(provide) 45W. + +We distinguish the energy provided :math:`E_{provided}` / consumed :math:`E_{consumed}` from the energy lost +:math:`E_{lost}` / gained :math:`E_{gained}`. The energy provided / consumed shows the external point of view, and the +energy lost / gained shows the internal point of view: + +.. math:: + + E_{lost} = {E_{provided} \over \eta_{discharge}} + + E_{gained} = E_{consumed} \times \eta_{charge} + +For instance, if you apply a load of 100W to a battery for 10s with a discharge efficiency of 0.8, the energy provided +will be equal to 10kJ, and the energy lost will be equal to 12.5kJ. + +All the energies are positive, but loads connected to a Battery may be positive or negative, as explained in the next +section. + +Use the battery reduces its State of Health :math:`SoH` and its capacity :math:`C` linearly in consequence: + +.. math:: + + SoH = 1 - {E_{lost} + E_{gained} \over E_{budget}} + + C = C_{initial} \times SoH + +With: + +.. math:: + + E_{budget} = C_{initial} \times N \times 2 + +Plotting the output of the example "battery-degradation" highlights the linear decrease of the :math:`SoH` due to a +continuous use of the battery alternating between charge and discharge: + +.. image:: /img/battery_degradation.svg + :align: center + +The natural depletion of batteries over time is not taken into account. + +Loads & Hosts +............. + +You can add named loads to a battery. Those loads may be positive and consume energy from the battery, or negative and +provide energy to the battery. You can also connect hosts to a battery. Theses hosts will consume their energy from the +battery until the battery is empty or until the connection between the hosts and the battery is set inactive. + +Handlers +........ + +You can schedule handlers that will happen at specific SoC of the battery and trigger a callback. +Theses handlers may be recurrent, for instance you may want to always set all loads to zero and deactivate all hosts +connections when the battery reaches 20% SoC. + +Connector +......... + +A Battery can act as a connector to connect Solar Panels direcly to loads. Such Battery is created without any +parameter, cannot store energy and has a transfer efficiency of 100%. + + @endrst + */ +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Battery, kernel, "Logging specific to the battery plugin"); + +namespace simgrid::plugins { + +/* BatteryModel */ + +BatteryModel::BatteryModel() : Model("BatteryModel") {} + +void BatteryModel::add_battery(BatteryPtr b) +{ + batteries_.push_back(b); +} + +void BatteryModel::update_actions_state(double now, double delta) +{ + for (auto battery : batteries_) + battery->update(); +} + +double BatteryModel::next_occurring_event(double now) +{ + static bool init = false; + if (!init) { + init = true; + return 0; + } + double time_delta = -1; + for (auto battery : batteries_) { + double time_delta_battery = battery->next_occurring_handler(); + time_delta = time_delta == -1 or time_delta_battery < time_delta ? time_delta_battery : time_delta; + } + return time_delta; +} + +/* Handler */ + +Battery::Handler::Handler(double state_of_charge, Flow flow, Persistancy p, std::function callback) + : state_of_charge_(state_of_charge), flow_(flow), callback_(callback), persistancy_(p) +{ +} + +std::shared_ptr Battery::Handler::init(double state_of_charge, Flow flow, Persistancy p, + std::function callback) +{ + return std::make_shared(state_of_charge, flow, p, callback); +} + +/* Battery */ + +std::shared_ptr Battery::battery_model_; + +void Battery::init_plugin() +{ + auto model = std::make_shared(); + simgrid::s4u::Engine::get_instance()->add_model(model); + Battery::battery_model_ = model; +} + +void Battery::update() +{ + kernel::actor::simcall_answered([this] { + double now = s4u::Engine::get_clock(); + double time_delta_s = now - last_updated_; + + // Nothing to update + if (time_delta_s <= 0) + return; + + // Calculate energy provided / consumed during this step + double provided_power_w = 0; + double consumed_power_w = 0; + for (auto const& [host, active] : host_loads_) + provided_power_w += active ? sg_host_get_current_consumption(host) : 0; + for (auto const& [name, pair] : named_loads_) { + if (not pair.first) + continue; + if (pair.second > 0) + provided_power_w += pair.second; + else + consumed_power_w += -pair.second; + } + + provided_power_w = std::min(provided_power_w, nominal_discharge_power_w_ * discharge_efficiency_); + consumed_power_w = std::min(consumed_power_w, -nominal_charge_power_w_); + + double energy_lost_delta_j = provided_power_w / discharge_efficiency_ * time_delta_s; + double energy_gained_delta_j = consumed_power_w * charge_efficiency_ * time_delta_s; + + // Check that the provided/consumed energy is valid + energy_lost_delta_j = std::min(energy_lost_delta_j, energy_stored_j_ + energy_gained_delta_j); + /* Charging deteriorate the capacity, but the capacity is used to evaluate the maximum charge so + we need to evaluate the theorethical new capacity in the worst case when we fully charge the battery */ + double new_tmp_capacity_wh = + (initial_capacity_wh_ * + (1 - (energy_provided_j_ + energy_lost_delta_j * discharge_efficiency_ + energy_consumed_j_ - + (energy_stored_j_ + energy_lost_delta_j) / charge_efficiency_) / + energy_budget_j_)) / + (1 + 3600 * initial_capacity_wh_ / (charge_efficiency_ * energy_budget_j_)); + energy_gained_delta_j = + std::min(energy_gained_delta_j, (3600 * new_tmp_capacity_wh) - energy_stored_j_ + energy_lost_delta_j); + + // Updating battery + energy_provided_j_ += energy_lost_delta_j * discharge_efficiency_; + energy_consumed_j_ += energy_gained_delta_j / charge_efficiency_; + + // This battery is a simple connector, we only update energy provided and consumed + if (energy_budget_j_ == 0) { + energy_consumed_j_ = energy_provided_j_; + last_updated_ = now; + return; + } + + capacity_wh_ = + initial_capacity_wh_ * + (1 - (energy_provided_j_ / discharge_efficiency_ + energy_consumed_j_ * charge_efficiency_) / energy_budget_j_); + energy_stored_j_ += energy_gained_delta_j - energy_lost_delta_j; + energy_stored_j_ = std::min(energy_stored_j_, 3600 * capacity_wh_); + last_updated_ = now; + + auto handlers_2 = handlers_; + for (auto handler : handlers_2) { + if (abs(handler->time_delta_ - time_delta_s) < 0.000000001) { + handler->callback_(); + if (handler->persistancy_ == Handler::Persistancy::PERSISTANT) + handler->time_delta_ = -1; + else + delete_handler(handler); + } + } + }); +} + +double Battery::next_occurring_handler() +{ + double provided_power_w = 0; + double consumed_power_w = 0; + for (auto const& [host, active] : host_loads_) + provided_power_w += active ? sg_host_get_current_consumption(host) : 0; + for (auto const& [name, pair] : named_loads_) { + if (not pair.first) + continue; + if (pair.second > 0) + provided_power_w += pair.second; + else + consumed_power_w += -pair.second; + } + + provided_power_w = std::min(provided_power_w, nominal_discharge_power_w_ * discharge_efficiency_); + consumed_power_w = std::min(consumed_power_w, -nominal_charge_power_w_); + + double time_delta = -1; + for (auto& handler : handlers_) { + double lost_power_w = provided_power_w / discharge_efficiency_; + double gained_power_w = consumed_power_w * charge_efficiency_; + if ((lost_power_w == gained_power_w) or (handler->state_of_charge_ == get_state_of_charge()) or + (lost_power_w > gained_power_w and + (handler->flow_ == Flow::CHARGE or handler->state_of_charge_ > get_state_of_charge())) or + (lost_power_w < gained_power_w and + (handler->flow_ == Flow::DISCHARGE or handler->state_of_charge_ < get_state_of_charge()))) { + continue; + } + // Evaluate time until handler happen + else { + /* The time to reach a state of charge depends on the capacity, but charging and discharging deteriorate the + * capacity, so we need to evaluate the time considering a capacity that also depends on time + */ + handler->time_delta_ = + (3600 * handler->state_of_charge_ * initial_capacity_wh_ * + (1 - (energy_provided_j_ / discharge_efficiency_ + energy_consumed_j_ * charge_efficiency_) / + energy_budget_j_) - + energy_stored_j_) / + (gained_power_w - lost_power_w + + 3600 * handler->state_of_charge_ * initial_capacity_wh_ * (gained_power_w + lost_power_w) / + energy_budget_j_); + if ((time_delta == -1 or handler->time_delta_ < time_delta) and abs(handler->time_delta_) > 0.000000001) + time_delta = handler->time_delta_; + } + } + return time_delta; +} + +Battery::Battery(const std::string& name, double state_of_charge, double nominal_charge_power_w, + double nominal_discharge_power_w, double charge_efficiency, double discharge_efficiency, + double initial_capacity_wh, int cycles) + : name_(name) + , nominal_charge_power_w_(nominal_charge_power_w) + , nominal_discharge_power_w_(nominal_discharge_power_w) + , charge_efficiency_(charge_efficiency) + , discharge_efficiency_(discharge_efficiency) + , initial_capacity_wh_(initial_capacity_wh) + , energy_budget_j_(initial_capacity_wh * 3600 * cycles * 2) + , capacity_wh_(initial_capacity_wh) + , energy_stored_j_(state_of_charge * 3600 * initial_capacity_wh) +{ + xbt_assert(nominal_charge_power_w <= 0, " : nominal charge power must be <= 0 (provided: %f)", + nominal_charge_power_w); + xbt_assert(nominal_discharge_power_w >= 0, " : nominal discharge power must be non-negative (provided: %f)", + nominal_discharge_power_w); + xbt_assert(state_of_charge >= 0 and state_of_charge <= 1, " : state of charge should be in [0, 1] (provided: %f)", + state_of_charge); + xbt_assert(charge_efficiency > 0 and charge_efficiency <= 1, " : charge efficiency should be in [0,1] (provided: %f)", + charge_efficiency); + xbt_assert(discharge_efficiency > 0 and discharge_efficiency <= 1, + " : discharge efficiency should be in [0,1] (provided: %f)", discharge_efficiency); + xbt_assert(initial_capacity_wh > 0, " : initial capacity should be > 0 (provided: %f)", initial_capacity_wh); + xbt_assert(cycles > 0, " : cycles should be > 0 (provided: %d)", cycles); +} + +/** @ingroup plugin_battery + * @brief Init a Battery with this constructor makes it only usable as a connector. + * A connector has no capacity and only delivers as much power as it receives + with a transfer efficiency of 100%. + * @return A BatteryPtr pointing to the new Battery. + */ +BatteryPtr Battery::init() +{ + static bool plugin_inited = false; + if (not plugin_inited) { + init_plugin(); + plugin_inited = true; + } + auto battery = BatteryPtr(new Battery()); + battery_model_->add_battery(battery); + return battery; +} + +/** @ingroup plugin_battery + * @param name The name of the Battery. + * @param state_of_charge The initial state of charge of the Battery [0,1]. + * @param nominal_charge_power_w The maximum power absorbed by the Battery in W (<= 0). + * @param nominal_discharge_power_w The maximum power delivered by the Battery in W (>= 0). + * @param charge_efficiency The charge efficiency of the Battery [0,1]. + * @param discharge_efficiency The discharge efficiency of the Battery [0,1]. + * @param initial_capacity_wh The initial capacity of the Battery in Wh (>0). + * @param cycles The number of charge-discharge cycles until complete depletion of the Battery capacity. + * @return A BatteryPtr pointing to the new Battery. + */ +BatteryPtr Battery::init(const std::string& name, double state_of_charge, double nominal_charge_power_w, + double nominal_discharge_power_w, double charge_efficiency, double discharge_efficiency, + double initial_capacity_wh, int cycles) +{ + static bool plugin_inited = false; + if (not plugin_inited) { + init_plugin(); + plugin_inited = true; + } + auto battery = BatteryPtr(new Battery(name, state_of_charge, nominal_charge_power_w, nominal_discharge_power_w, + charge_efficiency, discharge_efficiency, initial_capacity_wh, cycles)); + battery_model_->add_battery(battery); + return battery; +} + +/** @ingroup plugin_battery + * @param name The name of the load + * @param power_w Power of the load in W. A positive value discharges the Battery while a negative value charges it. + */ +void Battery::set_load(const std::string& name, double power_w) +{ + kernel::actor::simcall_answered([this, &name, &power_w] { + if (named_loads_.find(name) == named_loads_.end()) + named_loads_[name] = std::make_pair(true, power_w); + else + named_loads_[name].second = power_w; + }); +} + +/** @ingroup plugin_battery + * @param name The name of the load + * @param active Status of the load. If false then the load is ignored by the Battery. + */ +void Battery::set_load(const std::string& name, bool active) +{ + kernel::actor::simcall_answered([this, &name, &active] { named_loads_[name].first = active; }); +} + +/** @ingroup plugin_battery + * @param host The Host to connect. + * @param active Status of the connected Host (default true). + * @brief Connect a Host to the Battery with the status active. As long as the status is true the Host takes its energy + from the Battery. To modify this status connect again the same Host with a different status. + @warning Do NOT connect the same Host to multiple Batteries with the status true at the same time. + In this case all Batteries would have the full consumption from this Host. + */ +void Battery::connect_host(s4u::Host* host, bool active) +{ + kernel::actor::simcall_answered([this, &host, &active] { host_loads_[host] = active; }); +} + +/** @ingroup plugin_battery + * @return The state of charge of the battery. + */ +double Battery::get_state_of_charge() +{ + return energy_stored_j_ / (3600 * capacity_wh_); +} + +/** @ingroup plugin_battery + * @return The state of health of the Battery. + */ +double Battery::get_state_of_health() +{ + return 1 - + ((energy_provided_j_ / discharge_efficiency_ + energy_consumed_j_ * charge_efficiency_) / energy_budget_j_); +} + +/** @ingroup plugin_battery + * @return The current capacity of the Battery. + */ +double Battery::get_capacity() +{ + return capacity_wh_; +} + +/** @ingroup plugin_battery + * @return The energy provided by the Battery. + * @note It is the energy provided from an external point of view, after application of the discharge efficiency. + It means that the Battery lost more energy than it has provided. + */ +double Battery::get_energy_provided() +{ + return energy_provided_j_; +} + +/** @ingroup plugin_battery + * @return The energy consumed by the Battery. + * @note It is the energy consumed from an external point of view, before application of the charge efficiency. + It means that the Battery consumed more energy than is has absorbed. + */ +double Battery::get_energy_consumed() +{ + return energy_consumed_j_; +} + +/** @ingroup plugin_battery + * @param unit Valid units are J (default) and Wh. + * @return Energy stored in the Battery. + */ +double Battery::get_energy_stored(std::string unit) +{ + if (unit == "J") + return energy_stored_j_; + else if (unit == "Wh") + return energy_stored_j_ / 3600; + else + xbt_die("Invalid unit. Valid units are J (default) or Wh."); +} + +/** @ingroup plugin_battery + * @brief Schedule a new Handler. + * @param state_of_charge The state of charge at which the Handler will happen. + * @param flow The flow in which the Handler will happen, either when the Battery is charging or discharging. + * @param callback The callable to trigger when the Handler happen. + * @param p If the Handler is recurrent or unique. + * @return A shared pointer of the new Handler. + */ +std::shared_ptr Battery::schedule_handler(double state_of_charge, Flow flow, Handler::Persistancy p, + std::function callback) +{ + auto handler = Handler::init(state_of_charge, flow, p, callback); + handlers_.push_back(handler); + return handler; +} + +/** @ingroup plugin_battery + * @return A vector containing the Handlers associated to the Battery. + */ +std::vector> Battery::get_handlers() +{ + return handlers_; +} + +/** @ingroup plugin_battery + * @brief Remove an Handler from the Battery. + */ +void Battery::delete_handler(std::shared_ptr handler) +{ + handlers_.erase(std::remove_if(handlers_.begin(), handlers_.end(), + [&handler](std::shared_ptr e) { return handler == e; }), + handlers_.end()); +} +} // namespace simgrid::plugins \ No newline at end of file diff --git a/src/plugins/chaos_monkey.cpp b/src/plugins/chaos_monkey.cpp index da2ee32e8a..282bcd5477 100644 --- a/src/plugins/chaos_monkey.cpp +++ b/src/plugins/chaos_monkey.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2022-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2022-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,7 +10,7 @@ #include #include -#include "src/surf/surf_interface.hpp" // SIMGRID_REGISTER_PLUGIN +#include "src/simgrid/module.hpp" // SIMGRID_REGISTER_PLUGIN namespace sg4 = simgrid::s4u; static simgrid::config::Flag cfg_tell{"cmonkey/tell", "Request the Chaos Monkey to display all timestamps", @@ -18,60 +18,75 @@ static simgrid::config::Flag cfg_tell{"cmonkey/tell", "Request the Chaos M static simgrid::config::Flag cfg_time{"cmonkey/time", "When should the chaos monkey kill a resource", -1.}; static simgrid::config::Flag cfg_link{"cmonkey/link", "Which link should be killed (number)", -1}; static simgrid::config::Flag cfg_host{"cmonkey/host", "Which host should be killed (number)", -1}; -static void sg_chaos_monkey_plugin_init(); -// Makes sure that this plugin can be activated from the command line with ``--cfg=plugin:chaos_monkey`` -SIMGRID_REGISTER_PLUGIN(cmonkey, "Chaos monkey", &sg_chaos_monkey_plugin_init) XBT_LOG_NEW_DEFAULT_SUBCATEGORY(cmonkey, kernel, "Chaos Monkey plugin"); -static void sg_chaos_monkey_plugin_init() +static void sg_chaos_monkey_plugin_run() { - XBT_INFO("Initializing the chaos monkey"); + const auto* engine = sg4::Engine::get_instance(); + auto hosts = engine->get_all_hosts(); + auto links = engine->get_all_links(); - // delay the initialization until after the parameter are parsed - sg4::Engine::on_simulation_start_cb([]() { - auto engine = sg4::Engine::get_instance(); - auto hosts = engine->get_all_hosts(); - auto links = engine->get_all_links(); + sg4::Engine::on_deadlock_cb([]() { exit(2); }); - sg4::Engine::on_deadlock_cb([]() { exit(2); }); + if (not cfg_tell && cfg_time < 0 && cfg_host == -1 && cfg_link == -1) { + XBT_CRITICAL( + "You invoked the Chaos Monkey without anything to do.\n" + "Bored, it kills your simulation after this message about how to use it manually (note that the\n" + "simgrid-monkey script can tame the monkey for you if you prefer).\n\n" + "First of all, you need information. Use --cfg=cmonkey/tell:1 to get all information about the existing\n" + "resources and the timestamps of interest in your simulation.\n\n" + "Then, use --cfg=cmonkey/host:0 --cfg=cmonkey/time:0.1 to turn off and on the host #0 at time 0.1s,\n" + "or --cfg=cmonkey/link:22 --cfg=cmonkey/time:0.4 to turn the link #22 off and on again at time 0.4s.\n" + "Only one resource can be rebooted in a given run.\n\n" + "Please read the comments at the beginning of the simgrid-monkey script about how to exhaustively test a\n" + "program resilience.\n"); + exit(1); + } - if (cfg_tell) { - XBT_INFO("HOST_COUNT=%zu", hosts.size()); - XBT_INFO("LINK_COUNT=%zu", links.size()); - sg4::Engine::on_time_advance_cb([engine](double /* delta*/) { XBT_INFO("TIMESTAMP=%lf", engine->get_clock()); }); - } + if (cfg_tell) { + XBT_INFO("HOST_COUNT=%zu", hosts.size()); + XBT_INFO("LINK_COUNT=%zu", links.size()); + sg4::Engine::on_time_advance_cb([engine](double /* delta*/) { XBT_INFO("TIMESTAMP=%lf", engine->get_clock()); }); + } - if (cfg_time >= 0) { - int host = cfg_host; - int link = cfg_link; - xbt_assert(host >= 0 || link >= 0, - "If a kill time is given, you must also specify a resource to kill (either a link or an host)"); - xbt_assert(host < 0 || link < 0, "Cannot specify both a link and an host to kill"); - if (host >= 0) { - auto* h = hosts[host]; - simgrid::kernel::timer::Timer::set(cfg_time, [h]() { - XBT_INFO("Kill host %s", h->get_cname()); - h->turn_off(); - }); - simgrid::kernel::timer::Timer::set(cfg_time + 30, [h]() { - XBT_INFO("Restart host %s", h->get_cname()); - h->turn_on(); - }); - } - if (link >= 0) { - auto* l = links[link]; - simgrid::kernel::timer::Timer::set(cfg_time, [l]() { - XBT_INFO("Kill link %s", l->get_cname()); - l->turn_off(); - }); - simgrid::kernel::timer::Timer::set(cfg_time + 30, [l]() { - XBT_INFO("Restart host %s", l->get_cname()); - l->turn_on(); - }); - } + if (cfg_time >= 0) { + int host = cfg_host; + int link = cfg_link; + xbt_assert(host >= 0 || link >= 0, + "If a kill time is given, you must also specify a resource to kill (either a link or an host)"); + xbt_assert(host < 0 || link < 0, "Cannot specify both a link and an host to kill"); + if (host >= 0) { + auto* h = hosts.at(host); + simgrid::kernel::timer::Timer::set(cfg_time, [h]() { + XBT_INFO("Kill host %s", h->get_cname()); + h->turn_off(); + }); + simgrid::kernel::timer::Timer::set(cfg_time + 30, [h]() { + XBT_INFO("Restart host %s", h->get_cname()); + h->turn_on(); + }); + } + if (link >= 0) { + auto* l = links.at(link); + simgrid::kernel::timer::Timer::set(cfg_time, [l]() { + XBT_INFO("Kill link %s", l->get_cname()); + l->turn_off(); + }); + simgrid::kernel::timer::Timer::set(cfg_time + 30, [l]() { + XBT_INFO("Restart host %s", l->get_cname()); + l->turn_on(); + }); } + } - sg4::Engine::on_simulation_end_cb([]() { XBT_INFO("Chaos Monkey done!"); }); - }); + sg4::Engine::on_simulation_end_cb([]() { XBT_INFO("Chaos Monkey done!"); }); } + +// Makes sure that this plugin can be activated from the command line with ``--cfg=plugin:cmonkey`` +SIMGRID_REGISTER_PLUGIN(cmonkey, "Chaos monkey", []() { + XBT_INFO("Initializing the chaos monkey."); + + // delay the initialization until after the parameter are parsed + sg4::Engine::on_simulation_start_cb(sg_chaos_monkey_plugin_run); +}) diff --git a/src/plugins/chiller.cpp b/src/plugins/chiller.cpp new file mode 100644 index 0000000000..0a4d3afe4d --- /dev/null +++ b/src/plugins/chiller.cpp @@ -0,0 +1,305 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ +#include +#include +#include +#include +#include +#include + +#include "src/kernel/resource/CpuImpl.hpp" +#include "src/simgrid/module.hpp" + +SIMGRID_REGISTER_PLUGIN(chiller, "Chiller management", nullptr) + +/** @defgroup plugin_chiller Plugin Chiller + + @beginrst + +This is the chiller plugin, enabling management of chillers. + +Chiller +....... + +A chiller is placed inside a room with several machines. The role of the chiller is to keep the temperature of the room +below a threshold. This plugin and its equations are based on the paper "Co-simulation of FMUs and Distributed +Applications with SimGrid" by Camus et al. (https://hal.science/hal-01762540). + +The heat generated inside the room :math:`Q_{room}` depends on the heat from the machines :math:`Q_{machines}` and +from the heat of the other devices, such as lighing, accounted using a factor :math:`\alpha` such as: + +.. math:: + + Q_{room} = (1 + \alpha) \times Q_{machines} + +This energy heats the input temperature :math:`T_{in}` and gives an output temperature :math:`T_{out}` based on the +mass of air inside the room :math:`m_{air}` and its specific heat :math:`C_{p}`: + +.. math:: + + T_{out} = T_{in} + {Q_{room} \over m_{air} \times C_{p}} + +If the output temperature is above the goal temperature :math:`T_{goal}` the chiller compensates the excessive heat +using electrical energy :math:`Q_{cooling}` depending on its cooling efficiency :math:`\eta_{cooling}` : + +.. math:: + + Q_{cooling} = (T_{out} - T_{goal}) \times m_{air} \times C_{p} / \eta_{cooling} + +The chiller has a power threshold that cannot be exceeded. If the power needed is above this threshold, or if the +chiller is not active, the temperature of the room increases. + + @endrst + */ + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Chiller, kernel, "Logging specific to the solar panel plugin"); + +namespace simgrid::plugins { +xbt::signal Chiller::on_power_change; // initialisation of static field + +/* ChillerModel */ + +ChillerModel::ChillerModel() : Model("ChillerModel") {} + +void ChillerModel::add_chiller(ChillerPtr c) +{ + chillers_.push_back(c); +} + +void ChillerModel::update_actions_state(double now, double delta) +{ + for (auto chiller : chillers_) + chiller->update(); +} + +double ChillerModel::next_occurring_event(double now) +{ + static bool init = false; + if (not init) { + init = true; + return 0; + } else + return -1; +} + +/* Chiller */ + +std::shared_ptr Chiller::chiller_model_; + +void Chiller::init_plugin() +{ + auto model = std::make_shared(); + simgrid::s4u::Engine::get_instance()->add_model(model); + Chiller::chiller_model_ = model; +} + +void Chiller::update() +{ + simgrid::kernel::actor::simcall_answered([this] { + double now = s4u::Engine::get_clock(); + double time_delta_s = now - last_updated_; + + if (time_delta_s <= 0) + return; + + double hosts_power_w = 0; + for (auto const& host : hosts_) { + hosts_power_w += sg_host_get_current_consumption(host); + } + + double heat_generated_j = hosts_power_w * (1 + alpha_) * time_delta_s; + temp_out_c_ = temp_in_c_ + heat_generated_j / (air_mass_kg_ * specific_heat_j_per_kg_per_c_); + double cooling_demand_w = + std::max(temp_out_c_ - goal_temp_c_, 0.0) * air_mass_kg_ * specific_heat_j_per_kg_per_c_ / time_delta_s; + if (not active_) + power_w_ = 0; + else + power_w_ = std::min(max_power_w_, cooling_demand_w / cooling_efficiency_); + temp_in_c_ = + temp_out_c_ - (power_w_ * time_delta_s * cooling_efficiency_) / (air_mass_kg_ * specific_heat_j_per_kg_per_c_); + energy_consumed_j_ += power_w_ * time_delta_s; + last_updated_ = now; + }); +} + +Chiller::Chiller(const std::string& name, double air_mass_kg, double specific_heat_j_per_kg_per_c, double alpha, + double cooling_efficiency, double initial_temp_c, double goal_temp_c, double max_power_w) + : name_(name) + , air_mass_kg_(air_mass_kg) + , specific_heat_j_per_kg_per_c_(specific_heat_j_per_kg_per_c) + , alpha_(alpha) + , cooling_efficiency_(cooling_efficiency) + , temp_in_c_(initial_temp_c) + , temp_out_c_(initial_temp_c) + , goal_temp_c_(goal_temp_c) + , max_power_w_(max_power_w) +{ + xbt_assert(air_mass_kg > 0, ": air mass must be > 0 (provided: %f)", air_mass_kg); + xbt_assert(specific_heat_j_per_kg_per_c > 0, ": specific heat must be > 0 (provided: %f)", + specific_heat_j_per_kg_per_c); + xbt_assert(alpha >= 0, ": alpha must be >= 0 (provided: %f)", alpha); + xbt_assert(cooling_efficiency >= 0 and cooling_efficiency <= 1, + ": cooling efficiency must be in [0,1] (provided: %f)", cooling_efficiency); + xbt_assert(max_power_w >= 0, ": maximal power must be >=0 (provided: %f)", max_power_w); +} + +/** @ingroup plugin_chiller + * @param name The name of the Chiller. + * @param air_mass_kg The air mass of the room managed by the Chiller in kg (> 0). + * @param specific_heat_j_per_kg_per_c The specific heat of air in J per kg per °C (> 0). + * @param alpha The ratio of the other devices in the total heat dissipation (e.g. lighting, Power Distribution Unit) + * (>= 0). + * @param cooling_efficiency The cooling efficiency of the Chiller [0, 1]. + * @param initial_temp_c The initial temperature of the room managed by the Chiller. + * @param goal_temp_c The goal temperature of the room. The Chiller is idle below this temperature. + * @param max_power_w The maximal power delivered by the Chiller in W (> 0). If this power is reached the room + * temperature will raise above the goal temperature. + * @return A ChillerPtr pointing to the new Chiller. + */ +ChillerPtr Chiller::init(const std::string& name, double air_mass_kg, double specific_heat_j_per_kg_per_c, double alpha, + double cooling_efficiency, double initial_temp_c, double goal_temp_c, double max_power_w) +{ + static bool plugin_inited = false; + if (not plugin_inited) { + init_plugin(); + plugin_inited = true; + } + auto chiller = ChillerPtr(new Chiller(name, air_mass_kg, specific_heat_j_per_kg_per_c, alpha, cooling_efficiency, + initial_temp_c, goal_temp_c, max_power_w)); + chiller_model_->add_chiller(chiller); + return chiller; +} + +/** @ingroup plugin_chiller + * @param name The new name of the Chiller. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::set_name(std::string name) +{ + simgrid::kernel::actor::simcall_answered([this, name] { name_ = name; }); + return this; +} + +/** @ingroup plugin_chiller + * @param air_mass_kg The new air mass of the Chiller in kg. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::set_air_mass(double air_mass_kg) +{ + xbt_assert(air_mass_kg > 0, ": air mass must be > 0 (provided: %f)", air_mass_kg); + simgrid::kernel::actor::simcall_answered([this, air_mass_kg] { air_mass_kg_ = air_mass_kg; }); + return this; +} + +/** @ingroup plugin_chiller + * @param specific_heat_j_per_kg_per_c The specific heat of the Chiller in J per kg per °C. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::set_specific_heat(double specific_heat_j_per_kg_per_c) +{ + xbt_assert(specific_heat_j_per_kg_per_c > 0, ": specific heat must be > 0 (provided: %f)", + specific_heat_j_per_kg_per_c); + simgrid::kernel::actor::simcall_answered( + [this, specific_heat_j_per_kg_per_c] { specific_heat_j_per_kg_per_c_ = specific_heat_j_per_kg_per_c; }); + return this; +} + +/** @ingroup plugin_chiller + * @param alpha The new alpha of the Chiller. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::set_alpha(double alpha) +{ + xbt_assert(alpha >= 0, ": alpha must be >= 0 (provided: %f)", alpha); + simgrid::kernel::actor::simcall_answered([this, alpha] { alpha_ = alpha; }); + return this; +} + +/** @ingroup plugin_chiller + * @param cooling_efficiency The new coolingefficiency of the Chiller. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::set_cooling_efficiency(double cooling_efficiency) +{ + xbt_assert(cooling_efficiency >= 0 and cooling_efficiency <= 1, + ": cooling efficiency must be in [0,1] (provided: %f)", cooling_efficiency); + simgrid::kernel::actor::simcall_answered([this, cooling_efficiency] { cooling_efficiency_ = cooling_efficiency; }); + return this; +} + +/** @ingroup plugin_chiller + * @param goal_temp_c The new goal temperature of the Chiller in °C. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::set_goal_temp(double goal_temp_c) +{ + simgrid::kernel::actor::simcall_answered([this, goal_temp_c] { goal_temp_c_ = goal_temp_c; }); + return this; +} + +/** @ingroup plugin_chiller + * @param max_power_w The new maximal power of the Chiller in W. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::set_max_power(double max_power_w) +{ + xbt_assert(max_power_w >= 0, ": maximal power must be >=0 (provided: %f)", max_power_w); + simgrid::kernel::actor::simcall_answered([this, max_power_w] { max_power_w_ = max_power_w; }); + return this; +} + +/** @ingroup plugin_chiller + * @param active The new active status of the Chiller. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::set_active(bool active) +{ + simgrid::kernel::actor::simcall_answered([this, active] { active_ = active; }); + return this; +} + +/** @ingroup plugin_chiller + * @param host The host to add to the room managed by the Chiller. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::add_host(s4u::Host* host) +{ + simgrid::kernel::actor::simcall_answered([this, host] { hosts_.insert(host); }); + return this; +} + +/** @ingroup plugin_chiller + * @param host The host to remove from the room managed by the Chiller. + * @return A ChillerPtr pointing to the modified Chiller. + */ +ChillerPtr Chiller::remove_host(s4u::Host* host) +{ + simgrid::kernel::actor::simcall_answered([this, host] { hosts_.erase(host); }); + return this; +} + +/** @ingroup plugin_chiller + * @return The time to reach to goal temp, assuming that the system remain in the same state. + */ +double Chiller::get_time_to_goal_temp() const +{ + if (goal_temp_c_ == temp_in_c_) + return 0; + + double heat_power_w = 0; + for (auto const& host : hosts_) + heat_power_w += sg_host_get_current_consumption(host); + heat_power_w = heat_power_w * (1 + alpha_); + + if (temp_in_c_ < goal_temp_c_) + return air_mass_kg_ * (goal_temp_c_ - temp_in_c_) * specific_heat_j_per_kg_per_c_ / heat_power_w; + + if (not active_) + return -1; + else + return air_mass_kg_ * (temp_in_c_ - goal_temp_c_) * specific_heat_j_per_kg_per_c_ / + (power_w_ * cooling_efficiency_ - heat_power_w); +} +} // namespace simgrid::plugins diff --git a/src/plugins/file_system/s4u_FileSystem.cpp b/src/plugins/file_system/s4u_FileSystem.cpp index 20e5c27c8a..31b7fff93b 100644 --- a/src/plugins/file_system/s4u_FileSystem.cpp +++ b/src/plugins/file_system/s4u_FileSystem.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,18 +11,16 @@ #include #include #include +#include #include #include -#include "src/surf/surf_interface.hpp" - #include #include #include #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_file, s4u, "S4U files"); -int sg_storage_max_file_descriptors = 1024; /** @defgroup plugin_filesystem Plugin FileSystem * @@ -37,6 +35,7 @@ template class xbt::Extendable; namespace s4u { simgrid::xbt::Extension FileSystemDiskExt::EXTENSION_ID; simgrid::xbt::Extension FileDescriptorHostExt::EXTENSION_ID; +int FileDescriptorHostExt::max_file_descriptors; const Disk* File::find_local_disk_on(const Host* host) { @@ -58,7 +57,7 @@ const Disk* File::find_local_disk_on(const Host* host) host->get_cname()); /* Mount point found, split fullpath_ into mount_name and path+filename*/ mount_point_ = fullpath_.substr(0, longest_prefix_length); - if (mount_point_ == std::string("/")) + if (mount_point_ == "/") path_ = fullpath_; else path_ = fullpath_.substr(longest_prefix_length, fullpath_.length()); @@ -77,16 +76,15 @@ File::File(const std::string& fullpath, const_sg_host_t host, void* userdata) : local_disk_ = find_local_disk_on(host); // assign a file descriptor id to the newly opened File - auto* ext = host->extension(); + auto* ext = host->extension(); if (ext->file_descriptor_table == nullptr) { - ext->file_descriptor_table = std::make_unique>(sg_storage_max_file_descriptors); + ext->file_descriptor_table = std::make_unique>(FileDescriptorHostExt::max_file_descriptors); std::iota(ext->file_descriptor_table->rbegin(), ext->file_descriptor_table->rend(), 0); // Fill with ..., 1, 0. } xbt_assert(not ext->file_descriptor_table->empty(), "Too much files are opened! Some have to be closed."); desc_id = ext->file_descriptor_table->back(); ext->file_descriptor_table->pop_back(); - XBT_DEBUG("\tOpen file '%s'", path_.c_str()); std::map>* content = nullptr; content = local_disk_->extension()->get_content(); @@ -95,6 +93,7 @@ File::File(const std::string& fullpath, const_sg_host_t host, void* userdata) : auto sz = content->find(path_); if (sz != content->end()) { size_ = sz->second; + XBT_DEBUG("\tOpen file '%s', size %llu", path_.c_str(), size_); } else { size_ = 0; content->insert({path_, size_}); @@ -118,8 +117,7 @@ File* File::open(const std::string& fullpath, const_sg_host_t host, void* userda void File::close() { - std::vector* desc_table = - Host::current()->extension()->file_descriptor_table.get(); + std::vector* desc_table = Host::current()->extension()->file_descriptor_table.get(); kernel::actor::simcall_answered([this, desc_table] { desc_table->push_back(this->desc_id); }); delete this; } @@ -186,25 +184,11 @@ sg_size_t File::write(sg_size_t size, bool write_inside) // If the disk is full before even starting to write if (sg_disk_get_size_used(local_disk_) >= sg_disk_get_size(local_disk_)) return 0; - if (not write_inside) { + if (not write_inside) /* Subtract the part of the file that might disappear from the used sized on the storage element */ local_disk_->extension()->decr_used_size(size_ - current_position_); - write_size = local_disk_->write(size); - local_disk_->extension()->incr_used_size(write_size); - current_position_ += write_size; - size_ = current_position_; - } else { - write_size = local_disk_->write(size); - current_position_ += write_size; - if (current_position_ > size_) - size_ = current_position_; - } - kernel::actor::simcall_answered([this] { - std::map>* content = local_disk_->extension()->get_content(); - - content->erase(path_); - content->insert({path_, size_}); - }); + write_size = local_disk_->write(size); + update_position(current_position_ + write_size); return write_size; } @@ -223,19 +207,36 @@ void File::seek(sg_offset_t offset, int origin) { switch (origin) { case SEEK_SET: - current_position_ = offset; - break; + update_position(offset); + break; case SEEK_CUR: - current_position_ += offset; + update_position(current_position_ + offset); break; case SEEK_END: - current_position_ = size_ + offset; + update_position(size_ + offset); break; default: break; } } +void File::update_position(sg_offset_t position) +{ + xbt_assert(position >= 0, "Error in seek, cannot seek before file %s", get_path()); + current_position_ = position; + if(current_position_>size_){ + XBT_DEBUG("Updating size of file %s from %llu to %lld", path_.c_str(), size_, position); + local_disk_->extension()->incr_used_size(current_position_-size_); + size_ = current_position_; + + kernel::actor::simcall_answered([this] { + std::map>* content = local_disk_->extension()->get_content(); + content->erase(path_); + content->insert({path_, size_}); + }); + } +} + sg_size_t File::tell() const { return current_position_; @@ -244,7 +245,7 @@ sg_size_t File::tell() const void File::move(const std::string& fullpath) const { /* Check if the new full path is on the same mount point */ - if (fullpath.compare(0, mount_point_.length(), mount_point_) == 0) { + if (fullpath.rfind(mount_point_, 0) == 0) { std::map>* content = nullptr; content = local_disk_->extension()->get_content(); if (content) { @@ -274,10 +275,9 @@ int File::unlink() const XBT_WARN("File %s is not on disk %s. Impossible to unlink", path_.c_str(), name); return -1; } else { - XBT_DEBUG("UNLINK %s on disk '%s'", path_.c_str(), name); + XBT_DEBUG("UNLINK %s of size %llu on disk '%s'", path_.c_str(), size_, name); local_disk_->extension()->decr_used_size(size_); - // Remove the file from storage content->erase(path_); @@ -305,7 +305,7 @@ int File::remote_copy(sg_host_t host, const std::string& fullpath) for (auto const& disk : host->get_disks()) { std::string current_mount = disk->extension()->get_mount_point(); - std::string mount_point = std::string(fullpath).substr(0, current_mount.length()); + std::string mount_point = fullpath.substr(0, current_mount.length()); if (mount_point == current_mount && current_mount.length() > longest_prefix_length) { /* The current mount name is found in the full path and is bigger than the previous*/ longest_prefix_length = current_mount.length(); @@ -346,9 +346,9 @@ FileSystemDiskExt::FileSystemDiskExt(const Disk* ptr) } if (const char* current_mount_str = ptr->get_property("mount")) - mount_point_ = std::string(current_mount_str); + mount_point_ = current_mount_str; else - mount_point_ = std::string("/"); + mount_point_ = "/"; if (const char* content_str = ptr->get_property("content")) content_.reset(parse_content(content_str)); @@ -361,9 +361,9 @@ std::map>* FileSystemDiskExt::parse_content( auto* parse_content = new std::map>(); - auto fs = std::unique_ptr(surf_ifsopen(filename)); + auto fs = std::unique_ptr(simgrid::xbt::path_ifsopen(filename)); xbt_assert(not fs->fail(), "Cannot open file '%s' (path=%s)", filename.c_str(), - (boost::join(surf_path, ":")).c_str()); + simgrid::xbt::path_to_string().c_str()); std::string line; std::vector tokens; @@ -412,49 +412,28 @@ static void on_host_creation(simgrid::s4u::Host& host) host.extension_set(new FileDescriptorHostExt()); } -static void on_platform_created() -{ - for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) { - const char* remote_disk_str = host->get_property("remote_disk"); - if (remote_disk_str) { - std::vector tokens; - boost::split(tokens, remote_disk_str, boost::is_any_of(":")); - std::string mount_point = tokens[0]; - simgrid::s4u::Host* remote_host = simgrid::s4u::Host::by_name_or_null(tokens[2]); - xbt_assert(remote_host, "You're trying to access a host that does not exist. Please check your platform file"); - - const simgrid::s4u::Disk* disk = nullptr; - for (auto const& d : remote_host->get_disks()) - if (d->get_name() == tokens[1]) { - disk = d; - break; - } + static void on_platform_created() + { + for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) { + const char* remote_disk_str = host->get_property("remote_disk"); + if (not remote_disk_str) + continue; + std::vector tokens; + boost::split(tokens, remote_disk_str, boost::is_any_of(":")); + std::string mount_point = tokens[0]; + simgrid::s4u::Host* remote_host = simgrid::s4u::Host::by_name_or_null(tokens[2]); + xbt_assert(remote_host, "You're trying to access a host that does not exist. Please check your platform file"); - xbt_assert(disk, "You're trying to mount a disk that does not exist. Please check your platform file"); - disk->extension()->add_remote_mount(remote_host, mount_point); - host->add_disk(disk); + const simgrid::s4u::Disk* disk = nullptr; + for (auto const& d : remote_host->get_disks()) + if (d->get_name() == tokens[1]) { + disk = d; + break; + } - XBT_DEBUG("Host '%s' wants to mount a remote disk: %s of %s mounted on %s", host->get_cname(), disk->get_cname(), - remote_host->get_cname(), mount_point.c_str()); - XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size()); - } - } -} - -static void on_simulation_end() -{ - XBT_DEBUG("Simulation is over, time to unregister remote disks if any"); - for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) { - const char* remote_disk_str = host->get_property("remote_disk"); - if (remote_disk_str) { - std::vector tokens; - boost::split(tokens, remote_disk_str, boost::is_any_of(":")); - XBT_DEBUG("Host '%s' wants to unmount a remote disk: %s of %s mounted on %s", host->get_cname(), - tokens[1].c_str(), tokens[2].c_str(), tokens[0].c_str()); - host->remove_disk(tokens[1]); - XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size()); - } - } + xbt_assert(disk, "You're trying to mount a disk that does not exist. Please check your platform file"); + disk->extension()->add_remote_mount(remote_host, mount_point); + } } /* **************************** Public interface *************************** */ @@ -467,8 +446,8 @@ static void on_simulation_end() */ void sg_storage_file_system_init() { - sg_storage_max_file_descriptors = 1024; - simgrid::config::bind_flag(sg_storage_max_file_descriptors, "storage/max_file_descriptors", + FileDescriptorHostExt::max_file_descriptors = 1024; + simgrid::config::bind_flag(FileDescriptorHostExt::max_file_descriptors, "storage/max_file_descriptors", "Maximum number of concurrently opened files per host. Default is 1024"); if (not FileSystemDiskExt::EXTENSION_ID.valid()) { @@ -481,7 +460,6 @@ void sg_storage_file_system_init() simgrid::s4u::Host::on_creation_cb(&on_host_creation); } simgrid::s4u::Engine::on_platform_created_cb(&on_platform_created); - simgrid::s4u::Engine::on_simulation_end_cb(&on_simulation_end); } sg_file_t sg_file_open(const char* fullpath, void* data) diff --git a/src/plugins/host_dvfs.cpp b/src/plugins/host_dvfs.cpp index 9245029d21..138cdaee1b 100644 --- a/src/plugins/host_dvfs.cpp +++ b/src/plugins/host_dvfs.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,6 +14,7 @@ #include "src/internal_config.h" // HAVE_SMPI #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/resource/NetworkModel.hpp" +#include "src/simgrid/module.hpp" #if HAVE_SMPI #include "src/smpi/include/smpi_request.hpp" #include "src/smpi/plugins/ampi/ampi.hpp" @@ -58,12 +59,6 @@ static simgrid::config::Flag cfg_max_pstate("plugin/dvfs/max-pstate", "Which pstate is the maximum (and hence slowest) pstate for this governor?", MAX_PSTATE_NOT_LIMITED); -/** @addtogroup SURF_plugin_load - - This plugin makes it very simple for users to obtain the current load for each host. - -*/ - XBT_LOG_NEW_DEFAULT_SUBCATEGORY(host_dvfs, kernel, "Logging specific to the HostDvfs plugin"); namespace simgrid::plugin::dvfs { @@ -294,21 +289,18 @@ public: if (activity.get_host() == get_host()) pre_task(); }); - simgrid::s4u::Activity::on_completion_cb([this](simgrid::s4u::Activity const& activity) { - const auto* exec = dynamic_cast(&activity); - if (exec == nullptr) // Only Execs are concerned here - return; + simgrid::s4u::Exec::on_completion_cb([this](simgrid::s4u::Exec const& exec) { // For more than one host (not yet supported), we can access the host via // simcalls_.front()->issuer->get_iface()->get_host() - if (exec->get_host() == get_host() && iteration_running) { - comp_timer += exec->get_finish_time() - exec->get_start_time(); + if (exec.get_host() == get_host() && iteration_running) { + comp_timer += exec.get_finish_time() - exec.get_start_time(); } }); // FIXME I think that this fires at the same time for all hosts, so when the src sends something, // the dst will be notified even though it didn't even arrive at the recv yet - kernel::activity::CommImpl::on_start.connect([this](const kernel::activity::CommImpl& comm) { - const auto* act = static_cast(comm.surf_action_); - if ((get_host() == &act->get_src() || get_host() == &act->get_dst()) && iteration_running) { + simgrid::s4u::Comm::on_start_cb([this](const s4u::Comm& comm) { + if ((get_host() == comm.get_sender()->get_host() || get_host() == comm.get_receiver()->get_host()) && + iteration_running) { post_task(); } }); @@ -366,7 +358,7 @@ static void on_host_added(simgrid::s4u::Host& host) if (dynamic_cast(&host)) // Ignore virtual machines return; - std::string name = std::string("dvfs-daemon-") + host.get_cname(); + std::string name = "dvfs-daemon-" + host.get_name(); simgrid::s4u::ActorPtr daemon = simgrid::s4u::Actor::create(name.c_str(), &host, []() { /** * This lambda function is the function the actor (daemon) will execute @@ -379,7 +371,7 @@ static void on_host_added(simgrid::s4u::Host& host) std::string dvfs_governor; if (const char* host_conf = daemon_proc->get_host()->get_property("plugin/dvfs/governor")) { - dvfs_governor = std::string(host_conf); + dvfs_governor = host_conf; boost::algorithm::to_lower(dvfs_governor); } else { dvfs_governor = cfg_governor; diff --git a/src/plugins/host_energy.cpp b/src/plugins/host_energy.cpp index 6d9483d501..aab32cbff8 100644 --- a/src/plugins/host_energy.cpp +++ b/src/plugins/host_energy.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,7 +11,9 @@ #include #include +#include "src/kernel/activity/ActivityImpl.hpp" #include "src/kernel/resource/CpuImpl.hpp" +#include "src/simgrid/module.hpp" #include #include @@ -59,14 +61,25 @@ This is enough to compute the wattage as a function of the amount of loaded core - - +
    #Cores loadedWattageExplanation
    0 (idle) 100 Watts  Idle value
    0 (not idle) 120 Watts Epsilon value
    0 (idle) 100 Watts Idle value
    1 140 Watts Linear extrapolation between Epsilon and AllCores
    2 160 Watts Linear extrapolation between Epsilon and AllCores
    3 180 Watts Linear extrapolation between Epsilon and AllCores
    4 200 Watts AllCores value
    +Here is how it looks graphically: + +.. image:: img/plugin-energy.svg + :scale: 80% + :align: center + +As you can see, the ``Epsilon`` parameter allows to freely specify the slope you want, while using the 2 parameters +version of the model (with only ``Idle`` and ``AllCores``) requires that the ``Idle`` value is on the extension of the +line crossing the consumption you mesure for each core amount. Please note that specifying the consumption for each core +amount separately was not a solution because parallel tasks can use an amount of cores that is not an integer. The good +news is that it was not necessary, as our experiments (detailed in the paper) show that the proposed linear model is +sufficient to capture reality. .. raw:: html @@ -94,8 +107,8 @@ This encodes the following values: To change the pstate of a given CPU, use the following functions: -:cpp:func:`MSG_host_get_nb_pstates()`, :cpp:func:`simgrid::s4u::Host::set_pstate()`, -:cpp:func:`MSG_host_get_power_peak_at()`. +:cpp:func:`sg_host_get_nb_pstates()`, :cpp:func:`simgrid::s4u::Host::set_pstate()`, +:cpp:func:`sg_host_get_pstate_speed()`. .. raw:: html @@ -216,10 +229,10 @@ HostEnergy::HostEnergy(simgrid::s4u::Host* ptr) : host_(ptr) const char* off_power_str = host_->get_property("wattage_off"); if (off_power_str != nullptr) { try { - this->watts_off_ = std::stod(std::string(off_power_str)); + this->watts_off_ = std::stod(off_power_str); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid value for property wattage_off of host ") + host_->get_cname() + - ": " + off_power_str); + throw std::invalid_argument("Invalid value for property wattage_off of host " + host_->get_name() + ": " + + off_power_str); } } /* watts_off is 0 by default */ @@ -408,7 +421,7 @@ static void on_creation(simgrid::s4u::Host& host) static void on_action_state_change(simgrid::kernel::resource::CpuAction const& action, simgrid::kernel::resource::Action::State /*previous*/) { - for (simgrid::kernel::resource::CpuImpl* const& cpu : action.cpus()) { + for (simgrid::kernel::resource::CpuImpl const* cpu : action.cpus()) { simgrid::s4u::Host* host = cpu->get_iface(); if (host != nullptr) { // If it's a VM, take the corresponding PM @@ -426,14 +439,13 @@ static void on_action_state_change(simgrid::kernel::resource::CpuAction const& a /* This callback is fired either when the host changes its state (on/off) ("onStateChange") or its speed * (because the user changed the pstate, or because of external trace events) ("onSpeedChange") */ -static void on_host_change(simgrid::s4u::Host const& host) +static void on_host_change(simgrid::s4u::Host const& h) { - if (dynamic_cast(&host)) // Ignore virtual machines - return; + const auto* host = &h; + if (const auto* vm = dynamic_cast(host)) // Take the PM of virtual machines + host = vm->get_pm(); - auto* host_energy = host.extension(); - - host_energy->update(); + host->extension()->update(); } static void on_host_destruction(simgrid::s4u::Host const& host) @@ -461,6 +473,12 @@ static void on_simulation_end() used_hosts_energy, total_energy - used_hosts_energy); } +static void on_activity_suspend_resume(simgrid::s4u::Activity const& activity) +{ + if (const auto* action = dynamic_cast(activity.get_impl()->model_action_)) + on_action_state_change(*action, /*ignored*/ action->get_state()); +} + /* **************************** Public interface *************************** */ /** @ingroup plugin_host_energy @@ -475,20 +493,24 @@ void sg_host_energy_plugin_init() HostEnergy::EXTENSION_ID = simgrid::s4u::Host::extension_create(); simgrid::s4u::Host::on_creation_cb(&on_creation); - simgrid::s4u::Host::on_state_change_cb(&on_host_change); + simgrid::s4u::Host::on_onoff_cb(&on_host_change); simgrid::s4u::Host::on_speed_change_cb(&on_host_change); simgrid::s4u::Host::on_destruction_cb(&on_host_destruction); + simgrid::s4u::Host::on_exec_state_change_cb(&on_action_state_change); + simgrid::s4u::VirtualMachine::on_suspend_cb(&on_host_change); + simgrid::s4u::VirtualMachine::on_resume_cb(&on_host_change); + simgrid::s4u::Exec::on_suspend_cb(on_activity_suspend_resume); + simgrid::s4u::Exec::on_resume_cb(on_activity_suspend_resume); simgrid::s4u::Engine::on_simulation_end_cb(&on_simulation_end); - simgrid::kernel::resource::CpuAction::on_state_change.connect(&on_action_state_change); // We may only have one actor on a node. If that actor executes something like // compute -> recv -> compute - // the recv operation will not trigger a "CpuAction::on_state_change". This means + // the recv operation will not trigger a "Host::on_exec_state_change_cb". This means // that the next trigger would be the 2nd compute, hence ignoring the idle time // during the recv call. By updating at the beginning of a compute, we can // fix that. (If the cpu is not idle, this is not required.) simgrid::s4u::Exec::on_start_cb([](simgrid::s4u::Exec const& activity) { if (activity.get_host_number() == 1) { // We only run on one host - simgrid::s4u::Host* host = activity.get_host(); + simgrid::s4u::Host* host = activity.get_host(); if (const auto* vm = dynamic_cast(host)) host = vm->get_pm(); xbt_assert(host != nullptr); @@ -532,7 +554,7 @@ static void ensure_plugin_inited() double sg_host_get_consumed_energy(const_sg_host_t host) { ensure_plugin_inited(); - auto host_energy = host->extension(); + auto* host_energy = host->extension(); xbt_assert(host_energy->has_pstate_power_values(), "No power range properties specified for host %s", host->get_cname()); return host_energy->get_consumed_energy(); @@ -586,7 +608,7 @@ double sg_host_get_power_range_slope_at(const_sg_host_t host, int pstate) double sg_host_get_current_consumption(const_sg_host_t host) { ensure_plugin_inited(); - auto host_energy = host->extension(); + auto* host_energy = host->extension(); xbt_assert(host_energy->has_pstate_power_values(), "No power range properties specified for host %s", host->get_cname()); return host_energy->get_current_watts_value(); diff --git a/src/plugins/host_load.cpp b/src/plugins/host_load.cpp index 0c1d0753cf..a19b7202c5 100644 --- a/src/plugins/host_load.cpp +++ b/src/plugins/host_load.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,7 +10,7 @@ #include #include "src/kernel/activity/ExecImpl.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/module.hpp" // SIMGRID_REGISTER_PLUGIN // Makes sure that this plugin can be activated from the command line with ``--cfg=plugin:host_load`` SIMGRID_REGISTER_PLUGIN(host_load, "Cpu load", &sg_host_load_plugin_init) @@ -24,15 +24,14 @@ It attaches an extension to each host to store some data, and places callbacks i - :cpp:func:`simgrid::s4u::Host::on_creation_cb`: Attach a new extension to the newly created host. - :cpp:func:`simgrid::s4u::Exec::on_start_cb`: Make note that a new execution started, increasing the load. - :cpp:func:`simgrid::s4u::Exec::on_completion_cb`: Make note that an execution completed, decreasing the load. - - :cpp:func:`simgrid::s4u::Host::on_state_change_cb`: Do what is appropriate when the host gets suspended, turned off - or similar. + - :cpp:func:`simgrid::s4u::Host::on_onoff_cb`: Do what is appropriate when the host gets turned off or on. - :cpp:func:`simgrid::s4u::Host::on_speed_change_cb`: Do what is appropriate when the DVFS is modified. Note that extensions are automatically destroyed when the host gets destroyed. @endrst */ -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(host_load, kernel, "Logging specific to the HostLoad plugin"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(host_load, plugin, "Logging specific to the HostLoad plugin"); namespace simgrid::plugin { @@ -122,9 +121,9 @@ void HostLoad::update() // This loop updates the flops that the host executed for the ongoing computations auto iter = begin(current_activities); while (iter != end(current_activities)) { - auto& activity = iter->first; // Just an alias + const auto& activity = iter->first; // Just an alias auto& remaining_cost_after_last_update = iter->second; // Just an alias - auto& action = activity->surf_action_; + auto& action = activity->model_action_; auto current_iter = iter; ++iter; @@ -247,12 +246,9 @@ void sg_host_load_plugin_init() XBT_WARN("HostLoad plugin currently does not support executions on several hosts"); } }); - simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) { - const auto* exec = dynamic_cast(&activity); - if (exec == nullptr) // Only Execs are concerned here - return; - if (exec->get_host_number() == 1) { // We only run on one host - simgrid::s4u::Host* host = exec->get_host(); + simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) { + if (exec.get_host_number() == 1) { // We only run on one host + simgrid::s4u::Host* host = exec.get_host(); if (const auto* vm = dynamic_cast(host)) host = vm->get_pm(); xbt_assert(host != nullptr); @@ -261,7 +257,7 @@ void sg_host_load_plugin_init() XBT_WARN("HostLoad plugin currently does not support executions on several hosts"); } }); - simgrid::s4u::Host::on_state_change_cb(&on_host_change); + simgrid::s4u::Host::on_onoff_cb(&on_host_change); simgrid::s4u::Host::on_speed_change_cb(&on_host_change); } diff --git a/src/plugins/jbod.cpp b/src/plugins/jbod.cpp new file mode 100644 index 0000000000..8e169c45bd --- /dev/null +++ b/src/plugins/jbod.cpp @@ -0,0 +1,170 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include +#include +#include +#include +#include + + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_jbod, s4u, "Logging specific to the JBOD implmentation"); + +namespace simgrid::plugin { + +JbodPtr Jbod::create_jbod(s4u::NetZone* zone, const std::string& name, double speed, unsigned int num_disks, + RAID raid_level, double read_bandwidth, double write_bandwidth) +{ + xbt_assert(not ((raid_level == RAID::RAID4 || raid_level == RAID::RAID5) && num_disks < 3), + "RAID%d requires at least 3 disks", (int) raid_level); + xbt_assert(not (raid_level == RAID::RAID6 && num_disks < 4), "RAID6 requires at least 4 disks"); + + auto* jbod = new Jbod(); + jbod->set_controller(zone->create_host(name, speed)); + jbod->set_num_disks(num_disks); + jbod->set_parity_disk_idx(num_disks -1 ); + jbod->set_read_disk_idx(-1); + jbod->set_raid_level(raid_level); + for (unsigned int i = 0; i < num_disks; i++) + jbod->get_controller()->create_disk(name + "_disk_" + std::to_string(i), read_bandwidth, write_bandwidth); + + return JbodPtr(jbod, false); +} + +JbodIoPtr Jbod::read_async(sg_size_t size) +{ + auto comm = s4u::Comm::sendto_init()->set_source(this->controller_)->set_payload_size(size); + std::vector pending_ios; + sg_size_t read_size = 0; + std::vector targets; + switch(raid_level_) { + case RAID::RAID0: + read_size = size / num_disks_; + targets = controller_->get_disks(); + break; + case RAID::RAID1: + read_size = size; + targets.push_back(controller_->get_disks().at(get_next_read_disk_idx())); + break; + case RAID::RAID4: + read_size = size / (num_disks_ - 1); + targets = controller_->get_disks(); + targets.pop_back(); + break; + case RAID::RAID5: + read_size = size / (num_disks_ - 1); + targets = controller_->get_disks(); + targets.erase(targets.begin() + (get_parity_disk_idx() + 1 % num_disks_)); + break; + case RAID::RAID6: + read_size = size / (num_disks_ - 2); + targets = controller_->get_disks(); + if ( (get_parity_disk_idx() + 2 % num_disks_) == 0 ) { + targets.pop_back(); + targets.erase(targets.begin()); + } else if (get_parity_disk_idx() + 1 == static_cast(num_disks_)) { + targets.pop_back(); + targets.pop_back(); + } else { + targets.erase(targets.begin() + (get_parity_disk_idx() + 1) % num_disks_, + targets.begin() + get_parity_disk_idx() + 3); + } + break; + default: + xbt_die("Unsupported RAID level. Supported level are: 0, 1, 4, 5, and 6"); + } + for (const auto* disk : targets) { + auto io = s4u::IoPtr(disk->io_init(read_size, s4u::Io::OpType::READ)); + io->set_name(disk->get_name())->start(); + pending_ios.push_back(io); + } + + return JbodIoPtr(new JbodIo(this, comm, nullptr, pending_ios, s4u::Io::OpType::READ)); +} + +sg_size_t Jbod::read(sg_size_t size) +{ + read_async(size)->wait(); + return size; +} + +JbodIoPtr Jbod::write_async(sg_size_t size) +{ + auto comm = s4u::Comm::sendto_init(s4u::Host::current(), this->get_controller()); + std::vector pending_ios; + sg_size_t write_size = 0; + switch(raid_level_) { + case RAID::RAID0: + write_size = size / num_disks_; + break; + case RAID::RAID1: + write_size = size; + break; + case RAID::RAID4: + write_size = size / (num_disks_ - 1); + break; + case RAID::RAID5: + update_parity_disk_idx(); + write_size = size / (num_disks_ - 1); + break; + case RAID::RAID6: + update_parity_disk_idx(); + update_parity_disk_idx(); + write_size = size / (num_disks_ - 2); + break; + default: + xbt_die("Unsupported RAID level. Supported level are: 0, 1, 4, 5, and 6"); + } + for (const auto* disk : get_controller()->get_disks()) { + auto io = s4u::IoPtr(disk->io_init(write_size, s4u::Io::OpType::WRITE)); + io->set_name(disk->get_name()); + pending_ios.push_back(io); + } + + s4u::ExecPtr parity_block_comp = nullptr; + if (raid_level_ == RAID::RAID4 || raid_level_ == RAID::RAID5 || raid_level_ == RAID::RAID6) { + // Assume 1 flop per byte to write per parity block and two for RAID6. + // Do not assign the Exec yet, will be done after the completion of the CommPtr + if (raid_level_ == RAID::RAID6) + parity_block_comp = s4u::Exec::init()->set_flops_amount(200 * write_size); + else + parity_block_comp = s4u::Exec::init()->set_flops_amount(write_size); + } + + comm->set_payload_size(size)->start(); + return JbodIoPtr(new JbodIo(this, comm, parity_block_comp, pending_ios, s4u::Io::OpType::WRITE)); +} + +sg_size_t Jbod::write(sg_size_t size) +{ + write_async(size)->wait(); + return size; +} + +void JbodIo::wait() +{ + if (type_ == s4u::Io::OpType::WRITE) { + transfer_->wait(); + XBT_DEBUG("Data received on JBOD"); + if (parity_block_comp_) { + parity_block_comp_->set_host(jbod_->get_controller())->wait(); + XBT_DEBUG("Parity block computed"); + } + XBT_DEBUG("Start writing"); + for (const auto& io : pending_ios_) + io->start(); + } + + for (const auto& io : pending_ios_) { + XBT_DEBUG("Wait for I/O on %s", io->get_cname()); + io->wait(); + } + + if (type_ == s4u::Io::OpType::READ) { + XBT_DEBUG("Data read on JBOD, send it to %s", s4u::Host::current()->get_cname()); + transfer_->set_destination(s4u::Host::current())->wait(); + } +} +} // namespace simgrid::plugin diff --git a/src/plugins/link_energy.cpp b/src/plugins/link_energy.cpp index 51bd89c211..e16379978b 100644 --- a/src/plugins/link_energy.cpp +++ b/src/plugins/link_energy.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,10 +6,11 @@ #include "simgrid/Exception.hpp" #include "simgrid/host.h" #include "simgrid/plugins/energy.h" +#include "simgrid/s4u/Comm.hpp" #include "simgrid/s4u/Engine.hpp" #include "simgrid/s4u/Link.hpp" #include "src/kernel/activity/CommImpl.hpp" -#include "src/surf/surf_interface.hpp" +#include "src/simgrid/module.hpp" #include #include @@ -110,13 +111,13 @@ void LinkEnergy::init_watts_range_list() try { idle_ = std::stod(current_power_values.front()); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid idle power value for link ") + this->link_->get_cname()); + throw std::invalid_argument("Invalid idle power value for link " + this->link_->get_name()); } try { busy_ = std::stod(current_power_values.back()); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid busy power value for link ") + this->link_->get_cname()); + throw std::invalid_argument("Invalid busy power value for link " + this->link_->get_name()); } } } @@ -128,7 +129,7 @@ double LinkEnergy::get_power() const double power_slope = busy_ - idle_; - double normalized_link_usage = link_->get_usage() / link_->get_bandwidth(); + double normalized_link_usage = link_->get_load() / link_->get_bandwidth(); double dynamic_power = power_slope * normalized_link_usage; return idle_ + dynamic_power; @@ -161,15 +162,17 @@ static void on_simulation_end() XBT_INFO("Total energy over all links: %f", total_energy); } -static void on_communication(const simgrid::kernel::activity::CommImpl& comm) +static void on_communication(const simgrid::s4u::Comm& comm) { - for (auto const* link : comm.get_traversed_links()) { + const auto* pimpl = static_cast(comm.get_impl()); + for (auto const* link : pimpl->get_traversed_links()) { if (link != nullptr && link->get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::WIFI) { XBT_DEBUG("Update %s on Comm Start/End", link->get_cname()); link->extension()->update(); } } } + /* **************************** Public interface *************************** */ int sg_link_energy_is_inited() @@ -198,7 +201,7 @@ void sg_link_energy_plugin_init() } }); - simgrid::s4u::Link::on_state_change_cb([](simgrid::s4u::Link const& link) { + simgrid::s4u::Link::on_onoff_cb([](simgrid::s4u::Link const& link) { if (link.get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::WIFI) link.extension()->update(); }); @@ -209,8 +212,8 @@ void sg_link_energy_plugin_init() link.extension()->get_consumed_energy()); }); - simgrid::kernel::activity::CommImpl::on_start.connect(&on_communication); - simgrid::kernel::activity::CommImpl::on_completion.connect(&on_communication); + simgrid::s4u::Comm::on_start_cb(&on_communication); + simgrid::s4u::Comm::on_completion_cb(&on_communication); simgrid::s4u::Engine::on_simulation_end_cb(&on_simulation_end); } diff --git a/src/plugins/link_energy_wifi.cpp b/src/plugins/link_energy_wifi.cpp index 5b46eb975f..ec2e84ce34 100644 --- a/src/plugins/link_energy_wifi.cpp +++ b/src/plugins/link_energy_wifi.cpp @@ -1,15 +1,17 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include +#include #include #include #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" #include "src/kernel/resource/WifiLinkImpl.hpp" +#include "src/simgrid/module.hpp" #include #include @@ -186,7 +188,7 @@ void LinkEnergyWifi::update() * - if idle i.e. get_usage = 0, update P_{stat} * P_{tot} = P_{dyn}+P_{stat} */ - if (link_->get_usage() != 0.0) { + if (link_->get_load() != 0.0) { eDyn_ += /*duration * */ durUsage * ((host_count * pRx_) + pTx_); eStat_ += (duration - durUsage) * pIdle_ * (host_count + 1); XBT_DEBUG("eDyn += %f * ((%f * %f) + %f) | eDyn = %f (durusage =%f)", durUsage, host_count, pRx_, pTx_, eDyn_, @@ -214,7 +216,7 @@ void LinkEnergyWifi::init_watts_range_list() try { control_duration_ = std::stod(beacons_factor); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid beacons factor value for link ") + this->link_->get_cname()); + throw std::invalid_argument("Invalid beacons factor value for link " + this->link_->get_name()); } } @@ -237,22 +239,22 @@ void LinkEnergyWifi::init_watts_range_list() try { pSleep_ = std::stod(current_power_values.at(3)); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid idle power value for link ") + this->link_->get_cname()); + throw std::invalid_argument("Invalid idle power value for link " + this->link_->get_name()); } try { pRx_ = std::stod(current_power_values.at(2)); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid idle power value for link ") + this->link_->get_cname()); + throw std::invalid_argument("Invalid idle power value for link " + this->link_->get_name()); } try { pTx_ = std::stod(current_power_values.at(1)); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid idle power value for link ") + this->link_->get_cname()); + throw std::invalid_argument("Invalid idle power value for link " + this->link_->get_name()); } try { pIdle_ = std::stod(current_power_values.at(0)); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid busy power value for link ") + this->link_->get_cname()); + throw std::invalid_argument("Invalid busy power value for link " + this->link_->get_name()); } XBT_DEBUG("Values aa initialized with: pSleep=%f pIdle=%f pTx=%f pRx=%f", pSleep_, pIdle_, pTx_, pRx_); @@ -264,9 +266,10 @@ void LinkEnergyWifi::init_watts_range_list() using simgrid::plugin::LinkEnergyWifi; /* **************************** events callback *************************** */ -static void on_communication(const simgrid::kernel::activity::CommImpl& comm) +static void on_communication(const simgrid::s4u::Comm& comm) { - for (const auto* link : comm.get_traversed_links()) { + const auto* pimpl = static_cast(comm.get_impl()); + for (auto const* link : pimpl->get_traversed_links()) { if (link != nullptr && link->get_sharing_policy() == simgrid::s4u::Link::SharingPolicy::WIFI) { auto* link_energy = link->extension(); XBT_DEBUG("Update %s on Comm Start/End", link->get_cname()); @@ -323,6 +326,6 @@ void sg_wifi_energy_plugin_init() } }); - simgrid::kernel::activity::CommImpl::on_start.connect(&on_communication); - simgrid::kernel::activity::CommImpl::on_completion.connect(&on_communication); + simgrid::s4u::Comm::on_start_cb(&on_communication); + simgrid::s4u::Comm::on_completion_cb(&on_communication); } diff --git a/src/plugins/link_load.cpp b/src/plugins/link_load.cpp index 27c0cf21a2..d2df784b32 100644 --- a/src/plugins/link_load.cpp +++ b/src/plugins/link_load.cpp @@ -1,13 +1,15 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include +#include #include #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/resource/NetworkModel.hpp" +#include "src/simgrid/module.hpp" // SIMGRID_REGISTER_PLUGIN #include @@ -66,7 +68,7 @@ public: xbt::Extension LinkLoad::EXTENSION_ID; -LinkLoad::LinkLoad(s4u::Link* ptr) : link_(ptr), is_tracked_(false) +LinkLoad::LinkLoad(s4u::Link* ptr) : link_(ptr) { XBT_DEBUG("Instantiating a LinkLoad for link '%s'", link_->get_cname()); } @@ -110,7 +112,7 @@ void LinkLoad::update() " Please track your link with sg_link_load_track before trying to access any of its load metrics.", link_->get_cname()); - double current_instantaneous_bytes_per_second = link_->get_usage(); + double current_instantaneous_bytes_per_second = link_->get_load(); double now = simgrid::s4u::Engine::get_clock(); // Update minimum/maximum observed values if needed @@ -160,9 +162,10 @@ double LinkLoad::get_average_bytes() using simgrid::plugin::LinkLoad; /* **************************** events callback *************************** */ -static void on_communication(const simgrid::kernel::activity::CommImpl& comm) +static void on_communication(const simgrid::s4u::Comm& comm) { - for (const auto* link : comm.get_traversed_links()) { + const auto* pimpl = static_cast(comm.get_impl()); + for (auto const* link : pimpl->get_traversed_links()) { if (link != nullptr && link->get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::WIFI) { auto* link_load = link->extension(); XBT_DEBUG("Update %s on Comm Start/End", link->get_cname()); @@ -198,12 +201,12 @@ void sg_link_load_plugin_init() }); // Call this plugin on some of the links' events. - simgrid::kernel::activity::CommImpl::on_start.connect(&on_communication); - simgrid::kernel::activity::CommImpl::on_completion.connect(&on_communication); + simgrid::s4u::Comm::on_start_cb(&on_communication); + simgrid::s4u::Comm::on_completion_cb(&on_communication); - simgrid::s4u::Link::on_state_change_cb([](simgrid::s4u::Link const& link) { + simgrid::s4u::Link::on_onoff_cb([](simgrid::s4u::Link const& link) { if (link.get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::WIFI) { - auto link_load = link.extension(); + auto* link_load = link.extension(); if (link_load->is_tracked()) link_load->update(); } @@ -212,7 +215,7 @@ void sg_link_load_plugin_init() simgrid::kernel::resource::Action::State /* previous */) { for (auto const* link : action.get_links()) { if (link != nullptr && link->get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::WIFI) { - auto link_load = link->get_iface()->extension(); + auto* link_load = link->get_iface()->extension(); if (link_load->is_tracked()) link_load->update(); } diff --git a/src/plugins/solar_panel.cpp b/src/plugins/solar_panel.cpp new file mode 100644 index 0000000000..c6f2581f80 --- /dev/null +++ b/src/plugins/solar_panel.cpp @@ -0,0 +1,181 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ +#include +#include +#include +#include +#include + +#include "src/kernel/resource/CpuImpl.hpp" +#include "src/simgrid/module.hpp" + +SIMGRID_REGISTER_PLUGIN(solar_panel, "Solar Panel management", nullptr) + +/** @defgroup plugin_solar_panel Plugin Solar Panel + + @beginrst + +This is the solar panel plugin, enabling management of solar panels on hosts. + +This plugin allows the use of solar panels to generate power during simulation depending on size, solar +irradiance and conversion factor. + +The power model is taken from the paper `"Reinforcement Learning Based Load Balancing for +Geographically Distributed Data Centres" `_ by Max Mackie +et. al. + +Solar Panel +.................... + +A solar panel has an area :math:`A` in m², a conversion efficiency :math:`\eta` and a solar irradiance :math:`S` in +W/m². The power generated :math:`P` in W by a solar panel is given by the following equation: + +.. math:: + + P = A \times \eta \times S + + @endrst + */ + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(SolarPanel, kernel, "Logging specific to the solar panel plugin"); + +namespace simgrid::plugins { + +xbt::signal SolarPanel::on_power_change; + +/* SolarPanel */ + +void SolarPanel::update() +{ + simgrid::kernel::actor::simcall_answered([this] { + double power_w = conversion_efficiency_ * area_m2_ * solar_irradiance_w_per_m2_; + if (power_w < min_power_w_) + power_w = 0; + if (power_w > max_power_w_) + power_w = max_power_w_; + auto previous_power_w = power_w_; + power_w_ = power_w; + if (previous_power_w != power_w_) { + on_this_power_change(this); + on_power_change(this); + } + }); +} + +SolarPanel::SolarPanel(std::string name, double area_m2, double conversion_efficiency, double solar_irradiance_w_per_m2, + double min_power_w, double max_power_w) + : name_(name) + , area_m2_(area_m2) + , conversion_efficiency_(conversion_efficiency) + , solar_irradiance_w_per_m2_(solar_irradiance_w_per_m2) + , min_power_w_(min_power_w) + , max_power_w_(max_power_w) +{ + xbt_assert(area_m2 >= 0, " : area must be >= 0 (provided: %f)", area_m2); + xbt_assert(conversion_efficiency >= 0 and conversion_efficiency <= 1, + " : conversion efficiency must be in [0,1] (provided: %f)", conversion_efficiency); + xbt_assert(solar_irradiance_w_per_m2 >= 0, " : solar irradiance must be >= 0 (provided: %f)", + solar_irradiance_w_per_m2); + xbt_assert(min_power_w >= 0, " : minimal power must be >= 0 (provided: %f)", min_power_w); + xbt_assert(max_power_w > 0, " : maximal power must be > 0 (provided: %f)", max_power_w); + xbt_assert(max_power_w > min_power_w, " : maximal power must be above minimal power (provided: %f, %f)", max_power_w, + min_power_w); +} + +/** @ingroup plugin_solar_panel + * @param name The name of the Solar Panel. + * @param area_m2 The area of the Solar Panel in m² (> 0). + * @param conversion_efficiency The conversion efficiency of the Solar Panel [0,1]. + * @param solar_irradiance_w_per_m2 The solar irradiance of the Solar Panel in W/m² (> 0). + * @param min_power_w The minimal power delivered by the Solar Panel in W (> 0 and < max_power_w). + * @param max_power_w The maximal power delivered by the Solar Panel in W (> 0 and > min_power_w). + * @return A SolarPanelPtr pointing to the new SolarPanel. + */ +SolarPanelPtr SolarPanel::init(const std::string& name, double area_m2, double conversion_efficiency, + double solar_irradiance_w_per_m2, double min_power_w, double max_power_w) +{ + auto solar_panel = SolarPanelPtr( + new SolarPanel(name, area_m2, conversion_efficiency, solar_irradiance_w_per_m2, min_power_w, max_power_w)); + solar_panel->update(); + return solar_panel; +} + +/** @ingroup plugin_solar_panel + * @param name The new name of the Solar Panel. + * @return A SolarPanelPtr pointing to the modified SolarPanel. + */ +SolarPanelPtr SolarPanel::set_name(std::string name) +{ + kernel::actor::simcall_answered([this, name] { name_ = name; }); + return this; +} + +/** @ingroup plugin_solar_panel + * @param area_m2 The new area of the Solar Panel in m². + * @return A SolarPanelPtr pointing to the modified SolarPanel. + */ +SolarPanelPtr SolarPanel::set_area(double area_m2) +{ + xbt_assert(area_m2 >= 0, " : area must be > 0 (provided: %f)", area_m2); + kernel::actor::simcall_answered([this, area_m2] { area_m2_ = area_m2; }); + update(); + return this; +} + +/** @ingroup plugin_solar_panel + * @param e The new convesion efficiency of the Solar Panel. + * @return A SolarPanelPtr pointing to the modified SolarPanel. + */ +SolarPanelPtr SolarPanel::set_conversion_efficiency(double e) +{ + xbt_assert(e >= 0 and e <= 1, " : conversion efficiency must be in [0,1] (provided: %f)", e); + kernel::actor::simcall_answered([this, e] { conversion_efficiency_ = e; }); + update(); + return this; +} + +/** @ingroup plugin_solar_panel + * @param solar_irradiance_w_per_m2 The new solar irradiance of the Solar Panel in W/m². + * @return A SolarPanelPtr pointing to the modified SolarPanel. + */ +SolarPanelPtr SolarPanel::set_solar_irradiance(double solar_irradiance_w_per_m2) +{ + xbt_assert(solar_irradiance_w_per_m2 >= 0, " : solar irradiance must be >= 0 (provided: %f)", + solar_irradiance_w_per_m2); + kernel::actor::simcall_answered( + [this, solar_irradiance_w_per_m2] { solar_irradiance_w_per_m2_ = solar_irradiance_w_per_m2; }); + update(); + return this; +} + +/** @ingroup plugin_solar_panel + * @param power_w The new minimal power of the Solar Panel in W. + * @return A SolarPanelPtr pointing to the modified SolarPanel. + */ +SolarPanelPtr SolarPanel::set_min_power(double power_w) +{ + xbt_assert(power_w >= 0, " : minimal power must be >= 0 (provided: %f)", power_w); + xbt_assert(max_power_w_ > power_w, " : maximal power must be above minimal power (provided: %f, max: %f)", power_w, + max_power_w_); + kernel::actor::simcall_answered([this, power_w] { min_power_w_ = power_w; }); + update(); + return this; +} + +/** @ingroup plugin_solar_panel + * @param power_w The new maximal power of the Solar Panel in W. + * @return A SolarPanelPtr pointing to the modified SolarPanel. + */ +SolarPanelPtr SolarPanel::set_max_power(double power_w) +{ + xbt_assert(power_w > 0, " : maximal power must be > 0 (provided: %f)", power_w); + xbt_assert(min_power_w_ < power_w, " : maximal power must be above minimal power (provided: %f, min: %f)", power_w, + min_power_w_); + kernel::actor::simcall_answered([this, power_w] { max_power_w_ = power_w; }); + update(); + return this; +} + +} // namespace simgrid::plugins \ No newline at end of file diff --git a/src/plugins/vm/VmLiveMigration.cpp b/src/plugins/vm/VmLiveMigration.cpp index 192c4b29fa..be895e159d 100644 --- a/src/plugins/vm/VmLiveMigration.cpp +++ b/src/plugins/vm/VmLiveMigration.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -27,7 +27,7 @@ void MigrationRx::operator()() bool received_finalize = false; std::string finalize_task_name = - std::string("__mig_stage3:") + vm_->get_cname() + "(" + src_pm_->get_cname() + "-" + dst_pm_->get_cname() + ")"; + "__mig_stage3:" + vm_->get_name() + "(" + src_pm_->get_name() + "-" + dst_pm_->get_name() + ")"; while (not received_finalize) { auto payload = mbox->get_unique(); @@ -72,7 +72,7 @@ void MigrationRx::operator()() } // Inform the SRC that the migration has been correctly performed auto* payload = new std::string("__mig_stage4:"); - *payload = *payload + vm_->get_cname() + "(" + src_pm_->get_cname() + "-" + dst_pm_->get_cname() + ")"; + *payload = *payload + vm_->get_name() + "(" + src_pm_->get_name() + "-" + dst_pm_->get_name() + ")"; mbox_ctl->put(payload, 0); @@ -333,10 +333,8 @@ void sg_vm_migrate(simgrid::s4u::VirtualMachine* vm, simgrid::s4u::Host* dst_pm) vm->start_migration(); - std::string rx_name = - std::string("__pr_mig_rx:") + vm->get_cname() + "(" + src_pm->get_cname() + "-" + dst_pm->get_cname() + ")"; - std::string tx_name = - std::string("__pr_mig_tx:") + vm->get_cname() + "(" + src_pm->get_cname() + "-" + dst_pm->get_cname() + ")"; + std::string rx_name = "__pr_mig_rx:" + vm->get_name() + "(" + src_pm->get_name() + "-" + dst_pm->get_name() + ")"; + std::string tx_name = "__pr_mig_tx:" + vm->get_name() + "(" + src_pm->get_name() + "-" + dst_pm->get_name() + ")"; simgrid::s4u::ActorPtr rx = simgrid::s4u::Actor::create(rx_name.c_str(), dst_pm, simgrid::plugin::vm::MigrationRx(vm, dst_pm)); @@ -347,8 +345,8 @@ void sg_vm_migrate(simgrid::s4u::VirtualMachine* vm, simgrid::s4u::Host* dst_pm) /* wait until the migration have finished or on error has occurred */ XBT_DEBUG("wait for reception of the final ACK (i.e. migration has been correctly performed"); - simgrid::s4u::Mailbox* mbox_ctl = simgrid::s4u::Mailbox::by_name( - std::string("__mbox_mig_ctl:") + vm->get_cname() + "(" + src_pm->get_cname() + "-" + dst_pm->get_cname() + ")"); + simgrid::s4u::Mailbox* mbox_ctl = simgrid::s4u::Mailbox::by_name("__mbox_mig_ctl:" + vm->get_name() + "(" + + src_pm->get_name() + "-" + dst_pm->get_name() + ")"); mbox_ctl->get_unique(); tx->join(); rx->join(); diff --git a/src/plugins/vm/VmLiveMigration.hpp b/src/plugins/vm/VmLiveMigration.hpp index 26ed66c73a..0ac98a59f8 100644 --- a/src/plugins/vm/VmLiveMigration.hpp +++ b/src/plugins/vm/VmLiveMigration.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -38,10 +38,10 @@ public: { src_pm_ = vm_->get_pm(); - mbox_ctl = s4u::Mailbox::by_name(std::string("__mbox_mig_ctl:") + vm_->get_cname() + "(" + src_pm_->get_cname() + - "-" + dst_pm_->get_cname() + ")"); - mbox = s4u::Mailbox::by_name(std::string("__mbox_mig_src_dst:") + vm_->get_cname() + "(" + src_pm_->get_cname() + - "-" + dst_pm_->get_cname() + ")"); + mbox_ctl = s4u::Mailbox::by_name("__mbox_mig_ctl:" + vm_->get_name() + "(" + src_pm_->get_name() + "-" + + dst_pm_->get_name() + ")"); + mbox = s4u::Mailbox::by_name("__mbox_mig_src_dst:" + vm_->get_name() + "(" + src_pm_->get_name() + "-" + + dst_pm_->get_name() + ")"); } void operator()(); }; @@ -57,8 +57,8 @@ public: explicit MigrationTx(s4u::VirtualMachine* vm, s4u::Host* dst_pm) : vm_(vm), dst_pm_(dst_pm) { src_pm_ = vm_->get_pm(); - mbox = s4u::Mailbox::by_name(std::string("__mbox_mig_src_dst:") + vm_->get_cname() + "(" + src_pm_->get_cname() + - "-" + dst_pm_->get_cname() + ")"); + mbox = s4u::Mailbox::by_name("__mbox_mig_src_dst:" + vm_->get_name() + "(" + src_pm_->get_name() + "-" + + dst_pm_->get_name() + ")"); } void operator()(); sg_size_t sendMigrationData(sg_size_t size, int stage, int stage2_round, double mig_speed, double timeout); diff --git a/src/plugins/vm/dirty_page_tracking.cpp b/src/plugins/vm/dirty_page_tracking.cpp index bb83cae733..d30a1b015d 100644 --- a/src/plugins/vm/dirty_page_tracking.cpp +++ b/src/plugins/vm/dirty_page_tracking.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -76,7 +76,7 @@ static void on_virtual_machine_creation(const simgrid::s4u::VirtualMachine& vm) static void on_exec_creation(simgrid::s4u::Exec const& e) { - auto exec = static_cast(e.get_impl()); + const auto* exec = static_cast(e.get_impl()); const simgrid::s4u::VirtualMachine* vm = dynamic_cast(exec->get_host()); if (vm == nullptr) return; @@ -88,9 +88,9 @@ static void on_exec_creation(simgrid::s4u::Exec const& e) } } -static void on_exec_completion(const simgrid::s4u::Activity& e) +static void on_exec_completion(const simgrid::s4u::Exec& e) { - const auto exec = dynamic_cast(e.get_impl()); + const auto* exec = dynamic_cast(e.get_impl()); if (exec == nullptr) return; const simgrid::s4u::VirtualMachine* vm = dynamic_cast(exec->get_host()); @@ -113,7 +113,7 @@ void sg_vm_dirty_page_tracking_init() simgrid::kernel::resource::VirtualMachineImpl::extension_create(); simgrid::s4u::VirtualMachine::on_creation_cb(&on_virtual_machine_creation); simgrid::s4u::Exec::on_start_cb(&on_exec_creation); - simgrid::s4u::Activity::on_completion_cb(&on_exec_completion); + simgrid::s4u::Exec::on_completion_cb(&on_exec_completion); } } diff --git a/src/s4u/s4u_Activity.cpp b/src/s4u/s4u_Activity.cpp index 6032b0d08a..a1711b5fb5 100644 --- a/src/s4u/s4u_Activity.cpp +++ b/src/s4u/s4u_Activity.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "src/kernel/activity/ActivityImpl.hpp" @@ -24,11 +25,6 @@ template class xbt::Extendable; namespace s4u { -xbt::signal Activity::on_veto; -xbt::signal Activity::on_completion; -xbt::signal Activity::on_suspended; -xbt::signal Activity::on_resumed; - std::set* Activity::vetoed_activities_ = nullptr; void Activity::destroy() @@ -52,11 +48,13 @@ void Activity::wait_until(double time_limit) Activity* Activity::wait_for(double timeout) { if (state_ == State::INITED) - vetoable_start(); + start(); if (state_ == State::FAILED) { if (dynamic_cast(this)) throw NetworkFailureException(XBT_THROW_POINT, "Cannot wait for a failed comm"); + if (dynamic_cast(this)) + throw NetworkFailureException(XBT_THROW_POINT, "Cannot wait for a failed mess"); if (dynamic_cast(this)) throw HostFailureException(XBT_THROW_POINT, "Cannot wait for a failed exec"); if (dynamic_cast(this)) @@ -65,7 +63,7 @@ Activity* Activity::wait_for(double timeout) } kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActivityWaitSimcall observer{issuer, pimpl_.get(), timeout}; + kernel::actor::ActivityWaitSimcall observer{issuer, pimpl_.get(), timeout, "wait_for"}; if (kernel::actor::simcall_blocking( [&observer] { observer.get_activity()->wait_for(observer.get_issuer(), observer.get_timeout()); }, &observer)) throw TimeoutException(XBT_THROW_POINT, "Timeouted"); @@ -82,10 +80,10 @@ bool Activity::test() return true; if (state_ == State::INITED || state_ == State::STARTING) - this->vetoable_start(); + this->start(); kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActivityTestSimcall observer{issuer, pimpl_.get()}; + kernel::actor::ActivityTestSimcall observer{issuer, pimpl_.get(), "test"}; if (kernel::actor::simcall_answered([&observer] { return observer.get_activity()->test(observer.get_issuer()); }, &observer)) { complete(State::FINISHED); @@ -94,14 +92,14 @@ bool Activity::test() return false; } -ssize_t Activity::test_any(const std::vector& activities) +ssize_t Activity::test_any(const std::vector& activities) // XBT_ATTRIB_DEPRECATED_v339 { std::vector ractivities(activities.size()); std::transform(begin(activities), end(activities), begin(ractivities), [](const ActivityPtr& act) { return act->pimpl_.get(); }); kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActivityTestanySimcall observer{issuer, ractivities}; + kernel::actor::ActivityTestanySimcall observer{issuer, ractivities, "test_any"}; ssize_t changed_pos = kernel::actor::simcall_answered( [&observer] { return kernel::activity::ActivityImpl::test_any(observer.get_issuer(), observer.get_activities()); @@ -112,14 +110,14 @@ ssize_t Activity::test_any(const std::vector& activities) return changed_pos; } -ssize_t Activity::wait_any_for(const std::vector& activities, double timeout) +ssize_t Activity::deprecated_wait_any_for(const std::vector& activities, double timeout) // XBT_ATTRIB_DEPRECATED_v339 { std::vector ractivities(activities.size()); std::transform(begin(activities), end(activities), begin(ractivities), [](const ActivityPtr& activity) { return activity->pimpl_.get(); }); kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActivityWaitanySimcall observer{issuer, ractivities, timeout}; + kernel::actor::ActivityWaitanySimcall observer{issuer, ractivities, timeout, "wait_any_for"}; ssize_t changed_pos = kernel::actor::simcall_blocking( [&observer] { kernel::activity::ActivityImpl::wait_any_for(observer.get_issuer(), observer.get_activities(), diff --git a/src/s4u/s4u_ActivitySet.cpp b/src/s4u/s4u_ActivitySet.cpp new file mode 100644 index 0000000000..61957a3f9e --- /dev/null +++ b/src/s4u/s4u_ActivitySet.cpp @@ -0,0 +1,190 @@ +/* Copyright (c) 2023-. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "src/kernel/activity/ActivityImpl.hpp" +#include "src/kernel/actor/ActorImpl.hpp" +#include "src/kernel/actor/CommObserver.hpp" +#include +#include +#include +#include + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_activityset, s4u_activity, "S4U set of activities"); + +namespace simgrid { + +template class xbt::Extendable; + +namespace s4u { + +void ActivitySet::erase(ActivityPtr a) +{ + for (auto it = activities_.begin(); it != activities_.end(); it++) + if (*it == a) { + activities_.erase(it); + return; + } +} + +void ActivitySet::wait_all_for(double timeout) +{ + if (timeout < 0.0) { + for (const auto& act : activities_) + act->wait(); + + } else { + + double deadline = Engine::get_clock() + timeout; + for (const auto& act : activities_) + act->wait_until(deadline); + } +} + +ActivityPtr ActivitySet::test_any() +{ + std::vector act_impls(activities_.size()); + std::transform(begin(activities_), end(activities_), begin(act_impls), + [](const ActivityPtr& act) { return act->pimpl_.get(); }); + + kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); + kernel::actor::ActivityTestanySimcall observer{issuer, act_impls, "test_any"}; + ssize_t changed_pos = kernel::actor::simcall_answered( + [&observer] { + return kernel::activity::ActivityImpl::test_any(observer.get_issuer(), observer.get_activities()); + }, + &observer); + if (changed_pos == -1) + return ActivityPtr(nullptr); + + auto ret = activities_.at(changed_pos); + erase(ret); + ret->complete(Activity::State::FINISHED); + return ret; +} + +void ActivitySet::handle_failed_activities() +{ + for (size_t i = 0; i < activities_.size(); i++) { + auto act = activities_[i]; + if (act->pimpl_->get_state() == kernel::activity::State::FAILED) { + act->complete(Activity::State::FAILED); + + failed_activities_.push_back(act); + activities_[i] = activities_[activities_.size() - 1]; + activities_.resize(activities_.size() - 1); + i--; // compensate the i++ occuring at the end of the loop + } + } +} + +ActivityPtr ActivitySet::wait_any_for(double timeout) +{ + std::vector act_impls(activities_.size()); + std::transform(begin(activities_), end(activities_), begin(act_impls), + [](const ActivityPtr& activity) { return activity->pimpl_.get(); }); + + kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); + kernel::actor::ActivityWaitanySimcall observer{issuer, act_impls, timeout, "wait_any_for"}; + try { + ssize_t changed_pos = kernel::actor::simcall_blocking( + [&observer] { + kernel::activity::ActivityImpl::wait_any_for(observer.get_issuer(), observer.get_activities(), + observer.get_timeout()); + }, + &observer); + if (changed_pos == -1) + throw TimeoutException(XBT_THROW_POINT, "Timeouted"); + + auto ret = activities_.at(changed_pos); + erase(ret); + ret->complete(Activity::State::FINISHED); + return ret; + } catch (const HostFailureException& e) { + handle_failed_activities(); + throw; + } catch (const NetworkFailureException& e) { + handle_failed_activities(); + throw; + } catch (const StorageFailureException& e) { + handle_failed_activities(); + throw; + } +} + +ActivityPtr ActivitySet::get_failed_activity() +{ + if (failed_activities_.empty()) + return ActivityPtr(nullptr); + auto ret = failed_activities_.back(); + failed_activities_.pop_back(); + return ret; +} + +} // namespace s4u +} // namespace simgrid + +SG_BEGIN_DECL + +sg_activity_set_t sg_activity_set_init() +{ + return new simgrid::s4u::ActivitySet(); +} +void sg_activity_set_push(sg_activity_set_t as, sg_activity_t acti) +{ + as->push(acti); +} +void sg_activity_set_erase(sg_activity_set_t as, sg_activity_t acti) +{ + as->erase(acti); +} +size_t sg_activity_set_size(sg_activity_set_t as) +{ + return as->size(); +} +int sg_activity_set_empty(sg_activity_set_t as) +{ + return as->empty(); +} + +sg_activity_t sg_activity_set_test_any(sg_activity_set_t as) +{ + return as->test_any().get(); +} +void sg_activity_set_wait_all(sg_activity_set_t as) +{ + as->wait_all(); +} +int sg_activity_set_wait_all_for(sg_activity_set_t as, double timeout) +{ + try { + as->wait_all_for(timeout); + return 1; + } catch (const simgrid::TimeoutException& e) { + return 0; + } +} +sg_activity_t sg_activity_set_wait_any(sg_activity_set_t as) +{ + return as->wait_any().get(); +} +sg_activity_t sg_activity_set_wait_any_for(sg_activity_set_t as, double timeout) +{ + try { + return as->wait_any_for(timeout).get(); + } catch (const simgrid::TimeoutException& e) { + return nullptr; + } +} + +void sg_activity_set_delete(sg_activity_set_t as) +{ + delete as; +} +void sg_activity_unref(sg_activity_t acti) +{ + acti->unref(); +} + +SG_END_DECL diff --git a/src/s4u/s4u_Actor.cpp b/src/s4u/s4u_Actor.cpp index 8c0fc2e679..573d708555 100644 --- a/src/s4u/s4u_Actor.cpp +++ b/src/s4u/s4u_Actor.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,11 +11,11 @@ #include #include -#include "src/include/mc/mc.h" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" +#include "src/kernel/resource/HostImpl.hpp" +#include "src/mc/mc.h" #include "src/mc/mc_replay.hpp" -#include "src/surf/HostImpl.hpp" #include @@ -108,20 +108,21 @@ void Actor::join() const void Actor::join(double timeout) const { - xbt_assert(not(MC_is_active() || MC_record_replay_is_active()), - "Actor::join() is not usable in MC yet. Please report this bug."); - kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); const kernel::actor::ActorImpl* target = pimpl_; - kernel::actor::simcall_blocking([issuer, target, timeout] { - if (target->wannadie()) { - // The joined actor is already finished, just wake up the issuer right away - issuer->simcall_answer(); - } else { - kernel::activity::ActivityImplPtr sync = issuer->join(target, timeout); - sync->register_simcall(&issuer->simcall_); - } - }); + kernel::actor::ActorJoinSimcall observer{issuer, get_impl(), timeout}; + + kernel::actor::simcall_blocking( + [issuer, target, timeout] { + if (target->wannadie()) { + // The joined actor is already finished, just wake up the issuer right away + issuer->simcall_answer(); + } else { + kernel::activity::ActivityImplPtr sync = issuer->join(target, timeout); + sync->register_simcall(&issuer->simcall_); + } + }, + &observer); } Actor* Actor::set_auto_restart(bool autorestart) @@ -163,6 +164,7 @@ void Actor::set_host(Host* new_host) }); s4u::Actor::on_host_change(*this, *previous_location); + s4u::Actor::on_this_host_change(*this, *previous_location); } s4u::Host* Actor::get_host() const @@ -187,7 +189,7 @@ bool Actor::is_maestro() return self == nullptr || kernel::EngineImpl::get_instance()->is_maestro(self); } -const simgrid::xbt::string& Actor::get_name() const +const std::string& Actor::get_name() const { return this->pimpl_->get_name(); } @@ -212,6 +214,7 @@ void Actor::suspend() kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); kernel::actor::ActorImpl* target = pimpl_; s4u::Actor::on_suspend(*this); + s4u::Actor::on_this_suspend(*this); kernel::actor::simcall_blocking([issuer, target]() { target->suspend(); if (target != issuer) { @@ -225,6 +228,7 @@ void Actor::resume() { kernel::actor::simcall_answered([this] { pimpl_->resume(); }); s4u::Actor::on_resume(*this); + s4u::Actor::on_this_resume(*this); } bool Actor::is_suspended() const @@ -312,31 +316,37 @@ void sleep_for(double duration) if (duration <= 0) /* that's a no-op */ return; - if (duration < sg_surf_precision) { + if (duration < sg_precision_timing) { static unsigned int warned = 0; // At most 20 such warnings warned++; if (warned <= 20) XBT_INFO("The parameter to sleep_for() is smaller than the SimGrid numerical accuracy (%g < %g). " "Please refer to https://simgrid.org/doc/latest/Configuring_SimGrid.html#numerical-precision", - duration, sg_surf_precision); + duration, sg_precision_timing); if (warned == 20) XBT_VERB("(further warnings about the numerical accuracy of sleep_for() will be omitted)."); } kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - Actor::on_sleep(*issuer->get_ciface()); + kernel::actor::ActorSleepSimcall observer(issuer); - kernel::actor::simcall_blocking([issuer, duration]() { - if (MC_is_active() || MC_record_replay_is_active()) { - MC_process_clock_add(issuer, duration); - issuer->simcall_answer(); - return; - } - kernel::activity::ActivityImplPtr sync = issuer->sleep(duration); - sync->register_simcall(&issuer->simcall_); - }); + Actor::on_sleep(*issuer->get_ciface()); + issuer->get_ciface()->on_this_sleep(*issuer->get_ciface()); + + kernel::actor::simcall_blocking( + [issuer, duration]() { + if (MC_is_active() || MC_record_replay_is_active()) { + // MC_process_clock_add(issuer, duration); // BUG: Makes the exploration loop + issuer->simcall_answer(); + } else { + kernel::activity::ActivityImplPtr sync = issuer->sleep(duration); + sync->register_simcall(&issuer->simcall_); + } + }, + &observer); Actor::on_wake_up(*issuer->get_ciface()); + issuer->get_ciface()->on_this_wake_up(*issuer->get_ciface()); } void yield() @@ -358,7 +368,7 @@ void execute(double flops) void execute(double flops, double priority) { - exec_init(flops)->set_priority(priority)->vetoable_start()->wait(); + exec_init(flops)->set_priority(priority)->start()->wait(); } void parallel_execute(const std::vector& hosts, const std::vector& flops_amounts, @@ -406,13 +416,14 @@ ExecPtr exec_init(const std::vector& hosts, const std::vectorvetoable_start(); + res->start(); return res; } aid_t get_pid() { - return simgrid::kernel::actor::ActorImpl::self()->get_pid(); + const auto* self = simgrid::kernel::actor::ActorImpl::self(); + return self ? self->get_pid() : 0; } aid_t get_ppid() @@ -427,7 +438,8 @@ std::string get_name() const char* get_cname() { - return simgrid::kernel::actor::ActorImpl::self()->get_cname(); + const auto* self = simgrid::kernel::actor::ActorImpl::self(); + return self ? self->get_cname() : nullptr; } Host* get_host() @@ -439,6 +451,7 @@ void suspend() { kernel::actor::ActorImpl* self = simgrid::kernel::actor::ActorImpl::self(); s4u::Actor::on_suspend(*self->get_ciface()); + self->get_ciface()->on_this_suspend(*self->get_ciface()); kernel::actor::simcall_blocking([self] { self->suspend(); }); } @@ -752,6 +765,8 @@ aid_t sg_actor_self_get_ppid() const char* sg_actor_self_get_name() { + if (simgrid::s4u::Actor::is_maestro()) + return "maestro"; return simgrid::s4u::this_actor::get_cname(); } diff --git a/src/s4u/s4u_Barrier.cpp b/src/s4u/s4u_Barrier.cpp index b7f0c99ef8..4b5bd3f2d2 100644 --- a/src/s4u/s4u_Barrier.cpp +++ b/src/s4u/s4u_Barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -36,7 +36,7 @@ int Barrier::wait() kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); if (MC_is_active() || MC_record_replay_is_active()) { // Split in 2 simcalls for transition persistency - kernel::actor::BarrierObserver lock_observer{issuer, mc::Transition::Type::BARRIER_LOCK, pimpl_}; + kernel::actor::BarrierObserver lock_observer{issuer, mc::Transition::Type::BARRIER_ASYNC_LOCK, pimpl_}; auto acquisition = kernel::actor::simcall_answered([issuer, this] { return pimpl_->acquire_async(issuer); }, &lock_observer); diff --git a/src/s4u/s4u_Comm.cpp b/src/s4u/s4u_Comm.cpp index d1fe6f65c0..aec421bfa9 100644 --- a/src/s4u/s4u_Comm.cpp +++ b/src/s4u/s4u_Comm.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,14 +6,15 @@ #include #include #include +#include #include #include #include -#include "mc/mc.h" #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" +#include "src/mc/mc.h" #include "src/mc/mc_replay.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_comm, s4u_activity, "S4U asynchronous communications"); @@ -28,7 +29,8 @@ CommPtr Comm::set_copy_data_callback(const std::functiondst_buff_, buff, buff_size); @@ -39,7 +41,8 @@ void Comm::copy_buffer_callback(kernel::activity::CommImpl* comm, void* buff, si } } -void Comm::copy_pointer_callback(kernel::activity::CommImpl* comm, void* buff, size_t buff_size) +void Comm::copy_pointer_callback(kernel::activity::CommImpl* comm, void* buff, + size_t buff_size) // XBT_ATTRIB_DEPRECATED_v338 { xbt_assert((buff_size == sizeof(void*)), "Cannot copy %zu bytes: must be sizeof(void*)", buff_size); *(void**)(comm->dst_buff_) = buff; @@ -76,13 +79,14 @@ void Comm::send(kernel::actor::ActorImpl* sender, const Mailbox* mbox, double ta simgrid::kernel::activity::ActivityImplPtr comm = nullptr; simgrid::kernel::actor::CommIsendSimcall send_observer{ - sender, mbox->get_impl(), task_size, rate, static_cast(src_buff), src_buff_size, match_fun, - nullptr, copy_data_fun, data, false}; + sender, mbox->get_impl(), task_size, rate, static_cast(src_buff), + src_buff_size, match_fun, nullptr, copy_data_fun, data, + false, "Isend"}; comm = simgrid::kernel::actor::simcall_answered( [&send_observer] { return simgrid::kernel::activity::CommImpl::isend(&send_observer); }, &send_observer); - simgrid::kernel::actor::ActivityWaitSimcall wait_observer{sender, comm.get(), timeout}; - if (simgrid::kernel::actor::simcall_blocking( + if (simgrid::kernel::actor::ActivityWaitSimcall wait_observer{sender, comm.get(), timeout, "Wait"}; + simgrid::kernel::actor::simcall_blocking( [&wait_observer] { wait_observer.get_activity()->wait_for(wait_observer.get_issuer(), wait_observer.get_timeout()); }, @@ -93,7 +97,7 @@ void Comm::send(kernel::actor::ActorImpl* sender, const Mailbox* mbox, double ta } else { simgrid::kernel::actor::CommIsendSimcall observer(sender, mbox->get_impl(), task_size, rate, static_cast(src_buff), src_buff_size, match_fun, - nullptr, copy_data_fun, data, false); + nullptr, copy_data_fun, data, false, "Isend"); simgrid::kernel::actor::simcall_blocking([&observer, timeout] { simgrid::kernel::activity::ActivityImplPtr comm = simgrid::kernel::activity::CommImpl::isend(&observer); comm->wait_for(observer.get_issuer(), timeout); @@ -120,12 +124,13 @@ void Comm::recv(kernel::actor::ActorImpl* receiver, const Mailbox* mbox, void* d match_fun, copy_data_fun, data, - rate}; + rate, + "Irecv"}; comm = simgrid::kernel::actor::simcall_answered( [&observer] { return simgrid::kernel::activity::CommImpl::irecv(&observer); }, &observer); - simgrid::kernel::actor::ActivityWaitSimcall wait_observer{receiver, comm.get(), timeout}; - if (simgrid::kernel::actor::simcall_blocking( + if (simgrid::kernel::actor::ActivityWaitSimcall wait_observer{receiver, comm.get(), timeout, "wait"}; + simgrid::kernel::actor::simcall_blocking( [&wait_observer] { wait_observer.get_activity()->wait_for(wait_observer.get_issuer(), wait_observer.get_timeout()); }, @@ -135,7 +140,7 @@ void Comm::recv(kernel::actor::ActorImpl* receiver, const Mailbox* mbox, void* d comm = nullptr; } else { simgrid::kernel::actor::CommIrecvSimcall observer(receiver, mbox->get_impl(), static_cast(dst_buff), - dst_buff_size, match_fun, copy_data_fun, data, rate); + dst_buff_size, match_fun, copy_data_fun, data, rate, "Irecv"); simgrid::kernel::actor::simcall_blocking([&observer, timeout] { simgrid::kernel::activity::ActivityImplPtr comm = simgrid::kernel::activity::CommImpl::irecv(&observer); comm->wait_for(observer.get_issuer(), timeout); @@ -178,7 +183,7 @@ CommPtr Comm::set_source(Host* from) if (state_ == State::STARTING && remains_ <= 0) XBT_DEBUG("This communication has a payload size of 0 byte. It cannot start yet"); else - vetoable_start(); + start(); return this; } @@ -196,7 +201,7 @@ CommPtr Comm::set_destination(Host* to) if (state_ == State::STARTING && remains_ <= 0) XBT_DEBUG("This communication has a payload size of 0 byte. It cannot start yet"); else - vetoable_start(); + start(); return this; } @@ -209,7 +214,7 @@ Host* Comm::get_destination() const CommPtr Comm::set_rate(double rate) { xbt_assert(state_ == State::INITED, "You cannot use %s() once your communication started (not implemented)", - __FUNCTION__); + __func__); rate_ = rate; return this; } @@ -217,7 +222,7 @@ CommPtr Comm::set_rate(double rate) CommPtr Comm::set_mailbox(Mailbox* mailbox) { xbt_assert(state_ == State::INITED, "You cannot use %s() once your communication started (not implemented)", - __FUNCTION__); + __func__); mailbox_ = mailbox; return this; } @@ -225,7 +230,7 @@ CommPtr Comm::set_mailbox(Mailbox* mailbox) CommPtr Comm::set_src_data(void* buff) { xbt_assert(state_ == State::INITED, "You cannot use %s() once your communication started (not implemented)", - __FUNCTION__); + __func__); xbt_assert(dst_buff_ == nullptr, "Cannot set the src and dst buffers at the same time"); src_buff_ = buff; return this; @@ -234,7 +239,7 @@ CommPtr Comm::set_src_data(void* buff) CommPtr Comm::set_src_data_size(size_t size) { xbt_assert(state_ == State::INITED, "You cannot use %s() once your communication started (not implemented)", - __FUNCTION__); + __func__); src_buff_size_ = size; return this; } @@ -242,7 +247,7 @@ CommPtr Comm::set_src_data_size(size_t size) CommPtr Comm::set_src_data(void* buff, size_t size) { xbt_assert(state_ == State::INITED, "You cannot use %s() once your communication started (not implemented)", - __FUNCTION__); + __func__); xbt_assert(dst_buff_ == nullptr, "Cannot set the src and dst buffers at the same time"); src_buff_ = buff; @@ -253,7 +258,7 @@ CommPtr Comm::set_src_data(void* buff, size_t size) CommPtr Comm::set_dst_data(void** buff) { xbt_assert(state_ == State::INITED, "You cannot use %s() once your communication started (not implemented)", - __FUNCTION__); + __func__); xbt_assert(src_buff_ == nullptr, "Cannot set the src and dst buffers at the same time"); dst_buff_ = buff; return this; @@ -262,7 +267,7 @@ CommPtr Comm::set_dst_data(void** buff) CommPtr Comm::set_dst_data(void** buff, size_t size) { xbt_assert(state_ == State::INITED, "You cannot use %s() once your communication started (not implemented)", - __FUNCTION__); + __func__); xbt_assert(src_buff_ == nullptr, "Cannot set the src and dst buffers at the same time"); dst_buff_ = buff; @@ -272,13 +277,21 @@ CommPtr Comm::set_dst_data(void** buff, size_t size) CommPtr Comm::set_payload_size(uint64_t bytes) { - Activity::set_remaining(bytes); + set_remaining(bytes); if (pimpl_) { boost::static_pointer_cast(pimpl_)->set_size(bytes); } return this; } +void* Comm::get_payload() const +{ + xbt_assert(get_state() == State::FINISHED, + "You can only retrieve the payload of a communication that gracefully terminated, but its state is %s.", + get_state_str()); + return static_cast(pimpl_.get())->payload_; +} + Actor* Comm::get_sender() const { kernel::actor::ActorImplPtr sender = nullptr; @@ -287,16 +300,27 @@ Actor* Comm::get_sender() const return sender ? sender->get_ciface() : nullptr; } +Actor* Comm::get_receiver() const +{ + kernel::actor::ActorImplPtr receiver = nullptr; + if (pimpl_) + receiver = boost::static_pointer_cast(pimpl_)->dst_actor_; + return receiver ? receiver->get_ciface() : nullptr; +} + bool Comm::is_assigned() const { return (pimpl_ && boost::static_pointer_cast(pimpl_)->is_assigned()) || mailbox_ != nullptr; } -Comm* Comm::start() +Comm* Comm::do_start() { xbt_assert(get_state() == State::INITED || get_state() == State::STARTING, - "You cannot use %s() once your communication started (not implemented)", __FUNCTION__); + "You cannot use %s() once your communication started (not implemented)", __func__); + + auto myself = kernel::actor::ActorImpl::self(); + if (get_source() != nullptr || get_destination() != nullptr) { xbt_assert(is_assigned(), "When either from_ or to_ is specified, both must be."); xbt_assert(src_buff_ == nullptr && dst_buff_ == nullptr, @@ -306,8 +330,11 @@ Comm* Comm::start() pimpl_->set_state(kernel::activity::State::READY); boost::static_pointer_cast(pimpl_)->start(); }); - } else if (src_buff_ != nullptr) { // Sender side + fire_on_start(); + fire_on_this_start(); + } else if (myself == sender_) { on_send(*this); + on_this_send(*this); kernel::actor::CommIsendSimcall observer{sender_, mailbox_->get_impl(), remains_, @@ -318,12 +345,14 @@ Comm* Comm::start() clean_fun_, copy_data_function_, get_data(), - detached_}; + detached_, + "Isend"}; pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::CommImpl::isend(&observer); }, &observer); - } else if (dst_buff_ != nullptr) { // Receiver side + } else if (myself == receiver_) { xbt_assert(not detached_, "Receive cannot be detached"); on_recv(*this); + on_this_recv(*this); kernel::actor::CommIrecvSimcall observer{receiver_, mailbox_->get_impl(), static_cast(dst_buff_), @@ -331,7 +360,8 @@ Comm* Comm::start() match_fun_, copy_data_function_, get_data(), - rate_}; + rate_, + "Irecv"}; pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::CommImpl::irecv(&observer); }, &observer); } else { @@ -344,6 +374,11 @@ Comm* Comm::start() if (not detached_) { pimpl_->set_iface(this); pimpl_->set_actor(sender_); + // Only throw the signal when both sides are here and the status is READY + if (pimpl_->get_state() != kernel::activity::State::WAITING) { + fire_on_start(); + fire_on_this_start(); + } } state_ = State::STARTED; @@ -353,19 +388,28 @@ Comm* Comm::start() Comm* Comm::detach() { xbt_assert(state_ == State::INITED || state_ == State::STARTING, - "You cannot use %s() once your communication is %s (not implemented)", __FUNCTION__, get_state_str()); + "You cannot use %s() once your communication is %s (not implemented)", __func__, get_state_str()); xbt_assert(dst_buff_ == nullptr && dst_buff_size_ == 0, "You can only detach sends, not recvs"); detached_ = true; - vetoable_start(); + start(); return this; } -ssize_t Comm::test_any(const std::vector& comms) +ssize_t Comm::test_any(const std::vector& comms) // XBT_ATTRIB_DEPRECATED_v339 { - std::vector activities; - for (const auto& comm : comms) - activities.push_back(boost::dynamic_pointer_cast(comm)); - return Activity::test_any(activities); + std::vector ractivities(comms.size()); + std::transform(begin(comms), end(comms), begin(ractivities), [](const CommPtr& act) { return act->pimpl_.get(); }); + + kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); + kernel::actor::ActivityTestanySimcall observer{issuer, ractivities, "test_any"}; + ssize_t changed_pos = kernel::actor::simcall_answered( + [&observer] { + return kernel::activity::ActivityImpl::test_any(observer.get_issuer(), observer.get_activities()); + }, + &observer); + if (changed_pos != -1) + comms.at(changed_pos)->complete(State::FINISHED); + return changed_pos; } /** @brief Block the calling actor until the communication is finished, or until timeout @@ -386,14 +430,16 @@ Comm* Comm::wait_for(double timeout) case State::INITED: case State::STARTING: // It's not started yet. Do it in one simcall if it's a regular communication if (get_source() != nullptr || get_destination() != nullptr) { - return vetoable_start()->wait_for(timeout); // In the case of host2host comm, do it in two simcalls + return start()->wait_for(timeout); // In the case of host2host comm, do it in two simcalls } else if (src_buff_ != nullptr) { on_send(*this); + on_this_send(*this); send(sender_, mailbox_, remains_, rate_, src_buff_, src_buff_size_, match_fun_, copy_data_function_, get_data(), timeout); } else { // Receiver on_recv(*this); + on_this_recv(*this); recv(receiver_, mailbox_, dst_buff_, &dst_buff_size_, match_fun_, copy_data_function_, get_data(), timeout, rate_); } @@ -401,7 +447,7 @@ Comm* Comm::wait_for(double timeout) case State::STARTED: try { issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActivityWaitSimcall observer{issuer, pimpl_.get(), timeout}; + kernel::actor::ActivityWaitSimcall observer{issuer, pimpl_.get(), timeout, "Wait"}; if (kernel::actor::simcall_blocking( [&observer] { observer.get_activity()->wait_for(observer.get_issuer(), observer.get_timeout()); }, &observer)) { @@ -424,55 +470,60 @@ Comm* Comm::wait_for(double timeout) return this; } -ssize_t Comm::wait_any_for(const std::vector& comms, double timeout) +ssize_t Comm::deprecated_wait_any_for(const std::vector& comms, double timeout) // XBT_ATTRIB_DEPRECATED_v339 { - std::vector activities; + if (comms.empty()) + return -1; + ActivitySet set; for (const auto& comm : comms) - activities.push_back(boost::dynamic_pointer_cast(comm)); - ssize_t changed_pos; + set.push(comm); try { - changed_pos = Activity::wait_any_for(activities, timeout); + auto* ret = set.wait_any_for(timeout).get(); + for (size_t i = 0; i < comms.size(); i++) + if (comms[i].get() == ret) + return i; + + } catch (TimeoutException& e) { + return -1; } catch (const NetworkFailureException& e) { - changed_pos = -1; - for (auto c : comms) { - if (c->pimpl_->get_state() == kernel::activity::State::FAILED) { + for (auto c : comms) + if (c->pimpl_->get_state() == kernel::activity::State::FAILED) c->complete(State::FAILED); - } - } + e.rethrow_nested(XBT_THROW_POINT, boost::core::demangle(typeid(e).name()) + " raised in kernel mode."); } - return changed_pos; + return -1; } -void Comm::wait_all(const std::vector& comms) +void Comm::wait_all(const std::vector& comms) // XBT_ATTRIB_DEPRECATED_v339 { // TODO: this should be a simcall or something - for (auto& comm : comms) + for (const auto& comm : comms) comm->wait(); } -size_t Comm::wait_all_for(const std::vector& comms, double timeout) +size_t Comm::wait_all_for(const std::vector& comms, double timeout) // XBT_ATTRIB_DEPRECATED_v339 { if (timeout < 0.0) { - wait_all(comms); + for (const auto& comm : comms) + comm->wait(); return comms.size(); } - double deadline = Engine::get_clock() + timeout; - std::vector waited_comm(1, nullptr); - for (size_t i = 0; i < comms.size(); i++) { - double wait_timeout = std::max(0.0, deadline - Engine::get_clock()); - waited_comm[0] = comms[i]; - // Using wait_any_for() here (and not wait_for) because we don't want comms to be invalidated on timeout - if (wait_any_for(waited_comm, wait_timeout) == -1) { - XBT_DEBUG("Timeout (%g): i = %zu", wait_timeout, i); - return i; - } - } - return comms.size(); + ActivitySet set; + for (auto comm : comms) + set.push(comm); + set.wait_all_for(timeout); + + return set.size(); } } // namespace simgrid::s4u /* **************************** Public C interface *************************** */ +int sg_comm_isinstance(sg_activity_t acti) +{ + return dynamic_cast(acti) != nullptr; +} + void sg_comm_detach(sg_comm_t comm, void (*clean_function)(void*)) { comm->detach(clean_function); @@ -512,35 +563,36 @@ sg_error_t sg_comm_wait_for(sg_comm_t comm, double timeout) return status; } -void sg_comm_wait_all(sg_comm_t* comms, size_t count) +void sg_comm_wait_all(sg_comm_t* comms, size_t count) // XBT_ATTRIB_DEPRECATED_v339 { - sg_comm_wait_all_for(comms, count, -1); + simgrid::s4u::ActivitySet as; + for (size_t i = 0; i < count; i++) + as.push(comms[i]); + + as.wait_all(); } -size_t sg_comm_wait_all_for(sg_comm_t* comms, size_t count, double timeout) +ssize_t sg_comm_wait_any(sg_comm_t* comms, size_t count) // XBT_ATTRIB_DEPRECATED_v339 { std::vector s4u_comms; for (size_t i = 0; i < count; i++) s4u_comms.emplace_back(comms[i], false); - size_t pos = simgrid::s4u::Comm::wait_all_for(s4u_comms, timeout); - for (size_t i = pos; i < count; i++) - s4u_comms[i]->add_ref(); + ssize_t pos = simgrid::s4u::Comm::deprecated_wait_any_for(s4u_comms, -1); + for (size_t i = 0; i < count; i++) { + if (pos != -1 && static_cast(pos) != i) + s4u_comms[i]->add_ref(); + } return pos; } -ssize_t sg_comm_wait_any(sg_comm_t* comms, size_t count) -{ - return sg_comm_wait_any_for(comms, count, -1); -} - -ssize_t sg_comm_wait_any_for(sg_comm_t* comms, size_t count, double timeout) +ssize_t sg_comm_wait_any_for(sg_comm_t* comms, size_t count, double timeout) // XBT_ATTRIB_DEPRECATED_v339 { std::vector s4u_comms; for (size_t i = 0; i < count; i++) s4u_comms.emplace_back(comms[i], false); - ssize_t pos = simgrid::s4u::Comm::wait_any_for(s4u_comms, timeout); + ssize_t pos = simgrid::s4u::Comm::deprecated_wait_any_for(s4u_comms, timeout); for (size_t i = 0; i < count; i++) { if (pos != -1 && static_cast(pos) != i) s4u_comms[i]->add_ref(); diff --git a/src/s4u/s4u_ConditionVariable.cpp b/src/s4u/s4u_ConditionVariable.cpp index e7e772465a..74ae59b881 100644 --- a/src/s4u/s4u_ConditionVariable.cpp +++ b/src/s4u/s4u_ConditionVariable.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,8 +7,9 @@ #include #include +#include "src/kernel/activity/ActivityImpl.hpp" #include "src/kernel/activity/ConditionVariableImpl.hpp" -#include "src/kernel/actor/SimcallObserver.hpp" +#include "src/kernel/actor/SynchroObserver.hpp" #include @@ -27,7 +28,7 @@ ConditionVariablePtr ConditionVariable::create() void ConditionVariable::wait(MutexPtr lock) { kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ConditionWaitSimcall observer{issuer, pimpl_, lock->pimpl_}; + kernel::actor::ConditionVariableObserver observer{issuer, pimpl_, lock->pimpl_}; kernel::actor::simcall_blocking( [&observer] { observer.get_cond()->wait(observer.get_mutex(), -1.0, observer.get_issuer()); }, &observer); } @@ -35,7 +36,7 @@ void ConditionVariable::wait(MutexPtr lock) void ConditionVariable::wait(const std::unique_lock& lock) { kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ConditionWaitSimcall observer{issuer, pimpl_, lock.mutex()->pimpl_}; + kernel::actor::ConditionVariableObserver observer{issuer, pimpl_, lock.mutex()->pimpl_}; kernel::actor::simcall_blocking( [&observer] { observer.get_cond()->wait(observer.get_mutex(), -1.0, observer.get_issuer()); }, &observer); } @@ -47,7 +48,7 @@ std::cv_status s4u::ConditionVariable::wait_for(const std::unique_lock& l timeout = 0.0; kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ConditionWaitSimcall observer{issuer, pimpl_, lock.mutex()->pimpl_, timeout}; + kernel::actor::ConditionVariableObserver observer{issuer, pimpl_, lock.mutex()->pimpl_, timeout}; bool timed_out = kernel::actor::simcall_blocking( [&observer] { observer.get_cond()->wait(observer.get_mutex(), observer.get_timeout(), observer.get_issuer()); }, &observer); diff --git a/src/s4u/s4u_Disk.cpp b/src/s4u/s4u_Disk.cpp index fa64f72061..c97f72bc00 100644 --- a/src/s4u/s4u_Disk.cpp +++ b/src/s4u/s4u_Disk.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -17,7 +17,7 @@ namespace s4u { xbt::signal Disk::on_creation; xbt::signal Disk::on_destruction; -xbt::signal Disk::on_state_change; +xbt::signal Disk::on_onoff; const std::string& Disk::get_name() const { @@ -31,13 +31,13 @@ const char* Disk::get_cname() const Disk* Disk::set_read_bandwidth(double read_bw) { - kernel::actor::simcall_answered([this, read_bw] { pimpl_->set_read_bandwidth(read_bw); }); + kernel::actor::simcall_object_access(pimpl_, [this, read_bw] { pimpl_->set_read_bandwidth(read_bw); }); return this; } Disk* Disk::set_write_bandwidth(double write_bw) { - kernel::actor::simcall_answered([this, write_bw] { pimpl_->set_write_bandwidth(write_bw); }); + kernel::actor::simcall_object_access(pimpl_, [this, write_bw] { pimpl_->set_write_bandwidth(write_bw); }); return this; } @@ -48,7 +48,7 @@ double Disk::get_read_bandwidth() const Disk* Disk::set_readwrite_bandwidth(double bw) { - kernel::actor::simcall_answered([this, bw] { pimpl_->set_readwrite_bandwidth(bw); }); + kernel::actor::simcall_object_access(pimpl_, [this, bw] { pimpl_->set_readwrite_bandwidth(bw); }); return this; } @@ -80,34 +80,46 @@ const char* Disk::get_property(const std::string& key) const Disk* Disk::set_property(const std::string& key, const std::string& value) { - kernel::actor::simcall_answered([this, &key, &value] { this->pimpl_->set_property(key, value); }); + kernel::actor::simcall_object_access(pimpl_, [this, &key, &value] { this->pimpl_->set_property(key, value); }); return this; } Disk* Disk::set_properties(const std::unordered_map& properties) { - kernel::actor::simcall_answered([this, properties] { this->pimpl_->set_properties(properties); }); + kernel::actor::simcall_object_access(pimpl_, [this, properties] { this->pimpl_->set_properties(properties); }); return this; } Disk* Disk::set_state_profile(kernel::profile::Profile* profile) { xbt_assert(not pimpl_->is_sealed(), "Cannot set a state profile once the Disk is sealed"); - kernel::actor::simcall_answered([this, profile]() { this->pimpl_->set_state_profile(profile); }); + kernel::actor::simcall_object_access(pimpl_, [this, profile]() { this->pimpl_->set_state_profile(profile); }); return this; } Disk* Disk::set_read_bandwidth_profile(kernel::profile::Profile* profile) { xbt_assert(not pimpl_->is_sealed(), "Cannot set a bandwidth profile once the Disk is sealed"); - kernel::actor::simcall_answered([this, profile]() { this->pimpl_->set_read_bandwidth_profile(profile); }); + kernel::actor::simcall_object_access(pimpl_, + [this, profile]() { this->pimpl_->set_read_bandwidth_profile(profile); }); return this; } Disk* Disk::set_write_bandwidth_profile(kernel::profile::Profile* profile) { xbt_assert(not pimpl_->is_sealed(), "Cannot set a bandwidth profile once the Disk is sealed"); - kernel::actor::simcall_answered([this, profile]() { this->pimpl_->set_write_bandwidth_profile(profile); }); + kernel::actor::simcall_object_access(pimpl_, + [this, profile]() { this->pimpl_->set_write_bandwidth_profile(profile); }); + return this; +} +int Disk::get_concurrency_limit() const +{ + return pimpl_->get_concurrency_limit(); +} + +Disk* Disk::set_concurrency_limit(int limit) +{ + kernel::actor::simcall_object_access(pimpl_, [this, limit] { pimpl_->set_concurrency_limit(limit); }); return this; } @@ -118,45 +130,45 @@ IoPtr Disk::io_init(sg_size_t size, Io::OpType type) const IoPtr Disk::read_async(sg_size_t size) const { - return IoPtr(io_init(size, Io::OpType::READ))->vetoable_start(); + return IoPtr(io_init(size, Io::OpType::READ))->start(); } sg_size_t Disk::read(sg_size_t size) const { - return IoPtr(io_init(size, Io::OpType::READ))->vetoable_start()->wait()->get_performed_ioops(); + return IoPtr(io_init(size, Io::OpType::READ))->start()->wait()->get_performed_ioops(); } sg_size_t Disk::read(sg_size_t size, double priority) const { return IoPtr(io_init(size, Io::OpType::READ)) ->set_priority(priority) - ->vetoable_start() + ->start() ->wait() ->get_performed_ioops(); } IoPtr Disk::write_async(sg_size_t size) const { - return IoPtr(io_init(size, Io::OpType::WRITE)->vetoable_start()); + return IoPtr(io_init(size, Io::OpType::WRITE)->start()); } sg_size_t Disk::write(sg_size_t size) const { - return IoPtr(io_init(size, Io::OpType::WRITE))->vetoable_start()->wait()->get_performed_ioops(); + return IoPtr(io_init(size, Io::OpType::WRITE))->start()->wait()->get_performed_ioops(); } sg_size_t Disk::write(sg_size_t size, double priority) const { return IoPtr(io_init(size, Io::OpType::WRITE)) ->set_priority(priority) - ->vetoable_start() + ->start() ->wait() ->get_performed_ioops(); } Disk* Disk::set_sharing_policy(Disk::Operation op, Disk::SharingPolicy policy, const NonLinearResourceCb& cb) { - kernel::actor::simcall_answered([this, op, policy, &cb] { pimpl_->set_sharing_policy(op, policy, cb); }); + kernel::actor::simcall_object_access(pimpl_, [this, op, policy, &cb] { pimpl_->set_sharing_policy(op, policy, cb); }); return this; } @@ -167,7 +179,7 @@ Disk::SharingPolicy Disk::get_sharing_policy(Operation op) const Disk* Disk::set_factor_cb(const std::function& cb) { - kernel::actor::simcall_answered([this, &cb] { pimpl_->set_factor_cb(cb); }); + kernel::actor::simcall_object_access(pimpl_, [this, &cb] { pimpl_->set_factor_cb(cb); }); return this; } diff --git a/src/s4u/s4u_Engine.cpp b/src/s4u/s4u_Engine.cpp index b768ab40ef..094e8311d1 100644 --- a/src/s4u/s4u_Engine.cpp +++ b/src/s4u/s4u_Engine.cpp @@ -1,6 +1,6 @@ /* s4u::Engine Simulation Engine and global functions. */ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,23 +9,20 @@ #include #include -#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v333) -#include - -#include "mc/mc.h" #include "src/instr/instr_private.hpp" #include "src/kernel/EngineImpl.hpp" +#include "src/kernel/resource/HostImpl.hpp" #include "src/kernel/resource/NetworkModel.hpp" #include "src/kernel/resource/SplitDuplexLinkImpl.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" +#include "src/mc/mc.h" #include "src/mc/mc_replay.hpp" -#include "src/surf/HostImpl.hpp" #include "xbt/config.hpp" #include #include -XBT_LOG_NEW_CATEGORY(s4u, "Log channels of the S4U (Simgrid for you) interface"); +XBT_LOG_NEW_CATEGORY(s4u, "Log channels of the S4U (SimGrid for you) interface"); XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_engine, s4u, "Logging specific to S4U (engine)"); static simgrid::kernel::actor::ActorCode maestro_code; @@ -45,20 +42,20 @@ void Engine::initialize(int* argc, char** argv) xbt_assert(Engine::instance_ == nullptr, "It is currently forbidden to create more than one instance of s4u::Engine"); Engine::instance_ = this; instr::init(); - pimpl->initialize(argc, argv); + pimpl_->initialize(argc, argv); // Either create a new context with maestro or create // a context object with the current context maestro): kernel::actor::create_maestro(maestro_code); } -Engine::Engine(std::string name) : pimpl(new kernel::EngineImpl()) +Engine::Engine(std::string name) : pimpl_(new kernel::EngineImpl()) { int argc = 1; char* argv = &name[0]; initialize(&argc, &argv); } -Engine::Engine(int* argc, char** argv) : pimpl(new kernel::EngineImpl()) +Engine::Engine(int* argc, char** argv) : pimpl_(new kernel::EngineImpl()) { initialize(argc, argv); } @@ -79,15 +76,14 @@ Engine* Engine::get_instance() Engine* Engine::get_instance(int* argc, char** argv) { if (Engine::instance_ == nullptr) { - auto e = new Engine(argc, argv); + const auto* e = new Engine(argc, argv); xbt_assert(Engine::instance_ == e); } return Engine::instance_; } - -void Engine::shutdown() // XBT_ATTRIB_DEPRECATED_v335 +const std::vector& Engine::get_cmdline() const { - delete Engine::instance_; + return pimpl_->get_cmdline(); } double Engine::get_clock() @@ -102,34 +98,160 @@ double Engine::get_clock() void Engine::add_model(std::shared_ptr model, const std::vector& dependencies) { - kernel::actor::simcall_answered([this, &model, &dependencies] { pimpl->add_model(std::move(model), dependencies); }); + kernel::actor::simcall_answered([this, &model, &dependencies] { pimpl_->add_model(std::move(model), dependencies); }); } const std::vector& Engine::get_all_models() const { - return pimpl->get_all_models(); + return pimpl_->get_all_models(); } -/** - * Creates a new platform, including hosts, links, and the routing table. - * - * @beginrst - * See also: :ref:`platform`. - * @endrst - */ void Engine::load_platform(const std::string& platf) const { - pimpl->load_platform(platf); + pimpl_->load_platform(platf); } -/** - * @brief Seals the platform, finishing the creation of its resources. - * - * This method is optional. The seal() is done automatically when you call Engine::run. - */ void Engine::seal_platform() const { - pimpl->seal_platform(); + pimpl_->seal_platform(); +} + +static void flatify_hosts(Engine const& engine, std::stringstream& ss) +{ + // Regular hosts + std::vector hosts = engine.get_all_hosts(); + + for (auto const* h : hosts) { + ss << " get_name() << "\" speed=\"" << h->get_speed() << "\""; + const std::unordered_map* props = h->get_properties(); + if (h->get_core_count() > 1) + ss << " core=\"" << h->get_core_count() << "\""; + + // Sort the properties before displaying them, so that the tests are perfectly reproducible + std::vector keys; + for (auto const& [key, _] : *props) + keys.push_back(key); + if (not keys.empty()) { + ss << ">\n"; + std::sort(keys.begin(), keys.end()); + for (const std::string& key : keys) + ss << " at(key) << "\"/>\n"; + ss << " \n"; + } else { + ss << "/>\n"; + } + } + + // Routers + std::vector netpoints = engine.get_all_netpoints(); + std::sort(netpoints.begin(), netpoints.end(), + [](const simgrid::kernel::routing::NetPoint* a, const simgrid::kernel::routing::NetPoint* b) { + return a->get_name() < b->get_name(); + }); + + for (auto const& src : netpoints) + if (src->is_router()) + ss << " get_name() << "\"/>\n"; +} + +static void flatify_links(Engine const& engine, std::stringstream& ss) +{ + std::vector links = engine.get_all_links(); + + std::sort(links.begin(), links.end(), [](const Link* a, const Link* b) { return a->get_name() < b->get_name(); }); + + for (auto const* link : links) { + ss << " get_name() << "\""; + ss << " bandwidth=\"" << link->get_bandwidth() << "\""; + ss << " latency=\"" << link->get_latency() << "\""; + if (link->get_concurrency_limit() != -1) + ss << " concurrency=\"" << link->get_concurrency_limit() << "\""; + if (link->is_shared()) { + ss << "/>\n"; + } else { + ss << " sharing_policy=\"FATPIPE\"/>\n"; + } + } +} + +static void flatify_routes(Engine const& engine, std::stringstream& ss) +{ + auto hosts = engine.get_all_hosts(); + auto netpoints = engine.get_all_netpoints(); + std::sort(netpoints.begin(), netpoints.end(), + [](const simgrid::kernel::routing::NetPoint* a, const simgrid::kernel::routing::NetPoint* b) { + return a->get_name() < b->get_name(); + }); + + for (auto const* src_host : hosts) { // Routes from host + const simgrid::kernel::routing::NetPoint* src = src_host->get_netpoint(); + for (auto const* dst_host : hosts) { // Routes to host + std::vector route; + const simgrid::kernel::routing::NetPoint* dst = dst_host->get_netpoint(); + simgrid::kernel::routing::NetZoneImpl::get_global_route(src, dst, route, nullptr); + if (route.empty()) + continue; + ss << " get_name() << "\" dst=\"" << dst_host->get_name() << "\">\n "; + for (auto const& link : route) + ss << "get_name() << "\"/>"; + ss << "\n \n"; + } + + for (auto const& dst : netpoints) { // to router + if (not dst->is_router()) + continue; + ss << " get_name() << "\" dst=\"" << dst->get_name() << "\">\n "; + std::vector route; + simgrid::kernel::routing::NetZoneImpl::get_global_route(src, dst, route, nullptr); + for (auto const& link : route) + ss << "get_name() << "\"/>"; + ss << "\n \n"; + } + } + + for (auto const& value1 : netpoints) { // Routes from router + if (not value1->is_router()) + continue; + for (auto const& value2 : netpoints) { // to router + if (not value2->is_router()) + continue; + std::vector route; + simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, value2, route, nullptr); + if (route.empty()) + continue; + ss << " get_name() << "\" dst=\"" << value2->get_name() << "\">\n "; + for (auto const& link : route) + ss << "get_name() << "\"/>"; + ss << "\n \n"; + } + for (auto const* dst_host : hosts) { // Routes to host + ss << " get_name() << "\" dst=\"" << dst_host->get_name() << "\">\n "; + std::vector route; + const simgrid::kernel::routing::NetPoint* netcardDst = dst_host->get_netpoint(); + simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, netcardDst, route, nullptr); + for (auto const& link : route) + ss << "get_name() << "\"/>"; + ss << "\n \n"; + } + } +} +std::string Engine::flatify_platform() const +{ + std::string version = "4.1"; + std::stringstream ss; + + ss << "\n"; + ss << "\n"; + ss << "\n"; + ss << "get_name() << "\" routing=\"Full\">\n"; + + flatify_hosts(*this, ss); + flatify_links(*this, ss); + flatify_routes(*this, ss); + + ss << "\n"; + ss << "\n"; + return ss.str(); } /** Registers the main function of an actor that will be launched from the deployment file */ @@ -160,12 +282,12 @@ void Engine::register_default(const std::function& code) } void Engine::register_default(const kernel::actor::ActorCodeFactory& code) { - simgrid::kernel::actor::simcall_answered([this, &code]() { pimpl->register_default(code); }); + simgrid::kernel::actor::simcall_answered([this, &code]() { pimpl_->register_default(code); }); } void Engine::register_function(const std::string& name, const kernel::actor::ActorCodeFactory& code) { - simgrid::kernel::actor::simcall_answered([this, name, &code]() { pimpl->register_function(name, code); }); + simgrid::kernel::actor::simcall_answered([this, name, &code]() { pimpl_->register_function(name, code); }); } /** Load a deployment file and launch the actors that it contains @@ -176,7 +298,7 @@ void Engine::register_function(const std::string& name, const kernel::actor::Act */ void Engine::load_deployment(const std::string& deploy) const { - pimpl->load_deployment(deploy); + pimpl_->load_deployment(deploy); } /** Returns the amount of hosts in the platform */ @@ -193,8 +315,8 @@ std::vector Engine::get_all_hosts() const std::vector Engine::get_filtered_hosts(const std::function& filter) const { std::vector hosts; - if (pimpl->netzone_root_) { - hosts = pimpl->netzone_root_->get_filtered_hosts(filter); + if (pimpl_->netzone_root_) { + hosts = pimpl_->netzone_root_->get_filtered_hosts(filter); } /* Sort hosts in lexicographical order: keep same behavior when the hosts were saved on Engine * Some tests do a get_all_hosts() and selects hosts in this order */ @@ -211,7 +333,7 @@ Host* Engine::host_by_name(const std::string& name) const { auto* host = host_by_name_or_null(name); if (not host) - throw std::invalid_argument(std::string("Host not found: '") + name + std::string("'")); + throw std::invalid_argument("Host not found: '" + name + "'"); return host; } @@ -219,8 +341,8 @@ Host* Engine::host_by_name(const std::string& name) const Host* Engine::host_by_name_or_null(const std::string& name) const { Host* host = nullptr; - if (pimpl->netzone_root_) { - auto* host_impl = pimpl->netzone_root_->get_host_by_name_or_null(name); + if (pimpl_->netzone_root_) { + auto* host_impl = pimpl_->netzone_root_->get_host_by_name_or_null(name); if (host_impl) host = host_impl->get_iface(); } @@ -235,15 +357,16 @@ Link* Engine::link_by_name(const std::string& name) const { auto* link = link_by_name_or_null(name); if (not link) - throw std::invalid_argument(std::string("Link not found: ") + name); + throw std::invalid_argument("Link not found: " + name); return link; } SplitDuplexLink* Engine::split_duplex_link_by_name(const std::string& name) const { - auto* link_impl = pimpl->netzone_root_ ? pimpl->netzone_root_->get_split_duplex_link_by_name_or_null(name) : nullptr; + auto* link_impl = + pimpl_->netzone_root_ ? pimpl_->netzone_root_->get_split_duplex_link_by_name_or_null(name) : nullptr; if (not link_impl) - throw std::invalid_argument(std::string("Link not found: ") + name); + throw std::invalid_argument("Link not found: " + name); return link_impl->get_iface(); } @@ -251,11 +374,11 @@ SplitDuplexLink* Engine::split_duplex_link_by_name(const std::string& name) cons Link* Engine::link_by_name_or_null(const std::string& name) const { Link* link = nullptr; - if (pimpl->netzone_root_) { + if (pimpl_->netzone_root_) { /* keep behavior where internal __loopback__ link from network model is given to user */ if (name == "__loopback__") - return pimpl->netzone_root_->get_network_model()->loopback_->get_iface(); - auto* link_impl = pimpl->netzone_root_->get_link_by_name_or_null(name); + return pimpl_->netzone_root_->get_network_model()->loopback_->get_iface(); + auto* link_impl = pimpl_->netzone_root_->get_link_by_name_or_null(name); if (link_impl) link = link_impl->get_iface(); } @@ -267,7 +390,7 @@ Mailbox* Engine::mailbox_by_name_or_create(const std::string& name) const { /* two actors may have pushed the same mbox_create simcall at the same time */ kernel::activity::MailboxImpl* mbox = kernel::actor::simcall_answered([&name, this] { - auto [m, inserted] = pimpl->mailboxes_.try_emplace(name, nullptr); + auto [m, inserted] = pimpl_->mailboxes_.try_emplace(name, nullptr); if (inserted) { m->second = new kernel::activity::MailboxImpl(name); XBT_DEBUG("Creating a mailbox at %p with name %s", m->second, name.c_str()); @@ -277,14 +400,28 @@ Mailbox* Engine::mailbox_by_name_or_create(const std::string& name) const return mbox->get_iface(); } +MessageQueue* Engine::message_queue_by_name_or_create(const std::string& name) const +{ + /* two actors may have pushed the same mbox_create simcall at the same time */ + kernel::activity::MessageQueueImpl* queue = kernel::actor::simcall_answered([&name, this] { + auto [m, inserted] = pimpl_->mqueues_.try_emplace(name, nullptr); + if (inserted) { + m->second = new kernel::activity::MessageQueueImpl(name); + XBT_DEBUG("Creating a message queue at %p with name %s", m->second, name.c_str()); + } + return m->second; + }); + return queue->get_iface(); +} + /** @brief Returns the amount of links in the platform */ size_t Engine::get_link_count() const { int count = 0; - if (pimpl->netzone_root_) { - count += pimpl->netzone_root_->get_link_count(); + if (pimpl_->netzone_root_) { + count += pimpl_->netzone_root_->get_link_count(); /* keep behavior where internal __loopback__ link from network model is given to user */ - count += pimpl->netzone_root_->get_network_model()->loopback_ ? 1 : 0; + count += pimpl_->netzone_root_->get_network_model()->loopback_ ? 1 : 0; } return count; } @@ -298,25 +435,25 @@ std::vector Engine::get_all_links() const std::vector Engine::get_filtered_links(const std::function& filter) const { std::vector res; - if (pimpl->netzone_root_) { - res = pimpl->netzone_root_->get_filtered_links(filter); + if (pimpl_->netzone_root_) { + res = pimpl_->netzone_root_->get_filtered_links(filter); /* keep behavior where internal __loopback__ link from network model is given to user */ - if (pimpl->netzone_root_->get_network_model()->loopback_ && - filter(pimpl->netzone_root_->get_network_model()->loopback_->get_iface())) - res.push_back(pimpl->netzone_root_->get_network_model()->loopback_->get_iface()); + if (pimpl_->netzone_root_->get_network_model()->loopback_ && + filter(pimpl_->netzone_root_->get_network_model()->loopback_->get_iface())) + res.push_back(pimpl_->netzone_root_->get_network_model()->loopback_->get_iface()); } return res; } size_t Engine::get_actor_count() const { - return pimpl->get_actor_count(); + return pimpl_->get_actor_count(); } std::vector Engine::get_all_actors() const { std::vector actor_list; - for (auto const& [_, actor] : pimpl->get_actor_list()) { + for (auto const& [_, actor] : pimpl_->get_actor_list()) { actor_list.push_back(actor->get_iface()); } return actor_list; @@ -325,7 +462,7 @@ std::vector Engine::get_all_actors() const std::vector Engine::get_filtered_actors(const std::function& filter) const { std::vector actor_list; - for (auto const& [_, actor] : pimpl->get_actor_list()) { + for (auto const& [_, actor] : pimpl_->get_actor_list()) { if (filter(actor->get_iface())) actor_list.push_back(actor->get_iface()); } @@ -346,7 +483,7 @@ void Engine::run_until(double max_date) const fflush(stdout); fflush(stderr); - pimpl->run(max_date); + pimpl_->run(max_date); } void Engine::track_vetoed_activities(std::set* vetoed_activities) const @@ -357,15 +494,15 @@ void Engine::track_vetoed_activities(std::set* vetoed_activities) con /** @brief Retrieve the root netzone, containing all others */ s4u::NetZone* Engine::get_netzone_root() const { - if (pimpl->netzone_root_) - return pimpl->netzone_root_->get_iface(); + if (pimpl_->netzone_root_) + return pimpl_->netzone_root_->get_iface(); return nullptr; } /** @brief Set the root netzone, containing all others. Once set, it cannot be changed. */ void Engine::set_netzone_root(const s4u::NetZone* netzone) { - xbt_assert(pimpl->netzone_root_ == nullptr, "The root NetZone cannot be changed once set"); - pimpl->netzone_root_ = netzone->get_impl(); + xbt_assert(pimpl_->netzone_root_ == nullptr, "The root NetZone cannot be changed once set"); + pimpl_->netzone_root_ = netzone->get_impl(); } static NetZone* netzone_by_name_recursive(NetZone* current, const std::string& name) @@ -391,15 +528,15 @@ NetZone* Engine::netzone_by_name_or_null(const std::string& name) const /** @brief Retrieve the netpoint of the given name (or nullptr if not found) */ kernel::routing::NetPoint* Engine::netpoint_by_name_or_null(const std::string& name) const { - auto netp = pimpl->netpoints_.find(name); - return netp == pimpl->netpoints_.end() ? nullptr : netp->second; + auto netp = pimpl_->netpoints_.find(name); + return netp == pimpl_->netpoints_.end() ? nullptr : netp->second; } kernel::routing::NetPoint* Engine::netpoint_by_name(const std::string& name) const { - auto netp = netpoint_by_name_or_null(name); + auto* netp = netpoint_by_name_or_null(name); if (netp == nullptr) { - throw std::invalid_argument(std::string("Netpoint not found: %s") + name); + throw std::invalid_argument("Netpoint not found: " + name); } return netp; } @@ -407,7 +544,7 @@ kernel::routing::NetPoint* Engine::netpoint_by_name(const std::string& name) con std::vector Engine::get_all_netpoints() const { std::vector res; - for (auto const& [_, netpoint] : pimpl->netpoints_) + for (auto const& [_, netpoint] : pimpl_->netpoints_) res.push_back(netpoint); return res; } @@ -415,14 +552,14 @@ std::vector Engine::get_all_netpoints() const /** @brief Register a new netpoint to the system */ void Engine::netpoint_register(kernel::routing::NetPoint* point) { - simgrid::kernel::actor::simcall_answered([this, point] { pimpl->netpoints_[point->get_name()] = point; }); + simgrid::kernel::actor::simcall_answered([this, point] { pimpl_->netpoints_[point->get_name()] = point; }); } /** @brief Unregister a given netpoint */ void Engine::netpoint_unregister(kernel::routing::NetPoint* point) { kernel::actor::simcall_answered([this, point] { - pimpl->netpoints_.erase(point->get_name()); + pimpl_->netpoints_.erase(point->get_name()); delete point; }); } @@ -498,13 +635,5 @@ double simgrid_get_clock() void simgrid_set_maestro(void (*code)(void*), void* data) { -#ifdef _WIN32 - XBT_WARN("simgrid_set_maestro is believed to not work on windows. Please help us investigating this issue if " - "you need that feature"); -#endif maestro_code = std::bind(code, data); } -void SIMIX_set_maestro(void (*code)(void*), void* data) // XBT_ATTRIB_DEPRECATED_v333 -{ - simgrid_set_maestro(code, data); -} diff --git a/src/s4u/s4u_Exec.cpp b/src/s4u/s4u_Exec.cpp index 259ed33b3b..caa7466e2c 100644 --- a/src/s4u/s4u_Exec.cpp +++ b/src/s4u/s4u_Exec.cpp @@ -1,10 +1,12 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "simgrid/simix.hpp" #include #include +#include #include #include @@ -15,7 +17,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_exec, s4u_activity, "S4U asynchronous executions"); namespace simgrid::s4u { -xbt::signal Exec::on_start; Exec::Exec(kernel::activity::ExecImplPtr pimpl) { @@ -30,18 +31,10 @@ void Exec::reset() const ExecPtr Exec::init() { auto pimpl = kernel::activity::ExecImplPtr(new kernel::activity::ExecImpl()); - unsigned int cb_id = Host::on_state_change.connect([pimpl](s4u::Host const& h) { - if (not h.is_on() && pimpl->get_state() == kernel::activity::State::RUNNING && - std::find(pimpl->get_hosts().begin(), pimpl->get_hosts().end(), &h) != pimpl->get_hosts().end()) { - pimpl->set_state(kernel::activity::State::FAILED); - pimpl->post(); - } - }); - pimpl->set_cb_id(cb_id); return ExecPtr(static_cast(pimpl->get_iface())); } -Exec* Exec::start() +Exec* Exec::do_start() { kernel::actor::simcall_answered([this] { (*boost::static_pointer_cast(pimpl_)) @@ -54,16 +47,28 @@ Exec* Exec::start() pimpl_->suspend(); state_ = State::STARTED; - on_start(*this); + fire_on_start(); + fire_on_this_start(); return this; } -ssize_t Exec::wait_any_for(const std::vector& execs, double timeout) +ssize_t Exec::deprecated_wait_any_for(const std::vector& execs, double timeout) // XBT_ATTRIB_DEPRECATED_v339 { - std::vector activities; + if (execs.empty()) + return -1; + ActivitySet set; for (const auto& exec : execs) - activities.push_back(boost::dynamic_pointer_cast(exec)); - return Activity::wait_any_for(activities, timeout); + set.push(exec); + try { + auto* ret = set.wait_any_for(timeout).get(); + for (size_t i = 0; i < execs.size(); i++) + if (execs[i].get() == ret) + return i; + + } catch (TimeoutException& e) { + return -1; + } + return -1; } /** @brief change the execution bound @@ -74,8 +79,9 @@ ExecPtr Exec::set_bound(double bound) { xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot change the bound of an exec after its start"); - kernel::actor::simcall_answered( - [this, bound] { boost::static_pointer_cast(pimpl_)->set_bound(bound); }); + kernel::actor::simcall_object_access(pimpl_.get(), [this, bound] { + boost::static_pointer_cast(pimpl_)->set_bound(bound); + }); return this; } @@ -89,7 +95,7 @@ ExecPtr Exec::set_priority(double priority) { xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot change the priority of an exec after its start"); - kernel::actor::simcall_answered([this, priority] { + kernel::actor::simcall_object_access(pimpl_.get(), [this, priority] { boost::static_pointer_cast(pimpl_)->set_sharing_penalty(1. / priority); }); return this; @@ -107,10 +113,10 @@ ExecPtr Exec::set_flops_amount(double flops_amount) { xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot change the flop_amount of an exec after its start"); - kernel::actor::simcall_answered([this, flops_amount] { + kernel::actor::simcall_object_access(pimpl_.get(), [this, flops_amount] { boost::static_pointer_cast(pimpl_)->set_flops_amount(flops_amount); }); - Activity::set_remaining(flops_amount); + set_remaining(flops_amount); return this; } @@ -118,7 +124,7 @@ ExecPtr Exec::set_flops_amounts(const std::vector& flops_amounts) { xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot change the flops_amounts of an exec after its start"); - kernel::actor::simcall_answered([this, flops_amounts] { + kernel::actor::simcall_object_access(pimpl_.get(), [this, flops_amounts] { boost::static_pointer_cast(pimpl_)->set_flops_amounts(flops_amounts); }); parallel_ = true; @@ -129,7 +135,7 @@ ExecPtr Exec::set_bytes_amounts(const std::vector& bytes_amounts) { xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot change the bytes_amounts of an exec after its start"); - kernel::actor::simcall_answered([this, bytes_amounts] { + kernel::actor::simcall_object_access(pimpl_.get(), [this, bytes_amounts] { boost::static_pointer_cast(pimpl_)->set_bytes_amounts(bytes_amounts); }); parallel_ = true; @@ -140,7 +146,7 @@ ExecPtr Exec::set_thread_count(int thread_count) { xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot change the bytes_amounts of an exec after its start"); - kernel::actor::simcall_answered([this, thread_count] { + kernel::actor::simcall_object_access(pimpl_.get(), [this, thread_count] { boost::static_pointer_cast(pimpl_)->set_thread_count(thread_count); }); return this; @@ -158,6 +164,11 @@ unsigned int Exec::get_host_number() const return static_cast(pimpl_.get())->get_host_number(); } +int Exec::get_thread_count() const +{ + return static_cast(pimpl_.get())->get_thread_count(); +} + /** @brief Change the host on which this activity takes place. * * The activity cannot be terminated already (but it may be started). */ @@ -169,12 +180,12 @@ ExecPtr Exec::set_host(Host* host) if (state_ == State::STARTED) boost::static_pointer_cast(pimpl_)->migrate(host); - kernel::actor::simcall_answered( - [this, host] { boost::static_pointer_cast(pimpl_)->set_host(host); }); + kernel::actor::simcall_object_access( + pimpl_.get(), [this, host] { boost::static_pointer_cast(pimpl_)->set_host(host); }); if (state_ == State::STARTING) - // Setting the host may allow to start the activity, let's try - vetoable_start(); + // Setting the host may allow to start the activity, let's try + start(); return this; } @@ -184,13 +195,14 @@ ExecPtr Exec::set_hosts(const std::vector& hosts) xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot change the hosts of an exec once it's done (state: %s)", to_c_str(state_)); - kernel::actor::simcall_answered( - [this, hosts] { boost::static_pointer_cast(pimpl_)->set_hosts(hosts); }); + kernel::actor::simcall_object_access(pimpl_.get(), [this, hosts] { + boost::static_pointer_cast(pimpl_)->set_hosts(hosts); + }); parallel_ = true; // Setting the host may allow to start the activity, let's try if (state_ == State::STARTING) - vetoable_start(); + start(); return this; } @@ -205,7 +217,7 @@ ExecPtr Exec::unset_host() if (state_ == State::STARTED) cancel(); - vetoable_start(); + start(); return this; } @@ -213,7 +225,7 @@ ExecPtr Exec::unset_host() double Exec::get_cost() const { - return (pimpl_->surf_action_ == nullptr) ? -1 : pimpl_->surf_action_->get_cost(); + return (pimpl_->model_action_ == nullptr) ? -1 : pimpl_->model_action_->get_cost(); } double Exec::get_remaining() const @@ -247,6 +259,11 @@ bool Exec::is_assigned() const } // namespace simgrid::s4u /* **************************** Public C interface *************************** */ +int sg_exec_isinstance(sg_activity_t acti) +{ + return dynamic_cast(acti) != nullptr; +} + void sg_exec_set_bound(sg_exec_t exec, double bound) { exec->set_bound(bound); @@ -279,7 +296,7 @@ double sg_exec_get_remaining_ratio(const_sg_exec_t exec) void sg_exec_start(sg_exec_t exec) { - exec->vetoable_start(); + exec->start(); } void sg_exec_cancel(sg_exec_t exec) @@ -319,18 +336,27 @@ sg_error_t sg_exec_wait_for(sg_exec_t exec, double timeout) return status; } -ssize_t sg_exec_wait_any(sg_exec_t* execs, size_t count) +ssize_t sg_exec_wait_any(sg_exec_t* execs, size_t count) // XBT_ATTRIB_DEPRECATED_v339 { - return sg_exec_wait_any_for(execs, count, -1.0); + std::vector s4u_execs; + for (size_t i = 0; i < count; i++) + s4u_execs.emplace_back(execs[i], false); + + ssize_t pos = simgrid::s4u::Exec::deprecated_wait_any_for(s4u_execs, -1.0); + for (size_t i = 0; i < count; i++) { + if (pos != -1 && static_cast(pos) != i) + s4u_execs[i]->add_ref(); + } + return pos; } -ssize_t sg_exec_wait_any_for(sg_exec_t* execs, size_t count, double timeout) +ssize_t sg_exec_wait_any_for(sg_exec_t* execs, size_t count, double timeout) // XBT_ATTRIB_DEPRECATED_v339 { std::vector s4u_execs; for (size_t i = 0; i < count; i++) s4u_execs.emplace_back(execs[i], false); - ssize_t pos = simgrid::s4u::Exec::wait_any_for(s4u_execs, timeout); + ssize_t pos = simgrid::s4u::Exec::deprecated_wait_any_for(s4u_execs, timeout); for (size_t i = 0; i < count; i++) { if (pos != -1 && static_cast(pos) != i) s4u_execs[i]->add_ref(); diff --git a/src/s4u/s4u_Host.cpp b/src/s4u/s4u_Host.cpp index 35357f8d94..670882c392 100644 --- a/src/s4u/s4u_Host.cpp +++ b/src/s4u/s4u_Host.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,14 +13,15 @@ #include #include +#include "simgrid/simix.hpp" +#include "src/kernel/resource/HostImpl.hpp" #include "src/kernel/resource/StandardLinkImpl.hpp" #include "src/kernel/resource/VirtualMachineImpl.hpp" -#include "src/surf/HostImpl.hpp" #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_host, s4u, "Logging specific to the S4U hosts"); -XBT_LOG_EXTERNAL_CATEGORY(ker_routing); +XBT_LOG_EXTERNAL_CATEGORY(ker_platform); namespace simgrid { @@ -31,8 +32,9 @@ namespace s4u { #ifndef DOXYGEN xbt::signal Host::on_creation; xbt::signal Host::on_destruction; -xbt::signal Host::on_state_change; +xbt::signal Host::on_onoff; xbt::signal Host::on_speed_change; +xbt::signal Host::on_exec_state_change; #endif Host* Host::set_cpu(kernel::resource::CpuImpl* cpu) @@ -84,7 +86,7 @@ Host* Host::current() return self->get_host(); } -xbt::string const& Host::get_name() const +std::string const& Host::get_name() const { return this->pimpl_->get_name(); } @@ -100,7 +102,8 @@ void Host::turn_on() kernel::actor::simcall_answered([this] { this->pimpl_cpu_->turn_on(); this->pimpl_->turn_on(); - on_state_change(*this); + on_onoff(*this); + on_this_onoff(*this); }); } } @@ -114,7 +117,8 @@ void Host::turn_off() this->pimpl_cpu_->turn_off(); this->pimpl_->turn_off(self); - on_state_change(*this); + on_onoff(*this); + on_this_onoff(*this); }); } } @@ -163,16 +167,26 @@ void Host::route_to(const Host* dest, std::vector& links, double* latency for (auto* l : linkImpls) links.push_back(l->get_iface()); } +std::pair, double> Host::route_to(const Host* dest) const +{ + std::vector linkImpls; + std::vector links; + double latency = 0; + this->route_to(dest, linkImpls, &latency); + for (auto* l : linkImpls) + links.push_back(l->get_iface()); + return std::make_pair(links, latency); +} /** @brief Just like Host::routeTo, but filling an array of link implementations */ void Host::route_to(const Host* dest, std::vector& links, double* latency) const { kernel::routing::NetZoneImpl::get_global_route(pimpl_netpoint_, dest->get_netpoint(), links, latency); - if (XBT_LOG_ISENABLED(ker_routing, xbt_log_priority_debug)) { - XBT_CDEBUG(ker_routing, "Route from '%s' to '%s' (latency: %f):", get_cname(), dest->get_cname(), + if (XBT_LOG_ISENABLED(ker_platform, xbt_log_priority_debug)) { + XBT_CDEBUG(ker_platform, "Route from '%s' to '%s' (latency: %f):", get_cname(), dest->get_cname(), (latency == nullptr ? -1 : *latency)); for (auto const* link : links) - XBT_CDEBUG(ker_routing, " Link '%s'", link->get_cname()); + XBT_CDEBUG(ker_platform, " Link '%s'", link->get_cname()); } } @@ -196,13 +210,24 @@ const char* Host::get_property(const std::string& key) const Host* Host::set_property(const std::string& key, const std::string& value) { - kernel::actor::simcall_answered([this, &key, &value] { this->pimpl_->set_property(key, value); }); + kernel::actor::simcall_object_access(pimpl_, [this, &key, &value] { this->pimpl_->set_property(key, value); }); return this; } Host* Host::set_properties(const std::unordered_map& properties) { - kernel::actor::simcall_answered([this, &properties] { this->pimpl_->set_properties(properties); }); + kernel::actor::simcall_object_access(pimpl_, [this, &properties] { this->pimpl_->set_properties(properties); }); + return this; +} + +int Host::get_concurrency_limit() const +{ + return pimpl_cpu_->get_concurrency_limit(); +} + +Host* Host::set_concurrency_limit(int limit) +{ + kernel::actor::simcall_object_access(pimpl_cpu_, [this, limit] { pimpl_cpu_->set_concurrency_limit(limit); }); return this; } @@ -210,7 +235,7 @@ Host* Host::set_properties(const std::unordered_map& p * The profile must contain boolean values. */ Host* Host::set_state_profile(kernel::profile::Profile* p) { - kernel::actor::simcall_answered([this, p] { pimpl_cpu_->set_state_profile(p); }); + kernel::actor::simcall_object_access(pimpl_, [this, p] { pimpl_cpu_->set_state_profile(p); }); return this; } /** Specify a profile modeling the external load according to an exhaustive list or a stochastic law. @@ -221,7 +246,7 @@ Host* Host::set_state_profile(kernel::profile::Profile* p) */ Host* Host::set_speed_profile(kernel::profile::Profile* p) { - kernel::actor::simcall_answered([this, p] { pimpl_cpu_->set_speed_profile(p); }); + kernel::actor::simcall_object_access(pimpl_, [this, p] { pimpl_cpu_->set_speed_profile(p); }); return this; } @@ -246,7 +271,7 @@ double Host::get_available_speed() const Host* Host::set_sharing_policy(SharingPolicy policy, const s4u::NonLinearResourceCb& cb) { - kernel::actor::simcall_answered([this, policy, &cb] { pimpl_cpu_->set_sharing_policy(policy, cb); }); + kernel::actor::simcall_object_access(pimpl_, [this, policy, &cb] { pimpl_cpu_->set_sharing_policy(policy, cb); }); return this; } @@ -262,13 +287,14 @@ int Host::get_core_count() const Host* Host::set_core_count(int core_count) { - kernel::actor::simcall_answered([this, core_count] { this->pimpl_cpu_->set_core_count(core_count); }); + kernel::actor::simcall_object_access(pimpl_, [this, core_count] { this->pimpl_cpu_->set_core_count(core_count); }); return this; } Host* Host::set_pstate_speed(const std::vector& speed_per_state) { - kernel::actor::simcall_answered([this, &speed_per_state] { pimpl_cpu_->set_pstate_speed(speed_per_state); }); + kernel::actor::simcall_object_access(pimpl_, + [this, &speed_per_state] { pimpl_cpu_->set_pstate_speed(speed_per_state); }); return this; } @@ -281,7 +307,7 @@ std::vector Host::convert_pstate_speed_vector(const std::vector& speed_per_state) /** @brief Set the pstate at which the host should run */ Host* Host::set_pstate(unsigned long pstate_index) { - kernel::actor::simcall_answered([this, pstate_index] { this->pimpl_cpu_->set_pstate(pstate_index); }); + kernel::actor::simcall_object_access(pimpl_, [this, pstate_index] { this->pimpl_cpu_->set_pstate(pstate_index); }); return this; } @@ -308,14 +334,14 @@ unsigned long Host::get_pstate() const Host* Host::set_factor_cb(const std::function& cb) { - kernel::actor::simcall_answered([this, &cb] { pimpl_cpu_->set_factor_cb(cb); }); + kernel::actor::simcall_object_access(pimpl_, [this, &cb] { pimpl_cpu_->set_factor_cb(cb); }); return this; } Host* Host::set_coordinates(const std::string& coords) { if (not coords.empty()) - kernel::actor::simcall_answered([this, coords] { this->pimpl_netpoint_->set_coordinates(coords); }); + kernel::actor::simcall_object_access(pimpl_, [this, coords] { this->pimpl_netpoint_->set_coordinates(coords); }); return this; } std::vector Host::get_disks() const @@ -338,15 +364,13 @@ Disk* Host::create_disk(const std::string& name, const std::string& read_bandwid try { d_read = xbt_parse_get_bandwidth("", 0, read_bandwidth, ""); } catch (const simgrid::ParseError&) { - throw std::invalid_argument(std::string("Impossible to create disk: ") + name + - std::string(". Invalid read bandwidth: ") + read_bandwidth); + throw std::invalid_argument("Impossible to create disk: " + name + ". Invalid read bandwidth: " + read_bandwidth); } double d_write; try { d_write = xbt_parse_get_bandwidth("", 0, write_bandwidth, ""); } catch (const simgrid::ParseError&) { - throw std::invalid_argument(std::string("Impossible to create disk: ") + name + - std::string(". Invalid write bandwidth: ") + write_bandwidth); + throw std::invalid_argument("Impossible to create disk: " + name + ". Invalid write bandwidth: " + write_bandwidth); } return create_disk(name, d_read, d_write); } @@ -396,7 +420,7 @@ void Host::execute(double flops) const void Host::execute(double flops, double priority) const { - this_actor::exec_init(flops)->set_priority(1 / priority)->vetoable_start()->wait(); + Exec::init()->set_flops_amount(flops)->set_host(const_cast(this))->set_priority(1 / priority)->wait(); } Host* Host::seal() @@ -552,7 +576,7 @@ void sg_host_turn_on(sg_host_t host) * * @brief Stop the host if it is on * - * See also #MSG_host_is_on() to test the current state of the host and @ref plugin_host_energy + * See also #sg_host_is_on() to test the current state of the host and @ref plugin_host_energy * for more info on DVFS. */ void sg_host_turn_off(sg_host_t host) @@ -657,22 +681,6 @@ void sg_host_sendto(sg_host_t from, sg_host_t to, double byte_amount) simgrid::s4u::Comm::sendto(from, to, byte_amount); } -/** @brief Displays debugging information about a host */ -void sg_host_dump(const_sg_host_t host) // XBT_ATTRIB_DEPRECATED_v335 -{ - XBT_INFO("Displaying host %s", host->get_cname()); - XBT_INFO(" - speed: %.0f", host->get_speed()); - XBT_INFO(" - available speed: %.2f", sg_host_get_available_speed(host)); - const std::unordered_map* props = host->get_properties(); - - if (not props->empty()) { - XBT_INFO(" - properties:"); - for (auto const& [key, value] : *props) { - XBT_INFO(" %s->%s", key.c_str(), value.c_str()); - } - } -} - /** @brief Return the list of actors attached to a host. * * @param host a host diff --git a/src/s4u/s4u_Io.cpp b/src/s4u/s4u_Io.cpp index 71326434ad..c20e891862 100644 --- a/src/s4u/s4u_Io.cpp +++ b/src/s4u/s4u_Io.cpp @@ -1,8 +1,9 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include #include #include #include @@ -11,8 +12,9 @@ #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_io, s4u_activity, "S4U asynchronous I/Os"); + namespace simgrid::s4u { -xbt::signal Io::on_start; Io::Io(kernel::activity::IoImplPtr pimpl) { @@ -25,7 +27,61 @@ IoPtr Io::init() return IoPtr(static_cast(pimpl->get_iface())); } -Io* Io::start() +IoPtr Io::streamto_init(Host* from, const Disk* from_disk, Host* to, const Disk* to_disk) +{ + auto res = Io::init()->set_source(from, from_disk)->set_destination(to, to_disk); + res->set_state(State::STARTING); + return res; +} + +IoPtr Io::streamto_async(Host* from, const Disk* from_disk, Host* to, const Disk* to_disk, + uint64_t simulated_size_in_bytes) +{ + return Io::init()->set_size(simulated_size_in_bytes)->set_source(from, from_disk)->set_destination(to, to_disk); +} + +void Io::streamto(Host* from, const Disk* from_disk, Host* to, const Disk* to_disk, uint64_t simulated_size_in_bytes) +{ + streamto_async(from, from_disk, to, to_disk, simulated_size_in_bytes)->wait(); +} + +IoPtr Io::set_source(Host* from, const Disk* from_disk) +{ + xbt_assert(state_ == State::INITED || state_ == State::STARTING, + "Cannot change the source of an IO stream once it's started (state: %s)", to_c_str(state_)); + kernel::actor::simcall_object_access(pimpl_.get(), [this, from, from_disk] { + boost::static_pointer_cast(pimpl_)->set_host(from); + if (from_disk != nullptr) + boost::static_pointer_cast(pimpl_)->set_disk(from_disk->get_impl()); + }); + // Setting 'source' may allow to start the activity, let's try + if (state_ == State::STARTING && remains_ <= 0) + XBT_DEBUG("This IO has a size of 0 byte. It cannot start yet"); + else + start(); + + return this; +} + +IoPtr Io::set_destination(Host* to, const Disk* to_disk) +{ + xbt_assert(state_ == State::INITED || state_ == State::STARTING, + "Cannot change the source of an IO stream once it's started (state: %s)", to_c_str(state_)); + kernel::actor::simcall_object_access(pimpl_.get(), [this, to, to_disk] { + boost::static_pointer_cast(pimpl_)->set_dst_host(to); + if (to_disk != nullptr) + boost::static_pointer_cast(pimpl_)->set_dst_disk(to_disk->get_impl()); + }); + // Setting 'destination' may allow to start the activity, let's try + if (state_ == State::STARTING && remains_ <= 0) + XBT_DEBUG("This IO has a size of 0 byte. It cannot start yet"); + else + start(); + + return this; +} + +Io* Io::do_start() { kernel::actor::simcall_answered( [this] { (*boost::static_pointer_cast(pimpl_)).set_name(get_name()).start(); }); @@ -34,16 +90,23 @@ Io* Io::start() pimpl_->suspend(); state_ = State::STARTED; - on_start(*this); + fire_on_start(); + fire_on_this_start(); return this; } -ssize_t Io::wait_any_for(const std::vector& ios, double timeout) +ssize_t Io::deprecated_wait_any_for(const std::vector& ios, double timeout) // XBT_ATTRIB_DEPRECATED_v339 { - std::vector activities; + ActivitySet set; for (const auto& io : ios) - activities.push_back(boost::dynamic_pointer_cast(io)); - return Activity::wait_any_for(activities, timeout); + set.push(io); + + auto* ret = set.wait_any_for(timeout).get(); + for (size_t i = 0; i < ios.size(); i++) + if (ios[i].get() == ret) + return i; + + return -1; } IoPtr Io::set_disk(const_sg_disk_t disk) @@ -55,7 +118,7 @@ IoPtr Io::set_disk(const_sg_disk_t disk) // Setting the disk may allow to start the activity, let's try if (state_ == State::STARTING) - vetoable_start(); + start(); return this; } @@ -64,7 +127,7 @@ IoPtr Io::set_priority(double priority) { xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot change the priority of an io after its start"); - kernel::actor::simcall_answered([this, priority] { + kernel::actor::simcall_object_access(pimpl_.get(), [this, priority] { boost::static_pointer_cast(pimpl_)->set_sharing_penalty(1. / priority); }); return this; @@ -73,17 +136,17 @@ IoPtr Io::set_priority(double priority) IoPtr Io::set_size(sg_size_t size) { xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot set size once the Io is started"); - kernel::actor::simcall_answered( - [this, size] { boost::static_pointer_cast(pimpl_)->set_size(size); }); - Activity::set_remaining(size); + kernel::actor::simcall_object_access( + pimpl_.get(), [this, size] { boost::static_pointer_cast(pimpl_)->set_size(size); }); + set_remaining(size); return this; } IoPtr Io::set_op_type(OpType type) { xbt_assert(state_ == State::INITED || state_ == State::STARTING, "Cannot set size once the Io is started"); - kernel::actor::simcall_answered( - [this, type] { boost::static_pointer_cast(pimpl_)->set_type(type); }); + kernel::actor::simcall_object_access( + pimpl_.get(), [this, type] { boost::static_pointer_cast(pimpl_)->set_type(type); }); return this; } @@ -98,8 +161,8 @@ IoPtr Io::update_priority(double priority) /** @brief Returns the amount of flops that remain to be done */ double Io::get_remaining() const { - return kernel::actor::simcall_answered( - [this]() { return boost::static_pointer_cast(pimpl_)->get_remaining(); }); + return kernel::actor::simcall_object_access( + pimpl_.get(), [this]() { return boost::static_pointer_cast(pimpl_)->get_remaining(); }); } sg_size_t Io::get_performed_ioops() const @@ -109,7 +172,11 @@ sg_size_t Io::get_performed_ioops() const bool Io::is_assigned() const { - return boost::static_pointer_cast(pimpl_)->get_disk() != nullptr; + if (boost::static_pointer_cast(pimpl_)->get_host() == nullptr) { + return boost::static_pointer_cast(pimpl_)->get_disk() != nullptr; + } else { + return boost::static_pointer_cast(pimpl_)->get_dst_host() != nullptr; + } } } // namespace simgrid::s4u diff --git a/src/s4u/s4u_Link.cpp b/src/s4u/s4u_Link.cpp index c1d4ffb204..0a42518758 100644 --- a/src/s4u/s4u_Link.cpp +++ b/src/s4u/s4u_Link.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,7 +22,7 @@ namespace s4u { xbt::signal Link::on_creation; xbt::signal Link::on_destruction; -xbt::signal Link::on_state_change; +xbt::signal Link::on_onoff; xbt::signal Link::on_bandwidth_change; xbt::signal Link::on_communication_state_change; @@ -72,7 +72,7 @@ double Link::get_latency() const Link* Link::set_latency(double value) { - kernel::actor::simcall_answered([this, value] { pimpl_->set_latency(value); }); + kernel::actor::simcall_object_access(pimpl_, [this, value] { pimpl_->set_latency(value); }); return this; } @@ -82,8 +82,7 @@ Link* Link::set_latency(const std::string& value) try { d_value = xbt_parse_get_time("", 0, value, ""); } catch (const simgrid::ParseError&) { - throw std::invalid_argument(std::string("Impossible to set latency for link: ") + get_name() + - std::string(". Invalid value: ") + value); + throw std::invalid_argument("Impossible to set latency for link: " + get_name() + ". Invalid value: " + value); } return set_latency(d_value); } @@ -95,17 +94,17 @@ double Link::get_bandwidth() const Link* Link::set_bandwidth(double value) { - kernel::actor::simcall_answered([this, value] { pimpl_->set_bandwidth(value); }); + kernel::actor::simcall_object_access(pimpl_, [this, value] { pimpl_->set_bandwidth(value); }); return this; } Link* Link::set_sharing_policy(Link::SharingPolicy policy, const NonLinearResourceCb& cb) { if (policy == SharingPolicy::SPLITDUPLEX || policy == SharingPolicy::WIFI) - throw std::invalid_argument(std::string("Impossible to set wifi or split-duplex for the link: ") + get_name() + - std::string(". Use appropriate create function in NetZone.")); + throw std::invalid_argument("Impossible to set wifi or split-duplex for the link: " + get_name() + + ". Use appropriate create function in NetZone."); - kernel::actor::simcall_answered([this, policy, &cb] { pimpl_->set_sharing_policy(policy, cb); }); + kernel::actor::simcall_object_access(pimpl_, [this, policy, &cb] { pimpl_->set_sharing_policy(policy, cb); }); return this; } Link::SharingPolicy Link::get_sharing_policy() const @@ -120,15 +119,20 @@ void Link::set_host_wifi_rate(const s4u::Host* host, int level) const wlink->set_host_rate(host, level); } +int Link::get_concurrency_limit() const +{ + return pimpl_->get_concurrency_limit(); +} + Link* Link::set_concurrency_limit(int limit) { - kernel::actor::simcall_answered([this, limit] { pimpl_->set_concurrency_limit(limit); }); + kernel::actor::simcall_object_access(pimpl_, [this, limit] { pimpl_->set_concurrency_limit(limit); }); return this; } -double Link::get_usage() const +double Link::get_load() const { - return this->pimpl_->get_constraint()->get_usage(); + return this->pimpl_->get_constraint()->get_load(); } void Link::turn_on() @@ -154,21 +158,21 @@ bool Link::is_on() const Link* Link::set_state_profile(kernel::profile::Profile* profile) { xbt_assert(not pimpl_->is_sealed(), "Cannot set a state profile once the Link is sealed"); - kernel::actor::simcall_answered([this, profile]() { this->pimpl_->set_state_profile(profile); }); + kernel::actor::simcall_object_access(pimpl_, [this, profile]() { this->pimpl_->set_state_profile(profile); }); return this; } Link* Link::set_bandwidth_profile(kernel::profile::Profile* profile) { xbt_assert(not pimpl_->is_sealed(), "Cannot set a bandwidth profile once the Link is sealed"); - kernel::actor::simcall_answered([this, profile]() { this->pimpl_->set_bandwidth_profile(profile); }); + kernel::actor::simcall_object_access(pimpl_, [this, profile]() { this->pimpl_->set_bandwidth_profile(profile); }); return this; } Link* Link::set_latency_profile(kernel::profile::Profile* profile) { xbt_assert(not pimpl_->is_sealed(), "Cannot set a latency profile once the Link is sealed"); - kernel::actor::simcall_answered([this, profile]() { this->pimpl_->set_latency_profile(profile); }); + kernel::actor::simcall_object_access(pimpl_, [this, profile]() { this->pimpl_->set_latency_profile(profile); }); return this; } @@ -178,7 +182,7 @@ const char* Link::get_property(const std::string& key) const } Link* Link::set_property(const std::string& key, const std::string& value) { - kernel::actor::simcall_answered([this, &key, &value] { this->pimpl_->set_property(key, value); }); + kernel::actor::simcall_object_access(pimpl_, [this, &key, &value] { this->pimpl_->set_property(key, value); }); return this; } @@ -189,7 +193,7 @@ const std::unordered_map* Link::get_properties() const Link* Link::set_properties(const std::unordered_map& properties) { - kernel::actor::simcall_answered([this, &properties] { this->pimpl_->set_properties(properties); }); + kernel::actor::simcall_object_access(pimpl_, [this, &properties] { this->pimpl_->set_properties(properties); }); return this; } diff --git a/src/s4u/s4u_Mailbox.cpp b/src/s4u/s4u_Mailbox.cpp index 4621305dfd..76613fbfa8 100644 --- a/src/s4u/s4u_Mailbox.cpp +++ b/src/s4u/s4u_Mailbox.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,7 +14,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_channel, s4u, "S4U Communication Mailboxes") namespace simgrid::s4u { -const xbt::string& Mailbox::get_name() const +const std::string& Mailbox::get_name() const { return pimpl_->get_name(); } @@ -101,7 +101,7 @@ CommPtr Mailbox::put_async(void* payload, uint64_t simulated_size_in_bytes) xbt_assert(payload != nullptr, "You cannot send nullptr"); CommPtr res = put_init(payload, simulated_size_in_bytes); - res->vetoable_start(); + res->start(); return res; } @@ -109,7 +109,7 @@ void Mailbox::put(void* payload, uint64_t simulated_size_in_bytes) { xbt_assert(payload != nullptr, "You cannot send nullptr"); - put_init()->set_payload_size(simulated_size_in_bytes)->set_src_data(payload)->vetoable_start()->wait(); + put_init()->set_payload_size(simulated_size_in_bytes)->set_src_data(payload)->start()->wait(); } /** Blocking send with timeout */ @@ -117,7 +117,7 @@ void Mailbox::put(void* payload, uint64_t simulated_size_in_bytes, double timeou { xbt_assert(payload != nullptr, "You cannot send nullptr"); - put_init()->set_payload_size(simulated_size_in_bytes)->set_src_data(payload)->vetoable_start()->wait_for(timeout); + put_init()->set_payload_size(simulated_size_in_bytes)->set_src_data(payload)->start()->wait_for(timeout); } CommPtr Mailbox::get_init() @@ -127,6 +127,13 @@ CommPtr Mailbox::get_init() return res; } +CommPtr Mailbox::get_async() +{ + CommPtr res = get_init()->set_dst_data(nullptr, sizeof(void*)); + res->start(); + return res; +} + kernel::activity::ActivityImplPtr Mailbox::iprobe(int type, const std::function& match_fun, void* data) { diff --git a/src/s4u/s4u_Mess.cpp b/src/s4u/s4u_Mess.cpp new file mode 100644 index 0000000000..0a8da79d37 --- /dev/null +++ b/src/s4u/s4u_Mess.cpp @@ -0,0 +1,153 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include +#include +#include +#include +#include +#include + +#include "src/kernel/activity/MessImpl.hpp" +#include "src/kernel/actor/ActorImpl.hpp" +#include "src/kernel/actor/SimcallObserver.hpp" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_mess, s4u_activity, "S4U asynchronous messaging"); + +namespace simgrid::s4u { +xbt::signal Mess::on_send; +xbt::signal Mess::on_recv; + +MessPtr Mess::set_queue(MessageQueue* queue) +{ + queue_ = queue; + return this; +} + +MessPtr Mess::set_payload(void* payload) +{ + payload_ = payload; + return this; +} + +MessPtr Mess::set_dst_data(void** buff, size_t size) +{ + xbt_assert(state_ == State::INITED, "You cannot use %s() once your communication started (not implemented)", + __func__); + + dst_buff_ = buff; + dst_buff_size_ = size; + return this; +} + +Actor* Mess::get_sender() const +{ + kernel::actor::ActorImplPtr sender = nullptr; + if (pimpl_) + sender = boost::static_pointer_cast(pimpl_)->src_actor_; + return sender ? sender->get_ciface() : nullptr; +} + +Actor* Mess::get_receiver() const +{ + kernel::actor::ActorImplPtr receiver = nullptr; + if (pimpl_) + receiver = boost::static_pointer_cast(pimpl_)->dst_actor_; + return receiver ? receiver->get_ciface() : nullptr; +} + +Mess* Mess::do_start() +{ + xbt_assert(get_state() == State::INITED || get_state() == State::STARTING, + "You cannot use %s() once your message exchange has started (not implemented)", __func__); + + auto myself = kernel::actor::ActorImpl::self(); + if (myself == sender_) { + on_send(*this); + on_this_send(*this); + kernel::actor::MessIputSimcall observer{sender_, queue_->get_impl(), get_payload()}; + pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::MessImpl::iput(&observer); }, + &observer); + } else if (myself == receiver_) { + on_recv(*this); + on_this_recv(*this); + kernel::actor::MessIgetSimcall observer{receiver_, + queue_->get_impl(), + static_cast(dst_buff_), + &dst_buff_size_, + get_payload()}; + pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::MessImpl::iget(&observer); }, + &observer); + } else { + xbt_die("Cannot start a message exchange before specifying whether we are the sender or the receiver"); + } + + pimpl_->set_iface(this); + pimpl_->set_actor(sender_); + // Only throw the signal when both sides are here and the status is READY + if (pimpl_->get_state() != kernel::activity::State::WAITING) { + fire_on_start(); + fire_on_this_start(); + } + state_ = State::STARTED; + return this; +} + +Mess* Mess::wait_for(double timeout) +{ + XBT_DEBUG("Calling Mess::wait_for with state %s", get_state_str()); + kernel::actor::ActorImpl* issuer = nullptr; + switch (state_) { + case State::FINISHED: + break; + case State::FAILED: + throw NetworkFailureException(XBT_THROW_POINT, "Cannot wait for a failed communication"); + case State::INITED: + case State::STARTING: + if (get_payload() != nullptr) { + on_send(*this); + on_this_send(*this); + kernel::actor::MessIputSimcall observer{sender_, queue_->get_impl(), get_payload()}; + pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::MessImpl::iput(&observer); }, + &observer); + } else { // Receiver + on_recv(*this); + on_this_recv(*this); + kernel::actor::MessIgetSimcall observer{receiver_, + queue_->get_impl(), + static_cast(dst_buff_), + &dst_buff_size_, + get_payload()}; + pimpl_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::MessImpl::iget(&observer); }, + &observer); + } + break; + case State::STARTED: + try { + issuer = kernel::actor::ActorImpl::self(); + kernel::actor::ActivityWaitSimcall observer{issuer, pimpl_.get(), timeout, "Wait"}; + if (kernel::actor::simcall_blocking( + [&observer] { observer.get_activity()->wait_for(observer.get_issuer(), observer.get_timeout()); }, + &observer)) { + throw TimeoutException(XBT_THROW_POINT, "Timeouted"); + } + } catch (const NetworkFailureException& e) { + issuer->simcall_.observer_ = nullptr; // Comm failed on network failure, reset the observer to nullptr + complete(State::FAILED); + e.rethrow_nested(XBT_THROW_POINT, boost::core::demangle(typeid(e).name()) + " raised in kernel mode."); + } + break; + + case State::CANCELED: + throw CancelException(XBT_THROW_POINT, "Message canceled"); + + default: + THROW_IMPOSSIBLE; + } + complete(State::FINISHED); + return this; +} + +} // namespace simgrid::s4u diff --git a/src/s4u/s4u_MessageQueue.cpp b/src/s4u/s4u_MessageQueue.cpp new file mode 100644 index 0000000000..8fe34ac8a2 --- /dev/null +++ b/src/s4u/s4u_MessageQueue.cpp @@ -0,0 +1,98 @@ +/* Copyright (c) 2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include +#include +#include + +#include "src/kernel/activity/MessageQueueImpl.hpp" + +XBT_LOG_EXTERNAL_CATEGORY(s4u); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_mqueue, s4u, "S4U Message Queues"); + +namespace simgrid::s4u { + +const std::string& MessageQueue::get_name() const +{ + return pimpl_->get_name(); +} + +const char* MessageQueue::get_cname() const +{ + return pimpl_->get_cname(); +} + +MessageQueue* MessageQueue::by_name(const std::string& name) +{ + return Engine::get_instance()->message_queue_by_name_or_create(name); +} + +bool MessageQueue::empty() const +{ + return pimpl_->empty(); +} + +size_t MessageQueue::size() const +{ + return pimpl_->size(); +} + +kernel::activity::MessImplPtr MessageQueue::front() const +{ + return pimpl_->empty() ? nullptr : pimpl_->front(); +} + +MessPtr MessageQueue::put_init() +{ + MessPtr res(new Mess()); + res->set_queue(this); + res->sender_ = kernel::actor::ActorImpl::self(); + return res; +} + +MessPtr MessageQueue::put_init(void* payload) +{ + return put_init()->set_payload(payload); +} + +MessPtr MessageQueue::put_async(void* payload) +{ + xbt_assert(payload != nullptr, "You cannot send nullptr"); + MessPtr res = put_init(payload); + res->start(); + return res; +} + +void MessageQueue::put(void* payload) +{ + xbt_assert(payload != nullptr, "You cannot send nullptr"); + + put_async(payload)->wait(); +} + +/** Blocking send with timeout */ +void MessageQueue::put(void* payload, double timeout) +{ + xbt_assert(payload != nullptr, "You cannot send nullptr"); + + put_init()->set_payload(payload)->start()->wait_for(timeout); +} + +MessPtr MessageQueue::get_init() +{ + MessPtr res(new Mess()); + res->set_queue(this); + res->receiver_ = kernel::actor::ActorImpl::self(); + return res; +} + +MessPtr MessageQueue::get_async() +{ + MessPtr res = get_init()->set_payload(nullptr); + res->start(); + return res; +} + +} // namespace simgrid::s4u diff --git a/src/s4u/s4u_Mutex.cpp b/src/s4u/s4u_Mutex.cpp index 0adc7f026c..72c2481736 100644 --- a/src/s4u/s4u_Mutex.cpp +++ b/src/s4u/s4u_Mutex.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -19,7 +19,7 @@ void Mutex::lock() kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); if (MC_is_active() || MC_record_replay_is_active()) { // Split in 2 simcalls for transition persistency - kernel::actor::MutexObserver lock_observer{issuer, mc::Transition::Type::MUTEX_LOCK, pimpl_}; + kernel::actor::MutexObserver lock_observer{issuer, mc::Transition::Type::MUTEX_ASYNC_LOCK, pimpl_}; auto acquisition = kernel::actor::simcall_answered([issuer, this] { return pimpl_->lock_async(issuer); }, &lock_observer); @@ -55,10 +55,18 @@ bool Mutex::try_lock() * * See @ref s4u_raii. */ -MutexPtr Mutex::create() +MutexPtr Mutex::create(bool recursive) { - auto* mutex = new kernel::activity::MutexImpl(); - return MutexPtr(&mutex->mutex(), false); + auto* mutex = new kernel::activity::MutexImpl(recursive); + return MutexPtr(&mutex->get_iface(), false); +} + +Actor* Mutex::get_owner() +{ + auto* owner = pimpl_->get_owner(); + if (owner == nullptr) + return nullptr; + return owner->get_ciface(); } /* refcounting of the intrusive_ptr is delegated to the implementation object */ diff --git a/src/s4u/s4u_Netzone.cpp b/src/s4u/s4u_Netzone.cpp index bd00dc9e81..b62e620f10 100644 --- a/src/s4u/s4u_Netzone.cpp +++ b/src/s4u/s4u_Netzone.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -39,7 +39,7 @@ void NetZone::set_property(const std::string& key, const std::string& value) std::vector NetZone::get_children() const { std::vector res; - for (auto child : pimpl_->get_children()) + for (auto* child : pimpl_->get_children()) res.push_back(child->get_iface()); return res; } @@ -85,13 +85,71 @@ unsigned long NetZone::add_component(kernel::routing::NetPoint* elm) return pimpl_->add_component(elm); } +void NetZone::add_route(const NetZone* src, const NetZone* dst, const std::vector& links) +{ + std::vector links_direct; + std::vector links_reverse; + for (auto* l : links) { + links_direct.emplace_back(LinkInRoute(l, LinkInRoute::Direction::UP)); + links_reverse.emplace_back(LinkInRoute(l, LinkInRoute::Direction::DOWN)); + } + pimpl_->add_route(src ? src->get_netpoint() : nullptr, dst ? dst->get_netpoint(): nullptr, + src ? src->get_gateway() : nullptr, dst ? dst->get_gateway() : nullptr, + links_direct, false); + pimpl_->add_route(dst ? dst->get_netpoint(): nullptr, src ? src->get_netpoint() : nullptr, + dst ? dst->get_gateway() : nullptr, src ? src->get_gateway() : nullptr, + links_reverse, false); +} + +void NetZone::add_route(const NetZone* src, const NetZone* dst, const std::vector& link_list, bool symmetrical) +{ + pimpl_->add_route(src ? src->get_netpoint() : nullptr, dst ? dst->get_netpoint(): nullptr, + src ? src->get_gateway() : nullptr, dst ? dst->get_gateway() : nullptr, + link_list, symmetrical); +} + void NetZone::add_route(kernel::routing::NetPoint* src, kernel::routing::NetPoint* dst, kernel::routing::NetPoint* gw_src, kernel::routing::NetPoint* gw_dst, - const std::vector& link_list, bool symmetrical) + const std::vector& link_list, bool symmetrical) // XBT_ATTRIB_DEPRECATED_v339 { pimpl_->add_route(src, dst, gw_src, gw_dst, link_list, symmetrical); } +void NetZone::add_route(kernel::routing::NetPoint* src, kernel::routing::NetPoint* dst, + kernel::routing::NetPoint* gw_src, kernel::routing::NetPoint* gw_dst, + const std::vector& links) // XBT_ATTRIB_DEPRECATED_v339 +{ + std::vector links_direct; + std::vector links_reverse; + for (auto* l : links) { + links_direct.emplace_back(LinkInRoute(l, LinkInRoute::Direction::UP)); + links_reverse.emplace_back(LinkInRoute(l, LinkInRoute::Direction::DOWN)); + } + pimpl_->add_route(src, dst, gw_src, gw_dst, links_direct, false); + pimpl_->add_route(dst, src, gw_dst, gw_src, links_reverse, false); +} + +void NetZone::add_route(const Host* src, const Host* dst, const std::vector& link_list, bool symmetrical) +{ + pimpl_->add_route(src ? src->get_netpoint(): nullptr, dst ? dst->get_netpoint(): nullptr, nullptr, nullptr, + link_list, symmetrical); + +} + +void NetZone::add_route(const Host* src, const Host* dst, const std::vector& links) +{ + std::vector links_direct; + std::vector links_reverse; + for (auto* l : links) { + links_direct.emplace_back(LinkInRoute(l, LinkInRoute::Direction::UP)); + links_reverse.emplace_back(LinkInRoute(l, LinkInRoute::Direction::DOWN)); + } + pimpl_->add_route(src ? src->get_netpoint(): nullptr, dst ? dst->get_netpoint(): nullptr, nullptr, nullptr, + links_direct, false); + pimpl_->add_route(dst ? dst->get_netpoint(): nullptr, src ? src->get_netpoint(): nullptr, nullptr, nullptr, + links_reverse, false); +} + void NetZone::add_bypass_route(kernel::routing::NetPoint* src, kernel::routing::NetPoint* dst, kernel::routing::NetPoint* gw_src, kernel::routing::NetPoint* gw_dst, const std::vector& link_list) @@ -113,6 +171,20 @@ NetZone* NetZone::seal() kernel::actor::simcall_answered([this] { pimpl_->seal(); }); return this; } +void NetZone::set_latency_factor_cb( + std::function& /*links*/, + const std::unordered_set& /*netzones*/)> const& cb) const +{ + kernel::actor::simcall_answered([this, &cb]() { pimpl_->get_network_model()->set_lat_factor_cb(cb); }); +} +void NetZone::set_bandwidth_factor_cb( + std::function& /*links*/, + const std::unordered_set& /*netzones*/)> const& cb) const +{ + kernel::actor::simcall_answered([this, &cb]() { pimpl_->get_network_model()->set_bw_factor_cb(cb); }); +} s4u::Host* NetZone::create_host(const std::string& name, double speed) { @@ -156,8 +228,8 @@ s4u::SplitDuplexLink* NetZone::create_split_duplex_link(const std::string& name, try { speed = xbt_parse_get_bandwidth("", 0, bandwidth, ""); } catch (const simgrid::ParseError&) { - throw std::invalid_argument(std::string("Impossible to create split-duplex link: ") + name + - std::string(". Invalid bandwidth: ") + bandwidth); + throw std::invalid_argument("Impossible to create split-duplex link: " + name + + ". Invalid bandwidth: " + bandwidth); } return create_split_duplex_link(name, speed); } @@ -177,8 +249,7 @@ s4u::Link* NetZone::create_link(const std::string& name, const std::vectorcreate_router(name); }); } -kernel::routing::NetPoint* NetZone::get_netpoint() +kernel::routing::NetPoint* NetZone::get_netpoint() const { return pimpl_->get_netpoint(); } -kernel::resource::NetworkModelIntf* NetZone::get_network_model() const +kernel::routing::NetPoint* NetZone::get_gateway() const +{ + return pimpl_->get_gateway(); +} + +kernel::routing::NetPoint* NetZone::get_gateway(const std::string& name) const +{ + return pimpl_->get_gateway(name); +} + +void NetZone::set_gateway(kernel::routing::NetPoint* router) +{ + set_gateway("default", router); +} + +void NetZone::set_gateway(const std::string& name, kernel::routing::NetPoint* router) +{ + kernel::actor::simcall_answered([this, name, router] { pimpl_->set_gateway(name, router); }); +} + +kernel::resource::NetworkModel* NetZone::get_network_model() const { - kernel::resource::NetworkModelIntf* model = pimpl_->get_network_model().get(); - return model; + return pimpl_->get_network_model().get(); } } // namespace simgrid::s4u diff --git a/src/s4u/s4u_Semaphore.cpp b/src/s4u/s4u_Semaphore.cpp index c2021e5626..7144363c51 100644 --- a/src/s4u/s4u_Semaphore.cpp +++ b/src/s4u/s4u_Semaphore.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -29,7 +29,7 @@ bool Semaphore::acquire_timeout(double timeout) kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); if (MC_is_active() || MC_record_replay_is_active()) { // Split in 2 simcalls for transition persistency - kernel::actor::SemaphoreObserver lock_observer{issuer, mc::Transition::Type::SEM_LOCK, pimpl_}; + kernel::actor::SemaphoreObserver lock_observer{issuer, mc::Transition::Type::SEM_ASYNC_LOCK, pimpl_}; auto acquisition = kernel::actor::simcall_answered([issuer, this] { return pimpl_->acquire_async(issuer); }, &lock_observer); diff --git a/src/s4u/s4u_Task.cpp b/src/s4u/s4u_Task.cpp new file mode 100644 index 0000000000..bcc2f4eea4 --- /dev/null +++ b/src/s4u/s4u_Task.cpp @@ -0,0 +1,530 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/simgrid/module.hpp" + +SIMGRID_REGISTER_PLUGIN(task, "Battery management", nullptr) +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Task, kernel, "Logging specific to the task plugin"); + +namespace simgrid::s4u { + +Task::Task(const std::string& name) : name_(name) {} + +/** @param instance The Task instance to check. + * @brief Return True if this Task instance can start. + */ +bool Task::ready_to_run(std::string instance) +{ + return running_instances_[instance] < parallelism_degree_[instance] && queued_firings_[instance] > 0; +} + +/** @param source The sender. + * @brief Receive a token from another Task. + * @note Check upon reception if the Task has received a token from each of its predecessors, + * and in this case consumes those tokens and enqueue an execution. + */ +void Task::receive(Task* source) +{ + XBT_DEBUG("Task %s received a token from %s", name_.c_str(), source->name_.c_str()); + predecessors_[source]++; + if (source->token_ != nullptr) + tokens_received_[source].push_back(source->token_); + bool enough_tokens = true; + for (auto const& [key, val] : predecessors_) + if (val < 1) { + enough_tokens = false; + break; + } + if (enough_tokens) { + for (auto& [key, val] : predecessors_) + val--; + enqueue_firings(1); + } +} + +/** @param instance The Taks instance to complete. + * @brief Task instance routine when finishing an execution of an instance. + * @note The dispatcher instance enqueues a firing for the next instance. + * The collector instance triggers the on_completion signals and sends tokens to successors. + * Others instances enqueue a firing of the collector instance. + */ +void Task::complete(std::string instance) +{ + xbt_assert(Actor::is_maestro()); + running_instances_[instance]--; + count_[instance]++; + if (instance == "collector") { + on_this_completion(this); + on_completion(this); + for (auto const& t : successors_) + t->receive(this); + } else if (instance == "dispatcher") { + auto next_instance = load_balancing_function_(); + xbt_assert(next_instance != "dispatcher" and next_instance != "collector", "Invalid instance selected: %s", + next_instance.c_str()); + queued_firings_[next_instance] = queued_firings_.at(next_instance) + 1; + while (ready_to_run(next_instance)) + fire(next_instance); + } else { + queued_firings_["collector"]++; + while (ready_to_run("collector")) + fire("collector"); + } + if (ready_to_run(instance)) + fire(instance); +} + +/** @param n The new parallelism degree of the Task instance. + * @param instance The Task instance to modify. + * @note You can use instance "all" to modify the parallelism degree of all instances of this Task. + * When increasing the degree new executions are started if there is queued firings. + * When decreasing the degree instances already running are NOT stopped. + */ +void Task::set_parallelism_degree(int n, std::string instance) +{ + xbt_assert(n > 0, "Parallelism degree must be above 0."); + simgrid::kernel::actor::simcall_answered([this, n, &instance] { + if (instance == "all") { + for (auto& [key, value] : parallelism_degree_) { + parallelism_degree_[key] = n; + while (ready_to_run(key)) + fire(key); + } + } else { + parallelism_degree_[instance] = n; + while (ready_to_run(instance)) + fire(instance); + } + }); +} + +/** @param bytes The internal bytes of the Task instance. + * @param instance The Task instance to modify. + * @note Internal bytes are used for Comms between the dispatcher and instance_n, + * and between instance_n and the collector if they are not on the same host. + */ +void Task::set_internal_bytes(int bytes, std::string instance) +{ + simgrid::kernel::actor::simcall_answered([this, bytes, &instance] { internal_bytes_to_send_[instance] = bytes; }); +} + +/** @param func The load balancing function. + * @note The dispatcher uses this function to determine which instance to trigger next. + */ +void Task::set_load_balancing_function(std::function func) +{ + simgrid::kernel::actor::simcall_answered([this, func] { load_balancing_function_ = func; }); +} + +/** @param n The number of firings to enqueue. + */ +void Task::enqueue_firings(int n) +{ + simgrid::kernel::actor::simcall_answered([this, n] { + queued_firings_["dispatcher"] += n; + while (ready_to_run("dispatcher")) + fire("dispatcher"); + }); +} + +/** @param name The new name to set. + * @brief Set the name of the Task. + */ +void Task::set_name(std::string name) +{ + name_ = name; +} + +/** @param amount The amount to set. + * @param instance The Task instance to modify. + * @note Amount in flop for ExecTask and in bytes for CommTask. + */ +void Task::set_amount(double amount, std::string instance) +{ + simgrid::kernel::actor::simcall_answered([this, amount, &instance] { amount_[instance] = amount; }); +} + +/** @param token The token to set. + * @brief Set the token to send to successors. + * @note The token is passed to each successor after the Task instance collector end, i.e., after the on_completion + * callback. + */ +void Task::set_token(std::shared_ptr token) +{ + simgrid::kernel::actor::simcall_answered([this, token] { token_ = token; }); +} + +/** @param t The Task to deque a token from. + */ +void Task::deque_token_from(TaskPtr t) +{ + simgrid::kernel::actor::simcall_answered([this, &t] { tokens_received_[t].pop_front(); }); +} + +void Task::fire(std::string instance) +{ + if ((int)current_activities_[instance].size() > parallelism_degree_[instance]) { + current_activities_[instance].pop_front(); + } + if (instance != "dispatcher" and instance != "collector") { + on_this_start(this); + on_start(this); + } + running_instances_[instance]++; + queued_firings_[instance] = std::max(queued_firings_[instance] - 1, 0); +} + +/** @param successor The Task to add as a successor. + * @note It also adds this as a predecessor of successor. + */ +void Task::add_successor(TaskPtr successor) +{ + simgrid::kernel::actor::simcall_answered([this, successor_p = successor.get()] { + successors_.insert(successor_p); + successor_p->predecessors_.try_emplace(this, 0); + }); +} + +/** @param successor The Task to remove from the successors of this Task. + * @note It also remove this from the predecessors of successor. + */ +void Task::remove_successor(TaskPtr successor) +{ + simgrid::kernel::actor::simcall_answered([this, successor_p = successor.get()] { + successor_p->predecessors_.erase(this); + successors_.erase(successor_p); + }); +} + +/** @brief Remove all successors from this Task. + */ +void Task::remove_all_successors() +{ + simgrid::kernel::actor::simcall_answered([this] { + while (not successors_.empty()) { + auto* successor = *(successors_.begin()); + successor->predecessors_.erase(this); + successors_.erase(successor); + } + }); +} + +/** @param n The number of instances to add to this Task (>=0). + * @note Instances goes always from instance_0 to instance_x, + * where x is the current number of instance. + */ +void Task::add_instances(int n) +{ + xbt_assert(n >= 0, "Cannot add a negative number of instances (provided: %d)", n); + int instance_count = (int)amount_.size() - 2; + for (int i = instance_count; i < n + instance_count; i++) { + amount_["instance_" + std::to_string(i)] = amount_.at("instance_0"); + queued_firings_["instance_" + std::to_string(i)] = 0; + running_instances_["instance_" + std::to_string(i)] = 0; + count_["instance_" + std::to_string(i)] = 0; + parallelism_degree_["instance_" + std::to_string(i)] = parallelism_degree_.at("instance_0"); + current_activities_["instance_" + std::to_string(i)] = {}; + internal_bytes_to_send_["instance_" + std::to_string(i)] = internal_bytes_to_send_.at("instance_0"); + ; + } +} + +/** @param n The number of instances to remove from this Task (>=0). + * @note Instances goes always from instance_0 to instance_x, + * where x is the current number of instance. + * Running instances cannot be removed. + */ +void Task::remove_instances(int n) +{ + int instance_count = (int)amount_.size() - 2; + xbt_assert(n >= 0, "Cannot remove a negative number of instances (provided: %d)", n); + xbt_assert(instance_count - n > 0, "The number of instances must be above 0 (instances: %d, provided: %d)", + instance_count, n); + for (int i = instance_count - 1; i >= instance_count - n; i--) { + xbt_assert(running_instances_.at("instance_" + std::to_string(i)) == 0, + "Cannot remove a running instance (instances: %d)", i); + amount_.erase("instance_" + std::to_string(i)); + queued_firings_.erase("instance_" + std::to_string(i)); + running_instances_.erase("instance_" + std::to_string(i)); + count_.erase("instance_" + std::to_string(i)); + parallelism_degree_.erase("instance_" + std::to_string(i)); + current_activities_.erase("instance_" + std::to_string(i)); + } +} + +/** + * @brief Default constructor. + */ +ExecTask::ExecTask(const std::string& name) : Task(name) +{ + set_load_balancing_function([]() { return "instance_0"; }); +} + +/** + * @brief Smart Constructor. + */ +ExecTaskPtr ExecTask::init(const std::string& name) +{ + return ExecTaskPtr(new ExecTask(name)); +} + +/** + * @brief Smart Constructor. + */ +ExecTaskPtr ExecTask::init(const std::string& name, double flops, Host* host) +{ + return init(name)->set_flops(flops)->set_host(host); +} + +/** @param instance The Task instance to fire. + * @note Only the dispatcher instance triggers the on_start signal. + * Comms are created if hosts differ between dispatcher and the instance to fire, + * or between the instance and the collector. + */ +void ExecTask::fire(std::string instance) +{ + Task::fire(instance); + if (instance == "dispatcher" or instance == "collector") { + auto exec = Exec::init() + ->set_name(get_name() + "_" + instance) + ->set_flops_amount(get_amount(instance)) + ->set_host(host_[instance]); + exec->start(); + exec->on_this_completion_cb([this, instance](Exec const&) { complete(instance); }); + store_activity(exec, instance); + } else { + auto exec = Exec::init()->set_name(get_name())->set_flops_amount(get_amount())->set_host(host_[instance]); + if (host_["dispatcher"] == host_[instance]) { + exec->start(); + store_activity(exec, instance); + } else { + auto comm = Comm::sendto_init(host_["dispatcher"], host_[instance]) + ->set_name(get_name() + "_dispatcher_to_" + instance) + ->set_payload_size(get_internal_bytes("dispatcher")); + comm->add_successor(exec); + comm->start(); + store_activity(comm, instance); + } + if (host_[instance] == host_["collector"]) { + exec->on_this_completion_cb([this, instance](Exec const&) { complete(instance); }); + if (host_["dispatcher"] != host_[instance]) + store_activity(exec, instance); + } else { + auto comm = Comm::sendto_init(host_[instance], host_["collector"]) + ->set_name(get_name() + instance + "_to_collector") + ->set_payload_size(get_internal_bytes(instance)); + exec->add_successor(comm); + comm->on_this_completion_cb([this, instance](Comm const&) { complete(instance); }); + comm.detach(); + } + } +} + +/** @param host The host to set. + * @param instance The Task instance to modify. + * @brief Set a new host. + */ +ExecTaskPtr ExecTask::set_host(Host* host, std::string instance) +{ + kernel::actor::simcall_answered([this, host, &instance] { + if (instance == "all") + for (auto& [key, value] : host_) + host_[key] = host; + else + host_[instance] = host; + }); + return this; +} + +/** @param flops The amount of flops to set. + * @param instance The Task instance to modify. + */ +ExecTaskPtr ExecTask::set_flops(double flops, std::string instance) +{ + kernel::actor::simcall_answered([this, flops, &instance] { set_amount(flops, instance); }); + return this; +} + +/** @param n The number of instances to add to this Task (>=0). + @note Instances goes always from instance_0 to instance_x, + where x is the current number of instance. + */ +void ExecTask::add_instances(int n) +{ + Task::add_instances(n); + int instance_count = (int)host_.size() - 2; + for (int i = instance_count; i < n + instance_count; i++) + host_["instance_" + std::to_string(i)] = host_.at("instance_0"); +} + +/** @param n The number of instances to remove from this Task (>=0). + @note Instances goes always from instance_0 to instance_x, + where x is the current number of instance. + Running instance cannot be removed. + */ +void ExecTask::remove_instances(int n) +{ + Task::remove_instances(n); + int instance_count = (int)host_.size() - 2; + for (int i = instance_count - 1; i >= instance_count - n; i--) + host_.erase("instance_" + std::to_string(i)); +} + +/** + * @brief Default constructor. + */ +CommTask::CommTask(const std::string& name) : Task(name) +{ + set_load_balancing_function([]() { return "instance_0"; }); +} + +/** + * @brief Smart constructor. + */ +CommTaskPtr CommTask::init(const std::string& name) +{ + return CommTaskPtr(new CommTask(name)); +} + +/** + * @brief Smart constructor. + */ +CommTaskPtr CommTask::init(const std::string& name, double bytes, Host* source, Host* destination) +{ + return init(name)->set_bytes(bytes)->set_source(source)->set_destination(destination); +} + +/** @param instance The Task instance to fire. + * @note Only the dispatcher instance triggers the on_start signal. + */ +void CommTask::fire(std::string instance) +{ + Task::fire(instance); + if (instance == "dispatcher" or instance == "collector") { + auto exec = Exec::init() + ->set_name(get_name() + "_" + instance) + ->set_flops_amount(get_amount(instance)) + ->set_host(instance == "dispatcher" ? source_ : destination_); + exec->start(); + exec->on_this_completion_cb([this, instance](Exec const&) { complete(instance); }); + store_activity(exec, instance); + } else { + auto comm = Comm::sendto_init(source_, destination_)->set_name(get_name())->set_payload_size(get_amount()); + comm->start(); + comm->on_this_completion_cb([this, instance](Comm const&) { complete(instance); }); + store_activity(comm, instance); + } +} + +/** + * @param source The host to set. + * @brief Set a new source host. + */ +CommTaskPtr CommTask::set_source(Host* source) +{ + kernel::actor::simcall_answered([this, source] { source_ = source; }); + return this; +} + +/** + * @param destination The host to set. + * @brief Set a new destination host. + */ +CommTaskPtr CommTask::set_destination(Host* destination) +{ + kernel::actor::simcall_answered([this, destination] { destination_ = destination; }); + return this; +} + +/** + * @param bytes The amount of bytes to set. + */ +CommTaskPtr CommTask::set_bytes(double bytes) +{ + kernel::actor::simcall_answered([this, bytes] { set_amount(bytes); }); + return this; +} + +/** + * @brief Default constructor. + */ +IoTask::IoTask(const std::string& name) : Task(name) +{ + set_load_balancing_function([]() { return "instance_0"; }); +} + +/** + * @brief Smart Constructor. + */ +IoTaskPtr IoTask::init(const std::string& name) +{ + return IoTaskPtr(new IoTask(name)); +} + +/** + * @brief Smart Constructor. + */ +IoTaskPtr IoTask::init(const std::string& name, double bytes, Disk* disk, Io::OpType type) +{ + return init(name)->set_bytes(bytes)->set_disk(disk)->set_op_type(type); +} + +/** + * @param disk The disk to set. + */ +IoTaskPtr IoTask::set_disk(Disk* disk) +{ + kernel::actor::simcall_answered([this, disk] { disk_ = disk; }); + return this; +} + +/** + * @param bytes The amount of bytes to set. + */ +IoTaskPtr IoTask::set_bytes(double bytes) +{ + kernel::actor::simcall_answered([this, bytes] { set_amount(bytes); }); + return this; +} + +/** + * @param type The op type to set. + */ +IoTaskPtr IoTask::set_op_type(Io::OpType type) +{ + kernel::actor::simcall_answered([this, type] { type_ = type; }); + return this; +} + +/** @param instance The Task instance to fire. + * @note Only the dispatcher instance triggers the on_start signal. + */ +void IoTask::fire(std::string instance) +{ + Task::fire(instance); + if (instance == "dispatcher" or instance == "collector") { + auto exec = Exec::init() + ->set_name(get_name() + "_" + instance) + ->set_flops_amount(get_amount(instance)) + ->set_host(disk_->get_host()); + exec->start(); + exec->on_this_completion_cb([this, instance](Exec const&) { complete(instance); }); + store_activity(exec, instance); + } else { + auto io = Io::init()->set_name(get_name())->set_size(get_amount())->set_disk(disk_)->set_op_type(type_); + io->start(); + io->on_this_completion_cb([this, instance](Io const&) { complete(instance); }); + store_activity(io, instance); + } +} +} // namespace simgrid::s4u diff --git a/src/s4u/s4u_VirtualMachine.cpp b/src/s4u/s4u_VirtualMachine.cpp index f607ad859c..415b1f7d99 100644 --- a/src/s4u/s4u_VirtualMachine.cpp +++ b/src/s4u/s4u_VirtualMachine.cpp @@ -1,14 +1,15 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "simgrid/simix.hpp" #include #include #include #include "src/kernel/resource/VirtualMachineImpl.hpp" -#include "src/surf/cpu_cas01.hpp" +#include "src/kernel/resource/models/cpu_cas01.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_vm, s4u, "S4U virtual machines"); @@ -31,13 +32,6 @@ void VmHostExt::ensureVmExtInstalled() EXTENSION_ID = Host::extension_create(); } -VirtualMachine::VirtualMachine(const std::string& name, s4u::Host* physical_host, int core_amount, size_t ramsize) - : Host(new kernel::resource::VirtualMachineImpl(name, this, physical_host, core_amount, ramsize)) - , pimpl_vm_(dynamic_cast(Host::get_impl())) -{ - physical_host->get_impl()->create_vm(name, this); -} - VirtualMachine::VirtualMachine(kernel::resource::VirtualMachineImpl* impl) : Host(impl), pimpl_vm_(dynamic_cast(Host::get_impl())) { @@ -73,6 +67,7 @@ void VirtualMachine::destroy() XBT_DEBUG("destroy %s", get_cname()); on_vm_destruction(*this); + on_this_vm_destruction(*this); /* Then, destroy the VM object */ kernel::actor::simcall_answered( [this]() { get_vm_impl()->get_physical_host()->get_impl()->destroy_vm(get_name()); }); @@ -80,7 +75,7 @@ void VirtualMachine::destroy() if (not this_actor::is_maestro() && this_actor::get_host() == this) { XBT_VERB("Launch another actor on physical host %s to destroy my own VM: %s", get_pm()->get_cname(), get_cname()); - simgrid::s4u::Actor::create(get_cname() + std::string("-vm_destroy"), get_pm(), destroy_code); + simgrid::s4u::Actor::create(get_name() + "-vm_destroy", get_pm(), destroy_code); simgrid::s4u::this_actor::yield(); XBT_CRITICAL("I should be dead now!"); DIE_IMPOSSIBLE; @@ -118,7 +113,7 @@ VirtualMachine* VirtualMachine::set_ramsize(size_t ramsize) /** @brief Set a CPU bound for a given VM. * @ingroup msg_VMs * - * 1. Note that in some cases MSG_task_set_bound() may not intuitively work for VMs. + * 1. Note that in some cases sg_exec_set_bound() may not intuitively work for VMs. * * For example, * On PM0, there are Task1 and VM0. @@ -136,7 +131,7 @@ VirtualMachine* VirtualMachine::set_ramsize(size_t ramsize) * It should be the sum of all tasks on the VM. But, this solution might be costly, because we have to scan all tasks * on the VM in share_resource() or we have to trap both the start and end of task execution. * - * The current solution is to use setBound(), which allows us to directly set the bound of the dummy CPU action. + * The current solution is to use set_bound(), which allows us to directly set the bound of the dummy CPU action. * * 2. Note that bound == 0 means no bound (i.e., unlimited). But, if a host has multiple CPU cores, the CPU share of a * computation task (or a VM) never exceeds the capacity of a CPU core. diff --git a/src/simgrid/Exception.cpp b/src/simgrid/Exception.cpp index 89781bd198..7152419096 100644 --- a/src/simgrid/Exception.cpp +++ b/src/simgrid/Exception.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -12,6 +12,7 @@ namespace simgrid { // DO NOT define destructors for exceptions in Exception.hpp. // Defining it here ensures that the exceptions are defined only in libsimgrid, but not in libsimgrid-java. // Doing otherwise naturally breaks things (at least on freebsd with clang). +// TODO: is it still useful now that Java is gone? Exception::~Exception() = default; TimeoutException::~TimeoutException() = default; @@ -30,7 +31,7 @@ void ForcefulKillException::do_throw() throw ForcefulKillException(); } -bool ForcefulKillException::try_n_catch(const std::function& try_block) +bool ForcefulKillException::try_n_catch(const std::function& try_block) // XBT_ATTRIB_DEPRECATED_v338 { bool res; try { diff --git a/src/simgrid/math_utils.h b/src/simgrid/math_utils.h new file mode 100644 index 0000000000..84aa9d489d --- /dev/null +++ b/src/simgrid/math_utils.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MATH_UTILS_H_ +#define SIMGRID_MATH_UTILS_H_ + +#include +#include + +#include +#include + +static inline void double_update(double* variable, double value, double precision) +{ + if (false) { // debug + fprintf(stderr, "Updating %g -= %g +- %g\n", *variable, value, precision); + xbt_assert(value == 0.0 || value > precision); + // Check that precision is higher than the machine-dependent size of the mantissa. If not, brutal rounding may + // happen, and the precision mechanism is not active... + xbt_assert(FLT_RADIX == 2 && *variable < precision * exp2(DBL_MANT_DIG)); + } + *variable -= value; + if (*variable < precision) + *variable = 0.0; +} + +static inline int double_positive(double value, double precision) +{ + return (value > precision); +} + +static inline int double_equals(double value1, double value2, double precision) +{ + return (fabs(value1 - value2) < precision); +} + +#endif /* SIMGRID_MATH_UTILS_H_ */ diff --git a/src/simgrid/module.cpp b/src/simgrid/module.cpp new file mode 100644 index 0000000000..e3095bc180 --- /dev/null +++ b/src/simgrid/module.cpp @@ -0,0 +1,81 @@ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include +#include + +#include "src/simgrid/module.hpp" +#include "src/simgrid/sg_config.hpp" + +#include +#include + +XBT_LOG_NEW_CATEGORY(plugin, "Common category for the logging of all plugins"); +XBT_LOG_EXTERNAL_CATEGORY(xbt_help); + +using namespace simgrid; + +void ModuleGroup::create_flag(const std::string& opt_name, const std::string& descr, const std::string& default_value, + bool init_now) +{ + opt_name_ = opt_name; + std::string description = descr + ". Possible values (other compilation flags may activate more " + get_kind() + + "s): " + existing_values() + + ".\n (use 'help' as a value to see the long description of each one)"; + + simgrid::config::declare_flag( + opt_name, description, default_value, [this, default_value, init_now](const std::string& value) { + xbt_assert(_sg_cfg_init_status < 2, "Cannot load a %s after the initialization", kind_.c_str()); + + if (value == default_value) + return; + + if (value == "help") { + help(); + exit(0); + } + + if (init_now) + by_name(value).init(); + else + by_name(value); // Simply ensure that this value exists, it will be picked up later + }); +} +void ModuleGroup::init_from_flag_value() const +{ + by_name(simgrid::config::get_value(opt_name_)).init(); +} + +ModuleGroup& ModuleGroup::add(const char* id, const char* desc, std::function init) +{ + table_.emplace_back(id, desc, std::move(init)); + return *this; +} + +Module const& ModuleGroup::by_name(const std::string& name) const +{ + if (auto pos = std::find_if(table_.begin(), table_.end(), [&name](const Module& item) { return item.name_ == name; }); + pos != table_.end()) + return *pos; + + xbt_die("Unable to find %s '%s'. Valid values are: %s.", kind_.c_str(), name.c_str(), existing_values().c_str()); +} +/** Displays the long description of all registered models, and quit */ +void ModuleGroup::help() const +{ + XBT_HELP("Long description of the %s accepted by this simulator:", kind_.c_str()); + for (auto const& item : table_) + XBT_HELP(" %s: %s", item.name_, item.description_); +} +std::string ModuleGroup::existing_values() const +{ + std::stringstream ss; + std::string sep; + for (auto const& item : table_) { + ss << sep + item.name_; + sep = ", "; + } + return ss.str(); +} diff --git a/src/simgrid/module.hpp b/src/simgrid/module.hpp new file mode 100644 index 0000000000..771fe09c92 --- /dev/null +++ b/src/simgrid/module.hpp @@ -0,0 +1,109 @@ +/* Copyright (c) 2004-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SIMGRID_MODULE_HPP +#define SIMGRID_MODULE_HPP + +#include + +#include +#include +#include + +namespace simgrid { + +struct Module { + const char* name_; + const char* description_; + std::function init; + Module(const char* id, const char* desc, std::function init_fun) + : name_(id), description_(desc), init(std::move(init_fun)) + { + } +}; + +class ModuleGroup { + std::vector table_; + const std::string kind_; // either 'plugin' or 'CPU model' or whatever. Used in error messages only + std::string opt_name_; + +public: + explicit ModuleGroup(const std::string& kind) : kind_(kind) {} + + ModuleGroup& add(const char* id, const char* desc, std::function init); + Module const& by_name(const std::string& name) const; + void help() const; + const std::string& get_kind() const { return kind_; } + std::string existing_values() const; + void create_flag(const std::string& opt_name, const std::string& descr, const std::string& default_value, + bool init_now); + void init_from_flag_value() const; +}; + +}; // namespace simgrid + +#define SIMGRID_REGISTER_PLUGIN(id, desc, init) \ + static void XBT_ATTRIB_CONSTRUCTOR(800) _XBT_CONCAT3(simgrid_, id, _plugin_register)() \ + { \ + simgrid_plugins().add(_XBT_STRINGIFY(id), (desc), (init)); \ + } +/** @brief The list of all available plugins */ +inline auto& simgrid_plugins() // Function to avoid static initialization order fiasco +{ + static simgrid::ModuleGroup plugins("plugin"); + return plugins; +} + +#define SIMGRID_REGISTER_NETWORK_MODEL(id, desc, init) \ + static void XBT_ATTRIB_CONSTRUCTOR(800) _XBT_CONCAT3(simgrid_, id, _network_model_register)() \ + { \ + simgrid_network_models().add(_XBT_STRINGIFY(id), (desc), (init)); \ + } +/** @brief The list of all available network models (pick one with --cfg=network/model) */ +inline auto& simgrid_network_models() // Function to avoid static initialization order fiasco +{ + static simgrid::ModuleGroup models("network model"); + return models; +} + +#define SIMGRID_REGISTER_CPU_MODEL(id, desc, init) \ + static void XBT_ATTRIB_CONSTRUCTOR(800) _XBT_CONCAT3(simgrid_, id, _cpu_model_register)() \ + { \ + simgrid_cpu_models().add(_XBT_STRINGIFY(id), (desc), (init)); \ + } +/** @brief The list of all available CPU models (pick one with --cfg=cpu/model) */ +inline auto& simgrid_cpu_models() // Function to avoid static initialization order fiasco +{ + static simgrid::ModuleGroup models("CPU model"); + return models; +} + +#define SIMGRID_REGISTER_DISK_MODEL(id, desc, init) \ + static void XBT_ATTRIB_CONSTRUCTOR(800) _XBT_CONCAT3(simgrid_, id, _disk_model_register)() \ + { \ + simgrid_disk_models().add(_XBT_STRINGIFY(id), (desc), (init)); \ + } +/** @brief The list of all available disk models (pick one with --cfg=disk/model) */ +inline auto& simgrid_disk_models() // Function to avoid static initialization order fiasco +{ + static simgrid::ModuleGroup models("disk model"); + return models; +} + +#define SIMGRID_REGISTER_HOST_MODEL(id, desc, init) \ + static void XBT_ATTRIB_CONSTRUCTOR(800) _XBT_CONCAT3(simgrid_, id, _host_model_register)() \ + { \ + simgrid_host_models().add(_XBT_STRINGIFY(id), (desc), (init)); \ + } +/** @brief The list of all available host models (pick one with --cfg=host/model) */ +inline auto& simgrid_host_models() // Function to avoid static initialization order fiasco +{ + static simgrid::ModuleGroup models("host model"); + return models; +} + +XBT_PUBLIC void simgrid_vm_model_init_HL13(); + +#endif diff --git a/src/simgrid/sg_config.cpp b/src/simgrid/sg_config.cpp index e60efa33ba..5902d70865 100644 --- a/src/simgrid/sg_config.cpp +++ b/src/simgrid/sg_config.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,29 +8,31 @@ #include #include #include +#include -#include "simgrid/sg_config.hpp" #include "src/instr/instr_private.hpp" #include "src/internal_config.h" #include "src/kernel/context/Context.hpp" #include "src/kernel/lmm/maxmin.hpp" +#include "src/kernel/resource/NetworkModel.hpp" #include "src/mc/mc_config.hpp" #include "src/mc/mc_replay.hpp" +#include "src/simgrid/module.hpp" +#include "src/simgrid/sg_config.hpp" #include "src/smpi/include/smpi_config.hpp" -#include "src/surf/surf_interface.hpp" #include -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_config, surf, "About the configuration of SimGrid"); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(config, kernel, "About the configuration of SimGrid"); static simgrid::config::Flag cfg_continue_after_help {"help-nostop", "Do not stop the execution when --help is found", false}; /** @brief Allow other libraries to react to the --help flag, too * - * When finding --help on the command line, simgrid usually stops right after displaying its help message. - * If you are writing a library using simgrid, you may want to display your own help message before everything stops. - * If so, just call this function before having simgrid parsing the command line, and you will be given the control + * When finding --help on the command line, SimGrid usually stops right after displaying its help message. + * If you are writing a library using SimGrid, you may want to display your own help message before everything stops. + * If so, just call this function before having SimGrid parsing the command line, and you will be given the control * even if the user is asking for help. */ void sg_config_continue_after_help() @@ -91,15 +93,11 @@ static void sg_config_cmd_line(int *argc, char **argv) XBT_HELP("Please consider using the recent names"); shall_exit = true; } else if (parse_args && not strcmp(argv[i], "--help-models")) { - model_help("host", surf_host_model_description); + simgrid_host_models().help(); XBT_HELP("%s", ""); - model_help("CPU", surf_cpu_model_description); + simgrid_cpu_models().help(); XBT_HELP("%s", ""); - model_help("network", surf_network_model_description); - XBT_HELP("\nLong description of all optimization levels accepted by the models of this simulator:"); - for (auto const& item : surf_optimization_mode_description) - XBT_HELP(" %s: %s", item.name, item.description); - XBT_HELP("Both network and CPU models have 'Lazy' as default optimization level\n"); + simgrid_network_models().help(); shall_exit = true; } else if (parse_args && not strcmp(argv[i], "--help-tracing")) { TRACE_help(); @@ -116,121 +114,20 @@ static void sg_config_cmd_line(int *argc, char **argv) exit(0); } -/* callback of the plugin variable */ -static void _sg_cfg_cb__plugin(const std::string& value) -{ - xbt_assert(_sg_cfg_init_status < 2, "Cannot load a plugin after the initialization"); - - if (value.empty()) - return; - - if (value == "help") { - model_help("plugin", surf_plugin_description()); - exit(0); - } - - const auto* plugin = find_model_description(surf_plugin_description(), value); - plugin->model_init_preparse(); -} - -/* callback of the host/model variable */ -static void _sg_cfg_cb__host_model(const std::string& value) -{ - xbt_assert(_sg_cfg_init_status < 2, "Cannot change the model after the initialization"); - - if (value == "help") { - model_help("host", surf_host_model_description); - exit(0); - } - - /* Make sure that the model exists */ - find_model_description(surf_host_model_description, value); -} - -/* callback of the cpu/model variable */ -static void _sg_cfg_cb__cpu_model(const std::string& value) -{ - xbt_assert(_sg_cfg_init_status < 2, "Cannot change the model after the initialization"); - - if (value == "help") { - model_help("CPU", surf_cpu_model_description); - exit(0); - } - - /* New Module missing */ - find_model_description(surf_cpu_model_description, value); -} - -/* callback of the cpu/model variable */ -static void _sg_cfg_cb__optimization_mode(const std::string& value) -{ - xbt_assert(_sg_cfg_init_status < 2, "Cannot change the model after the initialization"); - - if (value == "help") { - model_help("optimization", surf_optimization_mode_description); - exit(0); - } - - /* New Module missing */ - find_model_description(surf_optimization_mode_description, value); -} - -static void _sg_cfg_cb__disk_model(const std::string& value) -{ - xbt_assert(_sg_cfg_init_status < 2, "Cannot change the model after the initialization"); - - if (value == "help") { - model_help("disk", surf_disk_model_description); - exit(0); - } - - find_model_description(surf_disk_model_description, value); -} - -/* callback of the network_model variable */ -static void _sg_cfg_cb__network_model(const std::string& value) -{ - xbt_assert(_sg_cfg_init_status < 2, "Cannot change the model after the initialization"); - - if (value == "help") { - model_help("network", surf_network_model_description); - exit(0); - } - - /* New Module missing */ - find_model_description(surf_network_model_description, value); -} - static void _sg_cfg_cb_contexts_parallel_mode(std::string_view mode_name) { if (mode_name == "posix") { - simgrid::kernel::context::set_parallel_mode(XBT_PARMAP_POSIX); + simgrid::kernel::context::Context::parallel_mode = XBT_PARMAP_POSIX; } else if (mode_name == "futex") { - simgrid::kernel::context::set_parallel_mode(XBT_PARMAP_FUTEX); + simgrid::kernel::context::Context::parallel_mode = XBT_PARMAP_FUTEX; } else if (mode_name == "busy_wait") { - simgrid::kernel::context::set_parallel_mode(XBT_PARMAP_BUSY_WAIT); + simgrid::kernel::context::Context::parallel_mode = XBT_PARMAP_BUSY_WAIT; } else { xbt_die("Command line setting of the parallel synchronization mode should " "be one of \"posix\", \"futex\" or \"busy_wait\""); } } -/* build description line with possible values */ -static void declare_model_flag(const std::string& name, const std::string& value, - const std::function& callback, - const std::vector& model_description, const std::string& type, - const std::string& descr) -{ - std::string description = descr + ". Possible values: "; - std::string sep = ""; - for (auto const& item : model_description) { - description += sep + item.name; - sep = ", "; - } - description += ".\n (use 'help' as a value to see the long description of each " + type + ")"; - simgrid::config::declare_flag(name, description, value, callback); -} - /* create the config set, register what should be and parse the command line*/ void sg_config_init(int *argc, char **argv) { @@ -239,29 +136,19 @@ void sg_config_init(int *argc, char **argv) XBT_WARN("Call to sg_config_init() after initialization ignored"); return; } + _sg_cfg_init_status = 1; - /* Plugins configuration */ - declare_model_flag("plugin", "", &_sg_cfg_cb__plugin, surf_plugin_description(), "plugin", "The plugins"); - - declare_model_flag("cpu/model", "Cas01", &_sg_cfg_cb__cpu_model, surf_cpu_model_description, "model", - "The model to use for the CPU"); - - declare_model_flag("disk/model", "default", &_sg_cfg_cb__disk_model, surf_disk_model_description, "model", - "The model to use for the disk"); - - declare_model_flag("network/model", "LV08", &_sg_cfg_cb__network_model, surf_network_model_description, "model", - "The model to use for the network"); - - declare_model_flag("network/optim", "Lazy", &_sg_cfg_cb__optimization_mode, surf_optimization_mode_description, - "optimization mode", "The optimization modes to use for the network"); - - declare_model_flag("host/model", "default", &_sg_cfg_cb__host_model, surf_host_model_description, "model", - "The model to use for the host"); + /* Plugins and models configuration */ + simgrid_plugins().create_flag("plugin", "The plugins", "", true); + simgrid_cpu_models().create_flag("cpu/model", "The model to use for the CPU", "Cas01", false); + simgrid_network_models().create_flag("network/model", "The model to use for the network", "LV08", false); + simgrid_host_models().create_flag("host/model", "The model to use for the host", "default", false); + simgrid_disk_models().create_flag("disk/model", "The model to use for the disk", "S19", false); - simgrid::config::bind_flag(sg_surf_precision, "surf/precision", + simgrid::config::bind_flag(sg_precision_timing, "precision/timing", {"surf/precision"}, "Numerical precision used when updating simulation times (in seconds)"); - simgrid::config::bind_flag(sg_maxmin_precision, "maxmin/precision", + simgrid::config::bind_flag(sg_precision_workamount, "precision/work-amount", {"maxmin/precision"}, "Numerical precision used when computing resource sharing (in flops/sec or bytes/sec)"); simgrid::config::bind_flag(sg_concurrency_limit, "maxmin/concurrency-limit", @@ -269,21 +156,6 @@ void sg_config_init(int *argc, char **argv) "processes on each host, at higher level. (default: -1 means no such limitation)"); /* The parameters of network models */ - - sg_latency_factor = 13.01; // comes from the default LV08 network model - simgrid::config::bind_flag(sg_latency_factor, "network/latency-factor", - "Correction factor to apply to the provided latency (default value set by network model)"); - - sg_bandwidth_factor = 0.97; // comes from the default LV08 network model - simgrid::config::bind_flag( - sg_bandwidth_factor, "network/bandwidth-factor", - "Correction factor to apply to the provided bandwidth (default value set by network model)"); - - sg_weight_S_parameter = 20537; // comes from the default LV08 network model - simgrid::config::bind_flag( - sg_weight_S_parameter, "network/weight-S", - "Correction factor to apply to the weight of competing streams (default value set by network model)"); - static simgrid::config::Flag _sg_network_loopback_latency{ "network/loopback-lat", "For network models with an implicit loopback link (L07, CM02, LV08), " @@ -298,9 +170,9 @@ void sg_config_init(int *argc, char **argv) /* Inclusion path */ static simgrid::config::Flag cfg_path{ - "path", "Lookup path for inclusions in platform and deployment XML files", "", [](std::string const& path) { + "path", "Lookup path for inclusions in platform and deployment XML files", "./", [](std::string const& path) { if (not path.empty()) - surf_path.push_back(path); + simgrid::xbt::path_push(path); }}; static simgrid::config::Flag cfg_cpu_maxmin_selective_update{ @@ -316,20 +188,21 @@ void sg_config_init(int *argc, char **argv) static simgrid::config::Flag cfg_context_stack_size{ "contexts/stack-size", "Stack size of contexts in KiB (not with threads)", 8 * 1024, - [](int value) { simgrid::kernel::context::stack_size = value * 1024; }}; + [](int value) { simgrid::kernel::context::Context::stack_size = value * 1024; }}; /* guard size for contexts stacks in memory pages */ -#if defined(_WIN32) || (PTH_STACKGROWTH != -1) +#if (PTH_STACKGROWTH != -1) int default_guard_size = 0; #else int default_guard_size = 1; #endif static simgrid::config::Flag cfg_context_guard_size{ "contexts/guard-size", "Guard size for contexts stacks in memory pages", default_guard_size, - [](int value) { simgrid::kernel::context::guard_size = value * xbt_pagesize; }}; - static simgrid::config::Flag cfg_context_nthreads{"contexts/nthreads", - "Number of parallel threads used to execute user contexts", 1, - &simgrid::kernel::context::set_nthreads}; + [](int value) { simgrid::kernel::context::Context::guard_size = value * xbt_pagesize; }}; + + static simgrid::config::Flag cfg_context_nthreads{ + "contexts/nthreads", "Number of parallel threads used to execute user contexts", 1, + [](int nthreads) { simgrid::kernel::context::Context::set_nthreads(nthreads); }}; /* synchronization mode for parallel user contexts */ #if HAVE_FUTEX_H @@ -343,18 +216,7 @@ void sg_config_init(int *argc, char **argv) default_synchro_mode, &_sg_cfg_cb_contexts_parallel_mode}; - // For smpi/bw-factor and smpi/lat-factor // SMPI model can be used without enable_smpi, so keep this out of the ifdef. - simgrid::config::declare_flag("smpi/bw-factor", - "Bandwidth factors for smpi. Format: " - "'threshold0:value0;threshold1:value1;...;thresholdN:valueN', " - "meaning if(size >=thresholdN ) return valueN.", - "65472:0.940694;15424:0.697866;9376:0.58729;5776:1.08739;3484:0.77493;" - "1426:0.608902;732:0.341987;257:0.338112;0:0.812084"); - - simgrid::config::declare_flag("smpi/lat-factor", "Latency factors for smpi.", - "65472:11.6436;15424:3.48845;9376:2.59299;5776:2.18796;3484:1.88101;" - "1426:1.61075;732:1.9503;257:1.95341;0:2.01467"); static simgrid::config::Flag cfg_smpi_IB_penalty_factors{ "smpi/IB-penalty-factors", "Correction factor to communications using Infiniband model with " @@ -365,14 +227,9 @@ void sg_config_init(int *argc, char **argv) static simgrid::config::Flag cfg_execution_cutpath{ "exception/cutpath", "Whether to cut all path information from call traces, used e.g. in exceptions.", false}; - if (surf_path.empty()) - simgrid::config::set_default("path", "./"); - - _sg_cfg_init_status = 1; - sg_config_cmd_line(argc, argv); - xbt_mallocator_initialization_is_done(simgrid::kernel::context::is_parallel()); + xbt_mallocator_initialization_is_done(simgrid::kernel::context::Context::is_parallel()); } void sg_config_finalize() diff --git a/src/include/simgrid/sg_config.hpp b/src/simgrid/sg_config.hpp similarity index 67% rename from src/include/simgrid/sg_config.hpp rename to src/simgrid/sg_config.hpp index df9e57d48e..25e4a168b2 100644 --- a/src/include/simgrid/sg_config.hpp +++ b/src/simgrid/sg_config.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,7 +10,7 @@ /** Config Globals */ -XBT_PUBLIC_DATA int _sg_cfg_init_status; +XBT_PUBLIC_DATA int _sg_cfg_init_status; /* 0: not inited; 1: config module inited; 2: root zone of platform created */ XBT_PUBLIC void sg_config_init(int* argc, char** argv); XBT_PUBLIC void sg_config_finalize(); diff --git a/src/simgrid/sg_version.cpp b/src/simgrid/sg_version.cpp index 3764e84566..953f6b1b49 100644 --- a/src/simgrid/sg_version.cpp +++ b/src/simgrid/sg_version.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,8 +9,6 @@ #include "xbt/misc.h" #include "xbt/sysdep.h" -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sg_version, surf, "About the versioning of SimGrid"); - void sg_version_check(int lib_version_major, int lib_version_minor, int lib_version_patch) { if ((lib_version_major != SIMGRID_VERSION_MAJOR) || (lib_version_minor != SIMGRID_VERSION_MINOR)) { @@ -52,12 +50,6 @@ void sg_version() XBT_HELP("This program was linked against %s (git: %s), found in %s.", SIMGRID_VERSION_STRING, SIMGRID_GIT_VERSION, SIMGRID_INSTALL_PREFIX); -#if SIMGRID_HAVE_MC - XBT_HELP(" Model-checking support compiled in."); -#else - XBT_HELP(" Model-checking support disabled at compilation."); -#endif - #if SIMGRID_HAVE_NS3 XBT_HELP(" ns-3 support compiled in."); #else diff --git a/src/simgrid/util.hpp b/src/simgrid/util.hpp index c12a9a477c..734b80b1ce 100644 --- a/src/simgrid/util.hpp +++ b/src/simgrid/util.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. +/* Copyright (c) 2015-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/simix/libsmx.cpp b/src/simix/libsmx.cpp deleted file mode 100644 index 4a2938abdb..0000000000 --- a/src/simix/libsmx.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* libsmx.c - public interface to simix */ -/* -------- */ -/* These functions are the only ones that are visible from the higher levels */ -/* (most of them simply add some documentation to the generated simcall body) */ -/* */ -/* This is somehow the "libc" of SimGrid */ - -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/kernel/EngineImpl.hpp" -#include "src/kernel/activity/CommImpl.hpp" -#include "src/kernel/actor/SimcallObserver.hpp" -#include - -#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v335) -#include - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ker_simcall); - -/** - * @ingroup simix_comm_management - */ -void simcall_comm_send(simgrid::kernel::actor::ActorImpl* sender, simgrid::kernel::activity::MailboxImpl* mbox, - double task_size, double rate, void* src_buff, size_t src_buff_size, - bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*), - void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, - double timeout) // XBT_ATTRIB_DEPRECATED_v335 -{ - xbt_assert(mbox, "No rendez-vous point defined for send"); - simgrid::s4u::Comm::send(sender, mbox->get_iface(), task_size, rate, src_buff, src_buff_size, match_fun, - copy_data_fun, data, timeout); -} - -/** - * @ingroup simix_comm_management - */ -simgrid::kernel::activity::ActivityImplPtr -simcall_comm_isend(simgrid::kernel::actor::ActorImpl* sender, simgrid::kernel::activity::MailboxImpl* mbox, - double task_size, double rate, void* src_buff, size_t src_buff_size, - bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*), void (*clean_fun)(void*), - void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, - bool detached) // XBT_ATTRIB_DEPRECATED_v335 -{ - /* checking for infinite values */ - xbt_assert(std::isfinite(task_size), "task_size is not finite!"); - xbt_assert(std::isfinite(rate), "rate is not finite!"); - - xbt_assert(mbox, "No rendez-vous point defined for isend"); - - simgrid::kernel::actor::CommIsendSimcall observer(sender, mbox, task_size, rate, - static_cast(src_buff), src_buff_size, match_fun, - clean_fun, copy_data_fun, data, detached); - return simgrid::kernel::actor::simcall_answered( - [&observer] { return simgrid::kernel::activity::CommImpl::isend(&observer); }); -} - -/** - * @ingroup simix_comm_management - */ -void simcall_comm_recv(simgrid::kernel::actor::ActorImpl* receiver, simgrid::kernel::activity::MailboxImpl* mbox, - void* dst_buff, size_t* dst_buff_size, - bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*), - void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, - double timeout, double rate) // XBT_ATTRIB_DEPRECATED_v335 -{ - xbt_assert(mbox, "No rendez-vous point defined for recv"); - simgrid::s4u::Comm::recv(receiver, mbox->get_iface(), dst_buff, dst_buff_size, match_fun, copy_data_fun, data, - timeout, rate); -} - -/** - * @ingroup simix_comm_management - */ -simgrid::kernel::activity::ActivityImplPtr -simcall_comm_irecv(simgrid::kernel::actor::ActorImpl* receiver, simgrid::kernel::activity::MailboxImpl* mbox, - void* dst_buff, size_t* dst_buff_size, - bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*), - void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, - double rate) // XBT_ATTRIB_DEPRECATED_v335 -{ - xbt_assert(mbox, "No rendez-vous point defined for irecv"); - - simgrid::kernel::actor::CommIrecvSimcall observer(receiver, mbox, static_cast(dst_buff), - dst_buff_size, match_fun, copy_data_fun, data, rate); - return simgrid::kernel::actor::simcall_answered( - [&observer] { return simgrid::kernel::activity::CommImpl::irecv(&observer); }); -} - -/** - * @ingroup simix_comm_management - */ -ssize_t simcall_comm_waitany(simgrid::kernel::activity::CommImpl* comms[], size_t count, - double timeout) // XBT_ATTRIB_DEPRECATED_v335 -{ - std::vector activities; - for (size_t i = 0; i < count; i++) - activities.push_back(static_cast(comms[i])); - simgrid::kernel::actor::ActorImpl* issuer = simgrid::kernel::actor::ActorImpl::self(); - simgrid::kernel::actor::ActivityWaitanySimcall observer{issuer, activities, timeout}; - ssize_t changed_pos = simgrid::kernel::actor::simcall_blocking( - [&observer] { - simgrid::kernel::activity::ActivityImpl::wait_any_for(observer.get_issuer(), observer.get_activities(), - observer.get_timeout()); - }, - &observer); - if (changed_pos != -1) - activities.at(changed_pos)->get_iface()->complete(simgrid::s4u::Activity::State::FINISHED); - return changed_pos; -} - -/** - * @ingroup simix_comm_management - */ -ssize_t simcall_comm_testany(simgrid::kernel::activity::CommImpl* comms[], size_t count) // XBT_ATTRIB_DEPRECATED_v335 -{ - if (count == 0) - return -1; - std::vector activities; - for (size_t i = 0; i < count; i++) - activities.push_back(static_cast(comms[i])); - - simgrid::kernel::actor::ActorImpl* issuer = simgrid::kernel::actor::ActorImpl::self(); - simgrid::kernel::actor::ActivityTestanySimcall observer{issuer, activities}; - ssize_t changed_pos = simgrid::kernel::actor::simcall_blocking( - [&observer] { - simgrid::kernel::activity::ActivityImpl::test_any(observer.get_issuer(), observer.get_activities()); - }, - &observer); - if (changed_pos != -1) - comms[changed_pos]->get_iface()->complete(simgrid::s4u::Activity::State::FINISHED); - return changed_pos; -} - -/** - * @ingroup simix_comm_management - */ -void simcall_comm_wait(simgrid::kernel::activity::ActivityImpl* comm, double timeout) // XBT_ATTRIB_DEPRECATED_v335 -{ - xbt_assert(std::isfinite(timeout), "timeout is not finite!"); - simgrid::kernel::actor::ActorImpl* issuer = simgrid::kernel::actor::ActorImpl::self(); - simgrid::kernel::actor::simcall_blocking([issuer, comm, timeout] { comm->wait_for(issuer, timeout); }); -} - -/** - * @ingroup simix_comm_management - * - */ -bool simcall_comm_test(simgrid::kernel::activity::ActivityImpl* comm) // XBT_ATTRIB_DEPRECATED_v335 -{ - simgrid::kernel::actor::ActorImpl* issuer = simgrid::kernel::actor::ActorImpl::self(); - simgrid::kernel::actor::ActivityTestSimcall observer{issuer, comm}; - if (simgrid::kernel::actor::simcall_blocking([&observer] { observer.get_activity()->test(observer.get_issuer()); }, - &observer)) { - comm->get_iface()->complete(simgrid::s4u::Activity::State::FINISHED); - return true; - } - return false; -} - -static void simcall(simgrid::kernel::actor::Simcall::Type call, std::function const& code, - simgrid::kernel::actor::SimcallObserver* observer) -{ - auto self = simgrid::kernel::actor::ActorImpl::self(); - self->simcall_.call_ = call; - self->simcall_.code_ = &code; - self->simcall_.observer_ = observer; - if (simgrid::kernel::EngineImpl::get_instance()->is_maestro(self)) { - self->simcall_handle(0); - } else { - XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), self->simcall_.get_cname()); - self->yield(); - } - self->simcall_.observer_ = nullptr; -} - -void simcall_run_answered(std::function const& code, simgrid::kernel::actor::SimcallObserver* observer) -{ - // The function `code` is called in kernel mode (either because we are already in maestor or after a context switch) - // and simcall_answer() is called - simcall(simgrid::kernel::actor::Simcall::Type::RUN_ANSWERED, code, observer); -} - -void simcall_run_blocking(std::function const& code, simgrid::kernel::actor::SimcallObserver* observer) -{ - // The function `code` is called in kernel mode (either because we are already in maestor or after a context switch) - // BUT simcall_answer IS NOT CALLED - simcall(simgrid::kernel::actor::Simcall::Type::RUN_BLOCKING, code, observer); -} diff --git a/src/simix/smx_context.cpp b/src/simix/smx_context.cpp deleted file mode 100644 index 86e1d7d339..0000000000 --- a/src/simix/smx_context.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* a fast and simple context switching library */ - -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/kernel/context/Context.hpp" - -#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v333) -#include - -int SIMIX_context_is_parallel() // XBT_ATTRIB_DEPRECATED_v333 -{ - return simgrid::kernel::context::is_parallel(); -} - -int SIMIX_context_get_nthreads() // XBT_ATTRIB_DEPRECATED_v333 -{ - return simgrid::kernel::context::get_nthreads(); -} - -void SIMIX_context_set_nthreads(int nb_threads) // XBT_ATTRIB_DEPRECATED_v333 -{ - simgrid::kernel::context::set_nthreads(nb_threads); -} - -e_xbt_parmap_mode_t SIMIX_context_get_parallel_mode() // XBT_ATTRIB_DEPRECATED_v333 -{ - return simgrid::kernel::context::get_parallel_mode(); -} - -void SIMIX_context_set_parallel_mode(e_xbt_parmap_mode_t mode) // XBT_ATTRIB_DEPRECATED_v333 -{ - simgrid::kernel::context::set_parallel_mode(mode); -} diff --git a/src/smpi/bindings/smpi_f77.cpp b/src/smpi/bindings/smpi_f77.cpp index 7a2578aa9a..33c9984bfb 100644 --- a/src/smpi/bindings/smpi_f77.cpp +++ b/src/smpi/bindings/smpi_f77.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -568,10 +568,8 @@ void mpi_op_commutative_(int* op, int* commute, int* ierr) void mpi_group_free_(int* group, int* ierr) { - if (MPI_Group tmp = simgrid::smpi::Group::f2c(*group); tmp != MPI_COMM_WORLD->group() && tmp != MPI_GROUP_EMPTY) { - simgrid::smpi::Group::unref(tmp); - } - *ierr = MPI_SUCCESS; + MPI_Group tmp = simgrid::smpi::Group::f2c(*group); + *ierr = MPI_Group_free(&tmp); } void mpi_group_size_(int* group, int* size, int* ierr) diff --git a/src/smpi/bindings/smpi_f77_coll.cpp b/src/smpi/bindings/smpi_f77_coll.cpp index d8730614bc..3679e5d22c 100644 --- a/src/smpi/bindings/smpi_f77_coll.cpp +++ b/src/smpi/bindings/smpi_f77_coll.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_f77_comm.cpp b/src/smpi/bindings/smpi_f77_comm.cpp index 7c1d7381bf..b3d9860778 100644 --- a/src/smpi/bindings/smpi_f77_comm.cpp +++ b/src/smpi/bindings/smpi_f77_comm.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_f77_file.cpp b/src/smpi/bindings/smpi_f77_file.cpp index 2ae8715ca7..34ef481a74 100644 --- a/src/smpi/bindings/smpi_f77_file.cpp +++ b/src/smpi/bindings/smpi_f77_file.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_f77_request.cpp b/src/smpi/bindings/smpi_f77_request.cpp index 6fe6914f18..e61c66c50e 100644 --- a/src/smpi/bindings/smpi_f77_request.cpp +++ b/src/smpi/bindings/smpi_f77_request.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_f77_type.cpp b/src/smpi/bindings/smpi_f77_type.cpp index 389f272ee0..79e531a0e5 100644 --- a/src/smpi/bindings/smpi_f77_type.cpp +++ b/src/smpi/bindings/smpi_f77_type.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_mpi.cpp b/src/smpi/bindings/smpi_mpi.cpp index 0144bc6420..4b9095c1d2 100644 --- a/src/smpi/bindings/smpi_mpi.cpp +++ b/src/smpi/bindings/smpi_mpi.cpp @@ -1,17 +1,22 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license ,(GNU LGPL) which comes with this package. */ #include "private.hpp" #include "simgrid/modelchecker.h" -#include "simgrid/sg_config.hpp" #include "smpi_comm.hpp" #include "smpi_file.hpp" #include "smpi_win.hpp" +#include "src/simgrid/sg_config.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi, smpi, "Logging specific to SMPI ,(mpi)"); +void MPI_Init() +{ + MPI_Init(nullptr, nullptr); +} + #define NOT_YET_IMPLEMENTED \ { \ xbt_die("Not yet implemented: %s. Please contact the SimGrid team if support is needed", __func__); \ @@ -26,13 +31,13 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi, smpi, "Logging specific to SMPI ,(mpi) #define NOT_YET_IMPLEMENTED_NOFAIL \ { \ - static bool warning_todo = true; \ - if (warning_todo) \ + if (static bool warned_todo = false; not warned_todo) { \ XBT_WARN("Not yet implemented: %s. " \ "Please contact the SimGrid team if support is needed. " \ "Run with --log=smpi_mpi.thresh:error to hide", \ __func__); \ - warning_todo = false; \ + warned_todo = true; \ + } \ return MPI_SUCCESS; \ } @@ -253,7 +258,9 @@ WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Scatter,(const void *sendbuf, int send WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Scatterv,(const void *sendbuf, const int *sendcounts, const int *displs, MPI_Datatype sendtype, void *recvbuf, int recvcount,MPI_Datatype recvtype, int root, MPI_Comm comm),(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm)) WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Send_init,(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request),(buf, count, datatype, dst, tag, comm, request)) WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Sendrecv_replace,(void *buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag,MPI_Comm comm, MPI_Status * status),(buf, count, datatype, dst, sendtag, src, recvtag, comm, status)) +WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Isendrecv_replace,(void *buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag,MPI_Comm comm, MPI_Request* req),(buf, count, datatype, dst, sendtag, src, recvtag, comm, req)) WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Sendrecv,(const void *sendbuf, int sendcount, MPI_Datatype sendtype,int dst, int sendtag, void *recvbuf, int recvcount,MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status * status),(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag,comm, status)) +WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Isendrecv,(const void *sendbuf, int sendcount, MPI_Datatype sendtype,int dst, int sendtag, void *recvbuf, int recvcount,MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Request* req),(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag,comm, req)) WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Send,(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm),(buf, count, datatype, dst, tag, comm)) WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Ssend_init,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request),(buf, count, datatype, dest, tag, comm, request)) WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Ssend,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) ,(buf, count, datatype, dest, tag, comm)) @@ -395,6 +402,10 @@ WRAPPED_PMPI_CALL_ERRHANDLER_FILE(int, MPI_File_set_errhandler,( MPI_File fh, MP WRAPPED_PMPI_CALL_ERRHANDLER_FILE(int, MPI_File_get_errhandler,( MPI_File fh, MPI_Errhandler *errhandler), (fh, errhandler)) WRAPPED_PMPI_CALL_ERRHANDLER_FILE(int, MPI_File_set_view,(MPI_File fh, MPI_Offset disp, MPI_Datatype etype, MPI_Datatype filetype, const char *datarep, MPI_Info info), (fh, disp, etype, filetype, datarep, info)) WRAPPED_PMPI_CALL_ERRHANDLER_FILE(int, MPI_File_get_view,(MPI_File fh, MPI_Offset *disp, MPI_Datatype *etype, MPI_Datatype *filetype, char *datarep), (fh, disp, etype, filetype, datarep)) +WRAPPED_PMPI_CALL_ERRHANDLER_FILE(int, MPI_File_get_type_extent,(MPI_File fh, MPI_Datatype datatype, MPI_Aint *extent), (fh, datatype, extent)) +WRAPPED_PMPI_CALL_ERRHANDLER_FILE(int, MPI_File_set_atomicity,(MPI_File fh, int flag), (fh, flag)) +WRAPPED_PMPI_CALL_ERRHANDLER_FILE(int, MPI_File_get_atomicity,(MPI_File fh, int *flag), (fh, flag)) +WRAPPED_PMPI_CALL_ERRHANDLER_FILE(int, MPI_File_get_byte_offset,(MPI_File fh, MPI_Offset offset, MPI_Offset *disp), (fh, offset, disp)) /* Unimplemented Calls - both PMPI and MPI calls are generated. When implementing, please move ahead, swap UNIMPLEMENTED_WRAPPED_PMPI_CALL for WRAPPED_PMPI_CALL, @@ -433,7 +444,6 @@ UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_iread,(MPI_File fh, void *buf, int UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_iwrite,(MPI_File fh, const void *buf, int count, MPI_Datatype datatype, MPI_Request *request), (fh, buf, count, datatype, request)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_iread_all,(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Request *request), (fh, buf, count, datatype, request)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_iwrite_all,(MPI_File fh, const void *buf, int count, MPI_Datatype datatype, MPI_Request *request), (fh, buf, count, datatype, request)) -UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_get_byte_offset,(MPI_File fh, MPI_Offset offset, MPI_Offset *disp), (fh, offset, disp)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_iread_shared,(MPI_File fh, void *buf, int count,MPI_Datatype datatype, MPI_Request *request), (fh, buf, count, datatype, request)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_iwrite_shared,(MPI_File fh, const void *buf, int count, MPI_Datatype datatype, MPI_Request *request), (fh, buf, count, datatype, request)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_read_at_all_begin,(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype), (fh, offset, buf, count, datatype)) @@ -448,9 +458,6 @@ UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_read_ordered_begin,(MPI_File fh, v UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_read_ordered_end,(MPI_File fh, void *buf, MPI_Status *status), (fh, buf, status)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_write_ordered_begin,(MPI_File fh, const void *buf, int count, MPI_Datatype datatype), (fh, buf, count, datatype)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_write_ordered_end,(MPI_File fh, const void *buf, MPI_Status *status), (fh, buf, status)) -UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_get_type_extent,(MPI_File fh, MPI_Datatype datatype, MPI_Aint *extent), (fh, datatype, extent)) -UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_set_atomicity,(MPI_File fh, int flag), (fh, flag)) -UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_File_get_atomicity,(MPI_File fh, int *flag), (fh, flag)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Get_elements,(MPI_Status* status, MPI_Datatype datatype, int* elements) ,(status, datatype, elements)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Get_elements_x,(MPI_Status* status, MPI_Datatype datatype, MPI_Count* elements) ,(status, datatype, elements)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Graph_create,(MPI_Comm comm_old, int nnodes, const int* index, const int* edges, int reorder, MPI_Comm* comm_graph) ,(comm_old, nnodes, index, edges, reorder, comm_graph)) @@ -496,3 +503,9 @@ UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Unpack_external,(char *datarep, void *in UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Unpublish_name,( char *service_name, MPI_Info info, char *port_name),( service_name, info, port_name)) UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Win_test,(MPI_Win win, int *flag),(win, flag)) UNIMPLEMENTED_WRAPPED_PMPI_CALL_NOFAIL(int,MPI_Win_sync,(MPI_Win win),(win)) +UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Parrived, (MPI_Request request, int partition, int *flag), (request, partition, flag)) +UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Pready, (int partitions, MPI_Request request), (partitions, request)) +UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Pready_range, (int partition_low, int partition_high, MPI_Request request),(partition_low, partition_high, request)) +UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Pready_list, (int length, int partition_list[], MPI_Request request), (length, partition_list, request)) +UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Precv_init, (void* buf, int partitions, MPI_Count count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Info info, MPI_Request *request), (buf, partitions, count, datatype, source, tag, comm, info, request)) +UNIMPLEMENTED_WRAPPED_PMPI_CALL(int, MPI_Psend_init, (const void* buf, int partitions, MPI_Count count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Info info, MPI_Request *request), (buf, partitions, count, datatype, dest, tag, comm, info, request)) diff --git a/src/smpi/bindings/smpi_pmpi.cpp b/src/smpi/bindings/smpi_pmpi.cpp index ef203b059b..93dca485d6 100644 --- a/src/smpi/bindings/smpi_pmpi.cpp +++ b/src/smpi/bindings/smpi_pmpi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -71,7 +71,7 @@ int PMPI_Finalize() smpi_process()->mark_as_finalizing(); TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::NoOpTIData("finalize")); - if(simgrid::config::get_value("smpi/finalization-barrier")) + if (simgrid::config::get_value("smpi/barrier-finalization")) simgrid::smpi::colls::barrier(MPI_COMM_WORLD); smpi_process()->finalize(); @@ -93,7 +93,7 @@ int PMPI_Get_version (int *version,int *subversion){ } int PMPI_Get_library_version (char *version,int *len){ - snprintf(version, MPI_MAX_LIBRARY_VERSION_STRING, "SMPI Version %d.%d. Copyright The SimGrid Team 2007-2022", + snprintf(version, MPI_MAX_LIBRARY_VERSION_STRING, "SMPI Version %d.%d. Copyright The SimGrid Team 2007-2023", SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR); *len = std::min(static_cast(strlen(version)), MPI_MAX_LIBRARY_VERSION_STRING); return MPI_SUCCESS; @@ -136,9 +136,9 @@ int PMPI_Abort(MPI_Comm comm, int /*errorcode*/) smpi_bench_end(); CHECK_COMM(1) XBT_WARN("MPI_Abort was called, something went probably wrong in this simulation ! Killing all processes sharing the same MPI_COMM_WORLD"); - auto myself = simgrid::kernel::actor::ActorImpl::self(); + auto* myself = simgrid::kernel::actor::ActorImpl::self(); for (int i = 0; i < comm->size(); i++){ - auto actor = simgrid::kernel::EngineImpl::get_instance()->get_actor_by_pid(comm->group()->actor(i)); + auto* actor = simgrid::kernel::EngineImpl::get_instance()->get_actor_by_pid(comm->group()->actor(i)); if (actor != nullptr && actor != myself) simgrid::kernel::actor::simcall_answered([actor] { actor->exit(); }); } @@ -152,10 +152,10 @@ double PMPI_Wtime() return smpi_mpi_wtime(); } -extern double sg_maxmin_precision; +extern double sg_precision_timing; double PMPI_Wtick() { - return sg_maxmin_precision; + return sg_precision_timing; } int PMPI_Address(const void* location, MPI_Aint* address) @@ -188,7 +188,7 @@ MPI_Aint PMPI_Aint_diff(MPI_Aint address, MPI_Aint disp) int PMPI_Get_processor_name(char *name, int *resultlen) { int len = std::min(static_cast(sg_host_self()->get_name().size()), MPI_MAX_PROCESSOR_NAME - 1); - std::string(sg_host_self()->get_name()).copy(name, len); + sg_host_self()->get_name().copy(name, len); name[len] = '\0'; *resultlen = len; diff --git a/src/smpi/bindings/smpi_pmpi_coll.cpp b/src/smpi/bindings/smpi_pmpi_coll.cpp index 5915270a67..7e613a5b63 100644 --- a/src/smpi/bindings/smpi_pmpi_coll.cpp +++ b/src/smpi/bindings/smpi_pmpi_coll.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -76,6 +76,10 @@ int PMPI_Ibcast(void* buf, int count, MPI_Datatype datatype, int root, MPI_Comm new simgrid::instr::CollTIData(request == MPI_REQUEST_IGNORED ? "bcast" : "ibcast", root, -1.0, count, 0, simgrid::smpi::Datatype::encode(datatype), "")); + if (simgrid::config::get_value("smpi/barrier-collectives") && + request == MPI_REQUEST_IGNORED) // No barrier in Ibcast + smpi_deployment_startup_barrier(smpi_process()->get_instance_id()); + if (comm->size() > 1) { if (request == MPI_REQUEST_IGNORED) simgrid::smpi::colls::bcast(buf, count, datatype, root, comm); @@ -117,7 +121,7 @@ int PMPI_Igather(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void } CHECK_ROOT(7) CHECK_REQUEST(9) - CHECK_COLLECTIVE(comm, std::string(request == MPI_REQUEST_IGNORED ? "PMPI_Gather" : "PMPI_Igather") + +" with root " + + CHECK_COLLECTIVE(comm, std::string(request == MPI_REQUEST_IGNORED ? "PMPI_Gather" : "PMPI_Igather") + " with root " + std::to_string(root)) const void* real_sendbuf = sendbuf; @@ -135,6 +139,10 @@ int PMPI_Igather(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void const SmpiBenchGuard suspend_bench; + if (simgrid::config::get_value("smpi/barrier-collectives") && + request == MPI_REQUEST_IGNORED) // no barrier in Igather + smpi_deployment_startup_barrier(smpi_process()->get_instance_id()); + aid_t pid = simgrid::s4u::this_actor::get_pid(); TRACE_smpi_comm_in(pid, request == MPI_REQUEST_IGNORED ? "PMPI_Gather" : "PMPI_Igather", @@ -190,6 +198,11 @@ int PMPI_Igatherv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, voi } const SmpiBenchGuard suspend_bench; + + if (simgrid::config::get_value("smpi/barrier-collectives") && + request == MPI_REQUEST_IGNORED) // no barrier in Igatherv + smpi_deployment_startup_barrier(smpi_process()->get_instance_id()); + const void* real_sendbuf = sendbuf; int real_sendcount = sendcount; MPI_Datatype real_sendtype = sendtype; @@ -306,6 +319,7 @@ int PMPI_Iallgatherv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, CHECK_COLLECTIVE(comm, MPI_REQUEST_IGNORED ? "PMPI_Allgatherv" : "PMPI_Iallgatherv") const SmpiBenchGuard suspend_bench; + if (sendbuf == MPI_IN_PLACE) { sendbuf = static_cast(recvbuf) + recvtype->get_extent() * displs[comm->rank()]; sendcount = recvcounts[comm->rank()]; @@ -374,6 +388,10 @@ int PMPI_Iscatter(const void* sendbuf, int sendcount, MPI_Datatype sendtype, voi const SmpiBenchGuard suspend_bench; + if (simgrid::config::get_value("smpi/barrier-collectives") && + request == MPI_REQUEST_IGNORED) // no barrier in Iscatter + smpi_deployment_startup_barrier(smpi_process()->get_instance_id()); + aid_t pid = simgrid::s4u::this_actor::get_pid(); TRACE_smpi_comm_in(pid, request == MPI_REQUEST_IGNORED ? "PMPI_Scatter" : "PMPI_Iscatter", @@ -430,6 +448,10 @@ int PMPI_Iscatterv(const void* sendbuf, const int* sendcounts, const int* displs const SmpiBenchGuard suspend_bench; + if (simgrid::config::get_value("smpi/barrier-collectives") && + request == MPI_REQUEST_IGNORED) // no barrier in Iscatterv + smpi_deployment_startup_barrier(smpi_process()->get_instance_id()); + aid_t pid = simgrid::s4u::this_actor::get_pid(); auto trace_sendcounts = std::make_shared>(); @@ -480,6 +502,11 @@ int PMPI_Ireduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype dat op->name() + " and root " + std::to_string(root)) const SmpiBenchGuard suspend_bench; + + if (simgrid::config::get_value("smpi/barrier-collectives") && + request == MPI_REQUEST_IGNORED) // no barrier in Ireduce + smpi_deployment_startup_barrier(smpi_process()->get_instance_id()); + aid_t pid = simgrid::s4u::this_actor::get_pid(); TRACE_smpi_comm_in(pid, request == MPI_REQUEST_IGNORED ? "PMPI_Reduce" : "PMPI_Ireduce", @@ -532,6 +559,7 @@ int PMPI_Iallreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype " with op " + op->name()) const SmpiBenchGuard suspend_bench; + std::vector tmp_sendbuf; const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, count, datatype); @@ -571,6 +599,11 @@ int PMPI_Iscan(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datat std::string(request == MPI_REQUEST_IGNORED ? "PMPI_Scan" : "PMPI_Iscan") + " with op " + op->name()) const SmpiBenchGuard suspend_bench; + + if (simgrid::config::get_value("smpi/barrier-collectives") && + request == MPI_REQUEST_IGNORED) // no barrier in Iscan + smpi_deployment_startup_barrier(smpi_process()->get_instance_id()); + aid_t pid = simgrid::s4u::this_actor::get_pid(); std::vector tmp_sendbuf; const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, count, datatype); @@ -608,6 +641,11 @@ int PMPI_Iexscan(const void *sendbuf, void *recvbuf, int count, MPI_Datatype dat op->name()) const SmpiBenchGuard suspend_bench; + + if (simgrid::config::get_value("smpi/barrier-collectives") && + request == MPI_REQUEST_IGNORED) // no barrier in Iexscan + smpi_deployment_startup_barrier(smpi_process()->get_instance_id()); + aid_t pid = simgrid::s4u::this_actor::get_pid(); std::vector tmp_sendbuf; const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, count, datatype); @@ -651,6 +689,7 @@ int PMPI_Ireduce_scatter(const void *sendbuf, void *recvbuf, const int *recvcoun " with op " + op->name()) const SmpiBenchGuard suspend_bench; + aid_t pid = simgrid::s4u::this_actor::get_pid(); auto trace_recvcounts = std::make_shared>(); trace_recvcounts->insert(trace_recvcounts->end(), &recvcounts[0], &recvcounts[comm->size()]); @@ -700,6 +739,7 @@ int PMPI_Ireduce_scatter_block(const void* sendbuf, void* recvbuf, int recvcount " with op " + op->name()) const SmpiBenchGuard suspend_bench; + int count = comm->size(); aid_t pid = simgrid::s4u::this_actor::get_pid(); @@ -819,6 +859,7 @@ int PMPI_Ialltoallv(const void* sendbuf, const int* sendcounts, const int* sendd } const SmpiBenchGuard suspend_bench; + int send_size = 0; int recv_size = 0; auto trace_sendcounts = std::make_shared>(); diff --git a/src/smpi/bindings/smpi_pmpi_comm.cpp b/src/smpi/bindings/smpi_pmpi_comm.cpp index 4416bfe208..c30dfda3e9 100644 --- a/src/smpi/bindings/smpi_pmpi_comm.cpp +++ b/src/smpi/bindings/smpi_pmpi_comm.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,9 +6,10 @@ #include #include "private.hpp" +#include "simgrid/s4u/Engine.hpp" #include "smpi_comm.hpp" -#include "smpi_info.hpp" #include "smpi_errhandler.hpp" +#include "smpi_info.hpp" #include "src/smpi/include/smpi_actor.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi); @@ -248,7 +249,7 @@ int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) { return MPI_SUCCESS; case MPI_UNIVERSE_SIZE: *flag = 1; - universe_size = smpi_get_universe_size(); + universe_size = simgrid::s4u::Engine::get_instance()->get_host_count(); *static_cast(attr_value) = &universe_size; return MPI_SUCCESS; case MPI_LASTUSEDCODE: diff --git a/src/smpi/bindings/smpi_pmpi_file.cpp b/src/smpi/bindings/smpi_pmpi_file.cpp index e87680f94b..bf7d6ff1b4 100644 --- a/src/smpi/bindings/smpi_pmpi_file.cpp +++ b/src/smpi/bindings/smpi_pmpi_file.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -65,7 +65,7 @@ int PMPI_File_close(MPI_File *fh){ int PMPI_File_seek(MPI_File fh, MPI_Offset offset, int whence){ CHECK_FILE(1, fh) const SmpiBenchGuard suspend_bench; - int ret = fh->seek(offset,whence); + int ret = fh->seek(offset*fh->etype()->get_extent(),whence); return ret; } @@ -73,7 +73,7 @@ int PMPI_File_seek_shared(MPI_File fh, MPI_Offset offset, int whence){ CHECK_FILE(1, fh) CHECK_COLLECTIVE(fh->comm(), __func__) const SmpiBenchGuard suspend_bench; - int ret = fh->seek_shared(offset,whence); + int ret = fh->seek_shared(offset*fh->etype()->get_extent(),whence); return ret; } @@ -200,9 +200,12 @@ int PMPI_File_read_at(MPI_File fh, MPI_Offset offset, void *buf, int count,MPI_D const SmpiBenchGuard suspend_bench; aid_t rank_traced = simgrid::s4u::this_actor::get_pid(); TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - read", count * datatype->size())); + MPI_Offset prev; + fh->get_position(&prev); int ret = fh->seek(offset,MPI_SEEK_SET); if (ret == MPI_SUCCESS) ret = simgrid::smpi::File::read(fh, buf, count, datatype, status); + fh->seek(prev,MPI_SEEK_SET); TRACE_smpi_comm_out(rank_traced); return ret; } @@ -215,9 +218,12 @@ int PMPI_File_read_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count,M aid_t rank_traced = simgrid::s4u::this_actor::get_pid(); TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - read_at_all", count * datatype->size())); + MPI_Offset prev; + fh->get_position(&prev); int ret = fh->seek(offset,MPI_SEEK_SET); if (ret == MPI_SUCCESS) ret = fh->op_all(buf, count, datatype, status); + fh->seek(prev,MPI_SEEK_SET); TRACE_smpi_comm_out(rank_traced); return ret; } @@ -229,9 +235,12 @@ int PMPI_File_write_at(MPI_File fh, MPI_Offset offset, const void *buf, int coun const SmpiBenchGuard suspend_bench; aid_t rank_traced = simgrid::s4u::this_actor::get_pid(); TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - write", count * datatype->size())); + MPI_Offset prev; + fh->get_position(&prev); int ret = fh->seek(offset,MPI_SEEK_SET); if (ret == MPI_SUCCESS) ret = simgrid::smpi::File::write(fh, const_cast(buf), count, datatype, status); + fh->seek(prev,MPI_SEEK_SET); TRACE_smpi_comm_out(rank_traced); return ret; } @@ -244,16 +253,18 @@ int PMPI_File_write_at_all(MPI_File fh, MPI_Offset offset, const void *buf, int aid_t rank_traced = simgrid::s4u::this_actor::get_pid(); TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - write_at_all", count * datatype->size())); + MPI_Offset prev; + fh->get_position(&prev); int ret = fh->seek(offset,MPI_SEEK_SET); if (ret == MPI_SUCCESS) ret = fh->op_all(const_cast(buf), count, datatype, status); + fh->seek(prev,MPI_SEEK_SET); TRACE_smpi_comm_out(rank_traced); return ret; } int PMPI_File_delete(const char *filename, MPI_Info info){ - if (filename == nullptr) - return MPI_ERR_FILE; + CHECK_NULL(1, MPI_ERR_FILE, filename) const SmpiBenchGuard suspend_bench; int ret = simgrid::smpi::File::del(filename, info); return ret; @@ -359,11 +370,37 @@ int PMPI_File_set_errhandler(MPI_File file, MPI_Errhandler errhandler){ } int PMPI_File_call_errhandler(MPI_File file,int errorcode){ - if (file == nullptr) { - return MPI_ERR_WIN; - } + CHECK_FILE(1, file) MPI_Errhandler err = file->errhandler(); err->call(file, errorcode); simgrid::smpi::Errhandler::unref(err); return MPI_SUCCESS; } + +int PMPI_File_get_type_extent(MPI_File fh, MPI_Datatype + datatype, MPI_Aint *extent){ + CHECK_FILE(1, fh) + CHECK_TYPE(2, datatype) + CHECK_NULL(3, MPI_ERR_OTHER, extent) + *extent = datatype->get_extent(); + return MPI_SUCCESS; +} + +int PMPI_File_set_atomicity(MPI_File fh, int a){ + CHECK_FILE(1, fh) + fh->set_atomicity(a != 0); + return MPI_SUCCESS; +} + +int PMPI_File_get_atomicity(MPI_File fh, int* a){ + CHECK_FILE(1, fh) + *a = fh->get_atomicity(); + return MPI_SUCCESS; +} + +int PMPI_File_get_byte_offset(MPI_File fh, MPI_Offset offset, MPI_Offset *disp){ + CHECK_FILE(1, fh) + CHECK_NULL(3, MPI_ERR_OTHER, disp) + *disp = offset * fh->etype()->get_extent(); + return MPI_SUCCESS; +} diff --git a/src/smpi/bindings/smpi_pmpi_group.cpp b/src/smpi/bindings/smpi_pmpi_group.cpp index b85685bde1..43733df943 100644 --- a/src/smpi/bindings/smpi_pmpi_group.cpp +++ b/src/smpi/bindings/smpi_pmpi_group.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_pmpi_info.cpp b/src/smpi/bindings/smpi_pmpi_info.cpp index 984d658398..8784a77d9b 100644 --- a/src/smpi/bindings/smpi_pmpi_info.cpp +++ b/src/smpi/bindings/smpi_pmpi_info.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_pmpi_op.cpp b/src/smpi/bindings/smpi_pmpi_op.cpp index 9d2998b62d..e693e10939 100644 --- a/src/smpi/bindings/smpi_pmpi_op.cpp +++ b/src/smpi/bindings/smpi_pmpi_op.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_pmpi_request.cpp b/src/smpi/bindings/smpi_pmpi_request.cpp index 96bb98b03e..0dc9e32f21 100644 --- a/src/smpi/bindings/smpi_pmpi_request.cpp +++ b/src/smpi/bindings/smpi_pmpi_request.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -381,6 +381,8 @@ int PMPI_Sendrecv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, int CHECK_TYPE(8, recvtype) CHECK_BUFFER(1, sendbuf, sendcount, sendtype) CHECK_BUFFER(6, recvbuf, recvcount, recvtype) + CHECK_ARGS(sendbuf == recvbuf && sendcount > 0 && recvcount > 0, MPI_ERR_BUFFER, + "%s: Invalid parameters 1 and 6: sendbuf and recvbuf must be disjoint", __func__) CHECK_TAG(10, recvtag) CHECK_COMM(11) const SmpiBenchGuard suspend_bench; @@ -427,6 +429,66 @@ int PMPI_Sendrecv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, int return retval; } +int PMPI_Isendrecv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf, + int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Request* request) +{ + int retval = 0; + SET_BUF1(sendbuf) + SET_BUF2(recvbuf) + CHECK_COUNT(2, sendcount) + CHECK_TYPE(3, sendtype) + CHECK_TAG(5, sendtag) + CHECK_COUNT(7, recvcount) + CHECK_TYPE(8, recvtype) + CHECK_BUFFER(1, sendbuf, sendcount, sendtype) + CHECK_BUFFER(6, recvbuf, recvcount, recvtype) + CHECK_ARGS(sendbuf == recvbuf && sendcount > 0 && recvcount > 0, MPI_ERR_BUFFER, + "%s: Invalid parameters 1 and 6: sendbuf and recvbuf must be disjoint", __func__) + CHECK_TAG(10, recvtag) + CHECK_COMM(11) + CHECK_REQUEST(12) + *request = MPI_REQUEST_NULL; + const SmpiBenchGuard suspend_bench; + + if (src == MPI_PROC_NULL && dst != MPI_PROC_NULL){ + *request=simgrid::smpi::Request::isend(sendbuf, sendcount, sendtype, dst, sendtag, comm); + retval = MPI_SUCCESS; + } else if (dst == MPI_PROC_NULL){ + *request = simgrid::smpi::Request::irecv(recvbuf, recvcount, recvtype, src, recvtag, comm); + retval = MPI_SUCCESS; + } else if (dst >= comm->group()->size() || dst <0 || + (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0))){ + retval = MPI_ERR_RANK; + } else { + aid_t my_proc_id = simgrid::s4u::this_actor::get_pid(); + aid_t dst_traced = MPI_COMM_WORLD->group()->rank(getPid(comm, dst)); + aid_t src_traced = MPI_COMM_WORLD->group()->rank(getPid(comm, src)); + + // FIXME: Hack the way to trace this one + auto dst_hack = std::make_shared>(); + auto src_hack = std::make_shared>(); + dst_hack->push_back(dst_traced); + src_hack->push_back(src_traced); + TRACE_smpi_comm_in(my_proc_id, __func__, + new simgrid::instr::VarCollTIData( + "isendRecv", -1, sendcount, + dst_hack, recvcount, src_hack, + simgrid::smpi::Datatype::encode(sendtype), simgrid::smpi::Datatype::encode(recvtype))); + + TRACE_smpi_send(my_proc_id, my_proc_id, dst_traced, sendtag, sendcount * sendtype->size()); + + simgrid::smpi::Request::isendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, + recvtag, comm, request); + retval = MPI_SUCCESS; + + TRACE_smpi_recv(src_traced, my_proc_id, recvtag); + TRACE_smpi_comm_out(my_proc_id); + } + + return retval; +} + + int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag, MPI_Comm comm, MPI_Status* status) { @@ -437,7 +499,10 @@ int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, CHECK_BUFFER(1, buf, count, datatype) int size = datatype->get_extent() * count; - xbt_assert(size > 0); + if (size == 0) + return MPI_SUCCESS; + else if (size <0) + return MPI_ERR_ARG; std::vector recvbuf(size); retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf.data(), count, datatype, src, recvtag, comm, status); @@ -447,6 +512,29 @@ int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, return retval; } +int PMPI_Isendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag, + MPI_Comm comm, MPI_Request* request) +{ + int retval = 0; + SET_BUF1(buf) + CHECK_COUNT(2, count) + CHECK_TYPE(3, datatype) + CHECK_BUFFER(1, buf, count, datatype) + CHECK_REQUEST(10) + *request = MPI_REQUEST_NULL; + + int size = datatype->get_extent() * count; + if (size == 0) + return MPI_SUCCESS; + else if (size <0) + return MPI_ERR_ARG; + std::vector sendbuf(size); + simgrid::smpi::Datatype::copy(buf, count, datatype, sendbuf.data(), count, datatype); + retval = + MPI_Isendrecv(sendbuf.data(), count, datatype, dst, sendtag, buf, count, datatype, src, recvtag, comm, request); + return retval; +} + int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status) { int retval = 0; diff --git a/src/smpi/bindings/smpi_pmpi_topo.cpp b/src/smpi/bindings/smpi_pmpi_topo.cpp index 9198240cdc..0bbda74969 100644 --- a/src/smpi/bindings/smpi_pmpi_topo.cpp +++ b/src/smpi/bindings/smpi_pmpi_topo.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_pmpi_type.cpp b/src/smpi/bindings/smpi_pmpi_type.cpp index bf1f43d468..ad08e3c43f 100644 --- a/src/smpi/bindings/smpi_pmpi_type.cpp +++ b/src/smpi/bindings/smpi_pmpi_type.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/bindings/smpi_pmpi_win.cpp b/src/smpi/bindings/smpi_pmpi_win.cpp index cd03d889a0..a125ec9b0f 100644 --- a/src/smpi/bindings/smpi_pmpi_win.cpp +++ b/src/smpi/bindings/smpi_pmpi_win.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -107,7 +107,9 @@ int PMPI_Win_free( MPI_Win* win){ return MPI_ERR_WIN; } const SmpiBenchGuard suspend_bench; - return simgrid::smpi::Win::del(*win); + simgrid::smpi::Win::del(*win); + *win = MPI_WIN_NULL; + return MPI_SUCCESS; } int PMPI_Win_set_name(MPI_Win win, const char * name) diff --git a/src/smpi/colls/allgather/allgather-2dmesh.cpp b/src/smpi/colls/allgather/allgather-2dmesh.cpp index 94d5507d73..54b7d745bc 100644 --- a/src/smpi/colls/allgather/allgather-2dmesh.cpp +++ b/src/smpi/colls/allgather/allgather-2dmesh.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-3dmesh.cpp b/src/smpi/colls/allgather/allgather-3dmesh.cpp index c1c94d5a0d..6cfa9dc83c 100644 --- a/src/smpi/colls/allgather/allgather-3dmesh.cpp +++ b/src/smpi/colls/allgather/allgather-3dmesh.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-GB.cpp b/src/smpi/colls/allgather/allgather-GB.cpp index b99d9dfdaa..18f7a4786c 100644 --- a/src/smpi/colls/allgather/allgather-GB.cpp +++ b/src/smpi/colls/allgather/allgather-GB.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-NTSLR-NB.cpp b/src/smpi/colls/allgather/allgather-NTSLR-NB.cpp index dbf78e3bd5..ff3527877c 100644 --- a/src/smpi/colls/allgather/allgather-NTSLR-NB.cpp +++ b/src/smpi/colls/allgather/allgather-NTSLR-NB.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-NTSLR.cpp b/src/smpi/colls/allgather/allgather-NTSLR.cpp index 782f72bf6b..ba60275822 100644 --- a/src/smpi/colls/allgather/allgather-NTSLR.cpp +++ b/src/smpi/colls/allgather/allgather-NTSLR.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-SMP-NTS.cpp b/src/smpi/colls/allgather/allgather-SMP-NTS.cpp index 2656955e5d..8a08fe8a8a 100644 --- a/src/smpi/colls/allgather/allgather-SMP-NTS.cpp +++ b/src/smpi/colls/allgather/allgather-SMP-NTS.cpp @@ -1,10 +1,11 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "../colls_private.hpp" +#include "xbt/string.hpp" namespace simgrid::smpi { diff --git a/src/smpi/colls/allgather/allgather-bruck.cpp b/src/smpi/colls/allgather/allgather-bruck.cpp index ed4983e4a2..df58663e03 100644 --- a/src/smpi/colls/allgather/allgather-bruck.cpp +++ b/src/smpi/colls/allgather/allgather-bruck.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-loosely-lr.cpp b/src/smpi/colls/allgather/allgather-loosely-lr.cpp index 67debf513d..4920915699 100644 --- a/src/smpi/colls/allgather/allgather-loosely-lr.cpp +++ b/src/smpi/colls/allgather/allgather-loosely-lr.cpp @@ -1,10 +1,10 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "../colls_private.hpp" +#include "xbt/string.hpp" namespace simgrid::smpi { diff --git a/src/smpi/colls/allgather/allgather-mvapich-smp.cpp b/src/smpi/colls/allgather/allgather-mvapich-smp.cpp index c465b0cd5d..18725e356b 100644 --- a/src/smpi/colls/allgather/allgather-mvapich-smp.cpp +++ b/src/smpi/colls/allgather/allgather-mvapich-smp.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-ompi-neighborexchange.cpp b/src/smpi/colls/allgather/allgather-ompi-neighborexchange.cpp index 66195e5516..2bdeb0f056 100644 --- a/src/smpi/colls/allgather/allgather-ompi-neighborexchange.cpp +++ b/src/smpi/colls/allgather/allgather-ompi-neighborexchange.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-pair.cpp b/src/smpi/colls/allgather/allgather-pair.cpp index 1654901692..7659cce465 100644 --- a/src/smpi/colls/allgather/allgather-pair.cpp +++ b/src/smpi/colls/allgather/allgather-pair.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-rdb.cpp b/src/smpi/colls/allgather/allgather-rdb.cpp index 54441b8fb4..6d1638f4e4 100644 --- a/src/smpi/colls/allgather/allgather-rdb.cpp +++ b/src/smpi/colls/allgather/allgather-rdb.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/allgather/allgather-rhv.cpp b/src/smpi/colls/allgather/allgather-rhv.cpp index 6992e4d79f..c2a4e5f51a 100644 --- a/src/smpi/colls/allgather/allgather-rhv.cpp +++ b/src/smpi/colls/allgather/allgather-rhv.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-ring.cpp b/src/smpi/colls/allgather/allgather-ring.cpp index 3ab41769f0..1500dbee63 100644 --- a/src/smpi/colls/allgather/allgather-ring.cpp +++ b/src/smpi/colls/allgather/allgather-ring.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgather/allgather-smp-simple.cpp b/src/smpi/colls/allgather/allgather-smp-simple.cpp index e69e2e849a..e3fb6a10af 100644 --- a/src/smpi/colls/allgather/allgather-smp-simple.cpp +++ b/src/smpi/colls/allgather/allgather-smp-simple.cpp @@ -1,10 +1,10 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "../colls_private.hpp" +#include "xbt/string.hpp" namespace simgrid::smpi { diff --git a/src/smpi/colls/allgather/allgather-spreading-simple.cpp b/src/smpi/colls/allgather/allgather-spreading-simple.cpp index 095aad1f8f..d5c59b03bb 100644 --- a/src/smpi/colls/allgather/allgather-spreading-simple.cpp +++ b/src/smpi/colls/allgather/allgather-spreading-simple.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgatherv/allgatherv-GB.cpp b/src/smpi/colls/allgatherv/allgatherv-GB.cpp index a168ce9926..6bb9d7c3ab 100644 --- a/src/smpi/colls/allgatherv/allgatherv-GB.cpp +++ b/src/smpi/colls/allgatherv/allgatherv-GB.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgatherv/allgatherv-mpich-rdb.cpp b/src/smpi/colls/allgatherv/allgatherv-mpich-rdb.cpp index 97acd93ce5..dd62a5d84e 100644 --- a/src/smpi/colls/allgatherv/allgatherv-mpich-rdb.cpp +++ b/src/smpi/colls/allgatherv/allgatherv-mpich-rdb.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/allgatherv/allgatherv-mpich-ring.cpp b/src/smpi/colls/allgatherv/allgatherv-mpich-ring.cpp index a7c6564f27..8be65a3c4b 100644 --- a/src/smpi/colls/allgatherv/allgatherv-mpich-ring.cpp +++ b/src/smpi/colls/allgatherv/allgatherv-mpich-ring.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgatherv/allgatherv-ompi-bruck.cpp b/src/smpi/colls/allgatherv/allgatherv-ompi-bruck.cpp index 8b089894f2..923c2f57f1 100644 --- a/src/smpi/colls/allgatherv/allgatherv-ompi-bruck.cpp +++ b/src/smpi/colls/allgatherv/allgatherv-ompi-bruck.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgatherv/allgatherv-ompi-neighborexchange.cpp b/src/smpi/colls/allgatherv/allgatherv-ompi-neighborexchange.cpp index 56e3a1f511..be321f512e 100644 --- a/src/smpi/colls/allgatherv/allgatherv-ompi-neighborexchange.cpp +++ b/src/smpi/colls/allgatherv/allgatherv-ompi-neighborexchange.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgatherv/allgatherv-pair.cpp b/src/smpi/colls/allgatherv/allgatherv-pair.cpp index 820fcf445c..96cc71a335 100644 --- a/src/smpi/colls/allgatherv/allgatherv-pair.cpp +++ b/src/smpi/colls/allgatherv/allgatherv-pair.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allgatherv/allgatherv-ring.cpp b/src/smpi/colls/allgatherv/allgatherv-ring.cpp index 94f69cf708..3a98941eef 100644 --- a/src/smpi/colls/allgatherv/allgatherv-ring.cpp +++ b/src/smpi/colls/allgatherv/allgatherv-ring.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-lr.cpp b/src/smpi/colls/allreduce/allreduce-lr.cpp index 7270c21943..517bd6993f 100644 --- a/src/smpi/colls/allreduce/allreduce-lr.cpp +++ b/src/smpi/colls/allreduce/allreduce-lr.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-mvapich-rs.cpp b/src/smpi/colls/allreduce/allreduce-mvapich-rs.cpp index 6cb04ffd30..a74dbfef44 100644 --- a/src/smpi/colls/allreduce/allreduce-mvapich-rs.cpp +++ b/src/smpi/colls/allreduce/allreduce-mvapich-rs.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-mvapich-two-level.cpp b/src/smpi/colls/allreduce/allreduce-mvapich-two-level.cpp index b643cdb1c7..841db601a7 100644 --- a/src/smpi/colls/allreduce/allreduce-mvapich-two-level.cpp +++ b/src/smpi/colls/allreduce/allreduce-mvapich-two-level.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-ompi-ring-segmented.cpp b/src/smpi/colls/allreduce/allreduce-ompi-ring-segmented.cpp index dfb61008ce..c26616934a 100644 --- a/src/smpi/colls/allreduce/allreduce-ompi-ring-segmented.cpp +++ b/src/smpi/colls/allreduce/allreduce-ompi-ring-segmented.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-rab-rdb.cpp b/src/smpi/colls/allreduce/allreduce-rab-rdb.cpp index 3b0a60595a..1cac314292 100644 --- a/src/smpi/colls/allreduce/allreduce-rab-rdb.cpp +++ b/src/smpi/colls/allreduce/allreduce-rab-rdb.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-rab1.cpp b/src/smpi/colls/allreduce/allreduce-rab1.cpp index 179f7faabd..6e8a5a7038 100644 --- a/src/smpi/colls/allreduce/allreduce-rab1.cpp +++ b/src/smpi/colls/allreduce/allreduce-rab1.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-rab2.cpp b/src/smpi/colls/allreduce/allreduce-rab2.cpp index 238b8bef3a..a66a765ccc 100644 --- a/src/smpi/colls/allreduce/allreduce-rab2.cpp +++ b/src/smpi/colls/allreduce/allreduce-rab2.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-rdb.cpp b/src/smpi/colls/allreduce/allreduce-rdb.cpp index bde40d2153..8c25cdee63 100644 --- a/src/smpi/colls/allreduce/allreduce-rdb.cpp +++ b/src/smpi/colls/allreduce/allreduce-rdb.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-redbcast.cpp b/src/smpi/colls/allreduce/allreduce-redbcast.cpp index dc2eea5e6b..9ca1db62cc 100644 --- a/src/smpi/colls/allreduce/allreduce-redbcast.cpp +++ b/src/smpi/colls/allreduce/allreduce-redbcast.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-smp-binomial-pipeline.cpp b/src/smpi/colls/allreduce/allreduce-smp-binomial-pipeline.cpp index f7c1b02f24..70d57da0ad 100644 --- a/src/smpi/colls/allreduce/allreduce-smp-binomial-pipeline.cpp +++ b/src/smpi/colls/allreduce/allreduce-smp-binomial-pipeline.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-smp-binomial.cpp b/src/smpi/colls/allreduce/allreduce-smp-binomial.cpp index c53fc38e24..40e4e86091 100644 --- a/src/smpi/colls/allreduce/allreduce-smp-binomial.cpp +++ b/src/smpi/colls/allreduce/allreduce-smp-binomial.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-smp-rdb.cpp b/src/smpi/colls/allreduce/allreduce-smp-rdb.cpp index ca90a5510f..5bebd235a9 100644 --- a/src/smpi/colls/allreduce/allreduce-smp-rdb.cpp +++ b/src/smpi/colls/allreduce/allreduce-smp-rdb.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-smp-rsag-lr.cpp b/src/smpi/colls/allreduce/allreduce-smp-rsag-lr.cpp index cd6eac455b..79692cb89f 100644 --- a/src/smpi/colls/allreduce/allreduce-smp-rsag-lr.cpp +++ b/src/smpi/colls/allreduce/allreduce-smp-rsag-lr.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-smp-rsag-rab.cpp b/src/smpi/colls/allreduce/allreduce-smp-rsag-rab.cpp index d638ee00f2..8203453618 100644 --- a/src/smpi/colls/allreduce/allreduce-smp-rsag-rab.cpp +++ b/src/smpi/colls/allreduce/allreduce-smp-rsag-rab.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/allreduce/allreduce-smp-rsag.cpp b/src/smpi/colls/allreduce/allreduce-smp-rsag.cpp index 5f43edc343..f975446148 100644 --- a/src/smpi/colls/allreduce/allreduce-smp-rsag.cpp +++ b/src/smpi/colls/allreduce/allreduce-smp-rsag.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-2dmesh.cpp b/src/smpi/colls/alltoall/alltoall-2dmesh.cpp index aa63c4157a..7a82ffe00e 100644 --- a/src/smpi/colls/alltoall/alltoall-2dmesh.cpp +++ b/src/smpi/colls/alltoall/alltoall-2dmesh.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-3dmesh.cpp b/src/smpi/colls/alltoall/alltoall-3dmesh.cpp index 3dceba3830..17ea7c1e41 100644 --- a/src/smpi/colls/alltoall/alltoall-3dmesh.cpp +++ b/src/smpi/colls/alltoall/alltoall-3dmesh.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-basic-linear.cpp b/src/smpi/colls/alltoall/alltoall-basic-linear.cpp index 9ee08afa0c..e7dcea9397 100644 --- a/src/smpi/colls/alltoall/alltoall-basic-linear.cpp +++ b/src/smpi/colls/alltoall/alltoall-basic-linear.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-bruck.cpp b/src/smpi/colls/alltoall/alltoall-bruck.cpp index da338eb9b4..21248d09f0 100644 --- a/src/smpi/colls/alltoall/alltoall-bruck.cpp +++ b/src/smpi/colls/alltoall/alltoall-bruck.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-mvapich-scatter-dest.cpp b/src/smpi/colls/alltoall/alltoall-mvapich-scatter-dest.cpp index 99a845640b..0a3cbc6cdb 100644 --- a/src/smpi/colls/alltoall/alltoall-mvapich-scatter-dest.cpp +++ b/src/smpi/colls/alltoall/alltoall-mvapich-scatter-dest.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-pair-light-barrier.cpp b/src/smpi/colls/alltoall/alltoall-pair-light-barrier.cpp index 5bdbcd0d15..68453e56fa 100644 --- a/src/smpi/colls/alltoall/alltoall-pair-light-barrier.cpp +++ b/src/smpi/colls/alltoall/alltoall-pair-light-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-pair-mpi-barrier.cpp b/src/smpi/colls/alltoall/alltoall-pair-mpi-barrier.cpp index 88467b1718..fbc71633b5 100644 --- a/src/smpi/colls/alltoall/alltoall-pair-mpi-barrier.cpp +++ b/src/smpi/colls/alltoall/alltoall-pair-mpi-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-pair-one-barrier.cpp b/src/smpi/colls/alltoall/alltoall-pair-one-barrier.cpp index 27275aa907..2ca9cabb50 100644 --- a/src/smpi/colls/alltoall/alltoall-pair-one-barrier.cpp +++ b/src/smpi/colls/alltoall/alltoall-pair-one-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-pair.cpp b/src/smpi/colls/alltoall/alltoall-pair.cpp index b73d5b2ba0..83aa58a85e 100644 --- a/src/smpi/colls/alltoall/alltoall-pair.cpp +++ b/src/smpi/colls/alltoall/alltoall-pair.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-rdb.cpp b/src/smpi/colls/alltoall/alltoall-rdb.cpp index ed942b9aa6..c2268a3d98 100644 --- a/src/smpi/colls/alltoall/alltoall-rdb.cpp +++ b/src/smpi/colls/alltoall/alltoall-rdb.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-ring-light-barrier.cpp b/src/smpi/colls/alltoall/alltoall-ring-light-barrier.cpp index 804dbca54b..ec91cf5607 100644 --- a/src/smpi/colls/alltoall/alltoall-ring-light-barrier.cpp +++ b/src/smpi/colls/alltoall/alltoall-ring-light-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-ring-mpi-barrier.cpp b/src/smpi/colls/alltoall/alltoall-ring-mpi-barrier.cpp index 0810da0bf0..086bf99b28 100644 --- a/src/smpi/colls/alltoall/alltoall-ring-mpi-barrier.cpp +++ b/src/smpi/colls/alltoall/alltoall-ring-mpi-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-ring-one-barrier.cpp b/src/smpi/colls/alltoall/alltoall-ring-one-barrier.cpp index 748d68990a..347ee9953a 100644 --- a/src/smpi/colls/alltoall/alltoall-ring-one-barrier.cpp +++ b/src/smpi/colls/alltoall/alltoall-ring-one-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoall/alltoall-ring.cpp b/src/smpi/colls/alltoall/alltoall-ring.cpp index 306734eb6e..deaec17b52 100644 --- a/src/smpi/colls/alltoall/alltoall-ring.cpp +++ b/src/smpi/colls/alltoall/alltoall-ring.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-bruck.cpp b/src/smpi/colls/alltoallv/alltoallv-bruck.cpp index 6a7268f3ac..bcab1ce068 100644 --- a/src/smpi/colls/alltoallv/alltoallv-bruck.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-bruck.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-ompi-basic-linear.cpp b/src/smpi/colls/alltoallv/alltoallv-ompi-basic-linear.cpp index 431d14fdcc..10e4574359 100644 --- a/src/smpi/colls/alltoallv/alltoallv-ompi-basic-linear.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-ompi-basic-linear.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-pair-light-barrier.cpp b/src/smpi/colls/alltoallv/alltoallv-pair-light-barrier.cpp index c773e31638..cdb9856d6d 100644 --- a/src/smpi/colls/alltoallv/alltoallv-pair-light-barrier.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-pair-light-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-pair-mpi-barrier.cpp b/src/smpi/colls/alltoallv/alltoallv-pair-mpi-barrier.cpp index c901225e5c..617722f3c1 100644 --- a/src/smpi/colls/alltoallv/alltoallv-pair-mpi-barrier.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-pair-mpi-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-pair-one-barrier.cpp b/src/smpi/colls/alltoallv/alltoallv-pair-one-barrier.cpp index 5a2bb886e4..e27ea9e6d5 100644 --- a/src/smpi/colls/alltoallv/alltoallv-pair-one-barrier.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-pair-one-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-pair.cpp b/src/smpi/colls/alltoallv/alltoallv-pair.cpp index a099450cd9..82e61c1668 100644 --- a/src/smpi/colls/alltoallv/alltoallv-pair.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-pair.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-ring-light-barrier.cpp b/src/smpi/colls/alltoallv/alltoallv-ring-light-barrier.cpp index 8231ebe83c..862dfdf601 100644 --- a/src/smpi/colls/alltoallv/alltoallv-ring-light-barrier.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-ring-light-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-ring-mpi-barrier.cpp b/src/smpi/colls/alltoallv/alltoallv-ring-mpi-barrier.cpp index 38cd26d0fa..a07805ea3f 100644 --- a/src/smpi/colls/alltoallv/alltoallv-ring-mpi-barrier.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-ring-mpi-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-ring-one-barrier.cpp b/src/smpi/colls/alltoallv/alltoallv-ring-one-barrier.cpp index 5007f91b54..fb63e173e9 100644 --- a/src/smpi/colls/alltoallv/alltoallv-ring-one-barrier.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-ring-one-barrier.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/alltoallv/alltoallv-ring.cpp b/src/smpi/colls/alltoallv/alltoallv-ring.cpp index 661a434673..24a929da85 100644 --- a/src/smpi/colls/alltoallv/alltoallv-ring.cpp +++ b/src/smpi/colls/alltoallv/alltoallv-ring.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/barrier/barrier-mpich-smp.cpp b/src/smpi/colls/barrier/barrier-mpich-smp.cpp index eee6c2f6ab..5ddb8536e8 100644 --- a/src/smpi/colls/barrier/barrier-mpich-smp.cpp +++ b/src/smpi/colls/barrier/barrier-mpich-smp.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/barrier/barrier-mvapich2-pair.cpp b/src/smpi/colls/barrier/barrier-mvapich2-pair.cpp index 4b5a0aaa4a..6c2e1ca0ba 100644 --- a/src/smpi/colls/barrier/barrier-mvapich2-pair.cpp +++ b/src/smpi/colls/barrier/barrier-mvapich2-pair.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/barrier/barrier-ompi.cpp b/src/smpi/colls/barrier/barrier-ompi.cpp index e897a3f2fd..117cd227c0 100644 --- a/src/smpi/colls/barrier/barrier-ompi.cpp +++ b/src/smpi/colls/barrier/barrier-ompi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-NTSB.cpp b/src/smpi/colls/bcast/bcast-NTSB.cpp index bfd343b32f..304c0dbb73 100644 --- a/src/smpi/colls/bcast/bcast-NTSB.cpp +++ b/src/smpi/colls/bcast/bcast-NTSB.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-NTSL-Isend.cpp b/src/smpi/colls/bcast/bcast-NTSL-Isend.cpp index 6cfcd11f48..c55600838e 100644 --- a/src/smpi/colls/bcast/bcast-NTSL-Isend.cpp +++ b/src/smpi/colls/bcast/bcast-NTSL-Isend.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-NTSL.cpp b/src/smpi/colls/bcast/bcast-NTSL.cpp index 9fdb21d651..f3bffdff76 100644 --- a/src/smpi/colls/bcast/bcast-NTSL.cpp +++ b/src/smpi/colls/bcast/bcast-NTSL.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-SMP-binary.cpp b/src/smpi/colls/bcast/bcast-SMP-binary.cpp index 0e2bc607e5..933a6075c1 100644 --- a/src/smpi/colls/bcast/bcast-SMP-binary.cpp +++ b/src/smpi/colls/bcast/bcast-SMP-binary.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-SMP-binomial.cpp b/src/smpi/colls/bcast/bcast-SMP-binomial.cpp index 4c9589fcd3..d336dd1d00 100644 --- a/src/smpi/colls/bcast/bcast-SMP-binomial.cpp +++ b/src/smpi/colls/bcast/bcast-SMP-binomial.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-SMP-linear.cpp b/src/smpi/colls/bcast/bcast-SMP-linear.cpp index 9d4dacda5f..c35df9916a 100644 --- a/src/smpi/colls/bcast/bcast-SMP-linear.cpp +++ b/src/smpi/colls/bcast/bcast-SMP-linear.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-arrival-pattern-aware-wait.cpp b/src/smpi/colls/bcast/bcast-arrival-pattern-aware-wait.cpp index 6e17bd4f23..445596b8ce 100644 --- a/src/smpi/colls/bcast/bcast-arrival-pattern-aware-wait.cpp +++ b/src/smpi/colls/bcast/bcast-arrival-pattern-aware-wait.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-arrival-pattern-aware.cpp b/src/smpi/colls/bcast/bcast-arrival-pattern-aware.cpp index f2952be551..2f553fb8c8 100644 --- a/src/smpi/colls/bcast/bcast-arrival-pattern-aware.cpp +++ b/src/smpi/colls/bcast/bcast-arrival-pattern-aware.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-arrival-scatter.cpp b/src/smpi/colls/bcast/bcast-arrival-scatter.cpp index d4d03e1391..040737ff94 100644 --- a/src/smpi/colls/bcast/bcast-arrival-scatter.cpp +++ b/src/smpi/colls/bcast/bcast-arrival-scatter.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-binomial-tree.cpp b/src/smpi/colls/bcast/bcast-binomial-tree.cpp index 0f19627116..dbdea7c4cf 100644 --- a/src/smpi/colls/bcast/bcast-binomial-tree.cpp +++ b/src/smpi/colls/bcast/bcast-binomial-tree.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-flattree-pipeline.cpp b/src/smpi/colls/bcast/bcast-flattree-pipeline.cpp index a1446463f0..e2282bfbf9 100644 --- a/src/smpi/colls/bcast/bcast-flattree-pipeline.cpp +++ b/src/smpi/colls/bcast/bcast-flattree-pipeline.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-flattree.cpp b/src/smpi/colls/bcast/bcast-flattree.cpp index 800777f1d5..904b21a27f 100644 --- a/src/smpi/colls/bcast/bcast-flattree.cpp +++ b/src/smpi/colls/bcast/bcast-flattree.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-mvapich-smp.cpp b/src/smpi/colls/bcast/bcast-mvapich-smp.cpp index 50ea2ae39e..8c540ab384 100644 --- a/src/smpi/colls/bcast/bcast-mvapich-smp.cpp +++ b/src/smpi/colls/bcast/bcast-mvapich-smp.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -48,7 +48,6 @@ extern int mv2_pipelined_zcpy_knomial_factor; extern int bcast_segment_size; extern int mv2_inter_node_knomial_factor; extern int mv2_intra_node_knomial_factor; -extern int mv2_bcast_two_level_system_size; #define INTRA_NODE_ROOT 0 #define MPIR_Pipelined_Bcast_Zcpy_MV2 bcast__mpich diff --git a/src/smpi/colls/bcast/bcast-ompi-pipeline.cpp b/src/smpi/colls/bcast/bcast-ompi-pipeline.cpp index e57fc37402..cb472fff7a 100644 --- a/src/smpi/colls/bcast/bcast-ompi-pipeline.cpp +++ b/src/smpi/colls/bcast/bcast-ompi-pipeline.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-ompi-split-bintree.cpp b/src/smpi/colls/bcast/bcast-ompi-split-bintree.cpp index 437905aebb..d245ab4d2b 100644 --- a/src/smpi/colls/bcast/bcast-ompi-split-bintree.cpp +++ b/src/smpi/colls/bcast/bcast-ompi-split-bintree.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/bcast/bcast-scatter-LR-allgather.cpp b/src/smpi/colls/bcast/bcast-scatter-LR-allgather.cpp index dcf21486e0..dccdb2d16f 100644 --- a/src/smpi/colls/bcast/bcast-scatter-LR-allgather.cpp +++ b/src/smpi/colls/bcast/bcast-scatter-LR-allgather.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/bcast/bcast-scatter-rdb-allgather.cpp b/src/smpi/colls/bcast/bcast-scatter-rdb-allgather.cpp index 1612f14ccf..6fa290eda0 100644 --- a/src/smpi/colls/bcast/bcast-scatter-rdb-allgather.cpp +++ b/src/smpi/colls/bcast/bcast-scatter-rdb-allgather.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2011-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/coll_tuned_topo.cpp b/src/smpi/colls/coll_tuned_topo.cpp index 9e0dc01fd9..2fe51b2722 100644 --- a/src/smpi/colls/coll_tuned_topo.cpp +++ b/src/smpi/colls/coll_tuned_topo.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/coll_tuned_topo.hpp b/src/smpi/colls/coll_tuned_topo.hpp index 3b5de1a70d..85467dae2e 100644 --- a/src/smpi/colls/coll_tuned_topo.hpp +++ b/src/smpi/colls/coll_tuned_topo.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/colls_global.cpp b/src/smpi/colls/colls_global.cpp index 532d2d9d73..94afac045d 100644 --- a/src/smpi/colls/colls_global.cpp +++ b/src/smpi/colls/colls_global.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/colls_private.hpp b/src/smpi/colls/colls_private.hpp index 22ff565ccf..bc13a86982 100644 --- a/src/smpi/colls/colls_private.hpp +++ b/src/smpi/colls/colls_private.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/gather/gather-mvapich.cpp b/src/smpi/colls/gather/gather-mvapich.cpp index e4ee3dc366..78698fc8aa 100644 --- a/src/smpi/colls/gather/gather-mvapich.cpp +++ b/src/smpi/colls/gather/gather-mvapich.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/gather/gather-ompi.cpp b/src/smpi/colls/gather/gather-ompi.cpp index 6ee45a8b77..d3c9be8e8b 100644 --- a/src/smpi/colls/gather/gather-ompi.cpp +++ b/src/smpi/colls/gather/gather-ompi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce/reduce-NTSL.cpp b/src/smpi/colls/reduce/reduce-NTSL.cpp index 27eb434393..618b7b6e2a 100644 --- a/src/smpi/colls/reduce/reduce-NTSL.cpp +++ b/src/smpi/colls/reduce/reduce-NTSL.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce/reduce-arrival-pattern-aware.cpp b/src/smpi/colls/reduce/reduce-arrival-pattern-aware.cpp index e9d028283e..8514d48d15 100644 --- a/src/smpi/colls/reduce/reduce-arrival-pattern-aware.cpp +++ b/src/smpi/colls/reduce/reduce-arrival-pattern-aware.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce/reduce-binomial.cpp b/src/smpi/colls/reduce/reduce-binomial.cpp index b88575d260..097fcd6e8a 100644 --- a/src/smpi/colls/reduce/reduce-binomial.cpp +++ b/src/smpi/colls/reduce/reduce-binomial.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce/reduce-flat-tree.cpp b/src/smpi/colls/reduce/reduce-flat-tree.cpp index 0dd1668039..af4b4e6406 100644 --- a/src/smpi/colls/reduce/reduce-flat-tree.cpp +++ b/src/smpi/colls/reduce/reduce-flat-tree.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce/reduce-mvapich-knomial.cpp b/src/smpi/colls/reduce/reduce-mvapich-knomial.cpp index e875ede94d..8f274d54f2 100644 --- a/src/smpi/colls/reduce/reduce-mvapich-knomial.cpp +++ b/src/smpi/colls/reduce/reduce-mvapich-knomial.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce/reduce-mvapich-two-level.cpp b/src/smpi/colls/reduce/reduce-mvapich-two-level.cpp index cf090d0766..1f0bae54bd 100644 --- a/src/smpi/colls/reduce/reduce-mvapich-two-level.cpp +++ b/src/smpi/colls/reduce/reduce-mvapich-two-level.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce/reduce-ompi.cpp b/src/smpi/colls/reduce/reduce-ompi.cpp index f1db121f0a..1a8b8b8114 100644 --- a/src/smpi/colls/reduce/reduce-ompi.cpp +++ b/src/smpi/colls/reduce/reduce-ompi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce/reduce-rab.cpp b/src/smpi/colls/reduce/reduce-rab.cpp index 758cf32cf2..4d3e128cf9 100644 --- a/src/smpi/colls/reduce/reduce-rab.cpp +++ b/src/smpi/colls/reduce/reduce-rab.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/reduce/reduce-scatter-gather.cpp b/src/smpi/colls/reduce/reduce-scatter-gather.cpp index 40242f36aa..731fb79aa3 100644 --- a/src/smpi/colls/reduce/reduce-scatter-gather.cpp +++ b/src/smpi/colls/reduce/reduce-scatter-gather.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce_scatter/reduce_scatter-mpich.cpp b/src/smpi/colls/reduce_scatter/reduce_scatter-mpich.cpp index f2607b9060..d45d98368f 100644 --- a/src/smpi/colls/reduce_scatter/reduce_scatter-mpich.cpp +++ b/src/smpi/colls/reduce_scatter/reduce_scatter-mpich.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/reduce_scatter/reduce_scatter-ompi.cpp b/src/smpi/colls/reduce_scatter/reduce_scatter-ompi.cpp index bd651f4927..a2d3687682 100644 --- a/src/smpi/colls/reduce_scatter/reduce_scatter-ompi.cpp +++ b/src/smpi/colls/reduce_scatter/reduce_scatter-ompi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/scatter/scatter-mvapich-two-level.cpp b/src/smpi/colls/scatter/scatter-mvapich-two-level.cpp index 901d14e231..4319efc042 100644 --- a/src/smpi/colls/scatter/scatter-mvapich-two-level.cpp +++ b/src/smpi/colls/scatter/scatter-mvapich-two-level.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/scatter/scatter-ompi.cpp b/src/smpi/colls/scatter/scatter-ompi.cpp index db47ef7cba..e0acfcdf2a 100644 --- a/src/smpi/colls/scatter/scatter-ompi.cpp +++ b/src/smpi/colls/scatter/scatter-ompi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/smpi_automatic_selector.cpp b/src/smpi/colls/smpi_automatic_selector.cpp index 01c108ce8c..77c0b0c90f 100644 --- a/src/smpi/colls/smpi_automatic_selector.cpp +++ b/src/smpi/colls/smpi_automatic_selector.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -28,7 +28,7 @@ simgrid::instr::Container::get_root()->get_type()->by_name_or_create( \ _XBT_STRINGIFY(cat)); \ \ - std::string cont_name = std::string("rank-" + std::to_string(simgrid::s4u::this_actor::get_pid())); \ + std::string cont_name = "rank-" + std::to_string(simgrid::s4u::this_actor::get_pid()); \ type->add_entity_value(desc->name, "1.0 1.0 1.0"); \ new simgrid::instr::NewEvent(simgrid::s4u::Engine::get_clock(), simgrid::instr::Container::by_name(cont_name), \ type, type->get_entity_value(desc->name)); \ diff --git a/src/smpi/colls/smpi_coll.cpp b/src/smpi/colls/smpi_coll.cpp index 3d704cda57..cf22e98031 100644 --- a/src/smpi/colls/smpi_coll.cpp +++ b/src/smpi/colls/smpi_coll.cpp @@ -1,6 +1,6 @@ /* smpi_coll.c -- various optimized routing for collectives */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,14 +13,17 @@ #include "smpi_request.hpp" #include "xbt/config.hpp" +#include #include +#include +#include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_coll, smpi, "Logging specific to SMPI collectives."); namespace simgrid::smpi { std::map, std::less<>> smpi_coll_descriptions( - {{std::string("gather"), + {{"gather", {{"default", "gather default collective", (void*)gather__default}, {"ompi", "gather ompi collective", (void*)gather__ompi}, {"ompi_basic_linear", "gather ompi_basic_linear collective", (void*)gather__ompi_basic_linear}, @@ -242,6 +245,29 @@ std::vector* colls::get_smpi_coll_descriptions(const s return &iter->second; } +std::string colls::get_smpi_coll_help() +{ + size_t max_name_len = + std::accumulate(begin(smpi_coll_descriptions), end(smpi_coll_descriptions), 0, [](auto len, auto const& coll) { + return std::max(len, std::accumulate(begin(coll.second), end(coll.second), 0, [](auto len, auto const& descr) { + return std::max(len, descr.name.length()); + })); + }); + std::ostringstream oss; + std::string title = "Available collective algorithms (select them with \"smpi/collective_name:algo_name\"):"; + oss << title << '\n' << std::setfill('=') << std::setw(title.length() + 1) << '\n'; + for (auto const& [coll, algos] : smpi_coll_descriptions) { + std::string line = "Collective: \"" + coll + "\""; + oss << line << '\n' << std::setfill('-') << std::setw(line.length() + 1) << '\n'; + oss << std::setfill(' ') << std::left; + for (auto const& [name, descr, _] : algos) + oss << " " << std::setw(max_name_len) << name << " " << descr << "\n"; + oss << std::right << '\n'; + } + oss << "Please see https://simgrid.org/doc/latest/app_smpi.html#available-algorithms for more information.\n"; + return oss.str(); +} + static s_mpi_coll_description_t* find_coll_description(const std::string& collective, const std::string& algo) { std::vector* table = colls::get_smpi_coll_descriptions(collective); @@ -258,7 +284,8 @@ static s_mpi_coll_description_t* find_coll_description(const std::string& collec std::string name_list = table->at(0).name; for (unsigned long i = 1; i < table->size(); i++) name_list = name_list + ", " + table->at(i).name; - xbt_die("Collective '%s' has no algorithm '%s'! Valid algorithms: %s.", collective.c_str(), algo.c_str(), name_list.c_str()); + xbt_die("Collective '%s' has no algorithm '%s'! Valid algorithms: %s. Please use --help-coll for details.", + collective.c_str(), algo.c_str(), name_list.c_str()); } int (*colls::gather)(const void* send_buff, int send_count, MPI_Datatype send_type, void* recv_buff, int recv_count, diff --git a/src/smpi/colls/smpi_default_selector.cpp b/src/smpi/colls/smpi_default_selector.cpp index efea3a1ca2..d3419b2039 100644 --- a/src/smpi/colls/smpi_default_selector.cpp +++ b/src/smpi/colls/smpi_default_selector.cpp @@ -1,6 +1,6 @@ -/* selector with default/naive Simgrid algorithms. These should not be trusted for performance evaluations */ +/* selector with default/naive SimGrid algorithms. These should not be trusted for performance evaluations */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/smpi_intel_mpi_selector.cpp b/src/smpi/colls/smpi_intel_mpi_selector.cpp index fd4b879dd6..1c053c2dfc 100644 --- a/src/smpi/colls/smpi_intel_mpi_selector.cpp +++ b/src/smpi/colls/smpi_intel_mpi_selector.cpp @@ -1,6 +1,6 @@ /* selector for collective algorithms based on openmpi's default coll_tuned_decision_fixed selector */ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/smpi_mpich_selector.cpp b/src/smpi/colls/smpi_mpich_selector.cpp index 4a3a6ae01d..d01a1a8714 100644 --- a/src/smpi/colls/smpi_mpich_selector.cpp +++ b/src/smpi/colls/smpi_mpich_selector.cpp @@ -1,6 +1,6 @@ /* selector for collective algorithms based on mpich decision logic */ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/smpi_mvapich2_selector.cpp b/src/smpi/colls/smpi_mvapich2_selector.cpp index c79a308f0c..2bfe308c6b 100644 --- a/src/smpi/colls/smpi_mvapich2_selector.cpp +++ b/src/smpi/colls/smpi_mvapich2_selector.cpp @@ -1,6 +1,6 @@ /* selector for collective algorithms based on mvapich decision logic */ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/colls/smpi_mvapich2_selector_stampede.hpp b/src/smpi/colls/smpi_mvapich2_selector_stampede.hpp index 7f273410d5..d6aa0a09a5 100644 --- a/src/smpi/colls/smpi_mvapich2_selector_stampede.hpp +++ b/src/smpi/colls/smpi_mvapich2_selector_stampede.hpp @@ -2,7 +2,7 @@ /* This is the tuning used by MVAPICH for Stampede platform based on (MV2_ARCH_INTEL_XEON_E5_2680_16, * MV2_HCA_MLX_CX_FDR) */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/smpi_nbc_impl.cpp b/src/smpi/colls/smpi_nbc_impl.cpp index cd893b058d..0b6788ac74 100644 --- a/src/smpi/colls/smpi_nbc_impl.cpp +++ b/src/smpi/colls/smpi_nbc_impl.cpp @@ -1,6 +1,6 @@ /* Asynchronous parts of the basic collective algorithms, meant to be used both for the naive default implementation, but also for non blocking collectives */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/colls/smpi_openmpi_selector.cpp b/src/smpi/colls/smpi_openmpi_selector.cpp index 404cbfaf08..51602c6134 100644 --- a/src/smpi/colls/smpi_openmpi_selector.cpp +++ b/src/smpi/colls/smpi_openmpi_selector.cpp @@ -1,7 +1,7 @@ /* selector for collective algorithms based on openmpi's default coll_tuned_decision_fixed selector * Updated 02/2022 */ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/include/private.hpp b/src/smpi/include/private.hpp index f92ea49c7c..cae46b978d 100644 --- a/src/smpi/include/private.hpp +++ b/src/smpi/include/private.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -54,14 +54,12 @@ constexpr int SMPI_RMA_TAG = -6666; #define MPI_REQUEST_IGNORED ((MPI_Request*)-100) /* Bindings for MPI special values */ -extern XBT_PUBLIC int mpi_in_place_; -extern XBT_PUBLIC int mpi_bottom_; -extern XBT_PUBLIC int mpi_status_ignore_; -extern XBT_PUBLIC int mpi_statuses_ignore_; +extern XBT_PUBLIC const int mpi_in_place_; +extern XBT_PUBLIC const int mpi_bottom_; +extern XBT_PUBLIC const int mpi_status_ignore_; +extern XBT_PUBLIC const int mpi_statuses_ignore_; /* Convert between Fortran and C */ -#define FORT_ADDR(addr, val, val2) \ - (((void *)(addr) == (void*) &(val2)) \ - ? (val) : (void *)(addr)) +#define FORT_ADDR(addr, val, val2) (((const void*)(addr) == (const void*)&(val2)) ? (val) : (void*)(addr)) #define FORT_BOTTOM(addr) FORT_ADDR((addr), MPI_BOTTOM, mpi_bottom_) #define FORT_IN_PLACE(addr) FORT_ADDR((addr), MPI_IN_PLACE, mpi_in_place_) #define FORT_STATUS_IGNORE(addr) static_cast(FORT_ADDR((addr), MPI_STATUS_IGNORE, mpi_status_ignore_)) @@ -76,7 +74,6 @@ using MPIR_Dist_Graph_Topology = SMPI_Dist_Graph_topology*; XBT_PRIVATE simgrid::smpi::ActorExt* smpi_process(); XBT_PRIVATE simgrid::smpi::ActorExt* smpi_process_remote(simgrid::s4u::ActorPtr actor); -XBT_PRIVATE int smpi_get_universe_size(); XBT_PRIVATE void smpi_deployment_register_process(const std::string& instance_id, int rank, const simgrid::s4u::Actor* actor); @@ -120,9 +117,6 @@ XBT_PRIVATE bool smpi_cfg_display_alloc(); // utilities XBT_PRIVATE void smpi_init_options_internal(bool called_by_smpi_main); -extern XBT_PRIVATE char* smpi_data_exe_start; // start of the data+bss segment of the executable -extern XBT_PRIVATE size_t smpi_data_exe_size; // size of the data+bss segment of the executable - XBT_PRIVATE bool smpi_switch_data_segment(simgrid::s4u::ActorPtr actor, const void* addr = nullptr); XBT_PRIVATE void smpi_prepare_global_memory_segment(); diff --git a/src/smpi/include/smpi_actor.hpp b/src/smpi/include/smpi_actor.hpp index 5879ef6082..cb097d26c3 100644 --- a/src/smpi/include/smpi_actor.hpp +++ b/src/smpi/include/smpi_actor.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -68,8 +68,8 @@ public: smpi_trace_call_location_t* call_location(); void set_privatized_region(smpi_privatization_region_t region); smpi_privatization_region_t privatized_region() const; - s4u::Mailbox* mailbox() const { return mailbox_; } - s4u::Mailbox* mailbox_small() const { return mailbox_small_; } + s4u::Mailbox* mailbox(); + s4u::Mailbox* mailbox_small(); s4u::MutexPtr mailboxes_mutex() const; #if HAVE_PAPI int papi_event_set() const; diff --git a/src/smpi/include/smpi_coll.hpp b/src/smpi/include/smpi_coll.hpp index 06e66e4a08..786a5e825c 100644 --- a/src/smpi/include/smpi_coll.hpp +++ b/src/smpi/include/smpi_coll.hpp @@ -1,5 +1,5 @@ /* High level handling of collective algorithms */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -57,6 +57,7 @@ struct s_mpi_coll_description_t { namespace colls { void set_collectives(); XBT_PUBLIC std::vector* get_smpi_coll_descriptions(const std::string& name); +std::string get_smpi_coll_help(); void set_gather(const std::string& name); void set_allgather(const std::string& name); diff --git a/src/smpi/include/smpi_comm.hpp b/src/smpi/include/smpi_comm.hpp index dcab19ec98..e9207554d8 100644 --- a/src/smpi/include/smpi_comm.hpp +++ b/src/smpi/include/smpi_comm.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -88,7 +88,6 @@ public: static int keyval_create(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval, void* extra_state); static int keyval_free(int* keyval); - static void keyval_cleanup(); void add_rma_win(MPI_Win win); void remove_rma_win(MPI_Win win); diff --git a/src/smpi/include/smpi_config.hpp b/src/smpi/include/smpi_config.hpp index 70474ac628..3403510c7a 100644 --- a/src/smpi/include/smpi_config.hpp +++ b/src/smpi/include/smpi_config.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/include/smpi_datatype.hpp b/src/smpi/include/smpi_datatype.hpp index a2e404ebaf..8e99738030 100644 --- a/src/smpi/include/smpi_datatype.hpp +++ b/src/smpi/include/smpi_datatype.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -128,7 +128,7 @@ public: Datatype(const Datatype&) = delete; Datatype& operator=(const Datatype&) = delete; ~Datatype() override; - std::string name() const override {return name_.empty() ? std::string("MPI_Datatype") : name_;} + std::string name() const override { return name_.empty() ? "MPI_Datatype" : name_; } size_t size() const { return size_; } MPI_Aint lb() const { return lb_; } MPI_Aint ub() const { return ub_; } @@ -154,9 +154,6 @@ public: virtual int clone(MPI_Datatype* type); virtual void serialize(const void* noncontiguous, void* contiguous, int count); virtual void unserialize(const void* contiguous, void* noncontiguous, int count, MPI_Op op); - static int keyval_create(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, - void* extra_state); - static int keyval_free(int* keyval); int pack(const void* inbuf, int incount, void* outbuf, int outcount, int* position, const Comm* comm); int unpack(const void* inbuf, int insize, int* position, void* outbuf, int outcount, const Comm* comm); int get_contents(int max_integers, int max_addresses, int max_datatypes, int* array_of_integers, diff --git a/src/smpi/include/smpi_datatype_derived.hpp b/src/smpi/include/smpi_datatype_derived.hpp index cd7a9e0979..277c670dd8 100644 --- a/src/smpi/include/smpi_datatype_derived.hpp +++ b/src/smpi/include/smpi_datatype_derived.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/include/smpi_errhandler.hpp b/src/smpi/include/smpi_errhandler.hpp index c4018495d3..d22f527061 100644 --- a/src/smpi/include/smpi_errhandler.hpp +++ b/src/smpi/include/smpi_errhandler.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/include/smpi_f2c.hpp b/src/smpi/include/smpi_f2c.hpp index 5b10ba78ef..344c838ccc 100644 --- a/src/smpi/include/smpi_f2c.hpp +++ b/src/smpi/include/smpi_f2c.hpp @@ -1,6 +1,6 @@ /* Handle Fortran - C conversion for MPI Types*/ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/include/smpi_file.hpp b/src/smpi/include/smpi_file.hpp index b79164b8df..41c20d9c3d 100644 --- a/src/smpi/include/smpi_file.hpp +++ b/src/smpi/include/smpi_file.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -14,7 +14,7 @@ #include "smpi_info.hpp" #include -XBT_LOG_EXTERNAL_CATEGORY(smpi_pmpi); +XBT_LOG_EXTERNAL_CATEGORY(smpi_io); namespace simgrid::smpi { class File : public F2C{ @@ -30,6 +30,8 @@ class File : public F2C{ MPI_Datatype etype_; MPI_Datatype filetype_; std::string datarep_; + MPI_Offset disp_; + bool atomicity_; public: File(MPI_Comm comm, const char *filename, int amode, MPI_Info info); @@ -40,8 +42,9 @@ class File : public F2C{ int get_position(MPI_Offset* offset) const; int get_position_shared(MPI_Offset* offset) const; int flags() const; + MPI_Datatype etype() const; MPI_Comm comm() const; - std::string name() const override {return file_ ? std::string("MPI_File: ")+ std::string(file_->get_path()): std::string("MPI_File");} + std::string name() const override { return file_ ? "MPI_File: " + std::string(file_->get_path()) : "MPI_File"; } int sync(); int seek(MPI_Offset offset, int whence); @@ -63,6 +66,8 @@ class File : public F2C{ static int del(const char* filename, const Info* info); MPI_Errhandler errhandler(); void set_errhandler( MPI_Errhandler errhandler); + void set_atomicity(bool a); + bool get_atomicity() const; static File* f2c(int id); }; @@ -102,24 +107,27 @@ int File::op_all(void* buf, int count, const Datatype* datatype, MPI_Status* sta max = max_offsets[i]; } - XBT_CDEBUG(smpi_pmpi, "my offsets to read : %lld:%lld, global min and max %lld:%lld", min_offset, max_offset, min, + XBT_CDEBUG(smpi_io, "my offsets to read : %lld:%lld, global min and max %lld:%lld", min_offset, max_offset, min, max); if (empty == 1) { if (status != MPI_STATUS_IGNORE) status->count = 0; return MPI_SUCCESS; } - if (max - min == tot && (datatype->flags() & DT_FLAG_CONTIGUOUS)) { + XBT_CDEBUG(smpi_io, "min:max : %lld:%lld, tot %lld contig %u", min, max, tot, (datatype->flags() & DT_FLAG_CONTIGUOUS)); + if ( size==1 || (max - min == tot && (datatype->flags() & DT_FLAG_CONTIGUOUS))) { // contiguous. Just have each proc perform its read if (status != MPI_STATUS_IGNORE) status->count = count * datatype->size(); - return T(this, buf, count, datatype, status); + int ret = T(this, buf, count, datatype, status); + seek(max_offset, MPI_SEEK_SET); + return ret; } // Interleaved case : How much do I need to read, and whom to send it ? - MPI_Offset my_chunk_start = (max - min + 1) / size * rank; - MPI_Offset my_chunk_end = ((max - min + 1) / size * (rank + 1)); - XBT_CDEBUG(smpi_pmpi, "my chunks to read : %lld:%lld", my_chunk_start, my_chunk_end); + MPI_Offset my_chunk_start = min + (max - min + 1) / size * rank; + MPI_Offset my_chunk_end = min + ((max - min + 1) / size * (rank + 1)) +1; + XBT_CDEBUG(smpi_io, "my chunks to read : %lld:%lld", my_chunk_start, my_chunk_end); std::vector send_sizes(size); std::vector recv_sizes(size); std::vector send_disps(size); @@ -130,11 +138,14 @@ int File::op_all(void* buf, int count, const Datatype* datatype, MPI_Status* sta send_disps[i] = 0; // cheat to avoid issues when send>recv as we use recv buffer if ((my_chunk_start >= min_offsets[i] && my_chunk_start < max_offsets[i]) || ((my_chunk_end <= max_offsets[i]) && my_chunk_end > min_offsets[i])) { - send_sizes[i] = (std::min(max_offsets[i] - 1, my_chunk_end - 1) - std::max(min_offsets[i], my_chunk_start)); + send_sizes[i] = (std::min(max_offsets[i], my_chunk_end) - std::max(min_offsets[i], my_chunk_start)); + //we want to send only useful data, so let's pretend we pack it + send_sizes[i]=send_sizes[i]/datatype->get_extent()*datatype->size(); // store min and max offset to actually read + min_offset = std::min(min_offset, min_offsets[i]); total_sent += send_sizes[i]; - XBT_CDEBUG(smpi_pmpi, "will have to send %d bytes to %d", send_sizes[i], i); + XBT_CDEBUG(smpi_io, "will have to send %d bytes to %d", send_sizes[i], i); } } min_offset = std::max(min_offset, my_chunk_start); @@ -169,15 +180,16 @@ int File::op_all(void* buf, int count, const Datatype* datatype, MPI_Status* sta else if (chunk_start > my_chunk_end) continue; else - totreads += (std::min(chunk_end, my_chunk_end - 1) - std::max(chunk_start, my_chunk_start)); + totreads += (std::min(chunk_end, my_chunk_end) - std::max(chunk_start, my_chunk_start)); } - XBT_CDEBUG(smpi_pmpi, "will have to access %lld from my chunk", totreads); + XBT_CDEBUG(smpi_io, "will have to access %lld from my chunk", totreads); unsigned char* sendbuf = smpi_get_tmp_sendbuffer(total_sent); if (totreads > 0) { seek(min_offset, MPI_SEEK_SET); - T(this, sendbuf, totreads / datatype->size(), datatype, status); + T(this, sendbuf, totreads / datatype->get_extent(), datatype, status); + seek(max_offset, MPI_SEEK_SET); } simgrid::smpi::colls::alltoall(send_sizes.data(), 1, MPI_INT, recv_sizes.data(), 1, MPI_INT, comm_); int total_recv = 0; diff --git a/src/smpi/include/smpi_group.hpp b/src/smpi/include/smpi_group.hpp index aed599bea1..a3ba4e4321 100644 --- a/src/smpi/include/smpi_group.hpp +++ b/src/smpi/include/smpi_group.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ public: void set_mapping(aid_t pid, int rank); int rank(aid_t pid) const; aid_t actor(int rank) const; - std::string name() const override {return std::string("MPI_Group");} + std::string name() const override { return "MPI_Group"; } void ref(); static void unref(MPI_Group group); int size() const { return static_cast(rank_to_pid_map_.size()); } diff --git a/src/smpi/include/smpi_host.hpp b/src/smpi/include/smpi_host.hpp index d75aa0ffd8..503df80ee0 100644 --- a/src/smpi/include/smpi_host.hpp +++ b/src/smpi/include/smpi_host.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,16 +9,20 @@ #include "smpi_utils.hpp" #include "simgrid/s4u/Host.hpp" +#include "src/kernel/resource/FactorSet.hpp" #include #include #include namespace simgrid::smpi { - +static auto factor_lambda(std::vector const& values, double size) +{ + return values[0] + values[1] * size; +} class Host { - std::vector orecv_parsed_values; - std::vector osend_parsed_values; - std::vector oisend_parsed_values; + kernel::resource::FactorSet orecv_{"smpi/or", 0.0, factor_lambda}; + kernel::resource::FactorSet osend_{"smpi/os", 0.0, factor_lambda}; + kernel::resource::FactorSet oisend_{"smpi/ois", 0.0, factor_lambda}; s4u::Host* host = nullptr; /** * @brief Generates warning message if user's config is conflicting (callback vs command line/xml) @@ -31,9 +35,9 @@ public: explicit Host(s4u::Host* ptr); - double orecv(size_t size, s4u::Host* src, s4u::Host* dst); - double osend(size_t size, s4u::Host* src, s4u::Host* dst); - double oisend(size_t size, s4u::Host* src, s4u::Host* dst); + double orecv(size_t size, s4u::Host* src, s4u::Host* dst) const; + double osend(size_t size, s4u::Host* src, s4u::Host* dst) const; + double oisend(size_t size, s4u::Host* src, s4u::Host* dst) const; }; } // namespace simgrid::smpi diff --git a/src/smpi/include/smpi_info.hpp b/src/smpi/include/smpi_info.hpp index d40680166b..a64851b076 100644 --- a/src/smpi/include/smpi_info.hpp +++ b/src/smpi/include/smpi_info.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ public: static void unref(MPI_Info info); void set(const char* key, const char* value) { map_[key] = value; } int get(const char* key, int valuelen, char* value, int* flag) const; - std::string name() const override {return std::string("MPI_Info");} + std::string name() const override { return "MPI_Info"; } int remove(const char* key); int get_nkeys(int* nkeys) const; int get_nthkey(int n, char* key) const; diff --git a/src/smpi/include/smpi_keyvals.hpp b/src/smpi/include/smpi_keyvals.hpp index a4a0305529..768bc51553 100644 --- a/src/smpi/include/smpi_keyvals.hpp +++ b/src/smpi/include/smpi_keyvals.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/include/smpi_op.hpp b/src/smpi/include/smpi_op.hpp index c8573dbfe0..2ec0c1c50a 100644 --- a/src/smpi/include/smpi_op.hpp +++ b/src/smpi/include/smpi_op.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/include/smpi_replay.hpp b/src/smpi/include/smpi_replay.hpp index 1f00a1921b..10fbc85e0b 100644 --- a/src/smpi/include/smpi_replay.hpp +++ b/src/smpi/include/smpi_replay.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -25,7 +25,7 @@ for (const auto& elem : (action)) { \ ss << elem << " "; \ } \ - ss << "\nPlease contact the Simgrid team if support is needed"; \ + ss << "\nPlease contact the SimGrid team if support is needed"; \ throw std::invalid_argument(ss.str()); \ } \ } @@ -58,11 +58,11 @@ public: void parse(xbt::ReplayAction& action, const std::string& name) override; }; -class SendRecvParser : public ActionArgParser { +class SendOrRecvParser : public ActionArgParser { public: /* communication partner; if we send, this is the receiver and vice versa */ int partner; - size_t size; + ssize_t size; int tag; MPI_Datatype datatype1; @@ -103,6 +103,18 @@ public: MPI_Datatype datatype2; }; +class SendRecvParser : public ActionArgParser { +public: + int dst; + int src; + int sendcount; + int recvcount; + MPI_Datatype datatype1; + MPI_Datatype datatype2; + + void parse(xbt::ReplayAction& action, const std::string& name) override; +}; + class BcastArgParser : public CollCommParser { public: void parse(xbt::ReplayAction& action, const std::string& name) override; @@ -185,7 +197,7 @@ public: template class ReplayAction { const std::string name_; const aid_t my_proc_id_ = s4u::this_actor::get_pid(); - T args_; + T args_{}; protected: const std::string& get_name() const { return name_; } @@ -219,7 +231,7 @@ public: void kernel(xbt::ReplayAction& action) override; }; -class SendAction : public ReplayAction { +class SendAction : public ReplayAction { RequestStorage& req_storage; public: @@ -227,7 +239,7 @@ public: void kernel(xbt::ReplayAction& action) override; }; -class RecvAction : public ReplayAction { +class RecvAction : public ReplayAction { RequestStorage& req_storage; public: @@ -282,6 +294,12 @@ public: void kernel(xbt::ReplayAction& action) override; }; +class SendRecvAction : public ReplayAction { +public: + explicit SendRecvAction() : ReplayAction("sendrecv") {} + void kernel(xbt::ReplayAction& action) override; +}; + class BarrierAction : public ReplayAction { public: explicit BarrierAction() : ReplayAction("barrier") {} diff --git a/src/smpi/include/smpi_request.hpp b/src/smpi/include/smpi_request.hpp index d63ed7b1e2..9b0a6ccab9 100644 --- a/src/smpi/include/smpi_request.hpp +++ b/src/smpi/include/smpi_request.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -47,11 +47,11 @@ class Request : public F2C { bool detached_; MPI_Request detached_sender_; int refcount_; - unsigned int message_id_; + std::vector message_id_; MPI_Op op_; std::unique_ptr generalized_funcs; std::vector nbc_requests_; - s4u::Host* src_host_ = nullptr; //!< save simgrid's source host since it can finished before the recv + s4u::Host* src_host_ = nullptr; //!< save SimGrid's source host since it can finished before the recv static bool match_common(MPI_Request req, MPI_Request sender, MPI_Request receiver); static bool match_types(MPI_Datatype stype, MPI_Datatype rtype); @@ -67,7 +67,7 @@ public: int tag() const { return tag_; } int flags() const { return flags_; } bool detached() const { return detached_; } - std::string name() const override { return std::string("MPI_Request"); } + std::string name() const override { return "MPI_Request"; } MPI_Datatype type() const { return type_; } void print_request(const char* message) const; void start(); @@ -102,6 +102,8 @@ public: static void sendrecv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf, int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status* status); + static void isendrecv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf, + int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Request* request); static void startall(int count, MPI_Request* requests); diff --git a/src/smpi/include/smpi_status.hpp b/src/smpi/include/smpi_status.hpp index 25446988f2..0fee9018c2 100644 --- a/src/smpi/include/smpi_status.hpp +++ b/src/smpi/include/smpi_status.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/include/smpi_topo.hpp b/src/smpi/include/smpi_topo.hpp index 0f5ff72bbe..e46d67e55a 100644 --- a/src/smpi/include/smpi_topo.hpp +++ b/src/smpi/include/smpi_topo.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,7 +6,6 @@ #ifndef SMPI_TOPO_HPP_INCLUDED #define SMPI_TOPO_HPP_INCLUDED -#include "smpi_comm.hpp" #include "smpi_status.hpp" #include diff --git a/src/smpi/include/smpi_utils.hpp b/src/smpi/include/smpi_utils.hpp index 99ff9c7d44..f0a35b001a 100644 --- a/src/smpi/include/smpi_utils.hpp +++ b/src/smpi/include/smpi_utils.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -16,14 +16,9 @@ #include // Methods used to parse and store the values for timing injections in smpi -struct s_smpi_factor_t { - size_t factor = 0; - std::vector values; -}; namespace simgrid::smpi::utils { -XBT_PUBLIC std::vector parse_factor(const std::string& smpi_coef_string); XBT_PUBLIC void add_benched_time(double time); XBT_PUBLIC void account_malloc_size(size_t size, std::string_view file, int line, const void* ptr); XBT_PUBLIC void account_shared_size(size_t size); diff --git a/src/smpi/include/smpi_win.hpp b/src/smpi/include/smpi_win.hpp index ea8b9c47b7..436bd279a7 100644 --- a/src/smpi/include/smpi_win.hpp +++ b/src/smpi/include/smpi_win.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ public: int attach (void *base, MPI_Aint size); int detach (const void *base); void get_name(char* name, int* length) const; - std::string name() const override {return name_.empty() ? std::string("MPI_Win") : name_;} + std::string name() const override { return name_.empty() ? "MPI_Win" : name_; } void get_group( MPI_Group* group); void set_name(const char* name); int rank() const; diff --git a/src/smpi/internals/instr_smpi.cpp b/src/smpi/internals/instr_smpi.cpp index 335b79e27b..63e8f338ee 100644 --- a/src/smpi/internals/instr_smpi.cpp +++ b/src/smpi/internals/instr_smpi.cpp @@ -1,20 +1,20 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "private.hpp" -#include -#include +#include "src/simgrid/sg_config.hpp" +#include "src/smpi/include/smpi_actor.hpp" #include #include #include -#include + +#include +#include #include #include -#include "src/smpi/include/smpi_actor.hpp" - XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_smpi, instr, "Tracing SMPI"); static std::unordered_map> keys; @@ -96,7 +96,7 @@ static const char* instr_find_color(const char* c_state) XBT_PRIVATE simgrid::instr::Container* smpi_container(aid_t pid) { - return simgrid::instr::Container::by_name(std::string("rank-") + std::to_string(pid)); + return simgrid::instr::Container::by_name("rank-" + std::to_string(pid)); } static std::string TRACE_smpi_put_key(aid_t src, aid_t dst, int tag, int send) @@ -139,7 +139,7 @@ void TRACE_smpi_setup_container(aid_t pid, const_sg_host_t host) parent = simgrid::instr::Container::by_name_or_null(host->get_name()); xbt_assert(parent != nullptr, "Could not find a parent for mpi rank 'rank-%ld' at function %s", pid, __func__); } - parent->create_child(std::string("rank-") + std::to_string(pid), "MPI"); // This container is of type MPI + parent->create_child("rank-" + std::to_string(pid), "MPI"); // This container is of type MPI } void TRACE_smpi_init(aid_t pid, const std::string& calling_func) @@ -147,7 +147,7 @@ void TRACE_smpi_init(aid_t pid, const std::string& calling_func) if (not TRACE_smpi_is_enabled()) return; - auto self = simgrid::s4u::Actor::self(); + const auto* self = simgrid::s4u::Actor::self(); TRACE_smpi_setup_container(pid, sg_host_self()); simgrid::s4u::this_actor::on_exit([self](bool) { smpi_container(self->get_pid())->remove_from_parent(); }); diff --git a/src/smpi/internals/smpi_actor.cpp b/src/smpi/internals/smpi_actor.cpp index e513fabf8d..056cecf48e 100644 --- a/src/smpi/internals/smpi_actor.cpp +++ b/src/smpi/internals/smpi_actor.cpp @@ -1,19 +1,19 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/smpi/include/smpi_actor.hpp" -#include "mc/mc.h" #include "simgrid/s4u/Engine.hpp" #include "simgrid/s4u/Mutex.hpp" #include "smpi_comm.hpp" #include "smpi_info.hpp" +#include "src/mc/mc.h" #include "src/mc/mc_replay.hpp" #include "xbt/str.h" #if HAVE_PAPI -#include "papi.h" +#include #endif XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_process, smpi, "Logging specific to SMPI (kernel)"); @@ -26,14 +26,12 @@ ActorExt::ActorExt(s4u::Actor* actor) : actor_(actor) if (not simgrid::smpi::ActorExt::EXTENSION_ID.valid()) simgrid::smpi::ActorExt::EXTENSION_ID = simgrid::s4u::Actor::extension_create(); - mailbox_ = s4u::Mailbox::by_name("SMPI-" + std::to_string(actor_->get_pid())); - mailbox_small_ = s4u::Mailbox::by_name("small-" + std::to_string(actor_->get_pid())); + mailbox_ = nullptr; + mailbox_small_ = nullptr; mailboxes_mutex_ = s4u::Mutex::create(); timer_ = xbt_os_timer_new(); state_ = SmpiProcessState::UNINITIALIZED; info_env_ = MPI_INFO_NULL; - if (MC_is_active()) - MC_ignore_heap(timer_, xbt_os_timer_size()); #if HAVE_PAPI if (not smpi_cfg_papi_events_file().empty()) { @@ -92,6 +90,22 @@ int ActorExt::initialized() const return (state_ == SmpiProcessState::INITIALIZED); } +/** @brief Return main mailbox of the process */ +s4u::Mailbox* ActorExt::mailbox() +{ + if(mailbox_==nullptr) + mailbox_=s4u::Mailbox::by_name("SMPI-" + std::to_string(actor_->get_pid())); + return mailbox_; +} + +/** @brief Return mailbox for small messages */ +s4u::Mailbox* ActorExt::mailbox_small() +{ + if(mailbox_small_==nullptr) + mailbox_small_=s4u::Mailbox::by_name("small-" + std::to_string(actor_->get_pid())); + return mailbox_small_; +} + /** @brief Mark a process as initialized (=MPI_Init called) */ void ActorExt::mark_as_initialized() { @@ -225,16 +239,16 @@ int ActorExt::sampling() const void ActorExt::init() { - xbt_assert(smpi_get_universe_size() != 0, "SimGrid was not initialized properly before entering MPI_Init. " - "Aborting, please check compilation process and use smpirun."); - ActorExt* ext = smpi_process(); // if we are in MPI_Init and argc handling has already been done. if (ext->initialized()) return; const simgrid::s4u::Actor* self = simgrid::s4u::Actor::self(); - ext->instance_id_ = self->get_property("instance_id"); + const char* id = self->get_property("instance_id"); + xbt_assert(id != nullptr, "Actor '%s' seem to be calling MPI_Init(), but it was created outside of MPI, wasn't it?", + self->get_cname()); + ext->instance_id_ = id; const int rank = static_cast(xbt_str_parse_int(self->get_property("rank"), "Cannot parse rank")); ext->state_ = SmpiProcessState::INITIALIZING; @@ -243,7 +257,7 @@ void ActorExt::init() ext->comm_world_ = smpi_deployment_comm_world(ext->instance_id_); // set the process attached to the mailbox - ext->mailbox_small_->set_receiver(ext->actor_); + ext->mailbox_small()->set_receiver(ext->actor_); XBT_DEBUG("<%ld> SMPI process has been initialized: %p", ext->actor_->get_pid(), ext->actor_); } diff --git a/src/smpi/internals/smpi_bench.cpp b/src/smpi/internals/smpi_bench.cpp index f4687afbd8..542c0ee1e6 100644 --- a/src/smpi/internals/smpi_bench.cpp +++ b/src/smpi/internals/smpi_bench.cpp @@ -1,9 +1,8 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "getopt.h" #include "private.hpp" #include "simgrid/host.h" #include "simgrid/modelchecker.h" @@ -12,19 +11,18 @@ #include "smpi_comm.hpp" #include "smpi_utils.hpp" #include "src/internal_config.h" +#include "src/kernel/lmm/System.hpp" // sg_precision_timing #include "src/mc/mc_replay.hpp" -#include "src/surf/surf_interface.hpp" // sg_surf_precision #include "xbt/config.hpp" #include "xbt/file.hpp" +#include #include "src/smpi/include/smpi_actor.hpp" -#include -#ifndef WIN32 -#include -#endif #include #include +#include +#include #if HAVE_PAPI #include @@ -211,7 +209,7 @@ int smpi_gettimeofday(struct timeval* tv, struct timezone* tz) double secs = trunc(now); double usecs = (now - secs) * 1e6; tv->tv_sec = static_cast(secs); - tv->tv_usec = static_casttv_usec)>(usecs); // suseconds_t (or useconds_t on WIN32) + tv->tv_usec = static_casttv_usec)>(usecs); // suseconds_t } if (smpi_wtime_sleep > 0) simgrid::s4u::this_actor::sleep_for(smpi_wtime_sleep); @@ -258,13 +256,13 @@ double smpi_mpi_wtime() unsigned long long smpi_rastro_resolution () { const SmpiBenchGuard suspend_bench; - return static_cast(1.0 / sg_surf_precision); + return static_cast(1.0 / sg_precision_timing); } unsigned long long smpi_rastro_timestamp () { const SmpiBenchGuard suspend_bench; - return static_cast(simgrid::s4u::Engine::get_clock() / sg_surf_precision); + return static_cast(simgrid::s4u::Engine::get_clock() / sg_precision_timing); } /* ****************************** Functions related to the SMPI_SAMPLE_ macros ************************************/ @@ -422,7 +420,7 @@ smpi_trace_call_location_t* smpi_trace_get_call_location() return smpi_process()->call_location(); } -void smpi_trace_set_call_location(const char* file, const int line) +void smpi_trace_set_call_location(const char* file, const int line, const char* call_name) { smpi_trace_call_location_t* loc = smpi_process()->call_location(); @@ -432,19 +430,21 @@ void smpi_trace_set_call_location(const char* file, const int line) loc->filename = simgrid::xbt::Path(file).get_base_name(); else loc->filename = file; + std::replace(loc->filename.begin(), loc->filename.end(), ' ', '_'); loc->linenumber = line; + loc->func_call = call_name; } /** Required for Fortran bindings */ -void smpi_trace_set_call_location_(const char* file, const int* line) +void smpi_trace_set_call_location_(const char* file, const int* line, const char* call_name) { - smpi_trace_set_call_location(file, *line); + smpi_trace_set_call_location(file, *line, call_name); } /** Required for Fortran if -fsecond-underscore is activated */ -void smpi_trace_set_call_location__(const char* file, const int* line) +void smpi_trace_set_call_location__(const char* file, const int* line, const char* call_name) { - smpi_trace_set_call_location(file, *line); + smpi_trace_set_call_location(file, *line, call_name); } void smpi_bench_destroy() @@ -483,3 +483,7 @@ int smpi_getopt (int argc, char *const *argv, const char *options) smpi_process()->set_optind(optind); return ret; } + +pid_t smpi_getpid(){ + return static_cast(simgrid::s4u::this_actor::get_pid()); +} diff --git a/src/smpi/internals/smpi_config.cpp b/src/smpi/internals/smpi_config.cpp index acd32c6b97..513694be8f 100644 --- a/src/smpi/internals/smpi_config.cpp +++ b/src/smpi/internals/smpi_config.cpp @@ -1,12 +1,31 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "smpi_config.hpp" -#include "include/xbt/config.hpp" -#include "mc/mc.h" + +#if defined(_GNU_SOURCE) + #define DEFINED_GNUSOURCE 1 +#else + #define _GNU_SOURCE +#endif + +#if defined(__linux__) + #include +//inspired by https://stackoverflow.com/a/70211227 + #if not defined(__USE_GNU) + #define __MUSL__ + #endif +#endif + +#ifndef DEFINED_GNUSOURCE + #undef _GNU_SOURCE +#endif + #include "private.hpp" #include "smpi_coll.hpp" +#include "smpi_config.hpp" +#include "src/mc/mc.h" +#include "xbt/config.hpp" #include "xbt/ex.h" #include "xbt/parse_units.hpp" @@ -14,17 +33,20 @@ #include /* trim */ #include -#if SIMGRID_HAVE_MC #include "src/mc/mc_config.hpp" -#endif +#include "src/mc/mc_replay.hpp" #if defined(__APPLE__) # include # ifndef MAC_OS_X_VERSION_10_12 # define MAC_OS_X_VERSION_10_12 101200 # endif -constexpr bool HAVE_WORKING_MMAP = (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12); -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__sun) || defined(__HAIKU__) +# ifndef __MAC_11_0 +# define __MAC_11_0 110000 +# endif + +constexpr bool HAVE_WORKING_MMAP = ((MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) && (MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_11_0)); +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__sun) || defined(__HAIKU__) || defined(__MUSL__) constexpr bool HAVE_WORKING_MMAP = false; #else constexpr bool HAVE_WORKING_MMAP = true; @@ -233,9 +255,9 @@ void smpi_init_options_internal(bool called_by_smpi_main) simgrid::config::declare_flag( "smpi/privatization", "How we should privatize global variable at runtime (no, yes, mmap, dlopen).", default_privatization, [](const std::string& smpi_privatize_option) { - if (smpi_privatize_option == "no" || smpi_privatize_option == "0") + if (smpi_privatize_option == "no" || smpi_privatize_option == "0" || smpi_privatize_option == "OFF") _smpi_cfg_privatization = SmpiPrivStrategies::NONE; - else if (smpi_privatize_option == "yes" || smpi_privatize_option == "1") + else if (smpi_privatize_option == "yes" || smpi_privatize_option == "1" || smpi_privatize_option == "ON") _smpi_cfg_privatization = SmpiPrivStrategies::DEFAULT; else if (smpi_privatize_option == "mmap") _smpi_cfg_privatization = SmpiPrivStrategies::MMAP; @@ -272,15 +294,19 @@ void smpi_init_options_internal(bool called_by_smpi_main) simgrid::config::declare_flag( "smpi/or", "Small messages timings (MPI_Recv minimum time for small messages)", "0:0:0:0:0"); - simgrid::config::declare_flag("smpi/finalization-barrier", "Do we add a barrier in MPI_Finalize or not", false); + simgrid::config::declare_flag("smpi/barrier-finalization", {"smpi/finalization-barrier"}, + "Do we add a barrier in MPI_Finalize or not", false); + simgrid::config::declare_flag("smpi/barrier-collectives", + "Inject a barrier in each colllective operation, to detect some deadlocks in " + "incorrect MPI codes, which may not be triggered in all cases", + false); smpi_options_initialized = true; } void smpi_check_options() { -#if SIMGRID_HAVE_MC - if (MC_is_active()) { + if (MC_is_active() || MC_record_replay_is_active()) { if (_sg_mc_buffering == "zero") simgrid::config::set_value("smpi/send-is-detached-thresh", 0); else if (_sg_mc_buffering == "infty") @@ -288,7 +314,6 @@ void smpi_check_options() else THROW_IMPOSSIBLE; } -#endif xbt_assert(smpi_cfg_async_small_thresh() <= smpi_cfg_detached_send_thresh(), "smpi/async-small-thresh (=%d) should be smaller or equal to smpi/send-is-detached-thresh (=%d)", @@ -307,4 +332,3 @@ void smpi_check_options() simgrid::smpi::colls::set_collectives(); simgrid::smpi::colls::smpi_coll_cleanup_callback = nullptr; } - diff --git a/src/smpi/internals/smpi_deployment.cpp b/src/smpi/internals/smpi_deployment.cpp index abc235f7a4..9c9d7c8bdf 100644 --- a/src/smpi/internals/smpi_deployment.cpp +++ b/src/smpi/internals/smpi_deployment.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. +/* Copyright (c) 2004-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -15,15 +15,12 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi); namespace simgrid::smpi::app { -static int universe_size = 0; - class Instance { public: explicit Instance(int max_no_processes) : size_(max_no_processes) { auto* group = new simgrid::smpi::Group(size_); comm_world_ = new simgrid::smpi::Comm(group, nullptr, false, -1); - universe_size += max_no_processes; bar_ = s4u::Barrier::create(size_); } s4u::BarrierPtr bar_; @@ -54,6 +51,38 @@ void SMPI_app_instance_register(const char *name, xbt_main_func_t code, int num_ smpi_instances.try_emplace(name, num_processes); } +void SMPI_app_instance_start(const char* name, const std::function& code, + std::vector const& hosts) +{ + xbt_assert(not hosts.empty(), "Cannot start a SMPI instance on 0 hosts"); + + auto [_, inserted] = smpi_instances.try_emplace(name, hosts.size()); + xbt_assert(inserted, "Cannot start two MPI applications of the same name '%s'", name); + + int rank = 0; + for (auto* host : hosts) { + auto rank_str = std::to_string(rank); + auto actor = simgrid::s4u::Actor::init(std::string(name) + "#" + rank_str, host); + actor->set_property("instance_id", name); + actor->set_property("rank", rank_str); + actor->start(code); + + smpi_deployment_register_process(name, rank, actor.get()); + + rank++; + } +} +void SMPI_app_instance_join(const std::string& instance_id) +{ + std::vector actors = + simgrid::s4u::Engine::get_instance()->get_filtered_actors([instance_id](simgrid::s4u::ActorPtr act) { + auto* actor_instance = act->get_property("instance_id"); + return actor_instance != nullptr && strcmp(actor_instance, instance_id.c_str()) == 0; + }); + + for (auto& act : actors) + act->join(); +} void smpi_deployment_register_process(const std::string& instance_id, int rank, const simgrid::s4u::Actor* actor) { @@ -80,10 +109,6 @@ void smpi_deployment_unregister_process(const std::string& instance_id) MPI_Comm* smpi_deployment_comm_world(const std::string& instance_id) { - if (smpi_instances - .empty()) { // no instance registered, we probably used smpirun. (FIXME: I guess this never happens for real) - return nullptr; - } Instance& instance = smpi_instances.at(instance_id); return &instance.comm_world_; } @@ -96,11 +121,6 @@ void smpi_deployment_cleanup_instances(){ smpi_instances.clear(); } -int smpi_get_universe_size() -{ - return simgrid::smpi::app::universe_size; -} - /** @brief Auxiliary method to get list of hosts to deploy app */ static std::vector smpi_get_hosts(const simgrid::s4u::Engine* e, const std::string& hostfile) { diff --git a/src/smpi/internals/smpi_global.cpp b/src/smpi/internals/smpi_global.cpp index 8b3a184c87..10203cbca8 100644 --- a/src/smpi/internals/smpi_global.cpp +++ b/src/smpi/internals/smpi_global.cpp @@ -1,9 +1,8 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "mc/mc.h" #include "simgrid/Exception.hpp" #include "simgrid/plugins/file_system.h" #include "simgrid/s4u/Engine.hpp" @@ -13,6 +12,8 @@ #include "smpi_host.hpp" #include "src/kernel/EngineImpl.hpp" #include "src/kernel/activity/CommImpl.hpp" +#include "src/mc/mc.h" +#include "src/mc/mc_replay.hpp" #include "src/smpi/include/smpi_actor.hpp" #include "xbt/config.hpp" #include "xbt/file.hpp" @@ -35,7 +36,7 @@ #endif #if HAVE_PAPI -#include "papi.h" +#include #endif #if not defined(__APPLE__) && not defined(__HAIKU__) @@ -58,51 +59,51 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_kernel, smpi, "Logging specific to SMPI (ke * See https://www.akkadia.org/drepper/dsohowto.pdf * and https://lists.freebsd.org/pipermail/freebsd-current/2016-March/060284.html */ -#if !RTLD_DEEPBIND || HAVE_SANITIZER_ADDRESS || HAVE_SANITIZER_THREAD +#if !defined(RTLD_DEEPBIND) || !RTLD_DEEPBIND || HAVE_SANITIZER_ADDRESS || HAVE_SANITIZER_THREAD #define WANT_RTLD_DEEPBIND 0 #else #define WANT_RTLD_DEEPBIND RTLD_DEEPBIND #endif #if HAVE_PAPI -std::map> units2papi_setup; + std::map> units2papi_setup; #endif -std::unordered_map location2speedup; + std::unordered_map location2speedup; -static int smpi_exit_status = 0; -xbt_os_timer_t global_timer; -static std::vector privatize_libs_paths; + static int smpi_exit_status = 0; + static xbt_os_timer_t global_timer; + static std::vector privatize_libs_paths; -// No instance gets manually created; check also the smpirun.in script as -// this default name is used there as well (when the tag is generated). -static const std::string smpi_default_instance_name("smpirun"); + // No instance gets manually created; check also the smpirun.in script as + // this default name is used there as well (when the tag is generated). + static const std::string smpi_default_instance_name("smpirun"); -static simgrid::config::Flag - smpi_hostfile("smpi/hostfile", - "Classical MPI hostfile containing list of machines to dispatch " - "the processes, one per line", - ""); + static simgrid::config::Flag + smpi_hostfile("smpi/hostfile", + "Classical MPI hostfile containing list of machines to dispatch " + "the processes, one per line", + ""); -static simgrid::config::Flag smpi_replay("smpi/replay", - "Replay a trace instead of executing the application", ""); + static simgrid::config::Flag smpi_replay("smpi/replay", + "Replay a trace instead of executing the application", ""); -static simgrid::config::Flag smpi_np("smpi/np", "Number of processes to be created", 0); + static simgrid::config::Flag smpi_np("smpi/np", "Number of processes to be created", 0); -static simgrid::config::Flag smpi_map("smpi/map", "Display the mapping between nodes and processes", 0); + static simgrid::config::Flag smpi_map("smpi/map", "Display the mapping between nodes and processes", 0); -std::function smpi_comm_copy_data_callback = - &smpi_comm_copy_buffer_callback; + std::function smpi_comm_copy_data_callback = + &smpi_comm_copy_buffer_callback; -simgrid::smpi::ActorExt* smpi_process() -{ - simgrid::s4u::ActorPtr me = simgrid::s4u::Actor::self(); + simgrid::smpi::ActorExt* smpi_process() + { + simgrid::s4u::ActorPtr me = simgrid::s4u::Actor::self(); - if (me == nullptr) // This happens sometimes (eg, when linking against NS3 because it pulls openMPI...) - return nullptr; + if (me == nullptr) // This happens sometimes (eg, when linking against NS3 because it pulls openMPI...) + return nullptr; - return me->extension(); -} + return me->extension(); + } simgrid::smpi::ActorExt* smpi_process_remote(simgrid::s4u::ActorPtr actor) { @@ -519,6 +520,10 @@ int smpi_main(const char* executable, int argc, char* argv[]) * configuration tools */ return 0; } + if (argv[0] == std::string("--help-coll")) { + std::cerr << simgrid::smpi::colls::get_smpi_coll_help(); + return 0; + } smpi_init_options_internal(true); simgrid::s4u::Engine engine(&argc, argv); @@ -528,6 +533,9 @@ int smpi_main(const char* executable, int argc, char* argv[]) engine.load_platform(argv[1]); engine.set_default_comm_data_copy_callback(smpi_comm_copy_buffer_callback); + xbt_assert(not MC_is_active() || smpi_cfg_privatization() != SmpiPrivStrategies::MMAP, + "Please use the dlopen privatization schema when model-checking SMPI code"); + if (smpi_cfg_privatization() == SmpiPrivStrategies::DLOPEN) smpi_init_privatization_dlopen(executable); else @@ -560,12 +568,15 @@ int smpi_main(const char* executable, int argc, char* argv[]) SMPI_app_instance_register(smpi_default_instance_name.c_str(), nullptr, rank_counts); MPI_COMM_WORLD = *smpi_deployment_comm_world(smpi_default_instance_name); - /* Clean IO before the run */ + /* Flush output streams before and after the run */ fflush(stdout); fflush(stderr); engine.get_impl()->run(-1); + fflush(stderr); + fflush(stdout); + xbt_os_walltimer_stop(global_timer); simgrid::smpi::utils::print_time_analysis(xbt_os_timer_elapsed(global_timer)); @@ -630,7 +641,7 @@ void smpi_mpi_init() { smpi_init_fortran_types(); if(_smpi_init_sleep > 0) simgrid::s4u::this_actor::sleep_for(_smpi_init_sleep); - if (not MC_is_active()) { + if (not MC_is_active() && not MC_record_replay_is_active()) { smpi_deployment_startup_barrier(smpi_process()->get_instance_id()); } } diff --git a/src/smpi/internals/smpi_host.cpp b/src/smpi/internals/smpi_host.cpp index d8daf0df72..8704fbeb08 100644 --- a/src/smpi/internals/smpi_host.cpp +++ b/src/smpi/internals/smpi_host.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -33,87 +33,31 @@ namespace simgrid::smpi { xbt::Extension Host::EXTENSION_ID; -double Host::orecv(size_t size, s4u::Host* src, s4u::Host* dst) +double Host::orecv(size_t size, s4u::Host* src, s4u::Host* dst) const { /* return user's callback if available */ if (auto it = cost_cbs.find(SmpiOperation::RECV); it != cost_cbs.end()) return it->second(size, src, dst); - /* fallback to smpi/or config */ - double current = orecv_parsed_values.empty() ? 0.0 : orecv_parsed_values.front().values[0] + - orecv_parsed_values.front().values[1] * size; - - // Iterate over all the sections that were specified and find the right value. (fact.factor represents the interval - // sizes; we want to find the section that has fact.factor <= size and no other such fact.factor <= size) - // Note: parse_factor() (used before) already sorts the vector we iterate over! - for (auto const& fact : orecv_parsed_values) { - if (size <= fact.factor) { // Values already too large, use the previously computed value of current! - XBT_DEBUG("or : %zu <= %zu return %.10f", size, fact.factor, current); - return current; - } else { - // If the next section is too large, the current section must be used. - // Hence, save the cost, as we might have to use it. - current=fact.values[0]+fact.values[1]*size; - } - } - XBT_DEBUG("smpi_or: %zu is larger than largest boundary, return %.10f", size, current); - - return current; + return orecv_(size); } -double Host::osend(size_t size, s4u::Host* src, s4u::Host* dst) +double Host::osend(size_t size, s4u::Host* src, s4u::Host* dst) const { /* return user's callback if available */ if (auto it = cost_cbs.find(SmpiOperation::SEND); it != cost_cbs.end()) return it->second(size, src, dst); - /* fallback to smpi/os config */ - double current = - osend_parsed_values.empty() ? 0.0 : osend_parsed_values[0].values[0] + osend_parsed_values[0].values[1] * size; - // Iterate over all the sections that were specified and find the right value. (fact.factor represents the interval - // sizes; we want to find the section that has fact.factor <= size and no other such fact.factor <= size) - // Note: parse_factor() (used before) already sorts the vector we iterate over! - for (auto const& fact : osend_parsed_values) { - if (size <= fact.factor) { // Values already too large, use the previously computed value of current! - XBT_DEBUG("os : %zu <= %zu return %.10f", size, fact.factor, current); - return current; - } else { - // If the next section is too large, the current section must be used. - // Hence, save the cost, as we might have to use it. - current = fact.values[0] + fact.values[1] * size; - } - } - XBT_DEBUG("Searching for smpi/os: %zu is larger than the largest boundary, return %.10f", size, current); - - return current; + return osend_(size); } -double Host::oisend(size_t size, s4u::Host* src, s4u::Host* dst) +double Host::oisend(size_t size, s4u::Host* src, s4u::Host* dst) const { /* return user's callback if available */ if (auto it = cost_cbs.find(SmpiOperation::ISEND); it != cost_cbs.end()) return it->second(size, src, dst); - /* fallback to smpi/ois config */ - double current = - oisend_parsed_values.empty() ? 0.0 : oisend_parsed_values[0].values[0] + oisend_parsed_values[0].values[1] * size; - - // Iterate over all the sections that were specified and find the right value. (fact.factor represents the interval - // sizes; we want to find the section that has fact.factor <= size and no other such fact.factor <= size) - // Note: parse_factor() (used before) already sorts the vector we iterate over! - for (auto const& fact : oisend_parsed_values) { - if (size <= fact.factor) { // Values already too large, use the previously computed value of current! - XBT_DEBUG("ois : %zu <= %zu return %.10f", size, fact.factor, current); - return current; - } else { - // If the next section is too large, the current section must be used. - // Hence, save the cost, as we might have to use it. - current = fact.values[0] + fact.values[1] * size; - } - } - XBT_DEBUG("Searching for smpi/ois: %zu is larger than the largest boundary, return %.10f", size, current); - - return current; + return oisend_(size); } void Host::check_factor_configs(const std::string& op) const @@ -133,25 +77,22 @@ Host::Host(s4u::Host* ptr) : host(ptr) smpi::Host::EXTENSION_ID = s4u::Host::extension_create(); check_factor_configs("smpi/or"); - if (const char* orecv_string = host->get_property("smpi/or")) { - orecv_parsed_values = simgrid::smpi::utils::parse_factor(orecv_string); - } else { - orecv_parsed_values = simgrid::smpi::utils::parse_factor(config::get_value("smpi/or")); - } + if (const char* orecv_string = host->get_property("smpi/or")) + orecv_.parse(orecv_string); + else + orecv_.parse(config::get_value("smpi/or")); check_factor_configs("smpi/os"); - if (const char* osend_string = host->get_property("smpi/os")) { - osend_parsed_values = simgrid::smpi::utils::parse_factor(osend_string); - } else { - osend_parsed_values = simgrid::smpi::utils::parse_factor(config::get_value("smpi/os")); - } + if (const char* osend_string = host->get_property("smpi/os")) + osend_.parse(osend_string); + else + osend_.parse(config::get_value("smpi/os")); check_factor_configs("smpi/ois"); - if (const char* oisend_string = host->get_property("smpi/ois")) { - oisend_parsed_values = simgrid::smpi::utils::parse_factor(oisend_string); - } else { - oisend_parsed_values = simgrid::smpi::utils::parse_factor(config::get_value("smpi/ois")); - } + if (const char* oisend_string = host->get_property("smpi/ois")) + oisend_.parse(oisend_string); + else + oisend_.parse(config::get_value("smpi/ois")); } } // namespace simgrid::smpi diff --git a/src/smpi/internals/smpi_memory.cpp b/src/smpi/internals/smpi_memory.cpp index dab12faeca..77ea460d03 100644 --- a/src/smpi/internals/smpi_memory.cpp +++ b/src/smpi/internals/smpi_memory.cpp @@ -1,8 +1,14 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "private.hpp" +#include "src/internal_config.h" +#include "src/kernel/EngineImpl.hpp" +#include "src/smpi/include/smpi_actor.hpp" +#include "src/xbt/memory_map.hpp" + #include #include #include @@ -12,25 +18,17 @@ #include #include #include +#include #include #include -#include - -#ifndef WIN32 -#include #include - -#include "private.hpp" -#include "src/internal_config.h" -#include "src/smpi/include/smpi_actor.hpp" -#include "src/xbt/memory_map.hpp" -#include "xbt/virtu.h" +#include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_memory, smpi, "Memory layout support for SMPI"); -char* smpi_data_exe_start = nullptr; -size_t smpi_data_exe_size = 0; -SmpiPrivStrategies smpi_privatize_global_variables; +static char* smpi_data_exe_start = nullptr; // start of the data+bss segment of the executable +static size_t smpi_data_exe_size = 0; // size of the data+bss segment of the executable +static SmpiPrivStrategies smpi_privatize_global_variables; static void* smpi_data_exe_copy; // Initialized by smpi_prepare_global_memory_segment(). @@ -54,8 +52,9 @@ void smpi_prepare_global_memory_segment() static void smpi_get_executable_global_size() { - char* buffer = realpath(simgrid::xbt::binary_name.c_str(), nullptr); - xbt_assert(buffer != nullptr, "Could not resolve real path of binary file '%s'", simgrid::xbt::binary_name.c_str()); + const auto* binary_name = simgrid::kernel::EngineImpl::get_instance()->get_cmdline().front().c_str(); + char* buffer = realpath(binary_name, nullptr); + xbt_assert(buffer != nullptr, "Could not resolve real path of binary file '%s'", binary_name); std::string full_name = buffer; free(buffer); @@ -85,7 +84,6 @@ static void smpi_get_executable_global_size() } xbt_die("Did not find my data segment."); } -#endif #if HAVE_SANITIZER_ADDRESS #include @@ -97,7 +95,7 @@ static void* asan_safe_memcpy(void* dest, void* src, size_t n) while (i < n && __asan_address_is_poisoned(psrc + i)) ++i; if (i < n) { - char* p = static_cast(__asan_region_is_poisoned(psrc + i, n - i)); + const char* p = static_cast(__asan_region_is_poisoned(psrc + i, n - i)); size_t j = p ? (p - psrc) : n; memcpy(pdest + i, psrc + i, j - i); i = j; diff --git a/src/smpi/internals/smpi_replay.cpp b/src/smpi/internals/smpi_replay.cpp index 218f14d988..701323fb28 100644 --- a/src/smpi/internals/smpi_replay.cpp +++ b/src/smpi/internals/smpi_replay.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -39,7 +39,7 @@ template inline void hash_combine(std::size_t& seed, T const& v) } // Recursive template code derived from Matthieu M. -template ::value - 1> class HashValueImpl { +template - 1> class HashValueImpl { public: static void apply(size_t& seed, Tuple const& tuple) { @@ -117,7 +117,7 @@ public: { for (auto const& [_, reqs] : store) { aid_t my_proc_id = simgrid::s4u::this_actor::get_pid(); - for (auto& req: reqs){ + for (const auto& req : reqs) { if (req != MPI_REQUEST_NULL && (req->src() == my_proc_id || req->dst() == my_proc_id)) { vec.push_back(req); req->print_request("MM"); @@ -162,12 +162,12 @@ void WaitTestParser::parse(simgrid::xbt::ReplayAction& action, const std::string tag = std::stoi(action[4]); } -void SendRecvParser::parse(simgrid::xbt::ReplayAction& action, const std::string&) +void SendOrRecvParser::parse(simgrid::xbt::ReplayAction& action, const std::string&) { CHECK_ACTION_PARAMS(action, 3, 1) partner = std::stoi(action[2]); tag = std::stoi(action[3]); - size = parse_integer(action[4]); + size = parse_integer(action[4]); datatype1 = parse_datatype(action, 5); } @@ -186,10 +186,21 @@ void SleepParser::parse(simgrid::xbt::ReplayAction& action, const std::string&) void LocationParser::parse(simgrid::xbt::ReplayAction& action, const std::string&) { CHECK_ACTION_PARAMS(action, 2, 0) - filename = std::string(action[2]); + filename = action[2]; line = std::stoi(action[3]); } +void SendRecvParser::parse(simgrid::xbt::ReplayAction& action, const std::string&) +{ + CHECK_ACTION_PARAMS(action, 6, 0) + sendcount = parse_integer(action[2]); + dst = std::stoi(action[3]); + recvcount = parse_integer(action[4]); + src = std::stoi(action[5]); + datatype1 = parse_datatype(action, 6); + datatype2 = parse_datatype(action, 7); +} + void BcastArgParser::parse(simgrid::xbt::ReplayAction& action, const std::string&) { CHECK_ACTION_PARAMS(action, 1, 2) @@ -445,7 +456,7 @@ void WaitAction::kernel(simgrid::xbt::ReplayAction& action) void SendAction::kernel(simgrid::xbt::ReplayAction&) { - const SendRecvParser& args = get_args(); + const SendOrRecvParser& args = get_args(); aid_t dst_traced = MPI_COMM_WORLD->group()->actor(args.partner); TRACE_smpi_comm_in( @@ -468,15 +479,15 @@ void SendAction::kernel(simgrid::xbt::ReplayAction&) void RecvAction::kernel(simgrid::xbt::ReplayAction&) { - const SendRecvParser& args = get_args(); + const SendOrRecvParser& args = get_args(); TRACE_smpi_comm_in( get_pid(), __func__, new simgrid::instr::Pt2PtTIData(get_name(), args.partner, args.size, args.tag, Datatype::encode(args.datatype1))); MPI_Status status; // unknown size from the receiver point of view - size_t arg_size = args.size; - if (arg_size == 0) { + ssize_t arg_size = args.size; + if (arg_size < 0) { Request::probe(args.partner, args.tag, MPI_COMM_WORLD, &status); arg_size = status.count; } @@ -499,6 +510,39 @@ void RecvAction::kernel(simgrid::xbt::ReplayAction&) } } +void SendRecvAction::kernel(simgrid::xbt::ReplayAction&) +{ + XBT_DEBUG("Enters SendRecv"); + const SendRecvParser& args = get_args(); + aid_t my_proc_id = simgrid::s4u::this_actor::get_pid(); + aid_t src_traced = MPI_COMM_WORLD->group()->actor(args.src); + aid_t dst_traced = MPI_COMM_WORLD->group()->actor(args.dst); + + MPI_Status status; + int sendtag=0; + int recvtag=0; + + // FIXME: Hack the way to trace this one + auto dst_hack = std::make_shared>(); + auto src_hack = std::make_shared>(); + dst_hack->push_back(dst_traced); + src_hack->push_back(src_traced); + TRACE_smpi_comm_in(my_proc_id, __func__, + new simgrid::instr::VarCollTIData( + "sendRecv", -1, args.sendcount, + dst_hack, args.recvcount, src_hack, + simgrid::smpi::Datatype::encode(args.datatype1), simgrid::smpi::Datatype::encode(args.datatype2))); + + TRACE_smpi_send(my_proc_id, my_proc_id, dst_traced, sendtag, args.sendcount * args.datatype1->size()); + + simgrid::smpi::Request::sendrecv(nullptr, args.sendcount, args.datatype1, args.dst, sendtag, nullptr, args.recvcount, args.datatype2, args.src, + recvtag, MPI_COMM_WORLD, &status); + + TRACE_smpi_recv(src_traced, my_proc_id, recvtag); + TRACE_smpi_comm_out(my_proc_id); + XBT_DEBUG("Exits SendRecv"); +} + void ComputeAction::kernel(simgrid::xbt::ReplayAction&) { const ComputeParser& args = get_args(); @@ -520,7 +564,7 @@ void SleepAction::kernel(simgrid::xbt::ReplayAction&) void LocationAction::kernel(simgrid::xbt::ReplayAction&) { const LocationParser& args = get_args(); - smpi_trace_set_call_location(args.filename.c_str(), args.line); + smpi_trace_set_call_location(args.filename.c_str(), args.line, "replay_action"); } void TestAction::kernel(simgrid::xbt::ReplayAction&) @@ -824,6 +868,7 @@ void smpi_replay_init(const char* instance_id, int rank, double start_delay_flop xbt_replay_action_register("recv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("recv", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); }); xbt_replay_action_register("irecv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::RecvAction("irecv", storage[simgrid::s4u::this_actor::get_pid()]).execute(action); }); xbt_replay_action_register("test", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::TestAction(storage[simgrid::s4u::this_actor::get_pid()]).execute(action); }); + xbt_replay_action_register("sendRecv", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::SendRecvAction().execute(action); }); xbt_replay_action_register("wait", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAction(storage[simgrid::s4u::this_actor::get_pid()]).execute(action); }); xbt_replay_action_register("waitall", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::WaitAllAction(storage[simgrid::s4u::this_actor::get_pid()]).execute(action); }); xbt_replay_action_register("barrier", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::BarrierAction().execute(action); }); @@ -875,7 +920,7 @@ void smpi_replay_main(int rank, const char* private_trace_filename) unsigned int i=0; for (auto const& [_, reqs] : storage[simgrid::s4u::this_actor::get_pid()].get_store()) { - for (auto& req : reqs) { + for (const auto& req : reqs) { requests[i] = req; // FIXME: overwritten at each iteration? } i++; @@ -883,7 +928,7 @@ void smpi_replay_main(int rank, const char* private_trace_filename) simgrid::smpi::Request::waitall(count_requests, requests.data(), MPI_STATUSES_IGNORE); } - if(simgrid::config::get_value("smpi/finalization-barrier")) + if (simgrid::config::get_value("smpi/barrier-finalization")) simgrid::smpi::colls::barrier(MPI_COMM_WORLD); active_processes--; diff --git a/src/smpi/internals/smpi_shared.cpp b/src/smpi/internals/smpi_shared.cpp index 086a7f9a42..42108cd182 100644 --- a/src/smpi/internals/smpi_shared.cpp +++ b/src/smpi/internals/smpi_shared.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -33,6 +33,7 @@ * \ | | * ---- */ +#include #include #include #include @@ -43,14 +44,11 @@ #include -#include -#ifndef WIN32 -#include -#endif +#include "smpi_utils.hpp" #include +#include #include #include -#include "smpi_utils.hpp" #ifndef MAP_ANONYMOUS #define MAP_ANONYMOUS MAP_ANON #endif @@ -61,7 +59,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_shared, smpi, "Logging specific to SMPI (shared memory macros)"); -namespace{ +namespace { /** Some location in the source code * * This information is used by SMPI_SHARED_MALLOC to allocate some shared memory for all simulated processes. @@ -94,12 +92,10 @@ struct shared_metadata_t { std::map allocs_metadata; std::map> calls; -#ifndef WIN32 int smpi_shared_malloc_bogusfile = -1; int smpi_shared_malloc_bogusfile_huge_page = -1; unsigned long smpi_shared_malloc_blocksize = 1UL << 20; -#endif -} +} // namespace void smpi_shared_destroy() { @@ -108,7 +104,6 @@ void smpi_shared_destroy() calls.clear(); } -#ifndef WIN32 static void* shm_map(int fd, size_t size, shared_data_key_type* data) { void* mem = smpi_temp_shm_mmap(fd, size); @@ -478,7 +473,6 @@ void smpi_shared_free(void *ptr) xbt_free(ptr); } } -#endif int smpi_shared_known_call(const char* func, const char* input) { diff --git a/src/smpi/internals/smpi_utils.cpp b/src/smpi/internals/smpi_utils.cpp index 967e7296b4..09688d88f2 100644 --- a/src/smpi/internals/smpi_utils.cpp +++ b/src/smpi/internals/smpi_utils.cpp @@ -1,5 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,21 +7,19 @@ #include "private.hpp" #include "smpi_config.hpp" -#include "src/surf/xml/platf.hpp" +#include "src/kernel/xml/platf.hpp" +#include "xbt/ex.h" #include "xbt/file.hpp" #include "xbt/log.h" -#include "xbt/ex.h" #include "xbt/parse_units.hpp" +#include "xbt/str.h" #include "xbt/sysdep.h" #include #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_utils, smpi, "Logging specific to SMPI (utils)"); -extern std::string surf_parsed_filename; -extern int surf_parse_lineno; - -namespace simgrid::smpi::utils { +namespace { double total_benched_time=0; unsigned long total_malloc_size=0; @@ -41,7 +38,7 @@ struct current_buffer_metadata_t { }; alloc_metadata_t max_malloc; -F2C* current_handle = nullptr; +simgrid::smpi::F2C* current_handle = nullptr; current_buffer_metadata_t current_buffer1; current_buffer_metadata_t current_buffer2; @@ -49,63 +46,9 @@ std::unordered_map allocs; std::unordered_map> collective_calls; -std::vector parse_factor(const std::string& smpi_coef_string) -{ - std::vector smpi_factor; - - /** Setup the tokenizer that parses the string **/ - using Tokenizer = boost::tokenizer>; - boost::char_separator sep(";"); - boost::char_separator factor_separator(":"); - Tokenizer tokens(smpi_coef_string, sep); - - /** - * Iterate over patterns like A:B:C:D;E:F;G:H - * These will be broken down into: - * A --> B, C, D - * E --> F - * G --> H - */ - for (auto token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) { - XBT_DEBUG("token: %s", token_iter->c_str()); - Tokenizer factor_values(*token_iter, factor_separator); - s_smpi_factor_t fact; - xbt_assert(factor_values.begin() != factor_values.end(), "Malformed radical for smpi factor: '%s'", - smpi_coef_string.c_str()); - unsigned int iteration = 0; - for (auto factor_iter = factor_values.begin(); factor_iter != factor_values.end(); ++factor_iter) { - iteration++; - - if (factor_iter == factor_values.begin()) { /* first element */ - try { - fact.factor = std::stoi(*factor_iter); - } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid factor in chunk ") + std::to_string(smpi_factor.size() + 1) + - ": " + *factor_iter); - } - } else { - try { - fact.values.push_back(xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, *factor_iter, "")); - } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid factor value ") + std::to_string(iteration) + " in chunk " + - std::to_string(smpi_factor.size() + 1) + ": " + *factor_iter); - } - } - } - - smpi_factor.push_back(fact); - XBT_DEBUG("smpi_factor:\t%zu: %zu values, first: %f", fact.factor, smpi_factor.size(), fact.values[0]); - } - std::sort(smpi_factor.begin(), smpi_factor.end(), [](const s_smpi_factor_t &pa, const s_smpi_factor_t &pb) { - return (pa.factor < pb.factor); - }); - for (auto const& fact : smpi_factor) { - XBT_DEBUG("smpi_factor:\t%zu: %zu values, first: %f", fact.factor, smpi_factor.size(), fact.values[0]); - } - smpi_factor.shrink_to_fit(); +} // namespace - return smpi_factor; -} +namespace simgrid::smpi::utils { void add_benched_time(double time){ total_benched_time += time; diff --git a/src/smpi/mpi/smpi_comm.cpp b/src/smpi/mpi/smpi_comm.cpp index 2aab0fffd9..ba3cf8100b 100644 --- a/src/smpi/mpi/smpi_comm.cpp +++ b/src/smpi/mpi/smpi_comm.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,8 +10,8 @@ #include "smpi_info.hpp" #include "smpi_request.hpp" #include "smpi_win.hpp" +#include "src/kernel/resource/HostImpl.hpp" #include "src/smpi/include/smpi_actor.hpp" -#include "src/surf/HostImpl.hpp" #include @@ -185,9 +185,9 @@ std::string Comm::name() const std::array name; this->get_name(name.data(), &size); if (name[0]=='\0') - return std::string("MPI_Comm"); + return "MPI_Comm"; else - return std::string(name.data()); + return name.data(); } diff --git a/src/smpi/mpi/smpi_datatype.cpp b/src/smpi/mpi/smpi_datatype.cpp index e2b864076e..539e567e25 100644 --- a/src/smpi/mpi/smpi_datatype.cpp +++ b/src/smpi/mpi/smpi_datatype.cpp @@ -1,5 +1,5 @@ /* smpi_datatype.cpp -- MPI primitives to handle datatypes */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -116,10 +116,6 @@ Datatype::Datatype(int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags) : D Datatype::Datatype(int size, MPI_Aint lb, MPI_Aint ub, int flags) : size_(size), lb_(lb), ub_(ub), flags_(flags) { this->add_f(); -#if SIMGRID_HAVE_MC - if(MC_is_active()) - MC_ignore(&refcount_, sizeof refcount_); -#endif } // for predefined types, so refcount_ = 0. @@ -127,10 +123,6 @@ Datatype::Datatype(const char* name, int ident, int size, MPI_Aint lb, MPI_Aint : name_(name), id(std::to_string(ident)), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(0) { id2type_lookup.try_emplace(id, this); -#if SIMGRID_HAVE_MC - if(MC_is_active()) - MC_ignore(&refcount_, sizeof refcount_); -#endif } Datatype::Datatype(Datatype* datatype, int* ret) @@ -211,11 +203,6 @@ int Datatype::clone(MPI_Datatype* type){ void Datatype::ref() { refcount_++; - -#if SIMGRID_HAVE_MC - if(MC_is_active()) - MC_ignore(&refcount_, sizeof refcount_); -#endif } void Datatype::unref(MPI_Datatype datatype) @@ -223,11 +210,6 @@ void Datatype::unref(MPI_Datatype datatype) if (datatype->refcount_ > 0) datatype->refcount_--; -#if SIMGRID_HAVE_MC - if(MC_is_active()) - MC_ignore(&datatype->refcount_, sizeof datatype->refcount_); -#endif - if (datatype->refcount_ == 0 && not(datatype->flags_ & DT_FLAG_PREDEFINED)) delete datatype; } diff --git a/src/smpi/mpi/smpi_datatype_derived.cpp b/src/smpi/mpi/smpi_datatype_derived.cpp index 3e3b3797fe..fd756811eb 100644 --- a/src/smpi/mpi/smpi_datatype_derived.cpp +++ b/src/smpi/mpi/smpi_datatype_derived.cpp @@ -1,5 +1,5 @@ /* smpi_datatype.cpp -- MPI primitives to handle datatypes */ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/mpi/smpi_errhandler.cpp b/src/smpi/mpi/smpi_errhandler.cpp index 300a0b2d41..d784da58dc 100644 --- a/src/smpi/mpi/smpi_errhandler.cpp +++ b/src/smpi/mpi/smpi_errhandler.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/mpi/smpi_f2c.cpp b/src/smpi/mpi/smpi_f2c.cpp index ab1da74628..a1e6be788b 100644 --- a/src/smpi/mpi/smpi_f2c.cpp +++ b/src/smpi/mpi/smpi_f2c.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,10 +8,10 @@ #include "src/smpi/include/smpi_actor.hpp" #include "src/instr/instr_smpi.hpp" -int mpi_in_place_; -int mpi_bottom_; -int mpi_status_ignore_; -int mpi_statuses_ignore_; +const int mpi_in_place_ = -222; +const int mpi_bottom_ = -111; +const int mpi_status_ignore_ = 0; +const int mpi_statuses_ignore_ = 0; namespace simgrid::smpi { @@ -25,7 +25,7 @@ F2C::F2C() = default; int F2C::add_f() { allocate_lookup(); - if (auto loc = smpi_process()->call_location(); loc && loc->linenumber != 0) + if (auto const* loc = smpi_process()->call_location(); loc && loc->linenumber != 0) call_location_= std::string (loc->filename + ":" + std::to_string(loc->linenumber)); my_f2c_id_ = global_f2c_id(); (*f2c_lookup_)[my_f2c_id_] = this; diff --git a/src/smpi/mpi/smpi_file.cpp b/src/smpi/mpi/smpi_file.cpp index b832510aef..47c73ebf2f 100644 --- a/src/smpi/mpi/smpi_file.cpp +++ b/src/smpi/mpi/smpi_file.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -17,6 +17,8 @@ #include "simgrid/s4u/Host.hpp" #include "simgrid/plugins/file_system.h" +#include // std::scoped_lock + #define FP_SIZE sizeof(MPI_Offset) XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_io, smpi, "Logging specific to SMPI (RMA operations)"); @@ -49,15 +51,17 @@ File::File(MPI_Comm comm, const char* filename, int amode, MPI_Info info) : comm fullname.insert(0, mount); } } - + XBT_DEBUG("Opening %s", fullname.c_str()); file_ = simgrid::s4u::File::open(fullname, nullptr); list_ = nullptr; + disp_ = 0; + etype_ = MPI_BYTE; + atomicity_ = true; if (comm_->rank() == 0) { int size = comm_->size() + FP_SIZE; - list_ = new char[size]; + list_ = new char[size](); errhandler_ = SMPI_default_File_Errhandler; errhandler_->ref(); - memset(list_, 0, size); shared_file_pointer_ = new MPI_Offset(); shared_mutex_ = s4u::Mutex::create(); *shared_file_pointer_ = 0; @@ -108,15 +112,14 @@ int File::del(const char* filename, const Info*) int File::get_position(MPI_Offset* offset) const { - *offset = file_->tell(); + *offset = file_->tell()/etype_->get_extent(); return MPI_SUCCESS; } int File::get_position_shared(MPI_Offset* offset) const { - shared_mutex_->lock(); - *offset = *shared_file_pointer_; - shared_mutex_->unlock(); + const std::scoped_lock lock(*shared_mutex_); + *offset = *shared_file_pointer_/etype_->get_extent(); return MPI_SUCCESS; } @@ -143,10 +146,9 @@ int File::seek(MPI_Offset offset, int whence) int File::seek_shared(MPI_Offset offset, int whence) { - shared_mutex_->lock(); + const std::scoped_lock lock(*shared_mutex_); seek(offset, whence); *shared_file_pointer_ = file_->tell(); - shared_mutex_->unlock(); return MPI_SUCCESS; } @@ -156,9 +158,9 @@ int File::read(MPI_File fh, void* /*buf*/, int count, const Datatype* datatype, MPI_Offset position = fh->file_->tell(); MPI_Offset movesize = datatype->get_extent() * count; MPI_Offset readsize = datatype->size() * count; - XBT_DEBUG("Position before read in MPI_File %s : %llu", fh->file_->get_path(), fh->file_->tell()); + XBT_DEBUG("Position before read in MPI_File %s : %llu, size %llu", fh->file_->get_path(), fh->file_->tell(), fh->file_->size()); MPI_Offset read = fh->file_->read(readsize); - XBT_VERB("Read in MPI_File %s, %lld bytes read, readsize %lld bytes, movesize %lld", fh->file_->get_path(), read, + XBT_VERB("Read in MPI_File %s, %lld bytes read, count %d, readsize %lld bytes, movesize %lld", fh->file_->get_path(), read, count, readsize, movesize); if (readsize != movesize) { fh->file_->seek(position + movesize, SEEK_SET); @@ -181,11 +183,12 @@ int File::read(MPI_File fh, void* /*buf*/, int count, const Datatype* datatype, /* }*/ int File::read_shared(MPI_File fh, void* buf, int count, const Datatype* datatype, MPI_Status* status) { - fh->shared_mutex_->lock(); + if (const std::scoped_lock lock(*fh->shared_mutex_); true) { + fh->seek(*(fh->shared_file_pointer_), MPI_SEEK_SET); + read(fh, buf, count, datatype, status); + *(fh->shared_file_pointer_) = fh->file_->tell(); + } fh->seek(*(fh->shared_file_pointer_), MPI_SEEK_SET); - read(fh, buf, count, datatype, status); - *(fh->shared_file_pointer_) = fh->file_->tell(); - fh->shared_mutex_->unlock(); return MPI_SUCCESS; } @@ -201,15 +204,17 @@ int File::read_ordered(MPI_File fh, void* buf, int count, const Datatype* dataty MPI_Offset result; simgrid::smpi::colls::scan(&val, &result, 1, MPI_OFFSET, MPI_SUM, fh->comm_); + MPI_Offset prev; + fh->get_position(&prev); fh->seek(result, MPI_SEEK_SET); int ret = fh->op_all(buf, count, datatype, status); if (fh->comm_->rank() == fh->comm_->size() - 1) { - fh->shared_mutex_->lock(); + const std::scoped_lock lock(*fh->shared_mutex_); *(fh->shared_file_pointer_)=fh->file_->tell(); - fh->shared_mutex_->unlock(); } char c; simgrid::smpi::colls::bcast(&c, 1, MPI_BYTE, fh->comm_->size() - 1, fh->comm_); + fh->seek(prev, MPI_SEEK_SET); return ret; } @@ -219,10 +224,10 @@ int File::write(MPI_File fh, void* /*buf*/, int count, const Datatype* datatype, MPI_Offset position = fh->file_->tell(); MPI_Offset movesize = datatype->get_extent() * count; MPI_Offset writesize = datatype->size() * count; - XBT_DEBUG("Position before write in MPI_File %s : %llu", fh->file_->get_path(), fh->file_->tell()); + XBT_DEBUG("Position before write in MPI_File %s : %llu, size %llu", fh->file_->get_path(), fh->file_->tell(), fh->file_->size()); MPI_Offset write = fh->file_->write(writesize, true); - XBT_VERB("Write in MPI_File %s, %lld bytes written, readsize %lld bytes, movesize %lld", fh->file_->get_path(), write, - writesize, movesize); + XBT_VERB("Write in MPI_File %s, %lld bytes written, count %d, writesize %lld bytes, movesize %lld", fh->file_->get_path(), write, + count, writesize, movesize); if (writesize != movesize) { fh->file_->seek(position + movesize, SEEK_SET); } @@ -234,13 +239,13 @@ int File::write(MPI_File fh, void* /*buf*/, int count, const Datatype* datatype, int File::write_shared(MPI_File fh, const void* buf, int count, const Datatype* datatype, MPI_Status* status) { - fh->shared_mutex_->lock(); + const std::scoped_lock lock(*fh->shared_mutex_); XBT_DEBUG("Write shared on %s - Shared ptr before : %lld", fh->file_->get_path(), *(fh->shared_file_pointer_)); fh->seek(*(fh->shared_file_pointer_), MPI_SEEK_SET); write(fh, const_cast(buf), count, datatype, status); *(fh->shared_file_pointer_) = fh->file_->tell(); XBT_DEBUG("Write shared on %s - Shared ptr after : %lld", fh->file_->get_path(), *(fh->shared_file_pointer_)); - fh->shared_mutex_->unlock(); + fh->seek(*(fh->shared_file_pointer_), MPI_SEEK_SET); return MPI_SUCCESS; } @@ -255,29 +260,39 @@ int File::write_ordered(MPI_File fh, const void* buf, int count, const Datatype* } MPI_Offset result; simgrid::smpi::colls::scan(&val, &result, 1, MPI_OFFSET, MPI_SUM, fh->comm_); + MPI_Offset prev; + fh->get_position(&prev); fh->seek(result, MPI_SEEK_SET); int ret = fh->op_all(const_cast(buf), count, datatype, status); if (fh->comm_->rank() == fh->comm_->size() - 1) { - fh->shared_mutex_->lock(); + const std::scoped_lock lock(*fh->shared_mutex_); *(fh->shared_file_pointer_)=fh->file_->tell(); - fh->shared_mutex_->unlock(); } char c; simgrid::smpi::colls::bcast(&c, 1, MPI_BYTE, fh->comm_->size() - 1, fh->comm_); + fh->seek(prev, MPI_SEEK_SET); return ret; } -int File::set_view(MPI_Offset /*disp*/, MPI_Datatype etype, MPI_Datatype filetype, const char* datarep, const Info*) +int File::set_view(MPI_Offset disp, MPI_Datatype etype, MPI_Datatype filetype, const char* datarep, const Info*) { etype_ = etype; filetype_ = filetype; - datarep_ = std::string(datarep); - seek_shared(0, MPI_SEEK_SET); + datarep_ = datarep; + disp_ = disp; + if (comm_->rank() == 0){ + if(disp != MPI_DISPLACEMENT_CURRENT) + seek_shared(disp, MPI_SEEK_SET); + else + seek_shared(0, MPI_SEEK_CUR); + } + sync(); return MPI_SUCCESS; } -int File::get_view(MPI_Offset* /*disp*/, MPI_Datatype* etype, MPI_Datatype* filetype, char* datarep) const +int File::get_view(MPI_Offset* disp, MPI_Datatype* etype, MPI_Datatype* filetype, char* datarep) const { + *disp = disp_; *etype = etype_; *filetype = filetype_; snprintf(datarep, MPI_MAX_NAME_STRING + 1, "%s", datarep_.c_str()); @@ -299,6 +314,11 @@ int File::flags() const return flags_; } +MPI_Datatype File::etype() const +{ + return etype_; +} + int File::sync() { // no idea @@ -344,4 +364,14 @@ File* File::f2c(int id) { return static_cast(F2C::f2c(id)); } + +void File::set_atomicity(bool a){ + atomicity_ = a; +} + +bool File::get_atomicity() const +{ + return atomicity_; +} + } // namespace simgrid::smpi diff --git a/src/smpi/mpi/smpi_group.cpp b/src/smpi/mpi/smpi_group.cpp index 1c3b813184..4b07f918d9 100644 --- a/src/smpi/mpi/smpi_group.cpp +++ b/src/smpi/mpi/smpi_group.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/mpi/smpi_info.cpp b/src/smpi/mpi/smpi_info.cpp index 31f157a882..0d696f4796 100644 --- a/src/smpi/mpi/smpi_info.cpp +++ b/src/smpi/mpi/smpi_info.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/mpi/smpi_keyvals.cpp b/src/smpi/mpi/smpi_keyvals.cpp index 5abfecc84f..b1c61a3c1f 100644 --- a/src/smpi/mpi/smpi_keyvals.cpp +++ b/src/smpi/mpi/smpi_keyvals.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/smpi/mpi/smpi_op.cpp b/src/smpi/mpi/smpi_op.cpp index 0daff56ba5..20246473e0 100644 --- a/src/smpi/mpi/smpi_op.cpp +++ b/src/smpi/mpi/smpi_op.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/mpi/smpi_request.cpp b/src/smpi/mpi/smpi_request.cpp index 0ceb1a398b..64008cd40c 100644 --- a/src/smpi/mpi/smpi_request.cpp +++ b/src/smpi/mpi/smpi_request.cpp @@ -1,11 +1,10 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "smpi_request.hpp" -#include "mc/mc.h" #include "private.hpp" #include "simgrid/Exception.hpp" #include "simgrid/s4u/ConditionVariable.hpp" @@ -19,11 +18,13 @@ #include "src/kernel/activity/CommImpl.hpp" #include "src/kernel/actor/ActorImpl.hpp" #include "src/kernel/actor/SimcallObserver.hpp" +#include "src/mc/mc.h" #include "src/mc/mc_replay.hpp" #include "src/smpi/include/smpi_actor.hpp" #include #include +#include // std::scoped_lock and std::unique_lock XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_request, smpi, "Logging specific to SMPI (request)"); @@ -32,8 +33,6 @@ static simgrid::config::Flag smpi_iprobe_sleep( static simgrid::config::Flag smpi_test_sleep( "smpi/test", "Minimum time to inject inside a call to MPI_Test", 1e-4); -std::vector smpi_ois_values; - extern std::function smpi_comm_copy_data_callback; namespace simgrid::smpi { @@ -70,7 +69,6 @@ Request::Request(const void* buf, int count, MPI_Datatype datatype, aid_t src, a refcount_ = 1; else refcount_ = 0; - message_id_ = 0; init_buffer(count); this->add_f(); } @@ -118,7 +116,7 @@ bool Request::match_types(MPI_Datatype stype, MPI_Datatype rtype){ (stype->duplicated_datatype()!=MPI_DATATYPE_NULL && match_types(stype->duplicated_datatype(), rtype)) || (rtype->duplicated_datatype()!=MPI_DATATYPE_NULL && match_types(stype, rtype->duplicated_datatype()))) match = true; - if (!match) + if (not match) XBT_WARN("Mismatched datatypes : sending %s and receiving %s", stype->name().c_str(), rtype->name().c_str()); return match; } @@ -150,8 +148,7 @@ bool Request::match_common(MPI_Request req, MPI_Request sender, MPI_Request rece receiver->truncated_ = true; } //0-sized datatypes/counts should not interfere and match - if ( sender->real_size_ != 0 && receiver->real_size_ != 0 && - !match_types(sender->type_, receiver->type_)) + if (sender->real_size_ != 0 && receiver->real_size_ != 0 && not match_types(sender->type_, receiver->type_)) receiver->unmatched_types_ = true; if (sender->detached_) receiver->detached_sender_ = sender; // tie the sender to the receiver, as it is detached and has to be freed in @@ -183,15 +180,16 @@ void Request::init_buffer(int count){ bool Request::match_recv(void* a, void* b, simgrid::kernel::activity::CommImpl*) { - auto ref = static_cast(a); - auto req = static_cast(b); + auto* ref = static_cast(a); + auto* req = static_cast(b); bool match = match_common(req, req, ref); if (not match || ref->comm_ == MPI_COMM_UNINITIALIZED || ref->comm_->is_smp_comm()) return match; - - if (ref->comm_->get_received_messages_count(ref->comm_->group()->rank(req->src_), - ref->comm_->group()->rank(req->dst_), req->tag_) == req->message_id_) { + auto it = std::find(req->message_id_.begin(), req->message_id_.end(), ref->comm_->get_received_messages_count(ref->comm_->group()->rank(req->src_), + ref->comm_->group()->rank(req->dst_), req->tag_)); + if (it != req->message_id_.end()) { if (((ref->flags_ & MPI_REQ_PROBE) == 0) && ((req->flags_ & MPI_REQ_PROBE) == 0)) { + req->message_id_.erase(it); XBT_DEBUG("increasing count in comm %p, which was %u from pid %ld, to pid %ld with tag %d", ref->comm_, ref->comm_->get_received_messages_count(ref->comm_->group()->rank(req->src_), ref->comm_->group()->rank(req->dst_), req->tag_), @@ -206,20 +204,20 @@ bool Request::match_recv(void* a, void* b, simgrid::kernel::activity::CommImpl*) match = false; req->flags_ &= ~MPI_REQ_MATCHED; ref->detached_sender_ = nullptr; - XBT_DEBUG("Refusing to match message, as its ID is not the one I expect. in comm %p, %u != %u, " + XBT_DEBUG("Refusing to match message, as its ID is not the one I expect. in comm %p, %u, " "from pid %ld to pid %ld, with tag %d", ref->comm_, ref->comm_->get_received_messages_count(ref->comm_->group()->rank(req->src_), ref->comm_->group()->rank(req->dst_), req->tag_), - req->message_id_, req->src_, req->dst_, req->tag_); + req->src_, req->dst_, req->tag_); } return match; } bool Request::match_send(void* a, void* b, simgrid::kernel::activity::CommImpl*) { - auto ref = static_cast(a); - auto req = static_cast(b); + auto* ref = static_cast(a); + auto* req = static_cast(b); return match_common(req, ref, req); } @@ -325,9 +323,9 @@ MPI_Request Request::irecv_init(void *buf, int count, MPI_Datatype datatype, int MPI_Request Request::ibsend(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - auto request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), - dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, - MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND | MPI_REQ_BSEND); + auto* request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), + dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, + MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND | MPI_REQ_BSEND); if(dst != MPI_PROC_NULL) request->start(); return request; @@ -335,9 +333,9 @@ MPI_Request Request::ibsend(const void *buf, int count, MPI_Datatype datatype, i MPI_Request Request::isend(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - auto request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), - dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, - MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND); + auto* request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), + dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, + MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND); if(dst != MPI_PROC_NULL) request->start(); return request; @@ -345,9 +343,9 @@ MPI_Request Request::isend(const void *buf, int count, MPI_Datatype datatype, in MPI_Request Request::issend(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - auto request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), - dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, - MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SSEND | MPI_REQ_SEND); + auto* request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), + dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, + MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SSEND | MPI_REQ_SEND); if(dst != MPI_PROC_NULL) request->start(); return request; @@ -360,8 +358,8 @@ MPI_Request Request::irecv(void *buf, int count, MPI_Datatype datatype, int src, source = MPI_ANY_SOURCE; else if (src != MPI_PROC_NULL) source = comm->group()->actor(src); - auto request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, source, - simgrid::s4u::this_actor::get_pid(), tag, comm, MPI_REQ_NON_PERSISTENT | MPI_REQ_RECV); + auto* request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, source, + simgrid::s4u::this_actor::get_pid(), tag, comm, MPI_REQ_NON_PERSISTENT | MPI_REQ_RECV); if(src != MPI_PROC_NULL) request->start(); return request; @@ -371,43 +369,39 @@ int Request::recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, { MPI_Request request = irecv(buf, count, datatype, src, tag, comm); int retval = wait(&request,status); - request = nullptr; return retval; } void Request::bsend(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - auto request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), - dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, - MPI_REQ_NON_PERSISTENT | MPI_REQ_SEND | MPI_REQ_BSEND); + auto* request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), + dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, + MPI_REQ_NON_PERSISTENT | MPI_REQ_SEND | MPI_REQ_BSEND); if(dst != MPI_PROC_NULL) request->start(); wait(&request, MPI_STATUS_IGNORE); - request = nullptr; } void Request::send(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - auto request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), - dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, - MPI_REQ_NON_PERSISTENT | MPI_REQ_SEND); + auto* request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), + dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, + MPI_REQ_NON_PERSISTENT | MPI_REQ_SEND); if(dst != MPI_PROC_NULL) request->start(); wait(&request, MPI_STATUS_IGNORE); - request = nullptr; } void Request::ssend(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) { - auto request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), - dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, - MPI_REQ_NON_PERSISTENT | MPI_REQ_SSEND | MPI_REQ_SEND); + auto* request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(), + dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm, + MPI_REQ_NON_PERSISTENT | MPI_REQ_SSEND | MPI_REQ_SEND); if(dst != MPI_PROC_NULL) request->start(); wait(&request,MPI_STATUS_IGNORE); - request = nullptr; } void Request::sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,int dst, int sendtag, @@ -445,6 +439,29 @@ void Request::sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype } } +void Request::isendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,int dst, int sendtag, + void *recvbuf, int recvcount, MPI_Datatype recvtype, int src, int recvtag, + MPI_Comm comm, MPI_Request* request) +{ + aid_t source = MPI_PROC_NULL; + if (src == MPI_ANY_SOURCE) + source = MPI_ANY_SOURCE; + else if (src != MPI_PROC_NULL) + source = comm->group()->actor(src); + aid_t destination = dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL; + + (*request) = new Request( nullptr, 0, MPI_BYTE, + src,dst, sendtag, comm, MPI_REQ_PERSISTENT|MPI_REQ_NBC); + std::vector requests; + if (aid_t myid = simgrid::s4u::this_actor::get_pid(); (destination == myid) && (source == myid)) { + Datatype::copy(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype); + return; + } + requests.push_back(isend_init(sendbuf, sendcount, sendtype, dst, sendtag, comm)); + requests.push_back(irecv_init(recvbuf, recvcount, recvtype, src, recvtag, comm)); + (*request)->start_nbc_requests(requests); +} + void Request::start() { s4u::Mailbox* mailbox; @@ -466,9 +483,9 @@ void Request::start() simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(dst_)); - simgrid::s4u::MutexPtr mut = process->mailboxes_mutex(); + std::unique_lock mut_lock; if (smpi_cfg_async_small_thresh() != 0 || (flags_ & MPI_REQ_RMA) != 0) - mut->lock(); + mut_lock = std::unique_lock(*process->mailboxes_mutex()); bool is_probe = ((flags_ & MPI_REQ_PROBE) != 0); flags_ |= MPI_REQ_PROBE; @@ -506,7 +523,7 @@ void Request::start() XBT_DEBUG("yes there was something for us in the small mailbox"); } } - if(!is_probe) + if (not is_probe) flags_ &= ~MPI_REQ_PROBE; kernel::actor::CommIrecvSimcall observer{process->get_actor()->get_impl(), mailbox->get_impl(), @@ -516,36 +533,32 @@ void Request::start() process->replaying() ? &smpi_comm_null_copy_buffer_callback : smpi_comm_copy_data_callback, this, - -1.0}; + -1.0, + process->call_location()->get_call_location()}; observer.set_tag(tag_); action_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::CommImpl::irecv(&observer); }, &observer); XBT_DEBUG("recv simcall posted"); - - if (smpi_cfg_async_small_thresh() != 0 || (flags_ & MPI_REQ_RMA) != 0) - mut->unlock(); } else { /* the RECV flag was not set, so this is a send */ - const simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(dst_)); + simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(dst_)); xbt_assert(process, "Actor pid=%ld is gone??", dst_); if (TRACE_smpi_view_internals()) TRACE_smpi_send(src_, src_, dst_, tag_, size_); this->print_request("New send"); - message_id_=comm_->get_sent_messages_count(comm_->group()->rank(src_), comm_->group()->rank(dst_), tag_); + message_id_.push_back(comm_->get_sent_messages_count(comm_->group()->rank(src_), comm_->group()->rank(dst_), tag_)); comm_->increment_sent_messages_count(comm_->group()->rank(src_), comm_->group()->rank(dst_), tag_); void* buf = buf_; - if ((flags_ & MPI_REQ_SSEND) == 0 && - ((flags_ & MPI_REQ_RMA) != 0 || (flags_ & MPI_REQ_BSEND) != 0 || - static_cast(size_) < smpi_cfg_detached_send_thresh())) { - void *oldbuf = nullptr; + if ((flags_ & MPI_REQ_SSEND) == 0 && ((flags_ & MPI_REQ_RMA) != 0 || (flags_ & MPI_REQ_BSEND) != 0 || + static_cast(size_) < smpi_cfg_detached_send_thresh())) { detached_ = true; XBT_DEBUG("Send request %p is detached", this); this->ref(); if (not(type_->flags() & DT_FLAG_DERIVED)) { - oldbuf = buf_; + void* oldbuf = buf_; if (not process->replaying() && oldbuf != nullptr && size_ != 0) { if (smpi_switch_data_segment(simgrid::s4u::Actor::by_pid(src_), buf_)) XBT_DEBUG("Privatization : We are sending from a zone inside global memory. Switch data segment "); @@ -577,10 +590,9 @@ void Request::start() XBT_DEBUG("sending size of %zu : sleep %f ", size_, sleeptime); } - simgrid::s4u::MutexPtr mut = process->mailboxes_mutex(); - + std::unique_lock mut_lock; if (smpi_cfg_async_small_thresh() != 0 || (flags_ & MPI_REQ_RMA) != 0) - mut->lock(); + mut_lock = std::unique_lock(*process->mailboxes_mutex()); if (not(smpi_cfg_async_small_thresh() != 0 || (flags_ & MPI_REQ_RMA) != 0)) { mailbox = process->mailbox(); @@ -607,7 +619,7 @@ void Request::start() } else { XBT_DEBUG("Yes there was something for us in the large mailbox"); } - if(!is_probe) + if (not is_probe) flags_ &= ~MPI_REQ_PROBE; } else { mailbox = process->mailbox(); @@ -621,7 +633,7 @@ void Request::start() &xbt_free_f, // how to free the userdata if a detached send fails process->replaying() ? &smpi_comm_null_copy_buffer_callback : smpi_comm_copy_data_callback, this, // detach if msg size < eager/rdv switch limit - detached_}; + detached_, process->call_location()->get_call_location()}; observer.set_tag(tag_); action_ = kernel::actor::simcall_answered([&observer] { return kernel::activity::CommImpl::isend(&observer); }, &observer); @@ -632,9 +644,6 @@ void Request::start() boost::static_pointer_cast(action_)->set_tracing_category( smpi_process()->get_tracing_category()); } - - if (smpi_cfg_async_small_thresh() != 0 || ((flags_ & MPI_REQ_RMA) != 0)) - mut->unlock(); } } @@ -681,7 +690,9 @@ int Request::test(MPI_Request * request, MPI_Status * status, int* flag) { if ((*request)->action_ != nullptr && ((*request)->flags_ & MPI_REQ_CANCELLED) == 0){ try{ kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActivityTestSimcall observer{issuer, (*request)->action_.get()}; + simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(issuer->get_pid())); + kernel::actor::ActivityTestSimcall observer{issuer, (*request)->action_.get(), + process->call_location()->get_call_location()}; *flag = kernel::actor::simcall_answered( [&observer] { return observer.get_activity()->test(observer.get_issuer()); }, &observer); } catch (const Exception&) { @@ -770,7 +781,8 @@ int Request::testany(int count, MPI_Request requests[], int *index, int* flag, M ssize_t i; try{ kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActivityTestanySimcall observer{issuer, comms}; + simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(issuer->get_pid())); + kernel::actor::ActivityTestanySimcall observer{issuer, comms, process->call_location()->get_call_location()}; i = kernel::actor::simcall_answered( [&observer] { return kernel::activity::ActivityImpl::test_any(observer.get_issuer(), observer.get_activities()); @@ -872,7 +884,7 @@ void Request::iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* static int nsleeps = 1; double speed = s4u::this_actor::get_host()->get_speed(); double maxrate = smpi_cfg_iprobe_cpu_usage(); - auto request = + auto* request = new Request(nullptr, 0, MPI_CHAR, source == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : comm->group()->actor(source), simgrid::s4u::this_actor::get_pid(), tag, comm, MPI_REQ_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PROBE); if (smpi_iprobe_sleep > 0) { @@ -1086,7 +1098,9 @@ int Request::wait(MPI_Request * request, MPI_Status * status) try{ // this is not a detached send kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActivityWaitSimcall observer{issuer, (*request)->action_.get(), -1}; + simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(issuer->get_pid())); + kernel::actor::ActivityWaitSimcall observer{issuer, (*request)->action_.get(), -1, + process->call_location()->get_call_location()}; kernel::actor::simcall_blocking([issuer, &observer] { observer.get_activity()->wait_for(issuer, -1); }, &observer); } catch (const CancelException&) { @@ -1096,9 +1110,8 @@ int Request::wait(MPI_Request * request, MPI_Status * status) if ((*request)->flags_ & MPI_REQ_GENERALIZED) { if (not((*request)->flags_ & MPI_REQ_COMPLETE)) { - ((*request)->generalized_funcs)->mutex->lock(); - ((*request)->generalized_funcs)->cond->wait(((*request)->generalized_funcs)->mutex); - ((*request)->generalized_funcs)->mutex->unlock(); + const std::scoped_lock lock(*(*request)->generalized_funcs->mutex); + (*request)->generalized_funcs->cond->wait((*request)->generalized_funcs->mutex); } MPI_Status tmp_status; MPI_Status* mystatus; @@ -1157,7 +1170,9 @@ int Request::waitany(int count, MPI_Request requests[], MPI_Status * status) ssize_t i; try{ kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self(); - kernel::actor::ActivityWaitanySimcall observer{issuer, comms, -1}; + simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(issuer->get_pid())); + kernel::actor::ActivityWaitanySimcall observer{issuer, comms, -1, + process->call_location()->get_call_location()}; i = kernel::actor::simcall_blocking( [&observer] { kernel::activity::ActivityImpl::wait_any_for(observer.get_issuer(), observer.get_activities(), @@ -1291,8 +1306,6 @@ void Request::free_f(int id) int Request::get_status(const Request* req, int* flag, MPI_Status* status) { - *flag=0; - if(req != MPI_REQUEST_NULL && req->action_ != nullptr) { req->iprobe(req->comm_->group()->rank(req->src_), req->tag_, req->comm_, flag, status); if(*flag) @@ -1336,10 +1349,9 @@ int Request::grequest_complete(MPI_Request request) { if ((not(request->flags_ & MPI_REQ_GENERALIZED)) || request->generalized_funcs->mutex == nullptr) return MPI_ERR_REQUEST; - request->generalized_funcs->mutex->lock(); + const std::scoped_lock lock(*request->generalized_funcs->mutex); request->flags_ |= MPI_REQ_COMPLETE; // in case wait would be called after complete request->generalized_funcs->cond->notify_one(); - request->generalized_funcs->mutex->unlock(); return MPI_SUCCESS; } diff --git a/src/smpi/mpi/smpi_status.cpp b/src/smpi/mpi/smpi_status.cpp index 9c6b765815..675fb2e4fe 100644 --- a/src/smpi/mpi/smpi_status.cpp +++ b/src/smpi/mpi/smpi_status.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/mpi/smpi_topo.cpp b/src/smpi/mpi/smpi_topo.cpp index 12ca7eca5f..48b723dc3c 100644 --- a/src/smpi/mpi/smpi_topo.cpp +++ b/src/smpi/mpi/smpi_topo.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/mpi/smpi_win.cpp b/src/smpi/mpi/smpi_win.cpp index c78dc3c18b..af63fe62d0 100644 --- a/src/smpi/mpi/smpi_win.cpp +++ b/src/smpi/mpi/smpi_win.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -17,6 +17,7 @@ #include "src/mc/mc_replay.hpp" #include +#include // std::scoped_lock XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_rma, smpi, "Logging specific to SMPI (RMA operations)"); @@ -90,12 +91,15 @@ int Win::del(Win* win){ colls::barrier(win->comm_); Comm::unref(win->comm_); - if (!win->lockers_.empty() || win->opened_ < 0){ + if (not win->lockers_.empty() || win->opened_ < 0) { XBT_WARN("Freeing a locked or opened window"); return MPI_ERR_WIN; } if (win->allocated_) xbt_free(win->base_); + for (auto m : {win->mut_, win->lock_mut_, win->atomic_mut_}) + if (m->get_owner() != nullptr) + m->unlock(); F2C::free_f(win->f2c_id()); win->cleanup_attr(); @@ -239,16 +243,14 @@ int Win::put(const void *origin_addr, int origin_count, MPI_Datatype origin_data if(request!=nullptr){ *request=sreq; }else{ - mut_->lock(); + const std::scoped_lock lock(*mut_); requests_.push_back(sreq); - mut_->unlock(); } //push request to receiver's win - recv_win->mut_->lock(); + const std::scoped_lock recv_lock(*recv_win->mut_); recv_win->requests_.push_back(rreq); rreq->start(); - recv_win->mut_->unlock(); } else { XBT_DEBUG("Entering MPI_Put from myself to myself, rank %d", target_rank); Datatype::copy(origin_addr, origin_count, origin_datatype, recv_addr, target_count, target_datatype); @@ -283,9 +285,9 @@ int Win::get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, //start the send, with another process than us as sender. sreq->start(); // push request to sender's win - send_win->mut_->lock(); - send_win->requests_.push_back(sreq); - send_win->mut_->unlock(); + if (const std::scoped_lock send_lock(*send_win->mut_); true) { + send_win->requests_.push_back(sreq); + } //start recv rreq->start(); @@ -293,9 +295,8 @@ int Win::get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, if(request!=nullptr){ *request=rreq; }else{ - mut_->lock(); + const std::scoped_lock lock(*mut_); requests_.push_back(rreq); - mut_->unlock(); } } else { Datatype::copy(send_addr, target_count, target_datatype, origin_addr, origin_count, origin_datatype); @@ -334,17 +335,16 @@ int Win::accumulate(const void *origin_addr, int origin_count, MPI_Datatype orig // start send sreq->start(); // push request to receiver's win - recv_win->mut_->lock(); - recv_win->requests_.push_back(rreq); - rreq->start(); - recv_win->mut_->unlock(); + if (const std::scoped_lock recv_lock(*recv_win->mut_); true) { + recv_win->requests_.push_back(rreq); + rreq->start(); + } if (request != nullptr) { *request = sreq; } else { - mut_->lock(); + const std::scoped_lock lock(*mut_); requests_.push_back(sreq); - mut_->unlock(); } // FIXME: The current implementation fails to ensure the correct ordering of the accumulate requests. The following @@ -367,7 +367,7 @@ int Win::get_accumulate(const void* origin_addr, int origin_count, MPI_Datatype XBT_DEBUG("Entering MPI_Get_accumulate from %d", target_rank); //need to be sure ops are correctly ordered, so finish request here ? slow. MPI_Request req = MPI_REQUEST_NULL; - send_win->atomic_mut_->lock(); + const std::scoped_lock lock(*send_win->atomic_mut_); get(result_addr, result_count, result_datatype, target_rank, target_disp, target_count, target_datatype, &req); if (req != MPI_REQUEST_NULL) @@ -377,7 +377,6 @@ int Win::get_accumulate(const void* origin_addr, int origin_count, MPI_Datatype target_disp, target_count, target_datatype, op, &req); if (req != MPI_REQUEST_NULL) Request::wait(&req, MPI_STATUS_IGNORE); - send_win->atomic_mut_->unlock(); return MPI_SUCCESS; } @@ -391,7 +390,7 @@ int Win::compare_and_swap(const void* origin_addr, const void* compare_addr, voi XBT_DEBUG("Entering MPI_Compare_and_swap with %d", target_rank); MPI_Request req = MPI_REQUEST_NULL; - send_win->atomic_mut_->lock(); + const std::scoped_lock lock(*send_win->atomic_mut_); get(result_addr, 1, datatype, target_rank, target_disp, 1, datatype, &req); if (req != MPI_REQUEST_NULL) @@ -400,7 +399,6 @@ int Win::compare_and_swap(const void* origin_addr, const void* compare_addr, voi put(origin_addr, 1, datatype, target_rank, target_disp, 1, datatype); } - send_win->atomic_mut_->unlock(); return MPI_SUCCESS; } @@ -614,7 +612,7 @@ int Win::finish_comms(){ // Without this, the vector could get redimensioned when another process pushes. // This would result in the array used by Request::waitall() to be invalidated. // Another solution would be to copy the data and cleanup the vector *before* Request::waitall - mut_->lock(); + const std::scoped_lock lock(*mut_); //Finish own requests int size = static_cast(requests_.size()); if (size > 0) { @@ -622,13 +620,12 @@ int Win::finish_comms(){ Request::waitall(size, treqs, MPI_STATUSES_IGNORE); requests_.clear(); } - mut_->unlock(); return size; } int Win::finish_comms(int rank){ // See comment about the mutex in finish_comms() above - mut_->lock(); + const std::scoped_lock lock(*mut_); // Finish own requests // Let's see if we're either the destination or the sender of this request // because we only wait for requests that we are responsible for. @@ -646,7 +643,6 @@ int Win::finish_comms(int rank){ Request::waitall(size, treqs, MPI_STATUSES_IGNORE); myreqqs.clear(); } - mut_->unlock(); return size; } diff --git a/src/smpi/plugins/ampi/ampi.cpp b/src/smpi/plugins/ampi/ampi.cpp index 35c981ac31..f287759afb 100644 --- a/src/smpi/plugins/ampi/ampi.cpp +++ b/src/smpi/plugins/ampi/ampi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/plugins/ampi/ampi.hpp b/src/smpi/plugins/ampi/ampi.hpp index 1923d739e1..1a88d01651 100644 --- a/src/smpi/plugins/ampi/ampi.hpp +++ b/src/smpi/plugins/ampi/ampi.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/plugins/ampi/instr_ampi.cpp b/src/smpi/plugins/ampi/instr_ampi.cpp index 99d5018cf9..485618ea81 100644 --- a/src/smpi/plugins/ampi/instr_ampi.cpp +++ b/src/smpi/plugins/ampi/instr_ampi.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/plugins/ampi/instr_ampi.hpp b/src/smpi/plugins/ampi/instr_ampi.hpp index 2d479735b1..3237a1ac4d 100644 --- a/src/smpi/plugins/ampi/instr_ampi.hpp +++ b/src/smpi/plugins/ampi/instr_ampi.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/smpi_main.c b/src/smpi/smpi_main.c index ac1f9f6e02..fdfc6d3ac6 100644 --- a/src/smpi/smpi_main.c +++ b/src/smpi/smpi_main.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/smpi/smpi_replay_main.cpp b/src/smpi/smpi_replay_main.cpp index 2762ca5be1..703ae54f88 100644 --- a/src/smpi/smpi_replay_main.cpp +++ b/src/smpi/smpi_replay_main.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -18,7 +18,7 @@ int main(int argc, char* argv[]) return 1; } - auto properties = simgrid::s4u::Actor::self()->get_properties(); + const auto* properties = simgrid::s4u::Actor::self()->get_properties(); if (properties->find("smpi_replay") == properties->end()) { XBT_ERROR("invalid smpireplaymain execution. Please use smpirun -replay instead."); return 1; diff --git a/src/smpi/smpicc.in b/src/smpi/smpicc.in index 6463ec80fb..4379ffea91 100755 --- a/src/smpi/smpicc.in +++ b/src/smpi/smpicc.in @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Copyright (c) 2007-2022. The SimGrid Team. +# Copyright (c) 2007-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it @@ -25,11 +25,7 @@ fi list_set CFLAGS @SMPI_C_FLAGS@ list_add LINKARGS -if [ "x@WIN32@" = "x1" ]; then - list_add CFLAGS "-include" "@includedir@/smpi/smpi_main.h" - list_add LINKARGS "@libdir@\libsimgrid.dll" -elif [ "x@APPLE@" = "x1" ]; then - list_add CFLAGS "-fPIC" +if [ "x@APPLE@" = "x1" ]; then if [ "x${SMPI_PRETEND_CC}" = "x" ]; then list_add CFLAGS "-include" "@includedir@/smpi/smpi_helpers.h" list_add LINKARGS "-shared" @@ -40,7 +36,6 @@ elif [ "x@APPLE@" = "x1" ]; then list_add LINKARGS "-lsimgrid" "-lm" ${LINKER_UNDEFINED_ERROR:+"-Wl,-undefined,error"} fi else - list_add CFLAGS "-fPIC" if [ "x${SMPI_PRETEND_CC}" = "x" ]; then list_add CFLAGS "-include" "@includedir@/smpi/smpi_helpers.h" list_add LINKARGS "-shared" @@ -78,7 +73,7 @@ while [ $# -gt 0 ]; do exit 0 ;; '-trace-call-location') - list_add_not_empty CMDARGS "-DTRACE_CALL_LOCATION" + list_add CMDARGS "-DTRACE_CALL_LOCATION" ;; '-compiler-version' | '--compiler-version') ${CC} --version @@ -93,6 +88,8 @@ while [ $# -gt 0 ]; do esac done +list_add CMDARGS "-fPIC" + list_set CMDLINE "${CC}" list_add_not_empty CMDLINE "${CFLAGS}" list_add_not_empty CMDLINE "${INCLUDEARGS}" diff --git a/src/smpi/smpicxx.in b/src/smpi/smpicxx.in index 944870c189..59c4eee3a9 100755 --- a/src/smpi/smpicxx.in +++ b/src/smpi/smpicxx.in @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Copyright (c) 2014-2022. The SimGrid Team. +# Copyright (c) 2014-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it @@ -25,11 +25,7 @@ else LINKER_UNDEFINED_ERROR="1" fi -if [ "x@WIN32@" = "x1" ]; then - list_add CXXFLAGS "-include" "@includedir@/smpi/smpi_main.h" - list_add LINKARGS "@libdir@\libsimgrid.dll" -elif [ "x@APPLE@" = "x1" ]; then - list_add CXXFLAGS "-fPIC" +if [ "x@APPLE@" = "x1" ]; then if [ "x${SMPI_PRETEND_CC}" = "x" ]; then list_add CXXFLAGS "-include" "@includedir@/smpi/smpi_helpers.h" list_add LINKARGS "-shared" @@ -40,7 +36,6 @@ elif [ "x@APPLE@" = "x1" ]; then list_add LINKARGS "-lsimgrid" "-lm" ${LINKER_UNDEFINED_ERROR:+"-Wl,-undefined,error"} fi else - list_add CXXFLAGS "-fPIC" if [ "x${SMPI_PRETEND_CC}" = "x" ]; then list_add CXXFLAGS "-include" "@includedir@/smpi/smpi_helpers.h" list_add LINKARGS "-shared" @@ -90,6 +85,8 @@ while [ $# -gt 0 ]; do esac done +list_add CMDARGS "-fPIC" + list_set CMDLINE "${CXX}" list_add_not_empty CMDLINE "${CXXFLAGS}" list_add_not_empty CMDLINE "${INCLUDEARGS}" diff --git a/src/smpi/smpif90.in b/src/smpi/smpif90.in index a8a95db973..e8c7a9d9d2 100644 --- a/src/smpi/smpif90.in +++ b/src/smpi/smpif90.in @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/src/smpi/smpiff.in b/src/smpi/smpiff.in index a5e8ccf3ee..17c4c82440 100644 --- a/src/smpi/smpiff.in +++ b/src/smpi/smpiff.in @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -128,7 +128,7 @@ while [ $# -gt 0 ]; do TRACE_CALL_LOCATION=1 # This should be list_add FFLAGS but it's not possible # anymore: FFLAGS was already moved into CMDLINE above. - list_add_not_empty CMDLINE "-ffixed-line-length-none" "-cpp" + list_add CMDLINE "-ffixed-line-length-none" "-cpp" ;; -o) list_add CMDLINE "-o$1" diff --git a/src/smpi/smpirun.in b/src/smpi/smpirun.in index 953a18e071..194934f9e8 100755 --- a/src/smpi/smpirun.in +++ b/src/smpi/smpirun.in @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -27,7 +27,7 @@ PRIVATIZE="--cfg=smpi/privatization:${SMPI_PRIVATIZATION:-@HAVE_PRIVATIZATION@}" NUMPROCS=0 DEPLOYOPTS="" -SIMOPTS="--cfg=surf/precision:1e-9 --cfg=network/model:SMPI" +SIMOPTS="--cfg=precision/timing:1e-9 --cfg=network/model:SMPI" SMPITMPDIR="$(dirname $(mktemp -u))" @@ -59,6 +59,8 @@ Options: -version # Displays the SimGrid version (human readable) -git-version # Displays the git hash of SimGrid + -help # Displays this information + -help-coll # Displays all available collective algorithms or (deprecated usage): $0 [-keep-temps] [-np ] [-bandwidth ] [-latency ] program [program-options] @@ -233,13 +235,17 @@ while true; do shift 1 ;; "-analyze") - SIMOPTS="$SIMOPTS --cfg=smpi/display-timing:yes --cfg=smpi/display-allocs:yes --cfg=smpi/list-leaks:50 --cfg=smpi/pedantic:true" + SIMOPTS="$SIMOPTS --cfg=smpi/display-timing:yes --cfg=smpi/display-allocs:yes --cfg=smpi/list-leaks:50 --cfg=smpi/pedantic:true --cfg=smpi/barrier-collectives:true" shift 1 ;; "-help" | "--help" | "-h") usage exit 0 ;; + "-help-coll" | "--help-coll") + ${WRAPPER} "@SMPIMAIN@" --help-coll + exit 0 + ;; "-version" | "--version" | "-v") printf '%b\n' "$SIMGRID_VERSION" exit 0 diff --git a/src/smpi/smpitools.sh b/src/smpi/smpitools.sh index 3dda8a07de..81d20aba69 100644 --- a/src/smpi/smpitools.sh +++ b/src/smpi/smpitools.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -# Copyright (c) 2013-2022. The SimGrid Team. +# Copyright (c) 2013-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/src/sthread/ObjectAccess.cpp b/src/sthread/ObjectAccess.cpp new file mode 100644 index 0000000000..25e9b52c32 --- /dev/null +++ b/src/sthread/ObjectAccess.cpp @@ -0,0 +1,143 @@ +/* Copyright (c) 2002-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +/* Object access checker, for use in sthread. */ + +#include "simgrid/modelchecker.h" +#include "simgrid/s4u/Actor.hpp" +#include "simgrid/simix.hpp" +#include "src/kernel/actor/ActorImpl.hpp" +#include "src/kernel/actor/SimcallObserver.hpp" +#include "src/sthread/sthread.h" +#include "xbt/string.hpp" + +#include + +XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(sthread); + +namespace simgrid::sthread { +XBT_DECLARE_ENUM_CLASS(AccessType, ENTER, EXIT, BOTH); + +class ObjectAccessObserver final : public simgrid::kernel::actor::SimcallObserver { + AccessType type_; + void* objaddr_; + const char* objname_; + const char* file_; + int line_; + +public: + ObjectAccessObserver(simgrid::kernel::actor::ActorImpl* actor, AccessType type, void* objaddr, const char* objname, + const char* file, int line) + : SimcallObserver(actor), type_(type), objaddr_(objaddr), objname_(objname), file_(file), line_(line) + { + } + void serialize(std::stringstream& stream) const override; + std::string to_string() const override; +}; +void ObjectAccessObserver::serialize(std::stringstream& stream) const +{ + stream << (short)mc::Transition::Type::OBJECT_ACCESS << ' '; + stream << (short)type_ << ' ' << objaddr_ << ' ' << objname_ << ' ' << file_ << ' ' << line_; +} +std::string ObjectAccessObserver::to_string() const +{ + return std::string("AccessObject(") + objname_ + ")"; +} +}; // namespace simgrid::sthread + +struct ObjectOwner { + simgrid::kernel::actor::ActorImpl* owner = nullptr; + const char* file = nullptr; + int line = -1; + int recursive_depth = 0; + explicit ObjectOwner(simgrid::kernel::actor::ActorImpl* o) : owner(o) {} +}; + +std::unordered_map owners; +static void clean_owners() +{ + for (auto it = owners.begin(); it != owners.end();) { + delete it->second; + it = owners.erase(it); + } +} +static ObjectOwner* get_owner(void* object) +{ + if (owners.empty()) + std::atexit(clean_owners); + if (auto it = owners.find(object); it != owners.end()) + return it->second; + auto* o = new ObjectOwner(nullptr); + owners.emplace(object, o); + return o; +} + +int sthread_access_begin(void* objaddr, const char* objname, const char* file, int line, const char* func) +{ + sthread_disable(); + auto* self = simgrid::kernel::actor::ActorImpl::self(); + simgrid::sthread::ObjectAccessObserver observer(self, simgrid::sthread::AccessType::ENTER, objaddr, objname, file, + line); + bool success = simgrid::kernel::actor::simcall_answered( + [self, objaddr, objname, file, line]() -> bool { + XBT_INFO("%s takes %s", self->get_cname(), objname); + auto* ownership = get_owner(objaddr); + if (ownership->owner == self) { + ownership->recursive_depth++; + return true; + } else if (ownership->owner != nullptr) { + auto msg = std::string("Unprotected concurent access to ") + objname + ": " + ownership->owner->get_name(); + if (not xbt_log_no_loc) { + msg += simgrid::xbt::string_printf(" at %s:%d", ownership->file, ownership->line); + if (ownership->recursive_depth > 1) { + msg += simgrid::xbt::string_printf(" (and %d other locations)", ownership->recursive_depth - 1); + if (ownership->recursive_depth != 2) + msg += "s"; + } + } else { + msg += simgrid::xbt::string_printf(" from %d location", ownership->recursive_depth); + if (ownership->recursive_depth != 1) + msg += "s"; + } + msg += " vs " + self->get_name(); + if (xbt_log_no_loc) + msg += std::string(" (locations hidden because of --log=no_loc)."); + else + msg += simgrid::xbt::string_printf(" at %s:%d.", file, line); + XBT_CRITICAL("%s", msg.c_str()); + return false; + } + ownership->owner = self; + ownership->file = file; + ownership->line = line; + ownership->recursive_depth = 1; + return true; + }, + &observer); + MC_assert(success); + xbt_assert(success, "Problem detected, bailing out"); + sthread_enable(); + return true; +} +void sthread_access_end(void* objaddr, const char* objname, const char* file, int line, const char* func) +{ + sthread_disable(); + auto* self = simgrid::kernel::actor::ActorImpl::self(); + simgrid::sthread::ObjectAccessObserver observer(self, simgrid::sthread::AccessType::EXIT, objaddr, objname, file, + line); + simgrid::kernel::actor::simcall_answered( + [self, objaddr, objname]() -> void { + XBT_INFO("%s releases %s", self->get_cname(), objname); + auto* ownership = get_owner(objaddr); + xbt_assert(ownership->owner == self, + "safety check failed: %s is not owner of the object it's releasing. That object owned by %s.", + self->get_cname(), (ownership->owner == nullptr ? "nobody" : ownership->owner->get_cname())); + ownership->recursive_depth--; + if (ownership->recursive_depth == 0) + ownership->owner = nullptr; + }, + &observer); + sthread_enable(); +} diff --git a/src/sthread/sthread.c b/src/sthread/sthread.c index 24213e0c72..ad27e3fa1d 100644 --- a/src/sthread/sthread.c +++ b/src/sthread/sthread.c @@ -1,44 +1,100 @@ +/* Copyright (c) 2002-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + /* SimGrid's pthread interposer. Redefinition of the pthread symbols (see the comment in sthread.h) */ #define _GNU_SOURCE -#include "src/internal_config.h" #include "src/sthread/sthread.h" +#include "src/internal_config.h" #include #include #include #include +#include #if HAVE_VALGRIND_H #include #include #endif -/* We don't want to intercept pthread within simgrid. Instead we should provide the real implem to simgrid */ +/* We don't want to intercept pthread within SimGrid. Instead we should provide the real implem to SimGrid */ static int (*raw_pthread_create)(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*); static int (*raw_pthread_join)(pthread_t, void**); -static int (*raw_mutex_init)(pthread_mutex_t*, const pthread_mutexattr_t*) = NULL; -static int (*raw_mutex_lock)(pthread_mutex_t*) = NULL; -static int (*raw_mutex_trylock)(pthread_mutex_t*) = NULL; -static int (*raw_mutex_unlock)(pthread_mutex_t*) = NULL; -static int (*raw_mutex_destroy)(pthread_mutex_t*) = NULL; -static sem_t* (*raw_sem_open)(const char*, int) = NULL; -static int (*raw_sem_init)(sem_t*, int, unsigned int) = NULL; -static int (*raw_sem_wait)(sem_t*) = NULL; -static int (*raw_sem_post)(sem_t*) = NULL; +static int (*raw_pthread_mutex_init)(pthread_mutex_t*, const pthread_mutexattr_t*); +static int (*raw_pthread_mutex_lock)(pthread_mutex_t*); +static int (*raw_pthread_mutex_trylock)(pthread_mutex_t*); +static int (*raw_pthread_mutex_unlock)(pthread_mutex_t*); +static int (*raw_pthread_mutex_destroy)(pthread_mutex_t*); + +static int (*raw_pthread_mutexattr_init)(pthread_mutexattr_t*); +static int (*raw_pthread_mutexattr_settype)(pthread_mutexattr_t*, int); +static int (*raw_pthread_mutexattr_gettype)(const pthread_mutexattr_t*, int*); +static int (*raw_pthread_mutexattr_getrobust)(const pthread_mutexattr_t*, int*); +static int (*raw_pthread_mutexattr_setrobust)(pthread_mutexattr_t*, int); + +static int (*raw_pthread_barrier_init)(pthread_barrier_t*, const pthread_barrierattr_t*, unsigned int count); +static int (*raw_pthread_barrier_wait)(pthread_barrier_t*); +static int (*raw_pthread_barrier_destroy)(pthread_barrier_t*); + +static int (*raw_pthread_cond_init)(pthread_cond_t*, const pthread_condattr_t*); +static int (*raw_pthread_cond_signal)(pthread_cond_t*); +static int (*raw_pthread_cond_broadcast)(pthread_cond_t*); +static int (*raw_pthread_cond_wait)(pthread_cond_t*, pthread_mutex_t*); +static int (*raw_pthread_cond_timedwait)(pthread_cond_t*, pthread_mutex_t*, const struct timespec* abstime); +static int (*raw_pthread_cond_destroy)(pthread_cond_t*); + +static unsigned int (*raw_sleep)(unsigned int); +static int (*raw_usleep)(useconds_t); +static int (*raw_gettimeofday)(struct timeval*, void*); + +static sem_t* (*raw_sem_open)(const char*, int); +static int (*raw_sem_init)(sem_t*, int, unsigned int); +static int (*raw_sem_wait)(sem_t*); +static int (*raw_sem_post)(sem_t*); +static int (*raw_sem_destroy)(sem_t*); +static int (*raw_sem_trywait)(sem_t*); +static int (*raw_sem_timedwait)(sem_t*, const struct timespec*); + static void intercepter_init() { - raw_pthread_create = (typeof(raw_pthread_create))dlsym(RTLD_NEXT, "pthread_create"); - raw_pthread_join = (typeof(raw_pthread_join))dlsym(RTLD_NEXT, "pthread_join"); - raw_mutex_init = (int (*)(pthread_mutex_t*, const pthread_mutexattr_t*))dlsym(RTLD_NEXT, "pthread_mutex_init"); - raw_mutex_lock = (int (*)(pthread_mutex_t*))dlsym(RTLD_NEXT, "pthread_mutex_lock"); - raw_mutex_trylock = (int (*)(pthread_mutex_t*))dlsym(RTLD_NEXT, "pthread_mutex_trylock"); - raw_mutex_unlock = (int (*)(pthread_mutex_t*))dlsym(RTLD_NEXT, "pthread_mutex_unlock"); - raw_mutex_destroy = (int (*)(pthread_mutex_t*))dlsym(RTLD_NEXT, "pthread_mutex_destroy"); - - raw_sem_open = (sem_t * (*)(const char*, int)) dlsym(RTLD_NEXT, "sem_open"); - raw_sem_init = (int (*)(sem_t*, int, unsigned int))dlsym(RTLD_NEXT, "sem_init"); - raw_sem_wait = (int (*)(sem_t*))dlsym(RTLD_NEXT, "sem_wait"); - raw_sem_post = (int (*)(sem_t*))dlsym(RTLD_NEXT, "sem_post"); + raw_pthread_create = dlsym(RTLD_NEXT, "pthread_create"); + raw_pthread_join = dlsym(RTLD_NEXT, "pthread_join"); + raw_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init"); + raw_pthread_mutex_lock = dlsym(RTLD_NEXT, "pthread_mutex_lock"); + raw_pthread_mutex_trylock = dlsym(RTLD_NEXT, "pthread_mutex_trylock"); + raw_pthread_mutex_unlock = dlsym(RTLD_NEXT, "pthread_mutex_unlock"); + raw_pthread_mutex_destroy = dlsym(RTLD_NEXT, "pthread_mutex_destroy"); + + raw_pthread_mutexattr_init = dlsym(RTLD_NEXT, "pthread_mutexattr_init"); + raw_pthread_mutexattr_settype = dlsym(RTLD_NEXT, "pthread_mutexattr_settype"); + raw_pthread_mutexattr_gettype = dlsym(RTLD_NEXT, "pthread_mutexattr_gettype"); + raw_pthread_mutexattr_getrobust = dlsym(RTLD_NEXT, "pthread_mutexattr_getrobust"); + raw_pthread_mutexattr_setrobust = dlsym(RTLD_NEXT, "pthread_mutexattr_setrobust"); + + raw_pthread_barrier_init = dlsym(RTLD_NEXT, "raw_pthread_barrier_init"); + raw_pthread_barrier_wait = dlsym(RTLD_NEXT, "raw_pthread_barrier_wait"); + raw_pthread_barrier_destroy = dlsym(RTLD_NEXT, "raw_pthread_barrier_destroy"); + + raw_pthread_cond_init = dlsym(RTLD_NEXT, "raw_pthread_cond_init"); + raw_pthread_cond_signal = dlsym(RTLD_NEXT, "raw_pthread_cond_signal"); + raw_pthread_cond_broadcast = dlsym(RTLD_NEXT, "raw_pthread_cond_broadcast"); + raw_pthread_cond_wait = dlsym(RTLD_NEXT, "raw_pthread_cond_wait"); + raw_pthread_cond_timedwait = dlsym(RTLD_NEXT, "raw_pthread_cond_timedwait"); + raw_pthread_cond_destroy = dlsym(RTLD_NEXT, "raw_pthread_cond_destroy"); + + raw_sleep = dlsym(RTLD_NEXT, "sleep"); + raw_usleep = dlsym(RTLD_NEXT, "usleep"); + raw_gettimeofday = dlsym(RTLD_NEXT, "gettimeofday"); + + raw_sem_open = dlsym(RTLD_NEXT, "sem_open"); + raw_sem_init = dlsym(RTLD_NEXT, "sem_init"); + raw_sem_wait = dlsym(RTLD_NEXT, "sem_wait"); + raw_sem_post = dlsym(RTLD_NEXT, "sem_post"); + raw_sem_destroy = dlsym(RTLD_NEXT, "sem_destroy"); + raw_sem_trywait = dlsym(RTLD_NEXT, "sem_trywait"); + raw_sem_timedwait = dlsym(RTLD_NEXT, "sem_timedwait"); } static int sthread_inside_simgrid = 1; @@ -50,151 +106,94 @@ void sthread_disable(void) { // Stop intercepting all pthread calls sthread_inside_simgrid = 1; } -int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine)(void*), void* arg) -{ - if (raw_pthread_create == NULL) - intercepter_init(); - - if (sthread_inside_simgrid) - return raw_pthread_create(thread, attr, start_routine, arg); - - sthread_inside_simgrid = 1; - int res = sthread_create(thread, attr, start_routine, arg); - sthread_inside_simgrid = 0; - return res; -} -int pthread_join(pthread_t thread, void** retval) -{ - if (raw_pthread_join == NULL) - intercepter_init(); - - if (sthread_inside_simgrid) - return raw_pthread_join(thread, retval); - - sthread_inside_simgrid = 1; - int res = sthread_join(thread, retval); - sthread_inside_simgrid = 0; - return res; -} - -int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr) -{ - if (raw_mutex_init == NULL) - intercepter_init(); - - if (sthread_inside_simgrid) - return raw_mutex_init(mutex, attr); - - sthread_inside_simgrid = 1; - int res = sthread_mutex_init((sthread_mutex_t*)mutex, attr); - sthread_inside_simgrid = 0; - return res; -} - -int pthread_mutex_lock(pthread_mutex_t* mutex) -{ - if (raw_mutex_lock == NULL) - intercepter_init(); - - if (sthread_inside_simgrid) - return raw_mutex_lock(mutex); - - sthread_inside_simgrid = 1; - int res = sthread_mutex_lock((sthread_mutex_t*)mutex); - sthread_inside_simgrid = 0; - return res; -} - -int pthread_mutex_trylock(pthread_mutex_t* mutex) -{ - if (raw_mutex_trylock == NULL) - intercepter_init(); - - if (sthread_inside_simgrid) - return raw_mutex_trylock(mutex); - - sthread_inside_simgrid = 1; - int res = sthread_mutex_trylock((sthread_mutex_t*)mutex); - sthread_inside_simgrid = 0; - return res; -} - -int pthread_mutex_unlock(pthread_mutex_t* mutex) -{ - if (raw_mutex_unlock == NULL) - intercepter_init(); - - if (sthread_inside_simgrid) - return raw_mutex_unlock(mutex); - - sthread_inside_simgrid = 1; - int res = sthread_mutex_unlock((sthread_mutex_t*)mutex); - sthread_inside_simgrid = 0; - return res; -} -int pthread_mutex_destroy(pthread_mutex_t* mutex) -{ - if (raw_mutex_destroy == NULL) - intercepter_init(); - - if (sthread_inside_simgrid) - return raw_mutex_destroy(mutex); - - sthread_inside_simgrid = 1; - int res = sthread_mutex_destroy((sthread_mutex_t*)mutex); - sthread_inside_simgrid = 0; - return res; -} - -#if 0 -int sem_init(sem_t *sem, int pshared, unsigned int value) { - int res; - - res=raw_sem_init(sem,pshared,value); - return res; -} -int sem_wait(sem_t *sem) { - int res; - - res = raw_sem_wait(sem); - return res; -} - -int sem_post(sem_t *sem) { - return raw_sem_post(sem); -} - -int pthread_join(pthread_t thread, void **retval) { - sg_actor_join(thread, -1); - return 0; -} - -int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr) { - *cond = sg_cond_init(); - return 0; -} - -int pthread_cond_signal(pthread_cond_t *cond) { - sg_cond_notify_one(*cond); - return 0; -} - -int pthread_cond_broadcast(pthread_cond_t *cond) { - sg_cond_notify_all(*cond); - return 0; -} - -int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { - sg_cond_wait(*cond, *mutex); - return 0; -} - -int pthread_cond_destroy(pthread_cond_t *cond) { - sg_cond_destroy(*cond); - return 0; -} +#define _STHREAD_CONCAT(a, b) a##b +#define intercepted_pthcall(name, raw_params, call_params, sim_params) \ + int _STHREAD_CONCAT(pthread_, name) raw_params \ + { \ + if (_STHREAD_CONCAT(raw_pthread_, name) == NULL) \ + intercepter_init(); \ + if (sthread_inside_simgrid) \ + return _STHREAD_CONCAT(raw_pthread_, name) call_params; \ + \ + sthread_disable(); \ + int res = _STHREAD_CONCAT(sthread_, name) sim_params; \ + sthread_enable(); \ + return res; \ + } + +intercepted_pthcall(mutexattr_init, (pthread_mutexattr_t * attr), (attr), ((sthread_mutexattr_t*)attr)); +intercepted_pthcall(mutexattr_settype, (pthread_mutexattr_t * attr, int type), (attr, type), + ((sthread_mutexattr_t*)attr, type)); +intercepted_pthcall(mutexattr_gettype, (const pthread_mutexattr_t* attr, int* type), (attr, type), + ((sthread_mutexattr_t*)attr, type)); +intercepted_pthcall(mutexattr_setrobust, (pthread_mutexattr_t * attr, int robustness), (attr, robustness), + ((sthread_mutexattr_t*)attr, robustness)); +intercepted_pthcall(mutexattr_getrobust, (const pthread_mutexattr_t* attr, int* robustness), (attr, robustness), + ((sthread_mutexattr_t*)attr, robustness)); + +intercepted_pthcall(create, (pthread_t * thread, const pthread_attr_t* attr, void* (*start_routine)(void*), void* arg), + (thread, attr, start_routine, arg), ((sthread_t*)thread, attr, start_routine, arg)); +intercepted_pthcall(join, (pthread_t thread, void** retval), (thread, retval), ((sthread_t)thread, retval)); + +intercepted_pthcall(mutex_init, (pthread_mutex_t * mutex, const pthread_mutexattr_t* attr), (mutex, attr), + ((sthread_mutex_t*)mutex, (sthread_mutexattr_t*)attr)); +intercepted_pthcall(mutex_lock, (pthread_mutex_t * mutex), (mutex), ((sthread_mutex_t*)mutex)); +intercepted_pthcall(mutex_trylock, (pthread_mutex_t * mutex), (mutex), ((sthread_mutex_t*)mutex)); +intercepted_pthcall(mutex_unlock, (pthread_mutex_t * mutex), (mutex), ((sthread_mutex_t*)mutex)); +intercepted_pthcall(mutex_destroy, (pthread_mutex_t * mutex), (mutex), ((sthread_mutex_t*)mutex)); + +intercepted_pthcall(barrier_init, (pthread_barrier_t * barrier, const pthread_barrierattr_t* attr, unsigned count), + (barrier, attr, count), ((sthread_barrier_t*)barrier, (const sthread_barrierattr_t*)attr, count)); +intercepted_pthcall(barrier_wait, (pthread_barrier_t* barrier),( barrier),((sthread_barrier_t*) barrier)); +intercepted_pthcall(barrier_destroy, (pthread_barrier_t* barrier),( barrier),((sthread_barrier_t*) barrier)); + +intercepted_pthcall(cond_init, (pthread_cond_t * cond, const pthread_condattr_t* attr), (cond, attr), + ((sthread_cond_t*)cond, (sthread_condattr_t*)attr)); +intercepted_pthcall(cond_signal, (pthread_cond_t * cond), (cond), ((sthread_cond_t*)cond)); +intercepted_pthcall(cond_broadcast, (pthread_cond_t * cond), (cond), ((sthread_cond_t*)cond)); +intercepted_pthcall(cond_wait, (pthread_cond_t * cond, pthread_mutex_t* mutex), (cond, mutex), + ((sthread_cond_t*)cond, (sthread_mutex_t*)mutex)); +intercepted_pthcall(cond_timedwait, (pthread_cond_t * cond, pthread_mutex_t* mutex, const struct timespec* abstime), + (cond, mutex, abstime), ((sthread_cond_t*)cond, (sthread_mutex_t*)mutex, abstime)); +intercepted_pthcall(cond_destroy, (pthread_cond_t * cond), (cond), ((sthread_cond_t*)cond)); + +#define intercepted_call(rettype, name, raw_params, call_params, sim_params) \ + rettype name raw_params \ + { \ + if (_STHREAD_CONCAT(raw_, name) == NULL) \ + intercepter_init(); \ + if (sthread_inside_simgrid) \ + return _STHREAD_CONCAT(raw_, name) call_params; \ + \ + sthread_disable(); \ + rettype res = _STHREAD_CONCAT(sthread_, name) sim_params; \ + sthread_enable(); \ + return res; \ + } + +intercepted_call(int, sem_init, (sem_t * sem, int pshared, unsigned int value), (sem, pshared, value), + ((sthread_sem_t*)sem, pshared, value)); +intercepted_call(int, sem_destroy, (sem_t * sem), (sem), ((sthread_sem_t*)sem)); +intercepted_call(int, sem_post, (sem_t * sem), (sem), ((sthread_sem_t*)sem)); +intercepted_call(int, sem_wait, (sem_t * sem), (sem), ((sthread_sem_t*)sem)); +intercepted_call(int, sem_trywait, (sem_t * sem), (sem), ((sthread_sem_t*)sem)); +intercepted_call(int, sem_timedwait, (sem_t * sem, const struct timespec* abs_timeout), (sem, abs_timeout), + ((sthread_sem_t*)sem, abs_timeout)); + +/* Glibc < 2.31 uses type "struct timezone *" for the second parameter of gettimeofday. + Other implementations use "void *" instead. */ +#ifdef __GLIBC__ +#if !__GLIBC_PREREQ(2, 31) +#define TIMEZONE_TYPE struct timezone +#endif +#endif +#ifndef TIMEZONE_TYPE +#define TIMEZONE_TYPE void #endif +intercepted_call(int, gettimeofday, (struct timeval * tv, XBT_ATTRIB_UNUSED TIMEZONE_TYPE* tz), (tv, tz), (tv)); +intercepted_call(unsigned int, sleep, (unsigned int seconds), (seconds), (seconds)); +intercepted_call(int, usleep, (useconds_t usec), (usec), (((double)usec) / 1000000.)); /* Trampoline for the real main() */ static int (*raw_main)(int, char**, char**); diff --git a/src/sthread/sthread.h b/src/sthread/sthread.h index 9bc6c50152..cf96500d2b 100644 --- a/src/sthread/sthread.h +++ b/src/sthread/sthread.h @@ -1,3 +1,8 @@ +/* Copyright (c) 2002-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + /* SimGrid's pthread interposer. Intercepts most of the pthread and semaphore calls to model-check them. * * Intercepting on pthread is somewhat complicated by the fact that pthread is used everywhere in the system headers. @@ -10,11 +15,8 @@ #ifndef SIMGRID_STHREAD_H #define SIMGRID_STHREAD_H -#if defined(__ELF__) -#define XBT_PUBLIC __attribute__((visibility("default"))) -#else -#define XBT_PUBLIC -#endif +#include "xbt/base.h" +#include #if defined(__cplusplus) extern "C" { @@ -29,17 +31,72 @@ typedef unsigned long int sthread_t; int sthread_create(sthread_t* thread, const /*pthread_attr_t*/ void* attr, void* (*start_routine)(void*), void* arg); int sthread_join(sthread_t thread, void** retval); +typedef struct { + unsigned recursive : 1; + unsigned errorcheck : 1; + unsigned robust : 1; +} sthread_mutexattr_t; + +int sthread_mutexattr_init(sthread_mutexattr_t* attr); +int sthread_mutexattr_settype(sthread_mutexattr_t* attr, int type); +int sthread_mutexattr_gettype(const sthread_mutexattr_t* attr, int* type); +int sthread_mutexattr_getrobust(const sthread_mutexattr_t* attr, int* robustness); +int sthread_mutexattr_setrobust(sthread_mutexattr_t* attr, int robustness); + typedef struct { void* mutex; } sthread_mutex_t; -int sthread_mutex_init(sthread_mutex_t* mutex, const /*pthread_mutexattr_t*/ void* attr); +int sthread_mutex_init(sthread_mutex_t* mutex, const sthread_mutexattr_t* attr); int sthread_mutex_lock(sthread_mutex_t* mutex); int sthread_mutex_trylock(sthread_mutex_t* mutex); int sthread_mutex_unlock(sthread_mutex_t* mutex); int sthread_mutex_destroy(sthread_mutex_t* mutex); +typedef struct { + unsigned unused : 1; +} sthread_barrierattr_t; + +typedef struct { + void* barrier; +} sthread_barrier_t; +int sthread_barrier_init(sthread_barrier_t* barrier, const sthread_barrierattr_t* attr, unsigned count); +int sthread_barrier_wait(sthread_barrier_t* barrier); +int sthread_barrier_destroy(sthread_barrier_t* barrier); + +typedef struct { + unsigned unused : 1; +} sthread_condattr_t; + +typedef struct { + void* cond; + void* mutex; +} sthread_cond_t; +int sthread_cond_init(sthread_cond_t* cond, sthread_condattr_t* attr); +int sthread_cond_signal(sthread_cond_t* cond); +int sthread_cond_broadcast(sthread_cond_t* cond); +int sthread_cond_wait(sthread_cond_t* cond, sthread_mutex_t* mutex); +int sthread_cond_timedwait(sthread_cond_t* cond, sthread_mutex_t* mutex, const struct timespec* abs_timeout); +int sthread_cond_destroy(sthread_cond_t* cond); + +typedef struct { + void* sem; +} sthread_sem_t; +int sthread_sem_init(sthread_sem_t* sem, int pshared, unsigned int value); +int sthread_sem_destroy(sthread_sem_t* sem); +int sthread_sem_post(sthread_sem_t* sem); +int sthread_sem_wait(sthread_sem_t* sem); +int sthread_sem_trywait(sthread_sem_t* sem); +int sthread_sem_timedwait(sthread_sem_t* sem, const struct timespec* abs_timeout); + +int sthread_gettimeofday(struct timeval* tv); +unsigned int sthread_sleep(double seconds); +int sthread_usleep(double seconds); + +int sthread_access_begin(void* objaddr, const char* objname, const char* file, int line, const char* function); +void sthread_access_end(void* objaddr, const char* objname, const char* file, int line, const char* function); + #if defined(__cplusplus) } #endif -#endif \ No newline at end of file +#endif diff --git a/src/sthread/sthread_impl.cpp b/src/sthread/sthread_impl.cpp index d1a88a7038..4a92967507 100644 --- a/src/sthread/sthread_impl.cpp +++ b/src/sthread/sthread_impl.cpp @@ -1,23 +1,37 @@ +/* Copyright (c) 2002-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + /* SimGrid's pthread interposer. Actual implementation of the symbols (see the comment in sthread.h) */ +#include "simgrid/s4u/Barrier.hpp" +#include "simgrid/s4u/ConditionVariable.hpp" #include "smpi/smpi.h" +#include "xbt/asserts.h" +#include "xbt/ex.h" +#include "xbt/log.h" +#include "xbt/string.hpp" #include #include #include #include #include +#include #include #include #include "src/internal_config.h" #include "src/sthread/sthread.h" +#include #include #include #include #include #include #include +#include #include XBT_LOG_NEW_DEFAULT_CATEGORY(sthread, "pthread intercepter"); @@ -29,14 +43,36 @@ int sthread_main(int argc, char** argv, char** envp, int (*raw_main)(int, char** { /* Do not intercept the main when run from SMPI: it will initialize the simulation properly */ for (int i = 0; envp[i] != nullptr; i++) - if (strncmp(envp[i], "SMPI_GLOBAL_SIZE", strlen("SMPI_GLOBAL_SIZE")) == 0) + if (std::string_view(envp[i]).rfind("SMPI_GLOBAL_SIZE", 0) == 0) { + printf("sthread refuses to intercept the SMPI application %s directly, as its interception is done otherwise.\n", + argv[0]); + return raw_main(argc, argv, envp); + } + + /* Do not intercept system binaries such as valgrind step 1 */ + std::vector binaries = {"/usr/bin/valgrind.bin", "/bin/sh", "/bin/bash", "gdb", "addr2line"}; + for (int i = 0; envp[i] != nullptr; i++) { + auto view = std::string_view(envp[i]); + /* If you want to ignore more than one binary, export STHREAD_IGNORE_BINARY1=toto STHREAD_IGNORE_BINARY2=tutu */ + /* Note that this cannot be configured with --cfg because we are before the main() */ + if (view.rfind("STHREAD_IGNORE_BINARY", 0) == 0) { + view.remove_prefix(std::min(view.rfind("=") + 1, view.size())); + binaries.push_back(std::string(view)); + } + } + auto binary_view = std::string_view(argv[0]); + for (auto binary : binaries) { + if (binary_view.rfind(binary) != std::string_view::npos) { + printf("sthread refuses to intercept the execution of %s. Running the application unmodified.\n", argv[0]); + fflush(stdout); return raw_main(argc, argv, envp); + } + } /* If not in SMPI, the old main becomes an actor in a newly created simulation */ - std::ostringstream id; - id << std::this_thread::get_id(); - - XBT_DEBUG("sthread main() is starting in thread %s", id.str().c_str()); + printf("sthread is intercepting the execution of %s. If it's not what you want, export STHREAD_IGNORE_BINARY=%s\n", + argv[0], argv[0]); + fflush(stdout); sg4::Engine e(&argc, argv); auto* zone = sg4::create_full_zone("world"); @@ -45,9 +81,8 @@ int sthread_main(int argc, char** argv, char** envp, int (*raw_main)(int, char** /* Launch the user's main() on an actor */ sthread_enable(); - sg4::ActorPtr main_actor = sg4::Actor::create("tid 0", lilibeth, raw_main, argc, argv, envp); + sg4::ActorPtr main_actor = sg4::Actor::create("main thread", lilibeth, raw_main, argc, argv, envp); - XBT_INFO("Starting the simulation."); sg4::Engine::get_instance()->run(); sthread_disable(); XBT_INFO("All threads exited. Terminating the simulation."); @@ -59,31 +94,32 @@ struct sthread_mutex { s4u_Mutex* mutex; }; -static void thread_create_wrapper(void* (*user_function)(void*), void* param) -{ -#if HAVE_SMPI - if (SMPI_is_inited()) - SMPI_thread_create(); -#endif - sthread_enable(); - user_function(param); - sthread_disable(); -} - int sthread_create(unsigned long int* thread, const void* /*pthread_attr_t* attr*/, void* (*start_routine)(void*), void* arg) { static int TID = 0; TID++; XBT_VERB("Create thread %d", TID); - int rank = 0; + std::string name = std::string("thread ") + std::to_string(TID); #if HAVE_SMPI - if (SMPI_is_inited()) + if (SMPI_is_inited()) { + int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); + name = simgrid::xbt::string_printf("%d:%d", rank, TID); + } #endif - std::string name = simgrid::xbt::string_printf("%d:%d", rank, TID); - sg4::ActorPtr actor = sg4::Actor::init(name.c_str(), lilibeth); - actor->start(thread_create_wrapper, start_routine, arg); + sg4::ActorPtr actor = sg4::Actor::create( + name, lilibeth, + [](auto* user_function, auto* param) { +#if HAVE_SMPI + if (SMPI_is_inited()) + SMPI_thread_create(); +#endif + sthread_enable(); + user_function(param); + sthread_disable(); + }, + start_routine, arg); intrusive_ptr_add_ref(actor.get()); *thread = reinterpret_cast(actor.get()); @@ -98,9 +134,57 @@ int sthread_join(sthread_t thread, void** /*retval*/) return 0; } -int sthread_mutex_init(sthread_mutex_t* mutex, const void* /*pthread_mutexattr_t* attr*/) +int sthread_mutexattr_init(sthread_mutexattr_t* attr) +{ + memset(attr, 0, sizeof(*attr)); + return 0; +} +int sthread_mutexattr_settype(sthread_mutexattr_t* attr, int type) +{ + switch (type) { + case PTHREAD_MUTEX_NORMAL: + xbt_assert(not attr->recursive, "S4U does not allow to remove the recursivness of a mutex."); + attr->recursive = 0; + break; + case PTHREAD_MUTEX_RECURSIVE: + attr->recursive = 1; + attr->errorcheck = 0; // reset + break; + case PTHREAD_MUTEX_ERRORCHECK: + attr->errorcheck = 1; + THROW_UNIMPLEMENTED; + break; + default: + THROW_IMPOSSIBLE; + } + return 0; +} +int sthread_mutexattr_gettype(const sthread_mutexattr_t* attr, int* type) +{ + if (attr->recursive) + *type = PTHREAD_MUTEX_RECURSIVE; + else if (attr->errorcheck) + *type = PTHREAD_MUTEX_ERRORCHECK; + else + *type = PTHREAD_MUTEX_NORMAL; + return 0; +} +int sthread_mutexattr_getrobust(const sthread_mutexattr_t* attr, int* robustness) +{ + *robustness = attr->robust; + return 0; +} +int sthread_mutexattr_setrobust(sthread_mutexattr_t* attr, int robustness) +{ + attr->robust = robustness; + if (robustness) + THROW_UNIMPLEMENTED; + return 0; +} + +int sthread_mutex_init(sthread_mutex_t* mutex, const sthread_mutexattr_t* attr) { - auto m = sg4::Mutex::create(); + auto m = sg4::Mutex::create(attr != nullptr && attr->recursive); intrusive_ptr_add_ref(m.get()); mutex->mutex = m.get(); @@ -109,72 +193,215 @@ int sthread_mutex_init(sthread_mutex_t* mutex, const void* /*pthread_mutexattr_t int sthread_mutex_lock(sthread_mutex_t* mutex) { + /* At least in glibc, PTHREAD_STATIC_INITIALIZER sets every fields to 0 */ + if (mutex->mutex == nullptr) + sthread_mutex_init(mutex, nullptr); + + XBT_DEBUG("%s(%p)", __func__, mutex); static_cast(mutex->mutex)->lock(); return 0; } int sthread_mutex_trylock(sthread_mutex_t* mutex) { - return static_cast(mutex->mutex)->try_lock(); + /* At least in glibc, PTHREAD_STATIC_INITIALIZER sets every fields to 0 */ + if (mutex->mutex == nullptr) + sthread_mutex_init(mutex, nullptr); + + XBT_DEBUG("%s(%p)", __func__, mutex); + if (static_cast(mutex->mutex)->try_lock()) + return 0; + return EBUSY; } int sthread_mutex_unlock(sthread_mutex_t* mutex) { + /* At least in glibc, PTHREAD_STATIC_INITIALIZER sets every fields to 0 */ + if (mutex->mutex == nullptr) + sthread_mutex_init(mutex, nullptr); + + XBT_DEBUG("%s(%p)", __func__, mutex); static_cast(mutex->mutex)->unlock(); return 0; } int sthread_mutex_destroy(sthread_mutex_t* mutex) { + /* At least in glibc, PTHREAD_STATIC_INITIALIZER sets every fields to 0 */ + if (mutex->mutex == nullptr) + sthread_mutex_init(mutex, nullptr); + + XBT_DEBUG("%s(%p)", __func__, mutex); intrusive_ptr_release(static_cast(mutex->mutex)); return 0; } -#if 0 -int sem_init(sem_t *sem, int pshared, unsigned int value) { - int res; +int sthread_barrier_init(sthread_barrier_t* barrier, const sthread_barrierattr_t* attr, unsigned count){ + auto b = sg4::Barrier::create(count); + intrusive_ptr_add_ref(b.get()); - res=raw_sem_init(sem,pshared,value); - return res; + barrier->barrier = b.get(); + return 0; +} +int sthread_barrier_wait(sthread_barrier_t* barrier){ + XBT_DEBUG("%s(%p)", __func__, barrier); + static_cast(barrier->barrier)->wait(); + return 0; +} +int sthread_barrier_destroy(sthread_barrier_t* barrier){ + XBT_DEBUG("%s(%p)", __func__, barrier); + intrusive_ptr_release(static_cast(barrier->barrier)); + return 0; } -int sem_wait(sem_t *sem) { - int res; +int sthread_cond_init(sthread_cond_t* cond, sthread_condattr_t* attr) +{ + auto cv = sg4::ConditionVariable::create(); + intrusive_ptr_add_ref(cv.get()); - res = raw_sem_wait(sem); - return res; + cond->cond = cv.get(); + cond->mutex = nullptr; + return 0; } - -int sem_post(sem_t *sem) { - return raw_sem_post(sem); +int sthread_cond_signal(sthread_cond_t* cond) +{ + XBT_DEBUG("%s(%p)", __func__, cond); + + if (cond->mutex == nullptr) + XBT_WARN("No mutex was associated so far with condition variable %p. Safety checks skipped.", cond); + else { + auto* owner = static_cast(cond->mutex)->get_owner(); + if (owner == nullptr) + XBT_WARN("The mutex associated to condition %p is not currently owned by anyone when calling " + "pthread_cond_signal(). The signal could get lost.", + cond); + else if (owner != simgrid::s4u::Actor::self()) + XBT_WARN("The mutex associated to condition %p is currently owned by %s, not by the thread currently calling " + "calling pthread_cond_signal(). The signal could get lost.", + cond, owner->get_cname()); + } + + static_cast(cond->cond)->notify_one(); + return 0; } - -int pthread_join(pthread_t thread, void **retval) { - sg_actor_join(thread, -1); - return 0; +int sthread_cond_broadcast(sthread_cond_t* cond) +{ + XBT_DEBUG("%s(%p)", __func__, cond); + + if (cond->mutex == nullptr) + XBT_WARN("No mutex was associated so far with condition variable %p. Safety checks skipped.", cond); + else { + auto* owner = static_cast(cond->mutex)->get_owner(); + if (owner == nullptr) + XBT_WARN("The mutex associated to condition %p is not currently owned by anyone when calling " + "pthread_cond_broadcast(). The signal could get lost.", + cond); + else if (owner != simgrid::s4u::Actor::self()) + XBT_WARN("The mutex associated to condition %p is currently owned by %s, not by the thread currently calling " + "calling pthread_cond_broadcast(). The signal could get lost.", + cond, owner->get_cname()); + } + + static_cast(cond->cond)->notify_all(); + return 0; } +int sthread_cond_wait(sthread_cond_t* cond, sthread_mutex_t* mutex) +{ + XBT_DEBUG("%s(%p)", __func__, cond); -int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr) { - *cond = sg_cond_init(); - return 0; + if (cond->mutex == nullptr) + cond->mutex = mutex->mutex; + else if (cond->mutex != mutex->mutex) + XBT_WARN("The condition %p is now waited with mutex %p while it was previoulsy waited with mutex %p. sthread may " + "not work with such a dangerous code.", + cond, cond->mutex, mutex->mutex); + + static_cast(cond->cond)->wait(static_cast(mutex->mutex)); + return 0; } +int sthread_cond_timedwait(sthread_cond_t* cond, sthread_mutex_t* mutex, const struct timespec* abs_timeout) +{ + XBT_DEBUG("%s(%p)", __func__, cond); -int pthread_cond_signal(pthread_cond_t *cond) { - sg_cond_notify_one(*cond); - return 0; + if (cond->mutex == nullptr) + cond->mutex = mutex->mutex; + else if (cond->mutex != mutex->mutex) + XBT_WARN("The condition %p is now waited with mutex %p while it was previoulsy waited with mutex %p. sthread may " + "not work with such a dangerous code.", + cond, cond->mutex, mutex->mutex); + + THROW_UNIMPLEMENTED; +} +int sthread_cond_destroy(sthread_cond_t* cond) +{ + XBT_DEBUG("%s(%p)", __func__, cond); + intrusive_ptr_release(static_cast(cond->cond)); + return 0; } -int pthread_cond_broadcast(pthread_cond_t *cond) { - sg_cond_notify_all(*cond); - return 0; +int sthread_sem_init(sthread_sem_t* sem, int /*pshared*/, unsigned int value) +{ + auto s = sg4::Semaphore::create(value); + intrusive_ptr_add_ref(s.get()); + + sem->sem = s.get(); + return 0; +} +int sthread_sem_destroy(sthread_sem_t* sem) +{ + intrusive_ptr_release(static_cast(sem->sem)); + return 0; +} +int sthread_sem_post(sthread_sem_t* sem) +{ + static_cast(sem->sem)->release(); + return 0; +} +int sthread_sem_wait(sthread_sem_t* sem) +{ + static_cast(sem->sem)->acquire(); + return 0; +} +int sthread_sem_trywait(sthread_sem_t* sem) +{ + auto* s = static_cast(sem->sem); + if (s->would_block()) { + errno = EAGAIN; + return -1; + } + s->acquire(); + return 0; +} +int sthread_sem_timedwait(sthread_sem_t* sem, const struct timespec* abs_timeout) +{ + if (static_cast(sem->sem)->acquire_timeout(static_cast(abs_timeout->tv_sec) + + static_cast(abs_timeout->tv_nsec) / 1E9)) { + errno = ETIMEDOUT; + return -1; + } + return 0; } -int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { - sg_cond_wait(*cond, *mutex); - return 0; +int sthread_gettimeofday(struct timeval* tv) +{ + if (tv) { + double now = simgrid::s4u::Engine::get_clock(); + double secs = trunc(now); + double usecs = (now - secs) * 1e6; + tv->tv_sec = static_cast(secs); + tv->tv_usec = static_casttv_usec)>(usecs); // suseconds_t + } + return 0; } -int pthread_cond_destroy(pthread_cond_t *cond) { - sg_cond_destroy(*cond); - return 0; +unsigned int sthread_sleep(double seconds) +{ + XBT_DEBUG("sleep(%lf)", seconds); + simgrid::s4u::this_actor::sleep_for(seconds); + return 0; +} +int sthread_usleep(double seconds) +{ + XBT_DEBUG("sleep(%lf)", seconds); + simgrid::s4u::this_actor::sleep_for(seconds); + return 0; } -#endif diff --git a/src/surf/network_smpi.cpp b/src/surf/network_smpi.cpp deleted file mode 100644 index 02d6a00d80..0000000000 --- a/src/surf/network_smpi.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include - -#include "simgrid/sg_config.hpp" -#include "smpi_utils.hpp" -#include "src/kernel/EngineImpl.hpp" -#include "src/surf/network_smpi.hpp" - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_network); - -/********* - * Model * - *********/ - -/************************************************************************/ -/* New model based on LV08 and experimental results of MPI ping-pongs */ -/************************************************************************/ -/* @Inproceedings{smpi_ipdps, */ -/* author={Pierre-Nicolas Clauss and Mark Stillwell and Stéphane Genaud and Frédéric Suter and Henri Casanova and - * Martin Quinson}, */ -/* title={Single Node On-Line Simulation of {MPI} Applications with SMPI}, */ -/* booktitle={25th IEEE International Parallel and Distributed Processing Symposium (IPDPS'11)}, */ -/* address={Anchorage (Alaska) USA}, */ -/* month=may, */ -/* year={2011} */ -/* } */ -void surf_network_model_init_SMPI() -{ - auto net_model = std::make_shared("Network_SMPI"); - auto* engine = simgrid::kernel::EngineImpl::get_instance(); - engine->add_model(net_model); - engine->get_netzone_root()->set_network_model(net_model); - - simgrid::config::set_default("network/weight-S", 8775); -} - -namespace simgrid::kernel::resource { - -void NetworkSmpiModel::check_lat_factor_cb() -{ - if (not simgrid::config::is_default("smpi/lat-factor")) { - throw std::invalid_argument( - "NetworkModelIntf: Cannot mix network/latency-factor and callback configuration. Choose only one of them."); - } -} - -void NetworkSmpiModel::check_bw_factor_cb() -{ - if (not simgrid::config::is_default("smpi/bw-factor")) { - throw std::invalid_argument( - "NetworkModelIntf: Cannot mix network/bandwidth-factor and callback configuration. Choose only one of them."); - } -} - -double NetworkSmpiModel::get_bandwidth_factor(double size) -{ - static std::vector smpi_bw_factor; - if (smpi_bw_factor.empty()) - smpi_bw_factor = smpi::utils::parse_factor(config::get_value("smpi/bw-factor")); - - double current = 1.0; - for (auto const& fact : smpi_bw_factor) { - if (size <= fact.factor) { - XBT_DEBUG("%f <= %zu return %f", size, fact.factor, current); - return current; - } else - current = fact.values.front(); - } - XBT_DEBUG("%f > %zu return %f", size, smpi_bw_factor.back().factor, current); - - return current; -} - -double NetworkSmpiModel::get_latency_factor(double size) -{ - static std::vector smpi_lat_factor; - if (smpi_lat_factor.empty()) - smpi_lat_factor = smpi::utils::parse_factor(config::get_value("smpi/lat-factor")); - - double current = 1.0; - for (auto const& fact : smpi_lat_factor) { - if (size <= fact.factor) { - XBT_DEBUG("%f <= %zu return %f", size, fact.factor, current); - return current; - } else - current = fact.values.front(); - } - XBT_DEBUG("%f > %zu return %f", size, smpi_lat_factor.back().factor, current); - - return current; -} -} // namespace simgrid::kernel::resource diff --git a/src/surf/network_smpi.hpp b/src/surf/network_smpi.hpp deleted file mode 100644 index a2c81fddfc..0000000000 --- a/src/surf/network_smpi.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SIMGRID_SURF_NETWORK_SMPI_HPP -#define SIMGRID_SURF_NETWORK_SMPI_HPP - -#include - -#include "network_cm02.hpp" - -namespace simgrid::kernel::resource { - -class XBT_PRIVATE NetworkSmpiModel : public NetworkCm02Model { -public: - using NetworkCm02Model::NetworkCm02Model; - - double get_latency_factor(double size) override; - double get_bandwidth_factor(double size) override; - -protected: - void check_lat_factor_cb() override; - void check_bw_factor_cb() override; -}; -} // namespace simgrid::kernel::resource - -#endif diff --git a/src/surf/surf_interface.cpp b/src/surf/surf_interface.cpp deleted file mode 100644 index 4766cdbbba..0000000000 --- a/src/surf/surf_interface.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include - -#include "mc/mc.h" -#include "simgrid/sg_config.hpp" -#include "src/kernel/resource/profile/FutureEvtSet.hpp" -#include "src/kernel/resource/profile/Profile.hpp" -#include "src/surf/HostImpl.hpp" -#include "src/surf/surf_interface.hpp" - -#include -#include - -#ifdef _WIN32 -#include -#endif - -XBT_LOG_NEW_CATEGORY(surf, "All SURF categories"); -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf, "Logging specific to SURF (kernel)"); - -/********* - * Utils * - *********/ - -simgrid::kernel::profile::FutureEvtSet future_evt_set; -std::vector surf_path; - -const std::vector surf_network_model_description = { - {"LV08", - "Realistic network analytic model (slow-start modeled by multiplying latency by 13.01, bandwidth by .97; " - "bottleneck sharing uses a payload of S=20537 for evaluating RTT). ", - &surf_network_model_init_LegrandVelho}, - {"Constant", - "Simplistic network model where all communication take a constant time (one second). This model " - "provides the lowest realism, but is (marginally) faster.", - &surf_network_model_init_Constant}, - {"SMPI", - "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with " - "correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)", - &surf_network_model_init_SMPI}, - {"IB", "Realistic network model specifically tailored for HPC settings, with Infiniband contention model", - &surf_network_model_init_IB}, - {"CM02", - "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of " - "small messages are thus poorly modeled).", - &surf_network_model_init_CM02}, - {"ns-3", "Network pseudo-model using the ns-3 tcp model instead of an analytic model", - &surf_network_model_init_NS3}, -}; - -#if !HAVE_SMPI -void surf_network_model_init_SMPI() -{ - xbt_die("Please activate SMPI support in cmake to use the SMPI network model."); -} -void surf_network_model_init_IB() -{ - xbt_die("Please activate SMPI support in cmake to use the IB network model."); -} -#endif -#if !SIMGRID_HAVE_NS3 -void surf_network_model_init_NS3() -{ - xbt_die("Please activate ns-3 support in cmake and install the dependencies to use the NS3 network model."); -} -#endif - -const std::vector surf_cpu_model_description = { - {"Cas01", "Simplistic CPU model (time=size/speed).", &surf_cpu_model_init_Cas01}, -}; - -const std::vector surf_host_model_description = { - {"default", "Default host model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)", - &surf_host_model_init_current_default}, - {"compound", "Host model that is automatically chosen if you change the network and CPU models", - &surf_host_model_init_compound}, - {"ptask_L07", "Host model somehow similar to Cas01+CM02 but allowing parallel tasks", - &surf_host_model_init_ptask_L07}, -}; - -const std::vector surf_optimization_mode_description = { - {"Lazy", "Lazy action management (partial invalidation in lmm + heap in action remaining).", nullptr}, - {"TI", - "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU " - "model for now).", - nullptr}, - {"Full", "Full update of remaining and variables. Slow but may be useful when debugging.", nullptr}, -}; - -const std::vector surf_disk_model_description = { - {"default", "Simplistic disk model.", &surf_disk_model_init_default}, -}; - -/* returns whether #file_path is an absolute file path. Surprising, isn't it ? */ -static bool is_absolute_file_path(const std::string& file_path) -{ -#ifdef _WIN32 - WIN32_FIND_DATA wfd = {0}; - HANDLE hFile = FindFirstFile(file_path.c_str(), &wfd); - - if (INVALID_HANDLE_VALUE == hFile) - return false; - - FindClose(hFile); - return true; -#else - return (file_path.c_str()[0] == '/'); -#endif -} - -std::ifstream* surf_ifsopen(const std::string& name) -{ - xbt_assert(not name.empty()); - - auto* fs = new std::ifstream(); - if (is_absolute_file_path(name)) { /* don't mess with absolute file names */ - fs->open(name.c_str(), std::ifstream::in); - } - - /* search relative files in the path */ - for (auto const& path_elm : surf_path) { - std::string buff = path_elm + "/" + name; - fs->open(buff.c_str(), std::ifstream::in); - - if (not fs->fail()) { - XBT_DEBUG("Found file at %s", buff.c_str()); - return fs; - } - } - - return fs; -} - -FILE* surf_fopen(const std::string& name, const char* mode) -{ - FILE* file = nullptr; - - if (is_absolute_file_path(name)) /* don't mess with absolute file names */ - return fopen(name.c_str(), mode); - - /* search relative files in the path */ - for (auto const& path_elm : surf_path) { - std::string buff = path_elm + "/" + name; - file = fopen(buff.c_str(), mode); - - if (file) - return file; - } - return nullptr; -} - -/** Displays the long description of all registered models, and quit */ -void model_help(const char* category, const std::vector& table) -{ - XBT_HELP("Long description of the %s models accepted by this simulator:", category); - for (auto const& item : table) - XBT_HELP(" %s: %s", item.name, item.description); -} - -const surf_model_description_t* find_model_description(const std::vector& table, - const std::string& name) -{ - if (auto pos = std::find_if(table.begin(), table.end(), - [&name](const surf_model_description_t& item) { return item.name == name; }); - pos != table.end()) - return &*pos; - - std::string sep; - std::string name_list; - for (auto const& item : table) { - name_list += sep + item.name; - sep = ", "; - } - xbt_die("Model '%s' is invalid! Valid models are: %s.", name.c_str(), name_list.c_str()); -} diff --git a/src/surf/surf_interface.hpp b/src/surf/surf_interface.hpp deleted file mode 100644 index 2cdc8f4210..0000000000 --- a/src/surf/surf_interface.hpp +++ /dev/null @@ -1,225 +0,0 @@ -/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SURF_MODEL_H_ -#define SURF_MODEL_H_ - -#include -#include - -#include "src/internal_config.h" - -#include -#include -#include -#include -#include -#include -#include - -/********* - * Utils * - *********/ -XBT_PRIVATE FILE* surf_fopen(const std::string& name, const char* mode); -XBT_PRIVATE std::ifstream* surf_ifsopen(const std::string& name); - -/* user-visible parameters */ -XBT_PUBLIC_DATA double sg_maxmin_precision; -XBT_PUBLIC_DATA double sg_surf_precision; -XBT_PUBLIC_DATA int sg_concurrency_limit; - -extern XBT_PRIVATE double sg_latency_factor; -extern XBT_PRIVATE double sg_bandwidth_factor; -extern XBT_PRIVATE double sg_weight_S_parameter; -extern XBT_PRIVATE std::vector surf_path; -extern XBT_PRIVATE std::unordered_map traces_set_list; - -/** set of hosts for which one want to be notified if they ever restart */ -inline auto& watched_hosts() // avoid static initialization order fiasco -{ - static std::set> value; - return value; -} - -static inline void double_update(double* variable, double value, double precision) -{ - if (false) { // debug - fprintf(stderr, "Updating %g -= %g +- %g\n", *variable, value, precision); - xbt_assert(value == 0.0 || value > precision); - // Check that precision is higher than the machine-dependent size of the mantissa. If not, brutal rounding may - // happen, and the precision mechanism is not active... - xbt_assert(FLT_RADIX == 2 && *variable < precision * exp2(DBL_MANT_DIG)); - } - *variable -= value; - if (*variable < precision) - *variable = 0.0; -} - -static inline int double_positive(double value, double precision) -{ - return (value > precision); -} - -static inline int double_equals(double value1, double value2, double precision) -{ - return (fabs(value1 - value2) < precision); -} - -/** @ingroup SURF_models - * @brief Initializes the CPU model with the model Cas01 - * - * By default, this model uses the lazy optimization mechanism that relies on partial invalidation in LMM and a heap - * for lazy action update. - * You can change this behavior by setting the cpu/optim configuration variable to a different value. - * - * You shouldn't have to call it by yourself. - */ -XBT_PUBLIC void surf_cpu_model_init_Cas01(); - -/** @ingroup SURF_models - * @brief Same as network model 'LagrangeVelho', only with different correction factors. - * - * This model is proposed by Pierre-Nicolas Clauss and Martin Quinson and Stéphane Génaud based on the model 'LV08' and - * different correction factors depending on the communication size (< 1KiB, < 64KiB, >= 64KiB). - * See comments in the code for more information. - * - * @see surf_host_model_init_SMPI() - */ -#if !HAVE_SMPI -XBT_ATTRIB_NORETURN -#endif -XBT_PUBLIC void surf_network_model_init_SMPI(); - -/** @ingroup SURF_models - * @brief Same as network model 'LagrangeVelho', only with different correction factors. - * - * This model implements a variant of the contention model on Infiniband networks based on - * the works of Jérôme Vienne : http://mescal.imag.fr/membres/jean-marc.vincent/index.html/PhD/Vienne.pdf - * - * @see surf_host_model_init_IB() - */ -#if !HAVE_SMPI -XBT_ATTRIB_NORETURN -#endif -XBT_PUBLIC void surf_network_model_init_IB(); - -/** @ingroup SURF_models - * @brief Initializes the platform with the network model 'LegrandVelho' - * - * This model is proposed by Arnaud Legrand and Pedro Velho based on the results obtained with the GTNets simulator for - * onelink and dogbone sharing scenarios. See comments in the code for more information. - * - * @see surf_host_model_init_LegrandVelho() - */ -XBT_PUBLIC void surf_network_model_init_LegrandVelho(); - -/** @ingroup SURF_models - * @brief Initializes the platform with the network model 'Constant' - * - * In this model, the communication time between two network cards is constant, hence no need for a routing table. - * This is particularly useful when simulating huge distributed algorithms where scalability is really an issue. This - * function is called in conjunction with surf_host_model_init_compound. - * - * @see surf_host_model_init_compound() - */ -XBT_PUBLIC void surf_network_model_init_Constant(); - -/** @ingroup SURF_models - * @brief Initializes the platform with the network model CM02 - * - * You should call this function by yourself only if you plan using surf_host_model_init_compound. - * See comments in the code for more information. - */ -XBT_PUBLIC void surf_network_model_init_CM02(); - -/** @ingroup SURF_models - * @brief Initializes the platform with the network model NS3 - * - * This function is called by surf_host_model_init_NS3 or by yourself only if you plan using - * surf_host_model_init_compound - * - * @see surf_host_model_init_NS3() - */ -#if !SIMGRID_HAVE_NS3 -XBT_ATTRIB_NORETURN -#endif -XBT_PUBLIC void surf_network_model_init_NS3(); - -/** @ingroup SURF_models - * @brief Initializes the VM model used in the platform - * - * A VM model depends on the physical CPU model to share the resources inside the VM - * It will also creates the CPU model for actions running inside the VM - * - * Such model is subject to modification with warning in the ChangeLog so monitor it! - */ -XBT_PUBLIC void surf_vm_model_init_HL13(simgrid::kernel::resource::CpuModel* cpu_pm_model); - -/** @ingroup SURF_models - * @brief Initializes the platform with a compound host model - * - * This function should be called after a cpu_model and a network_model have been set up. - */ -XBT_PUBLIC void surf_host_model_init_compound(); - -/** @ingroup SURF_models - * @brief Initializes the platform with the current best network and cpu models at hand - * - * This platform model separates the host model and the network model. - * The host model will be initialized with the model compound, the network model with the model LV08 (with cross - * traffic support) and the CPU model with the model Cas01. - * Such model is subject to modification with warning in the ChangeLog so monitor it! - */ -XBT_PUBLIC void surf_host_model_init_current_default(); - -/** @ingroup SURF_models - * @brief Initializes the platform with the model L07 - * - * With this model, only parallel tasks can be used. Resource sharing is done by identifying bottlenecks and giving an - * equal share of the model to each action. - */ -XBT_PUBLIC void surf_host_model_init_ptask_L07(); - -XBT_PUBLIC void surf_disk_model_init_default(); - -/* -------------------- - * Model Descriptions - * -------------------- */ -/** @brief Resource model description */ -struct surf_model_description_t { - const char* name; - const char* description; - std::function model_init_preparse; -}; - -XBT_PUBLIC const surf_model_description_t* find_model_description(const std::vector& table, - const std::string& name); -XBT_PUBLIC void model_help(const char* category, const std::vector& table); - -#define SIMGRID_REGISTER_PLUGIN(id, desc, init) \ - static void XBT_ATTRIB_CONSTRUCTOR(800) _XBT_CONCAT3(simgrid_, id, _plugin_register)() \ - { \ - surf_plugin_description().emplace_back(surf_model_description_t{_XBT_STRINGIFY(id), (desc), (init)}); \ - } - -/** @brief The list of all available plugins */ -inline auto& surf_plugin_description() // Function to avoid static initialization order fiasco -{ - static std::vector plugin_description_table; - return plugin_description_table; -} -/** @brief The list of all available optimization modes (both for cpu and networks). - * These optimization modes can be set using --cfg=cpu/optim:... and --cfg=network/optim:... */ -XBT_PUBLIC_DATA const std::vector surf_optimization_mode_description; -/** @brief The list of all cpu models (pick one with --cfg=cpu/model) */ -XBT_PUBLIC_DATA const std::vector surf_cpu_model_description; -/** @brief The list of all network models (pick one with --cfg=network/model) */ -XBT_PUBLIC_DATA const std::vector surf_network_model_description; -/** @brief The list of all disk models (pick one with --cfg=disk/model) */ -XBT_PUBLIC_DATA const std::vector surf_disk_model_description; -/** @brief The list of all host models (pick one with --cfg=host/model:) */ -XBT_PUBLIC_DATA const std::vector surf_host_model_description; - -#endif /* SURF_MODEL_H_ */ diff --git a/src/surf/xml/platf.hpp b/src/surf/xml/platf.hpp deleted file mode 100644 index e87645bcbc..0000000000 --- a/src/surf/xml/platf.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#ifndef SURF_SURFXML_PARSE_HPP -#define SURF_SURFXML_PARSE_HPP - -#include -#include -#include - -/* Module management functions */ -XBT_PUBLIC void sg_platf_init(); -XBT_PUBLIC void sg_platf_exit(); - -XBT_PUBLIC void surf_parse_open(const std::string& file); -XBT_PUBLIC void surf_parse_close(); -XBT_PUBLIC void surf_parse_assert(bool cond, const std::string& msg); -XBT_ATTRIB_NORETURN XBT_PUBLIC void surf_parse_error(const std::string& msg); -XBT_PUBLIC void surf_parse_assert_netpoint(const std::string& hostname, const std::string& pre, - const std::string& post); - -XBT_PUBLIC double surf_parse_get_double(const std::string& s); -XBT_PUBLIC int surf_parse_get_int(const std::string& s); - -XBT_PUBLIC void surf_parse(); /* Entry-point to the parser */ -XBT_PUBLIC void parse_platform_file(const std::string& file); - -#endif diff --git a/src/surf/xml/simgrid_dtd.h b/src/surf/xml/simgrid_dtd.h deleted file mode 100644 index 7558fc01ff..0000000000 --- a/src/surf/xml/simgrid_dtd.h +++ /dev/null @@ -1,774 +0,0 @@ -/* XML processor/application API for src/surf/xml/simgrid.dtd. - * - * This program was generated with the FleXML XML processor generator. - * FleXML is Copyright (C) 1999-2005 Kristoffer Rose. All rights reserved. - * FleXML is Copyright (C) 2003-2013 Martin Quinson. All rights reserved. - * (1.9.6). - * - * There are two, intertwined parts to this program, part A and part B. - * - * Part A - * ------ - * - * Some parts, here collectively called "Part A", are found in the - * FleXML package. They are Copyright (C) 1999-2005 Kristoffer Rose - * and Copyright (C) 2003-2013 Martin Quinson. All rights reserved. - * - * You can redistribute, use, perform, display and/or modify "Part A" - * provided the following two conditions hold: - * - * 1. The program is distributed WITHOUT ANY WARRANTY from the author of - * FleXML; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * 2. The program distribution conditions do not in any way affect the - * distribution conditions of the FleXML system used to generate this - * file or any version of FleXML derived from that system. - * - * Notice that these are explicit rights granted to you for files - * generated by the FleXML system. For your rights in connection with - * the FleXML system itself please consult the GNU General Public License. - * - * Part B - * ------ - * - * The other parts, here collectively called "Part B", and which came - * from the DTD used by FleXML to generate this program, can be - * distributed (or not, as the case may be) under the terms of whoever - * wrote them, provided these terms respect and obey the two conditions - * above under the heading "Part A". - * - * The author of and contributors to FleXML specifically disclaim - * any copyright interest in "Part B", unless "Part B" was written - * by the author of or contributors to FleXML. - * - */ - -#ifndef _FLEXML_simgrid_H -#define _FLEXML_simgrid_H - -/* XML application entry points. */ -XBT_PUBLIC void STag_surfxml_AS(void); -XBT_PUBLIC void ETag_surfxml_AS(void); -XBT_PUBLIC void STag_surfxml_ASroute(void); -XBT_PUBLIC void ETag_surfxml_ASroute(void); -XBT_PUBLIC void STag_surfxml_actor(void); -XBT_PUBLIC void ETag_surfxml_actor(void); -XBT_PUBLIC void STag_surfxml_argument(void); -XBT_PUBLIC void ETag_surfxml_argument(void); -XBT_PUBLIC void STag_surfxml_backbone(void); -XBT_PUBLIC void ETag_surfxml_backbone(void); -XBT_PUBLIC void STag_surfxml_bypassASroute(void); -XBT_PUBLIC void ETag_surfxml_bypassASroute(void); -XBT_PUBLIC void STag_surfxml_bypassRoute(void); -XBT_PUBLIC void ETag_surfxml_bypassRoute(void); -XBT_PUBLIC void STag_surfxml_bypassZoneRoute(void); -XBT_PUBLIC void ETag_surfxml_bypassZoneRoute(void); -XBT_PUBLIC void STag_surfxml_cabinet(void); -XBT_PUBLIC void ETag_surfxml_cabinet(void); -XBT_PUBLIC void STag_surfxml_cluster(void); -XBT_PUBLIC void ETag_surfxml_cluster(void); -XBT_PUBLIC void STag_surfxml_config(void); -XBT_PUBLIC void ETag_surfxml_config(void); -XBT_PUBLIC void STag_surfxml_disk(void); -XBT_PUBLIC void ETag_surfxml_disk(void); -XBT_PUBLIC void STag_surfxml_host(void); -XBT_PUBLIC void ETag_surfxml_host(void); -XBT_PUBLIC void STag_surfxml_host___link(void); -XBT_PUBLIC void ETag_surfxml_host___link(void); -XBT_ATTRIB_NORETURN XBT_PUBLIC void STag_surfxml_include(void); -XBT_PUBLIC void ETag_surfxml_include(void); -XBT_PUBLIC void STag_surfxml_link(void); -XBT_PUBLIC void ETag_surfxml_link(void); -XBT_PUBLIC void STag_surfxml_link___ctn(void); -XBT_PUBLIC void ETag_surfxml_link___ctn(void); -XBT_PUBLIC void STag_surfxml_model___prop(void); -XBT_PUBLIC void ETag_surfxml_model___prop(void); -XBT_ATTRIB_NORETURN XBT_PUBLIC void STag_surfxml_mount(void); -XBT_PUBLIC void ETag_surfxml_mount(void); -XBT_PUBLIC void STag_surfxml_peer(void); -XBT_PUBLIC void ETag_surfxml_peer(void); -XBT_PUBLIC void STag_surfxml_platform(void); -XBT_PUBLIC void ETag_surfxml_platform(void); -XBT_PUBLIC void STag_surfxml_process(void); -XBT_PUBLIC void ETag_surfxml_process(void); -XBT_PUBLIC void STag_surfxml_prop(void); -XBT_PUBLIC void ETag_surfxml_prop(void); -XBT_PUBLIC void STag_surfxml_random(void); -XBT_PUBLIC void ETag_surfxml_random(void); -XBT_PUBLIC void STag_surfxml_route(void); -XBT_PUBLIC void ETag_surfxml_route(void); -XBT_PUBLIC void STag_surfxml_router(void); -XBT_PUBLIC void ETag_surfxml_router(void); -XBT_ATTRIB_NORETURN XBT_PUBLIC void STag_surfxml_storage(void); -XBT_PUBLIC void ETag_surfxml_storage(void); -XBT_ATTRIB_NORETURN XBT_PUBLIC void STag_surfxml_storage___type(void); -XBT_PUBLIC void ETag_surfxml_storage___type(void); -XBT_PUBLIC void STag_surfxml_trace(void); -XBT_PUBLIC void ETag_surfxml_trace(void); -XBT_PUBLIC void STag_surfxml_trace___connect(void); -XBT_PUBLIC void ETag_surfxml_trace___connect(void); -XBT_PUBLIC void STag_surfxml_zone(void); -XBT_PUBLIC void ETag_surfxml_zone(void); -XBT_PUBLIC void STag_surfxml_zoneRoute(void); -XBT_PUBLIC void ETag_surfxml_zoneRoute(void); - -/* XML application data. */ -typedef int AT_surfxml_AS_id; -#define AU_surfxml_AS_id NULL -typedef int AT_surfxml_AS_routing; -#define AU_surfxml_AS_routing NULL -typedef int AT_surfxml_ASroute_dst; -#define AU_surfxml_ASroute_dst NULL -typedef int AT_surfxml_ASroute_gw___dst; -#define AU_surfxml_ASroute_gw___dst NULL -typedef int AT_surfxml_ASroute_gw___src; -#define AU_surfxml_ASroute_gw___src NULL -typedef int AT_surfxml_ASroute_src; -#define AU_surfxml_ASroute_src NULL -typedef enum { AU_surfxml_ASroute_symmetrical, A_surfxml_ASroute_symmetrical_YES,A_surfxml_ASroute_symmetrical_NO,A_surfxml_ASroute_symmetrical_yes,A_surfxml_ASroute_symmetrical_no } AT_surfxml_ASroute_symmetrical; -typedef int AT_surfxml_actor_function; -#define AU_surfxml_actor_function NULL -typedef int AT_surfxml_actor_host; -#define AU_surfxml_actor_host NULL -typedef int AT_surfxml_actor_kill___time; -#define AU_surfxml_actor_kill___time NULL -typedef enum { AU_surfxml_actor_on___failure, A_surfxml_actor_on___failure_DIE,A_surfxml_actor_on___failure_RESTART } AT_surfxml_actor_on___failure; -typedef int AT_surfxml_actor_start___time; -#define AU_surfxml_actor_start___time NULL -typedef int AT_surfxml_argument_value; -#define AU_surfxml_argument_value NULL -typedef int AT_surfxml_backbone_bandwidth; -#define AU_surfxml_backbone_bandwidth NULL -typedef int AT_surfxml_backbone_id; -#define AU_surfxml_backbone_id NULL -typedef int AT_surfxml_backbone_latency; -#define AU_surfxml_backbone_latency NULL -typedef int AT_surfxml_bypassASroute_dst; -#define AU_surfxml_bypassASroute_dst NULL -typedef int AT_surfxml_bypassASroute_gw___dst; -#define AU_surfxml_bypassASroute_gw___dst NULL -typedef int AT_surfxml_bypassASroute_gw___src; -#define AU_surfxml_bypassASroute_gw___src NULL -typedef int AT_surfxml_bypassASroute_src; -#define AU_surfxml_bypassASroute_src NULL -typedef int AT_surfxml_bypassRoute_dst; -#define AU_surfxml_bypassRoute_dst NULL -typedef int AT_surfxml_bypassRoute_src; -#define AU_surfxml_bypassRoute_src NULL -typedef int AT_surfxml_bypassZoneRoute_dst; -#define AU_surfxml_bypassZoneRoute_dst NULL -typedef int AT_surfxml_bypassZoneRoute_gw___dst; -#define AU_surfxml_bypassZoneRoute_gw___dst NULL -typedef int AT_surfxml_bypassZoneRoute_gw___src; -#define AU_surfxml_bypassZoneRoute_gw___src NULL -typedef int AT_surfxml_bypassZoneRoute_src; -#define AU_surfxml_bypassZoneRoute_src NULL -typedef int AT_surfxml_cabinet_bw; -#define AU_surfxml_cabinet_bw NULL -typedef int AT_surfxml_cabinet_id; -#define AU_surfxml_cabinet_id NULL -typedef int AT_surfxml_cabinet_lat; -#define AU_surfxml_cabinet_lat NULL -typedef int AT_surfxml_cabinet_prefix; -#define AU_surfxml_cabinet_prefix NULL -typedef int AT_surfxml_cabinet_radical; -#define AU_surfxml_cabinet_radical NULL -typedef int AT_surfxml_cabinet_speed; -#define AU_surfxml_cabinet_speed NULL -typedef int AT_surfxml_cabinet_suffix; -#define AU_surfxml_cabinet_suffix NULL -typedef int AT_surfxml_cluster_bb___bw; -#define AU_surfxml_cluster_bb___bw NULL -typedef int AT_surfxml_cluster_bb___lat; -#define AU_surfxml_cluster_bb___lat NULL -typedef enum { AU_surfxml_cluster_bb___sharing___policy, A_surfxml_cluster_bb___sharing___policy_SHARED,A_surfxml_cluster_bb___sharing___policy_FATPIPE } AT_surfxml_cluster_bb___sharing___policy; -typedef int AT_surfxml_cluster_bw; -#define AU_surfxml_cluster_bw NULL -typedef int AT_surfxml_cluster_core; -#define AU_surfxml_cluster_core NULL -typedef int AT_surfxml_cluster_id; -#define AU_surfxml_cluster_id NULL -typedef int AT_surfxml_cluster_lat; -#define AU_surfxml_cluster_lat NULL -typedef int AT_surfxml_cluster_limiter___link; -#define AU_surfxml_cluster_limiter___link NULL -typedef int AT_surfxml_cluster_loopback___bw; -#define AU_surfxml_cluster_loopback___bw NULL -typedef int AT_surfxml_cluster_loopback___lat; -#define AU_surfxml_cluster_loopback___lat NULL -typedef int AT_surfxml_cluster_prefix; -#define AU_surfxml_cluster_prefix NULL -typedef int AT_surfxml_cluster_radical; -#define AU_surfxml_cluster_radical NULL -typedef int AT_surfxml_cluster_router___id; -#define AU_surfxml_cluster_router___id NULL -typedef enum { AU_surfxml_cluster_sharing___policy, A_surfxml_cluster_sharing___policy_SHARED,A_surfxml_cluster_sharing___policy_SPLITDUPLEX,A_surfxml_cluster_sharing___policy_FULLDUPLEX,A_surfxml_cluster_sharing___policy_FATPIPE } AT_surfxml_cluster_sharing___policy; -typedef int AT_surfxml_cluster_speed; -#define AU_surfxml_cluster_speed NULL -typedef int AT_surfxml_cluster_suffix; -#define AU_surfxml_cluster_suffix NULL -typedef int AT_surfxml_cluster_topo___parameters; -#define AU_surfxml_cluster_topo___parameters NULL -typedef enum { AU_surfxml_cluster_topology, A_surfxml_cluster_topology_FLAT,A_surfxml_cluster_topology_TORUS,A_surfxml_cluster_topology_FAT___TREE,A_surfxml_cluster_topology_DRAGONFLY } AT_surfxml_cluster_topology; -typedef int AT_surfxml_config_id; -#define AU_surfxml_config_id NULL -typedef int AT_surfxml_disk_id; -#define AU_surfxml_disk_id NULL -typedef int AT_surfxml_disk_read___bw; -#define AU_surfxml_disk_read___bw NULL -typedef int AT_surfxml_disk_write___bw; -#define AU_surfxml_disk_write___bw NULL -typedef int AT_surfxml_host_availability___file; -#define AU_surfxml_host_availability___file NULL -typedef int AT_surfxml_host_coordinates; -#define AU_surfxml_host_coordinates NULL -typedef int AT_surfxml_host_core; -#define AU_surfxml_host_core NULL -typedef int AT_surfxml_host_id; -#define AU_surfxml_host_id NULL -typedef int AT_surfxml_host_pstate; -#define AU_surfxml_host_pstate NULL -typedef int AT_surfxml_host_speed; -#define AU_surfxml_host_speed NULL -typedef int AT_surfxml_host_speed___file; -#define AU_surfxml_host_speed___file NULL -typedef int AT_surfxml_host_state___file; -#define AU_surfxml_host_state___file NULL -typedef int AT_surfxml_host___link_down; -#define AU_surfxml_host___link_down NULL -typedef int AT_surfxml_host___link_id; -#define AU_surfxml_host___link_id NULL -typedef int AT_surfxml_host___link_up; -#define AU_surfxml_host___link_up NULL -typedef int AT_surfxml_include_file; -#define AU_surfxml_include_file NULL -typedef int AT_surfxml_link_bandwidth; -#define AU_surfxml_link_bandwidth NULL -typedef int AT_surfxml_link_bandwidth___file; -#define AU_surfxml_link_bandwidth___file NULL -typedef int AT_surfxml_link_id; -#define AU_surfxml_link_id NULL -typedef int AT_surfxml_link_latency; -#define AU_surfxml_link_latency NULL -typedef int AT_surfxml_link_latency___file; -#define AU_surfxml_link_latency___file NULL -typedef enum { AU_surfxml_link_sharing___policy, A_surfxml_link_sharing___policy_SHARED,A_surfxml_link_sharing___policy_SPLITDUPLEX,A_surfxml_link_sharing___policy_FULLDUPLEX,A_surfxml_link_sharing___policy_FATPIPE,A_surfxml_link_sharing___policy_WIFI } AT_surfxml_link_sharing___policy; -typedef int AT_surfxml_link_state___file; -#define AU_surfxml_link_state___file NULL -typedef enum { AU_surfxml_link___ctn_direction, A_surfxml_link___ctn_direction_UP,A_surfxml_link___ctn_direction_DOWN,A_surfxml_link___ctn_direction_NONE } AT_surfxml_link___ctn_direction; -typedef int AT_surfxml_link___ctn_id; -#define AU_surfxml_link___ctn_id NULL -typedef int AT_surfxml_model___prop_id; -#define AU_surfxml_model___prop_id NULL -typedef int AT_surfxml_model___prop_value; -#define AU_surfxml_model___prop_value NULL -typedef int AT_surfxml_mount_name; -#define AU_surfxml_mount_name NULL -typedef int AT_surfxml_mount_storageId; -#define AU_surfxml_mount_storageId NULL -typedef int AT_surfxml_peer_availability___file; -#define AU_surfxml_peer_availability___file NULL -typedef int AT_surfxml_peer_bw___in; -#define AU_surfxml_peer_bw___in NULL -typedef int AT_surfxml_peer_bw___out; -#define AU_surfxml_peer_bw___out NULL -typedef int AT_surfxml_peer_coordinates; -#define AU_surfxml_peer_coordinates NULL -typedef int AT_surfxml_peer_id; -#define AU_surfxml_peer_id NULL -typedef int AT_surfxml_peer_lat; -#define AU_surfxml_peer_lat NULL -typedef int AT_surfxml_peer_speed; -#define AU_surfxml_peer_speed NULL -typedef int AT_surfxml_peer_speed___file; -#define AU_surfxml_peer_speed___file NULL -typedef int AT_surfxml_peer_state___file; -#define AU_surfxml_peer_state___file NULL -typedef int AT_surfxml_platform_version; -#define AU_surfxml_platform_version NULL -typedef int AT_surfxml_process_function; -#define AU_surfxml_process_function NULL -typedef int AT_surfxml_process_host; -#define AU_surfxml_process_host NULL -typedef int AT_surfxml_process_kill___time; -#define AU_surfxml_process_kill___time NULL -typedef enum { AU_surfxml_process_on___failure, A_surfxml_process_on___failure_DIE,A_surfxml_process_on___failure_RESTART } AT_surfxml_process_on___failure; -typedef int AT_surfxml_process_start___time; -#define AU_surfxml_process_start___time NULL -typedef int AT_surfxml_prop_id; -#define AU_surfxml_prop_id NULL -typedef int AT_surfxml_prop_value; -#define AU_surfxml_prop_value NULL -typedef enum { AU_surfxml_random_generator, A_surfxml_random_generator_DRAND48,A_surfxml_random_generator_RAND,A_surfxml_random_generator_RNGSTREAM,A_surfxml_random_generator_NONE } AT_surfxml_random_generator; -typedef int AT_surfxml_random_id; -#define AU_surfxml_random_id NULL -typedef int AT_surfxml_random_max; -#define AU_surfxml_random_max NULL -typedef int AT_surfxml_random_mean; -#define AU_surfxml_random_mean NULL -typedef int AT_surfxml_random_min; -#define AU_surfxml_random_min NULL -typedef int AT_surfxml_random_radical; -#define AU_surfxml_random_radical NULL -typedef int AT_surfxml_random_seed; -#define AU_surfxml_random_seed NULL -typedef int AT_surfxml_random_std___deviation; -#define AU_surfxml_random_std___deviation NULL -typedef int AT_surfxml_route_dst; -#define AU_surfxml_route_dst NULL -typedef int AT_surfxml_route_src; -#define AU_surfxml_route_src NULL -typedef enum { AU_surfxml_route_symmetrical, A_surfxml_route_symmetrical_YES,A_surfxml_route_symmetrical_NO,A_surfxml_route_symmetrical_yes,A_surfxml_route_symmetrical_no } AT_surfxml_route_symmetrical; -typedef int AT_surfxml_router_coordinates; -#define AU_surfxml_router_coordinates NULL -typedef int AT_surfxml_router_id; -#define AU_surfxml_router_id NULL -typedef int AT_surfxml_storage_attach; -#define AU_surfxml_storage_attach NULL -typedef int AT_surfxml_storage_content; -#define AU_surfxml_storage_content NULL -typedef int AT_surfxml_storage_id; -#define AU_surfxml_storage_id NULL -typedef int AT_surfxml_storage_typeId; -#define AU_surfxml_storage_typeId NULL -typedef int AT_surfxml_storage___type_content; -#define AU_surfxml_storage___type_content NULL -typedef int AT_surfxml_storage___type_id; -#define AU_surfxml_storage___type_id NULL -typedef int AT_surfxml_storage___type_model; -#define AU_surfxml_storage___type_model NULL -typedef int AT_surfxml_storage___type_size; -#define AU_surfxml_storage___type_size NULL -typedef int AT_surfxml_trace_file; -#define AU_surfxml_trace_file NULL -typedef int AT_surfxml_trace_id; -#define AU_surfxml_trace_id NULL -typedef int AT_surfxml_trace_periodicity; -#define AU_surfxml_trace_periodicity NULL -typedef int AT_surfxml_trace___connect_element; -#define AU_surfxml_trace___connect_element NULL -typedef enum { AU_surfxml_trace___connect_kind, A_surfxml_trace___connect_kind_HOST___AVAIL,A_surfxml_trace___connect_kind_SPEED,A_surfxml_trace___connect_kind_LINK___AVAIL,A_surfxml_trace___connect_kind_BANDWIDTH,A_surfxml_trace___connect_kind_LATENCY } AT_surfxml_trace___connect_kind; -typedef int AT_surfxml_trace___connect_trace; -#define AU_surfxml_trace___connect_trace NULL -typedef int AT_surfxml_zone_id; -#define AU_surfxml_zone_id NULL -typedef int AT_surfxml_zone_routing; -#define AU_surfxml_zone_routing NULL -typedef int AT_surfxml_zoneRoute_dst; -#define AU_surfxml_zoneRoute_dst NULL -typedef int AT_surfxml_zoneRoute_gw___dst; -#define AU_surfxml_zoneRoute_gw___dst NULL -typedef int AT_surfxml_zoneRoute_gw___src; -#define AU_surfxml_zoneRoute_gw___src NULL -typedef int AT_surfxml_zoneRoute_src; -#define AU_surfxml_zoneRoute_src NULL -typedef enum { AU_surfxml_zoneRoute_symmetrical, A_surfxml_zoneRoute_symmetrical_YES,A_surfxml_zoneRoute_symmetrical_NO,A_surfxml_zoneRoute_symmetrical_yes,A_surfxml_zoneRoute_symmetrical_no } AT_surfxml_zoneRoute_symmetrical; - -/* FleXML-provided data. */ -XBT_PUBLIC_DATA int surfxml_pcdata_ix; -XBT_PUBLIC_DATA char *surfxml_bufferstack; -#define surfxml_pcdata (surfxml_bufferstack + surfxml_pcdata_ix) -XBT_PUBLIC_DATA AT_surfxml_AS_id AX_surfxml_AS_id; -#define A_surfxml_AS_id (surfxml_bufferstack + AX_surfxml_AS_id) -XBT_PUBLIC_DATA short int surfxml_AS_id_isset; -XBT_PUBLIC_DATA AT_surfxml_AS_routing AX_surfxml_AS_routing; -#define A_surfxml_AS_routing (surfxml_bufferstack + AX_surfxml_AS_routing) -XBT_PUBLIC_DATA short int surfxml_AS_routing_isset; -XBT_PUBLIC_DATA AT_surfxml_ASroute_dst AX_surfxml_ASroute_dst; -#define A_surfxml_ASroute_dst (surfxml_bufferstack + AX_surfxml_ASroute_dst) -XBT_PUBLIC_DATA short int surfxml_ASroute_dst_isset; -XBT_PUBLIC_DATA AT_surfxml_ASroute_gw___dst AX_surfxml_ASroute_gw___dst; -#define A_surfxml_ASroute_gw___dst (surfxml_bufferstack + AX_surfxml_ASroute_gw___dst) -XBT_PUBLIC_DATA short int surfxml_ASroute_gw___dst_isset; -XBT_PUBLIC_DATA AT_surfxml_ASroute_gw___src AX_surfxml_ASroute_gw___src; -#define A_surfxml_ASroute_gw___src (surfxml_bufferstack + AX_surfxml_ASroute_gw___src) -XBT_PUBLIC_DATA short int surfxml_ASroute_gw___src_isset; -XBT_PUBLIC_DATA AT_surfxml_ASroute_src AX_surfxml_ASroute_src; -#define A_surfxml_ASroute_src (surfxml_bufferstack + AX_surfxml_ASroute_src) -XBT_PUBLIC_DATA short int surfxml_ASroute_src_isset; -XBT_PUBLIC_DATA AT_surfxml_ASroute_symmetrical AX_surfxml_ASroute_symmetrical; -#define A_surfxml_ASroute_symmetrical AX_surfxml_ASroute_symmetrical -XBT_PUBLIC_DATA short int surfxml_ASroute_symmetrical_isset; -XBT_PUBLIC_DATA AT_surfxml_actor_function AX_surfxml_actor_function; -#define A_surfxml_actor_function (surfxml_bufferstack + AX_surfxml_actor_function) -XBT_PUBLIC_DATA short int surfxml_actor_function_isset; -XBT_PUBLIC_DATA AT_surfxml_actor_host AX_surfxml_actor_host; -#define A_surfxml_actor_host (surfxml_bufferstack + AX_surfxml_actor_host) -XBT_PUBLIC_DATA short int surfxml_actor_host_isset; -XBT_PUBLIC_DATA AT_surfxml_actor_kill___time AX_surfxml_actor_kill___time; -#define A_surfxml_actor_kill___time (surfxml_bufferstack + AX_surfxml_actor_kill___time) -XBT_PUBLIC_DATA short int surfxml_actor_kill___time_isset; -XBT_PUBLIC_DATA AT_surfxml_actor_on___failure AX_surfxml_actor_on___failure; -#define A_surfxml_actor_on___failure AX_surfxml_actor_on___failure -XBT_PUBLIC_DATA short int surfxml_actor_on___failure_isset; -XBT_PUBLIC_DATA AT_surfxml_actor_start___time AX_surfxml_actor_start___time; -#define A_surfxml_actor_start___time (surfxml_bufferstack + AX_surfxml_actor_start___time) -XBT_PUBLIC_DATA short int surfxml_actor_start___time_isset; -XBT_PUBLIC_DATA AT_surfxml_argument_value AX_surfxml_argument_value; -#define A_surfxml_argument_value (surfxml_bufferstack + AX_surfxml_argument_value) -XBT_PUBLIC_DATA short int surfxml_argument_value_isset; -XBT_PUBLIC_DATA AT_surfxml_backbone_bandwidth AX_surfxml_backbone_bandwidth; -#define A_surfxml_backbone_bandwidth (surfxml_bufferstack + AX_surfxml_backbone_bandwidth) -XBT_PUBLIC_DATA short int surfxml_backbone_bandwidth_isset; -XBT_PUBLIC_DATA AT_surfxml_backbone_id AX_surfxml_backbone_id; -#define A_surfxml_backbone_id (surfxml_bufferstack + AX_surfxml_backbone_id) -XBT_PUBLIC_DATA short int surfxml_backbone_id_isset; -XBT_PUBLIC_DATA AT_surfxml_backbone_latency AX_surfxml_backbone_latency; -#define A_surfxml_backbone_latency (surfxml_bufferstack + AX_surfxml_backbone_latency) -XBT_PUBLIC_DATA short int surfxml_backbone_latency_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassASroute_dst AX_surfxml_bypassASroute_dst; -#define A_surfxml_bypassASroute_dst (surfxml_bufferstack + AX_surfxml_bypassASroute_dst) -XBT_PUBLIC_DATA short int surfxml_bypassASroute_dst_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassASroute_gw___dst AX_surfxml_bypassASroute_gw___dst; -#define A_surfxml_bypassASroute_gw___dst (surfxml_bufferstack + AX_surfxml_bypassASroute_gw___dst) -XBT_PUBLIC_DATA short int surfxml_bypassASroute_gw___dst_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassASroute_gw___src AX_surfxml_bypassASroute_gw___src; -#define A_surfxml_bypassASroute_gw___src (surfxml_bufferstack + AX_surfxml_bypassASroute_gw___src) -XBT_PUBLIC_DATA short int surfxml_bypassASroute_gw___src_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassASroute_src AX_surfxml_bypassASroute_src; -#define A_surfxml_bypassASroute_src (surfxml_bufferstack + AX_surfxml_bypassASroute_src) -XBT_PUBLIC_DATA short int surfxml_bypassASroute_src_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassRoute_dst AX_surfxml_bypassRoute_dst; -#define A_surfxml_bypassRoute_dst (surfxml_bufferstack + AX_surfxml_bypassRoute_dst) -XBT_PUBLIC_DATA short int surfxml_bypassRoute_dst_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassRoute_src AX_surfxml_bypassRoute_src; -#define A_surfxml_bypassRoute_src (surfxml_bufferstack + AX_surfxml_bypassRoute_src) -XBT_PUBLIC_DATA short int surfxml_bypassRoute_src_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassZoneRoute_dst AX_surfxml_bypassZoneRoute_dst; -#define A_surfxml_bypassZoneRoute_dst (surfxml_bufferstack + AX_surfxml_bypassZoneRoute_dst) -XBT_PUBLIC_DATA short int surfxml_bypassZoneRoute_dst_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassZoneRoute_gw___dst AX_surfxml_bypassZoneRoute_gw___dst; -#define A_surfxml_bypassZoneRoute_gw___dst (surfxml_bufferstack + AX_surfxml_bypassZoneRoute_gw___dst) -XBT_PUBLIC_DATA short int surfxml_bypassZoneRoute_gw___dst_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassZoneRoute_gw___src AX_surfxml_bypassZoneRoute_gw___src; -#define A_surfxml_bypassZoneRoute_gw___src (surfxml_bufferstack + AX_surfxml_bypassZoneRoute_gw___src) -XBT_PUBLIC_DATA short int surfxml_bypassZoneRoute_gw___src_isset; -XBT_PUBLIC_DATA AT_surfxml_bypassZoneRoute_src AX_surfxml_bypassZoneRoute_src; -#define A_surfxml_bypassZoneRoute_src (surfxml_bufferstack + AX_surfxml_bypassZoneRoute_src) -XBT_PUBLIC_DATA short int surfxml_bypassZoneRoute_src_isset; -XBT_PUBLIC_DATA AT_surfxml_cabinet_bw AX_surfxml_cabinet_bw; -#define A_surfxml_cabinet_bw (surfxml_bufferstack + AX_surfxml_cabinet_bw) -XBT_PUBLIC_DATA short int surfxml_cabinet_bw_isset; -XBT_PUBLIC_DATA AT_surfxml_cabinet_id AX_surfxml_cabinet_id; -#define A_surfxml_cabinet_id (surfxml_bufferstack + AX_surfxml_cabinet_id) -XBT_PUBLIC_DATA short int surfxml_cabinet_id_isset; -XBT_PUBLIC_DATA AT_surfxml_cabinet_lat AX_surfxml_cabinet_lat; -#define A_surfxml_cabinet_lat (surfxml_bufferstack + AX_surfxml_cabinet_lat) -XBT_PUBLIC_DATA short int surfxml_cabinet_lat_isset; -XBT_PUBLIC_DATA AT_surfxml_cabinet_prefix AX_surfxml_cabinet_prefix; -#define A_surfxml_cabinet_prefix (surfxml_bufferstack + AX_surfxml_cabinet_prefix) -XBT_PUBLIC_DATA short int surfxml_cabinet_prefix_isset; -XBT_PUBLIC_DATA AT_surfxml_cabinet_radical AX_surfxml_cabinet_radical; -#define A_surfxml_cabinet_radical (surfxml_bufferstack + AX_surfxml_cabinet_radical) -XBT_PUBLIC_DATA short int surfxml_cabinet_radical_isset; -XBT_PUBLIC_DATA AT_surfxml_cabinet_speed AX_surfxml_cabinet_speed; -#define A_surfxml_cabinet_speed (surfxml_bufferstack + AX_surfxml_cabinet_speed) -XBT_PUBLIC_DATA short int surfxml_cabinet_speed_isset; -XBT_PUBLIC_DATA AT_surfxml_cabinet_suffix AX_surfxml_cabinet_suffix; -#define A_surfxml_cabinet_suffix (surfxml_bufferstack + AX_surfxml_cabinet_suffix) -XBT_PUBLIC_DATA short int surfxml_cabinet_suffix_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_bb___bw AX_surfxml_cluster_bb___bw; -#define A_surfxml_cluster_bb___bw (surfxml_bufferstack + AX_surfxml_cluster_bb___bw) -XBT_PUBLIC_DATA short int surfxml_cluster_bb___bw_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_bb___lat AX_surfxml_cluster_bb___lat; -#define A_surfxml_cluster_bb___lat (surfxml_bufferstack + AX_surfxml_cluster_bb___lat) -XBT_PUBLIC_DATA short int surfxml_cluster_bb___lat_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_bb___sharing___policy AX_surfxml_cluster_bb___sharing___policy; -#define A_surfxml_cluster_bb___sharing___policy AX_surfxml_cluster_bb___sharing___policy -XBT_PUBLIC_DATA short int surfxml_cluster_bb___sharing___policy_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_bw AX_surfxml_cluster_bw; -#define A_surfxml_cluster_bw (surfxml_bufferstack + AX_surfxml_cluster_bw) -XBT_PUBLIC_DATA short int surfxml_cluster_bw_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_core AX_surfxml_cluster_core; -#define A_surfxml_cluster_core (surfxml_bufferstack + AX_surfxml_cluster_core) -XBT_PUBLIC_DATA short int surfxml_cluster_core_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_id AX_surfxml_cluster_id; -#define A_surfxml_cluster_id (surfxml_bufferstack + AX_surfxml_cluster_id) -XBT_PUBLIC_DATA short int surfxml_cluster_id_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_lat AX_surfxml_cluster_lat; -#define A_surfxml_cluster_lat (surfxml_bufferstack + AX_surfxml_cluster_lat) -XBT_PUBLIC_DATA short int surfxml_cluster_lat_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_limiter___link AX_surfxml_cluster_limiter___link; -#define A_surfxml_cluster_limiter___link (surfxml_bufferstack + AX_surfxml_cluster_limiter___link) -XBT_PUBLIC_DATA short int surfxml_cluster_limiter___link_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_loopback___bw AX_surfxml_cluster_loopback___bw; -#define A_surfxml_cluster_loopback___bw (surfxml_bufferstack + AX_surfxml_cluster_loopback___bw) -XBT_PUBLIC_DATA short int surfxml_cluster_loopback___bw_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_loopback___lat AX_surfxml_cluster_loopback___lat; -#define A_surfxml_cluster_loopback___lat (surfxml_bufferstack + AX_surfxml_cluster_loopback___lat) -XBT_PUBLIC_DATA short int surfxml_cluster_loopback___lat_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_prefix AX_surfxml_cluster_prefix; -#define A_surfxml_cluster_prefix (surfxml_bufferstack + AX_surfxml_cluster_prefix) -XBT_PUBLIC_DATA short int surfxml_cluster_prefix_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_radical AX_surfxml_cluster_radical; -#define A_surfxml_cluster_radical (surfxml_bufferstack + AX_surfxml_cluster_radical) -XBT_PUBLIC_DATA short int surfxml_cluster_radical_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_router___id AX_surfxml_cluster_router___id; -#define A_surfxml_cluster_router___id (surfxml_bufferstack + AX_surfxml_cluster_router___id) -XBT_PUBLIC_DATA short int surfxml_cluster_router___id_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_sharing___policy AX_surfxml_cluster_sharing___policy; -#define A_surfxml_cluster_sharing___policy AX_surfxml_cluster_sharing___policy -XBT_PUBLIC_DATA short int surfxml_cluster_sharing___policy_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_speed AX_surfxml_cluster_speed; -#define A_surfxml_cluster_speed (surfxml_bufferstack + AX_surfxml_cluster_speed) -XBT_PUBLIC_DATA short int surfxml_cluster_speed_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_suffix AX_surfxml_cluster_suffix; -#define A_surfxml_cluster_suffix (surfxml_bufferstack + AX_surfxml_cluster_suffix) -XBT_PUBLIC_DATA short int surfxml_cluster_suffix_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_topo___parameters AX_surfxml_cluster_topo___parameters; -#define A_surfxml_cluster_topo___parameters (surfxml_bufferstack + AX_surfxml_cluster_topo___parameters) -XBT_PUBLIC_DATA short int surfxml_cluster_topo___parameters_isset; -XBT_PUBLIC_DATA AT_surfxml_cluster_topology AX_surfxml_cluster_topology; -#define A_surfxml_cluster_topology AX_surfxml_cluster_topology -XBT_PUBLIC_DATA short int surfxml_cluster_topology_isset; -XBT_PUBLIC_DATA AT_surfxml_config_id AX_surfxml_config_id; -#define A_surfxml_config_id (surfxml_bufferstack + AX_surfxml_config_id) -XBT_PUBLIC_DATA short int surfxml_config_id_isset; -XBT_PUBLIC_DATA AT_surfxml_disk_id AX_surfxml_disk_id; -#define A_surfxml_disk_id (surfxml_bufferstack + AX_surfxml_disk_id) -XBT_PUBLIC_DATA short int surfxml_disk_id_isset; -XBT_PUBLIC_DATA AT_surfxml_disk_read___bw AX_surfxml_disk_read___bw; -#define A_surfxml_disk_read___bw (surfxml_bufferstack + AX_surfxml_disk_read___bw) -XBT_PUBLIC_DATA short int surfxml_disk_read___bw_isset; -XBT_PUBLIC_DATA AT_surfxml_disk_write___bw AX_surfxml_disk_write___bw; -#define A_surfxml_disk_write___bw (surfxml_bufferstack + AX_surfxml_disk_write___bw) -XBT_PUBLIC_DATA short int surfxml_disk_write___bw_isset; -XBT_PUBLIC_DATA AT_surfxml_host_availability___file AX_surfxml_host_availability___file; -#define A_surfxml_host_availability___file (surfxml_bufferstack + AX_surfxml_host_availability___file) -XBT_PUBLIC_DATA short int surfxml_host_availability___file_isset; -XBT_PUBLIC_DATA AT_surfxml_host_coordinates AX_surfxml_host_coordinates; -#define A_surfxml_host_coordinates (surfxml_bufferstack + AX_surfxml_host_coordinates) -XBT_PUBLIC_DATA short int surfxml_host_coordinates_isset; -XBT_PUBLIC_DATA AT_surfxml_host_core AX_surfxml_host_core; -#define A_surfxml_host_core (surfxml_bufferstack + AX_surfxml_host_core) -XBT_PUBLIC_DATA short int surfxml_host_core_isset; -XBT_PUBLIC_DATA AT_surfxml_host_id AX_surfxml_host_id; -#define A_surfxml_host_id (surfxml_bufferstack + AX_surfxml_host_id) -XBT_PUBLIC_DATA short int surfxml_host_id_isset; -XBT_PUBLIC_DATA AT_surfxml_host_pstate AX_surfxml_host_pstate; -#define A_surfxml_host_pstate (surfxml_bufferstack + AX_surfxml_host_pstate) -XBT_PUBLIC_DATA short int surfxml_host_pstate_isset; -XBT_PUBLIC_DATA AT_surfxml_host_speed AX_surfxml_host_speed; -#define A_surfxml_host_speed (surfxml_bufferstack + AX_surfxml_host_speed) -XBT_PUBLIC_DATA short int surfxml_host_speed_isset; -XBT_PUBLIC_DATA AT_surfxml_host_speed___file AX_surfxml_host_speed___file; -#define A_surfxml_host_speed___file (surfxml_bufferstack + AX_surfxml_host_speed___file) -XBT_PUBLIC_DATA short int surfxml_host_speed___file_isset; -XBT_PUBLIC_DATA AT_surfxml_host_state___file AX_surfxml_host_state___file; -#define A_surfxml_host_state___file (surfxml_bufferstack + AX_surfxml_host_state___file) -XBT_PUBLIC_DATA short int surfxml_host_state___file_isset; -XBT_PUBLIC_DATA AT_surfxml_host___link_down AX_surfxml_host___link_down; -#define A_surfxml_host___link_down (surfxml_bufferstack + AX_surfxml_host___link_down) -XBT_PUBLIC_DATA short int surfxml_host___link_down_isset; -XBT_PUBLIC_DATA AT_surfxml_host___link_id AX_surfxml_host___link_id; -#define A_surfxml_host___link_id (surfxml_bufferstack + AX_surfxml_host___link_id) -XBT_PUBLIC_DATA short int surfxml_host___link_id_isset; -XBT_PUBLIC_DATA AT_surfxml_host___link_up AX_surfxml_host___link_up; -#define A_surfxml_host___link_up (surfxml_bufferstack + AX_surfxml_host___link_up) -XBT_PUBLIC_DATA short int surfxml_host___link_up_isset; -XBT_PUBLIC_DATA AT_surfxml_include_file AX_surfxml_include_file; -#define A_surfxml_include_file (surfxml_bufferstack + AX_surfxml_include_file) -XBT_PUBLIC_DATA short int surfxml_include_file_isset; -XBT_PUBLIC_DATA AT_surfxml_link_bandwidth AX_surfxml_link_bandwidth; -#define A_surfxml_link_bandwidth (surfxml_bufferstack + AX_surfxml_link_bandwidth) -XBT_PUBLIC_DATA short int surfxml_link_bandwidth_isset; -XBT_PUBLIC_DATA AT_surfxml_link_bandwidth___file AX_surfxml_link_bandwidth___file; -#define A_surfxml_link_bandwidth___file (surfxml_bufferstack + AX_surfxml_link_bandwidth___file) -XBT_PUBLIC_DATA short int surfxml_link_bandwidth___file_isset; -XBT_PUBLIC_DATA AT_surfxml_link_id AX_surfxml_link_id; -#define A_surfxml_link_id (surfxml_bufferstack + AX_surfxml_link_id) -XBT_PUBLIC_DATA short int surfxml_link_id_isset; -XBT_PUBLIC_DATA AT_surfxml_link_latency AX_surfxml_link_latency; -#define A_surfxml_link_latency (surfxml_bufferstack + AX_surfxml_link_latency) -XBT_PUBLIC_DATA short int surfxml_link_latency_isset; -XBT_PUBLIC_DATA AT_surfxml_link_latency___file AX_surfxml_link_latency___file; -#define A_surfxml_link_latency___file (surfxml_bufferstack + AX_surfxml_link_latency___file) -XBT_PUBLIC_DATA short int surfxml_link_latency___file_isset; -XBT_PUBLIC_DATA AT_surfxml_link_sharing___policy AX_surfxml_link_sharing___policy; -#define A_surfxml_link_sharing___policy AX_surfxml_link_sharing___policy -XBT_PUBLIC_DATA short int surfxml_link_sharing___policy_isset; -XBT_PUBLIC_DATA AT_surfxml_link_state___file AX_surfxml_link_state___file; -#define A_surfxml_link_state___file (surfxml_bufferstack + AX_surfxml_link_state___file) -XBT_PUBLIC_DATA short int surfxml_link_state___file_isset; -XBT_PUBLIC_DATA AT_surfxml_link___ctn_direction AX_surfxml_link___ctn_direction; -#define A_surfxml_link___ctn_direction AX_surfxml_link___ctn_direction -XBT_PUBLIC_DATA short int surfxml_link___ctn_direction_isset; -XBT_PUBLIC_DATA AT_surfxml_link___ctn_id AX_surfxml_link___ctn_id; -#define A_surfxml_link___ctn_id (surfxml_bufferstack + AX_surfxml_link___ctn_id) -XBT_PUBLIC_DATA short int surfxml_link___ctn_id_isset; -XBT_PUBLIC_DATA AT_surfxml_model___prop_id AX_surfxml_model___prop_id; -#define A_surfxml_model___prop_id (surfxml_bufferstack + AX_surfxml_model___prop_id) -XBT_PUBLIC_DATA short int surfxml_model___prop_id_isset; -XBT_PUBLIC_DATA AT_surfxml_model___prop_value AX_surfxml_model___prop_value; -#define A_surfxml_model___prop_value (surfxml_bufferstack + AX_surfxml_model___prop_value) -XBT_PUBLIC_DATA short int surfxml_model___prop_value_isset; -XBT_PUBLIC_DATA AT_surfxml_mount_name AX_surfxml_mount_name; -#define A_surfxml_mount_name (surfxml_bufferstack + AX_surfxml_mount_name) -XBT_PUBLIC_DATA short int surfxml_mount_name_isset; -XBT_PUBLIC_DATA AT_surfxml_mount_storageId AX_surfxml_mount_storageId; -#define A_surfxml_mount_storageId (surfxml_bufferstack + AX_surfxml_mount_storageId) -XBT_PUBLIC_DATA short int surfxml_mount_storageId_isset; -XBT_PUBLIC_DATA AT_surfxml_peer_availability___file AX_surfxml_peer_availability___file; -#define A_surfxml_peer_availability___file (surfxml_bufferstack + AX_surfxml_peer_availability___file) -XBT_PUBLIC_DATA short int surfxml_peer_availability___file_isset; -XBT_PUBLIC_DATA AT_surfxml_peer_bw___in AX_surfxml_peer_bw___in; -#define A_surfxml_peer_bw___in (surfxml_bufferstack + AX_surfxml_peer_bw___in) -XBT_PUBLIC_DATA short int surfxml_peer_bw___in_isset; -XBT_PUBLIC_DATA AT_surfxml_peer_bw___out AX_surfxml_peer_bw___out; -#define A_surfxml_peer_bw___out (surfxml_bufferstack + AX_surfxml_peer_bw___out) -XBT_PUBLIC_DATA short int surfxml_peer_bw___out_isset; -XBT_PUBLIC_DATA AT_surfxml_peer_coordinates AX_surfxml_peer_coordinates; -#define A_surfxml_peer_coordinates (surfxml_bufferstack + AX_surfxml_peer_coordinates) -XBT_PUBLIC_DATA short int surfxml_peer_coordinates_isset; -XBT_PUBLIC_DATA AT_surfxml_peer_id AX_surfxml_peer_id; -#define A_surfxml_peer_id (surfxml_bufferstack + AX_surfxml_peer_id) -XBT_PUBLIC_DATA short int surfxml_peer_id_isset; -XBT_PUBLIC_DATA AT_surfxml_peer_lat AX_surfxml_peer_lat; -#define A_surfxml_peer_lat (surfxml_bufferstack + AX_surfxml_peer_lat) -XBT_PUBLIC_DATA short int surfxml_peer_lat_isset; -XBT_PUBLIC_DATA AT_surfxml_peer_speed AX_surfxml_peer_speed; -#define A_surfxml_peer_speed (surfxml_bufferstack + AX_surfxml_peer_speed) -XBT_PUBLIC_DATA short int surfxml_peer_speed_isset; -XBT_PUBLIC_DATA AT_surfxml_peer_speed___file AX_surfxml_peer_speed___file; -#define A_surfxml_peer_speed___file (surfxml_bufferstack + AX_surfxml_peer_speed___file) -XBT_PUBLIC_DATA short int surfxml_peer_speed___file_isset; -XBT_PUBLIC_DATA AT_surfxml_peer_state___file AX_surfxml_peer_state___file; -#define A_surfxml_peer_state___file (surfxml_bufferstack + AX_surfxml_peer_state___file) -XBT_PUBLIC_DATA short int surfxml_peer_state___file_isset; -XBT_PUBLIC_DATA AT_surfxml_platform_version AX_surfxml_platform_version; -#define A_surfxml_platform_version (surfxml_bufferstack + AX_surfxml_platform_version) -XBT_PUBLIC_DATA short int surfxml_platform_version_isset; -XBT_PUBLIC_DATA AT_surfxml_process_function AX_surfxml_process_function; -#define A_surfxml_process_function (surfxml_bufferstack + AX_surfxml_process_function) -XBT_PUBLIC_DATA short int surfxml_process_function_isset; -XBT_PUBLIC_DATA AT_surfxml_process_host AX_surfxml_process_host; -#define A_surfxml_process_host (surfxml_bufferstack + AX_surfxml_process_host) -XBT_PUBLIC_DATA short int surfxml_process_host_isset; -XBT_PUBLIC_DATA AT_surfxml_process_kill___time AX_surfxml_process_kill___time; -#define A_surfxml_process_kill___time (surfxml_bufferstack + AX_surfxml_process_kill___time) -XBT_PUBLIC_DATA short int surfxml_process_kill___time_isset; -XBT_PUBLIC_DATA AT_surfxml_process_on___failure AX_surfxml_process_on___failure; -#define A_surfxml_process_on___failure AX_surfxml_process_on___failure -XBT_PUBLIC_DATA short int surfxml_process_on___failure_isset; -XBT_PUBLIC_DATA AT_surfxml_process_start___time AX_surfxml_process_start___time; -#define A_surfxml_process_start___time (surfxml_bufferstack + AX_surfxml_process_start___time) -XBT_PUBLIC_DATA short int surfxml_process_start___time_isset; -XBT_PUBLIC_DATA AT_surfxml_prop_id AX_surfxml_prop_id; -#define A_surfxml_prop_id (surfxml_bufferstack + AX_surfxml_prop_id) -XBT_PUBLIC_DATA short int surfxml_prop_id_isset; -XBT_PUBLIC_DATA AT_surfxml_prop_value AX_surfxml_prop_value; -#define A_surfxml_prop_value (surfxml_bufferstack + AX_surfxml_prop_value) -XBT_PUBLIC_DATA short int surfxml_prop_value_isset; -XBT_PUBLIC_DATA AT_surfxml_random_generator AX_surfxml_random_generator; -#define A_surfxml_random_generator AX_surfxml_random_generator -XBT_PUBLIC_DATA short int surfxml_random_generator_isset; -XBT_PUBLIC_DATA AT_surfxml_random_id AX_surfxml_random_id; -#define A_surfxml_random_id (surfxml_bufferstack + AX_surfxml_random_id) -XBT_PUBLIC_DATA short int surfxml_random_id_isset; -XBT_PUBLIC_DATA AT_surfxml_random_max AX_surfxml_random_max; -#define A_surfxml_random_max (surfxml_bufferstack + AX_surfxml_random_max) -XBT_PUBLIC_DATA short int surfxml_random_max_isset; -XBT_PUBLIC_DATA AT_surfxml_random_mean AX_surfxml_random_mean; -#define A_surfxml_random_mean (surfxml_bufferstack + AX_surfxml_random_mean) -XBT_PUBLIC_DATA short int surfxml_random_mean_isset; -XBT_PUBLIC_DATA AT_surfxml_random_min AX_surfxml_random_min; -#define A_surfxml_random_min (surfxml_bufferstack + AX_surfxml_random_min) -XBT_PUBLIC_DATA short int surfxml_random_min_isset; -XBT_PUBLIC_DATA AT_surfxml_random_radical AX_surfxml_random_radical; -#define A_surfxml_random_radical (surfxml_bufferstack + AX_surfxml_random_radical) -XBT_PUBLIC_DATA short int surfxml_random_radical_isset; -XBT_PUBLIC_DATA AT_surfxml_random_seed AX_surfxml_random_seed; -#define A_surfxml_random_seed (surfxml_bufferstack + AX_surfxml_random_seed) -XBT_PUBLIC_DATA short int surfxml_random_seed_isset; -XBT_PUBLIC_DATA AT_surfxml_random_std___deviation AX_surfxml_random_std___deviation; -#define A_surfxml_random_std___deviation (surfxml_bufferstack + AX_surfxml_random_std___deviation) -XBT_PUBLIC_DATA short int surfxml_random_std___deviation_isset; -XBT_PUBLIC_DATA AT_surfxml_route_dst AX_surfxml_route_dst; -#define A_surfxml_route_dst (surfxml_bufferstack + AX_surfxml_route_dst) -XBT_PUBLIC_DATA short int surfxml_route_dst_isset; -XBT_PUBLIC_DATA AT_surfxml_route_src AX_surfxml_route_src; -#define A_surfxml_route_src (surfxml_bufferstack + AX_surfxml_route_src) -XBT_PUBLIC_DATA short int surfxml_route_src_isset; -XBT_PUBLIC_DATA AT_surfxml_route_symmetrical AX_surfxml_route_symmetrical; -#define A_surfxml_route_symmetrical AX_surfxml_route_symmetrical -XBT_PUBLIC_DATA short int surfxml_route_symmetrical_isset; -XBT_PUBLIC_DATA AT_surfxml_router_coordinates AX_surfxml_router_coordinates; -#define A_surfxml_router_coordinates (surfxml_bufferstack + AX_surfxml_router_coordinates) -XBT_PUBLIC_DATA short int surfxml_router_coordinates_isset; -XBT_PUBLIC_DATA AT_surfxml_router_id AX_surfxml_router_id; -#define A_surfxml_router_id (surfxml_bufferstack + AX_surfxml_router_id) -XBT_PUBLIC_DATA short int surfxml_router_id_isset; -XBT_PUBLIC_DATA AT_surfxml_storage_attach AX_surfxml_storage_attach; -#define A_surfxml_storage_attach (surfxml_bufferstack + AX_surfxml_storage_attach) -XBT_PUBLIC_DATA short int surfxml_storage_attach_isset; -XBT_PUBLIC_DATA AT_surfxml_storage_content AX_surfxml_storage_content; -#define A_surfxml_storage_content (surfxml_bufferstack + AX_surfxml_storage_content) -XBT_PUBLIC_DATA short int surfxml_storage_content_isset; -XBT_PUBLIC_DATA AT_surfxml_storage_id AX_surfxml_storage_id; -#define A_surfxml_storage_id (surfxml_bufferstack + AX_surfxml_storage_id) -XBT_PUBLIC_DATA short int surfxml_storage_id_isset; -XBT_PUBLIC_DATA AT_surfxml_storage_typeId AX_surfxml_storage_typeId; -#define A_surfxml_storage_typeId (surfxml_bufferstack + AX_surfxml_storage_typeId) -XBT_PUBLIC_DATA short int surfxml_storage_typeId_isset; -XBT_PUBLIC_DATA AT_surfxml_storage___type_content AX_surfxml_storage___type_content; -#define A_surfxml_storage___type_content (surfxml_bufferstack + AX_surfxml_storage___type_content) -XBT_PUBLIC_DATA short int surfxml_storage___type_content_isset; -XBT_PUBLIC_DATA AT_surfxml_storage___type_id AX_surfxml_storage___type_id; -#define A_surfxml_storage___type_id (surfxml_bufferstack + AX_surfxml_storage___type_id) -XBT_PUBLIC_DATA short int surfxml_storage___type_id_isset; -XBT_PUBLIC_DATA AT_surfxml_storage___type_model AX_surfxml_storage___type_model; -#define A_surfxml_storage___type_model (surfxml_bufferstack + AX_surfxml_storage___type_model) -XBT_PUBLIC_DATA short int surfxml_storage___type_model_isset; -XBT_PUBLIC_DATA AT_surfxml_storage___type_size AX_surfxml_storage___type_size; -#define A_surfxml_storage___type_size (surfxml_bufferstack + AX_surfxml_storage___type_size) -XBT_PUBLIC_DATA short int surfxml_storage___type_size_isset; -XBT_PUBLIC_DATA AT_surfxml_trace_file AX_surfxml_trace_file; -#define A_surfxml_trace_file (surfxml_bufferstack + AX_surfxml_trace_file) -XBT_PUBLIC_DATA short int surfxml_trace_file_isset; -XBT_PUBLIC_DATA AT_surfxml_trace_id AX_surfxml_trace_id; -#define A_surfxml_trace_id (surfxml_bufferstack + AX_surfxml_trace_id) -XBT_PUBLIC_DATA short int surfxml_trace_id_isset; -XBT_PUBLIC_DATA AT_surfxml_trace_periodicity AX_surfxml_trace_periodicity; -#define A_surfxml_trace_periodicity (surfxml_bufferstack + AX_surfxml_trace_periodicity) -XBT_PUBLIC_DATA short int surfxml_trace_periodicity_isset; -XBT_PUBLIC_DATA AT_surfxml_trace___connect_element AX_surfxml_trace___connect_element; -#define A_surfxml_trace___connect_element (surfxml_bufferstack + AX_surfxml_trace___connect_element) -XBT_PUBLIC_DATA short int surfxml_trace___connect_element_isset; -XBT_PUBLIC_DATA AT_surfxml_trace___connect_kind AX_surfxml_trace___connect_kind; -#define A_surfxml_trace___connect_kind AX_surfxml_trace___connect_kind -XBT_PUBLIC_DATA short int surfxml_trace___connect_kind_isset; -XBT_PUBLIC_DATA AT_surfxml_trace___connect_trace AX_surfxml_trace___connect_trace; -#define A_surfxml_trace___connect_trace (surfxml_bufferstack + AX_surfxml_trace___connect_trace) -XBT_PUBLIC_DATA short int surfxml_trace___connect_trace_isset; -XBT_PUBLIC_DATA AT_surfxml_zone_id AX_surfxml_zone_id; -#define A_surfxml_zone_id (surfxml_bufferstack + AX_surfxml_zone_id) -XBT_PUBLIC_DATA short int surfxml_zone_id_isset; -XBT_PUBLIC_DATA AT_surfxml_zone_routing AX_surfxml_zone_routing; -#define A_surfxml_zone_routing (surfxml_bufferstack + AX_surfxml_zone_routing) -XBT_PUBLIC_DATA short int surfxml_zone_routing_isset; -XBT_PUBLIC_DATA AT_surfxml_zoneRoute_dst AX_surfxml_zoneRoute_dst; -#define A_surfxml_zoneRoute_dst (surfxml_bufferstack + AX_surfxml_zoneRoute_dst) -XBT_PUBLIC_DATA short int surfxml_zoneRoute_dst_isset; -XBT_PUBLIC_DATA AT_surfxml_zoneRoute_gw___dst AX_surfxml_zoneRoute_gw___dst; -#define A_surfxml_zoneRoute_gw___dst (surfxml_bufferstack + AX_surfxml_zoneRoute_gw___dst) -XBT_PUBLIC_DATA short int surfxml_zoneRoute_gw___dst_isset; -XBT_PUBLIC_DATA AT_surfxml_zoneRoute_gw___src AX_surfxml_zoneRoute_gw___src; -#define A_surfxml_zoneRoute_gw___src (surfxml_bufferstack + AX_surfxml_zoneRoute_gw___src) -XBT_PUBLIC_DATA short int surfxml_zoneRoute_gw___src_isset; -XBT_PUBLIC_DATA AT_surfxml_zoneRoute_src AX_surfxml_zoneRoute_src; -#define A_surfxml_zoneRoute_src (surfxml_bufferstack + AX_surfxml_zoneRoute_src) -XBT_PUBLIC_DATA short int surfxml_zoneRoute_src_isset; -XBT_PUBLIC_DATA AT_surfxml_zoneRoute_symmetrical AX_surfxml_zoneRoute_symmetrical; -#define A_surfxml_zoneRoute_symmetrical AX_surfxml_zoneRoute_symmetrical -XBT_PUBLIC_DATA short int surfxml_zoneRoute_symmetrical_isset; - -/* XML application utilities. */ -XBT_PUBLIC int surfxml_element_context(int); - -/* XML processor entry point. */ -XBT_PUBLIC int yylex(void); - -/* Flexml error handling function (useful only when -q flag passed to flexml) */ -const char * surfxml_parse_err_msg(void); -#endif diff --git a/src/surf/xml/surfxml_parseplatf.cpp b/src/surf/xml/surfxml_parseplatf.cpp deleted file mode 100644 index a46d4acd80..0000000000 --- a/src/surf/xml/surfxml_parseplatf.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include - -#include "src/kernel/resource/CpuImpl.hpp" -#include "src/kernel/resource/LinkImpl.hpp" -#include "src/surf/surf_interface.hpp" -#include "src/surf/xml/platf.hpp" -#include "src/surf/xml/platf_private.hpp" - -#include - -XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_parse); - -/* Trace related stuff */ -XBT_PRIVATE std::unordered_map traces_set_list; -XBT_PRIVATE std::unordered_map trace_connect_list_host_avail; -XBT_PRIVATE std::unordered_map trace_connect_list_host_speed; -XBT_PRIVATE std::unordered_map trace_connect_list_link_avail; -XBT_PRIVATE std::unordered_map trace_connect_list_link_bw; -XBT_PRIVATE std::unordered_map trace_connect_list_link_lat; - -void sg_platf_trace_connect(simgrid::kernel::routing::TraceConnectCreationArgs* trace_connect) -{ - surf_parse_assert(traces_set_list.find(trace_connect->trace) != traces_set_list.end(), - std::string("Cannot connect trace ") + trace_connect->trace + " to " + trace_connect->element + - ": trace unknown"); - - switch (trace_connect->kind) { - case simgrid::kernel::routing::TraceConnectKind::HOST_AVAIL: - trace_connect_list_host_avail.try_emplace(trace_connect->trace, trace_connect->element); - break; - case simgrid::kernel::routing::TraceConnectKind::SPEED: - trace_connect_list_host_speed.try_emplace(trace_connect->trace, trace_connect->element); - break; - case simgrid::kernel::routing::TraceConnectKind::LINK_AVAIL: - trace_connect_list_link_avail.try_emplace(trace_connect->trace, trace_connect->element); - break; - case simgrid::kernel::routing::TraceConnectKind::BANDWIDTH: - trace_connect_list_link_bw.try_emplace(trace_connect->trace, trace_connect->element); - break; - case simgrid::kernel::routing::TraceConnectKind::LATENCY: - trace_connect_list_link_lat.try_emplace(trace_connect->trace, trace_connect->element); - break; - default: - surf_parse_error(std::string("Cannot connect trace ") + trace_connect->trace + " to " + trace_connect->element + - ": unknown kind of trace"); - } -} - -/* This function acts as a main in the parsing area. */ -void parse_platform_file(const std::string& file) -{ - sg_platf_init(); - - /* init the flex parser */ - surf_parse_open(file); - - /* Do the actual parsing */ - surf_parse(); - - /* Get the Engine singleton once and for all*/ - const auto engine = simgrid::s4u::Engine::get_instance(); - - /* connect all profiles relative to hosts */ - for (auto const& [trace, name] : trace_connect_list_host_avail) { - surf_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), - std::string(": Trace ") + trace + " undefined."); - auto profile = traces_set_list.at(trace); - - auto host = engine->host_by_name_or_null(name); - surf_parse_assert(host, std::string(": Host ") + name + " undefined."); - host->set_state_profile(profile); - } - - for (auto const& [trace, name] : trace_connect_list_host_speed) { - surf_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), - std::string(": Trace ") + trace + " undefined."); - auto profile = traces_set_list.at(trace); - - auto host = engine->host_by_name_or_null(name); - surf_parse_assert(host, std::string(": Host ") + name + " undefined."); - host->set_speed_profile(profile); - } - - for (auto const& [trace, name] : trace_connect_list_link_avail) { - surf_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), - std::string(": Trace ") + trace + " undefined."); - auto profile = traces_set_list.at(trace); - - auto link = engine->link_by_name_or_null(name); - surf_parse_assert(link, std::string(": Link ") + name + " undefined."); - link->set_state_profile(profile); - } - - for (auto const& [trace, name] : trace_connect_list_link_bw) { - surf_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), - std::string(": Trace ") + trace + " undefined."); - auto profile = traces_set_list.at(trace); - - auto link = engine->link_by_name_or_null(name); - surf_parse_assert(link, std::string(": Link ") + name + " undefined."); - link->set_bandwidth_profile(profile); - } - - for (auto const& [trace, name] : trace_connect_list_link_lat) { - surf_parse_assert(traces_set_list.find(trace) != traces_set_list.end(), - std::string(": Trace ") + trace + " undefined."); - auto profile = traces_set_list.at(trace); - - auto link = engine->link_by_name_or_null(name); - surf_parse_assert(link, std::string(": Link ") + name + " undefined."); - link->set_latency_profile(profile); - } - - surf_parse_close(); -} diff --git a/src/surf/xml/surfxml_sax_cb.cpp b/src/surf/xml/surfxml_sax_cb.cpp deleted file mode 100644 index 8e1598bf02..0000000000 --- a/src/surf/xml/surfxml_sax_cb.cpp +++ /dev/null @@ -1,862 +0,0 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include -#include -#include - -#include "simgrid/sg_config.hpp" -#include "src/kernel/resource/LinkImpl.hpp" -#include "src/kernel/resource/profile/FutureEvtSet.hpp" -#include "src/kernel/resource/profile/Profile.hpp" -#include "src/surf/surf_interface.hpp" -#include "src/surf/xml/platf.hpp" -#include "src/surf/xml/platf_private.hpp" - -#include -#include -#include -#include -#include -#include - -#include "simgrid_dtd.c" - -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_parse, surf, "Logging specific to the SURF parsing module"); - -std::string surf_parsed_filename; // Currently parsed file (for the error messages) -std::vector parsed_link_list; /* temporary store of current link list of a route */ - -/* Helping functions */ -void surf_parse_assert(bool cond, const std::string& msg) -{ - if (not cond) - surf_parse_error(msg); -} - -void surf_parse_error(const std::string& msg) -{ - throw simgrid::ParseError(surf_parsed_filename, surf_parse_lineno, msg); -} - -void surf_parse_assert_netpoint(const std::string& hostname, const std::string& pre, const std::string& post) -{ - if (simgrid::s4u::Engine::get_instance()->netpoint_by_name_or_null(hostname) != nullptr) // found - return; - - std::string msg = pre + hostname + post + " Existing netpoints:\n"; - - std::vector netpoints = - simgrid::s4u::Engine::get_instance()->get_all_netpoints(); - std::sort(netpoints.begin(), netpoints.end(), - [](const simgrid::kernel::routing::NetPoint* a, const simgrid::kernel::routing::NetPoint* b) { - return a->get_name() < b->get_name(); - }); - bool first = true; - for (auto const& np : netpoints) { - if (np->is_netzone()) - continue; - - if (not first) - msg += ","; - first = false; - msg += "'" + np->get_name() + "'"; - if (msg.length() > 4096) { - msg.pop_back(); // remove trailing quote - msg += "...(list truncated)......"; - break; - } - } - surf_parse_error(msg); -} - -double surf_parse_get_double(const std::string& s) -{ - try { - return std::stod(s); - } catch (const std::invalid_argument&) { - surf_parse_error(s + " is not a double"); - } -} - -int surf_parse_get_int(const std::string& s) -{ - try { - return std::stoi(s); - } catch (const std::invalid_argument&) { - surf_parse_error(s + " is not an int"); - } -} - -/* Turn something like "1-4,6,9-11" into the vector {1,2,3,4,6,9,10,11} */ -static void explodesRadical(const std::string& radicals, std::vector* exploded) -{ - // Make all hosts - std::vector radical_elements; - boost::split(radical_elements, radicals, boost::is_any_of(",")); - for (auto const& group : radical_elements) { - std::vector radical_ends; - boost::split(radical_ends, group, boost::is_any_of("-")); - int start = surf_parse_get_int(radical_ends.front()); - int end = 0; - - switch (radical_ends.size()) { - case 1: - end = start; - break; - case 2: - end = surf_parse_get_int(radical_ends.back()); - break; - default: - surf_parse_error(std::string("Malformed radical: ") + group); - } - for (int i = start; i <= end; i++) - exploded->push_back(i); - } -} - - -/* - * All the callback lists that can be overridden anywhere. - * (this list should probably be reduced to the bare minimum to allow the models to work) - */ - -/* make sure these symbols are defined as strong ones in this file so that the linker can resolve them */ - -std::vector> property_sets; - -FILE *surf_file_to_parse = nullptr; - -/* Stuff relative to storage */ -void STag_surfxml_storage() -{ - xbt_die(" tag was removed in SimGrid v3.27. Please stop using it now."); -} - -void ETag_surfxml_storage() -{ - /* Won't happen since is now removed since v3.27. */ -} -void STag_surfxml_storage___type() -{ - xbt_die(" tag was removed in SimGrid v3.27. Please stop using it now."); -} -void ETag_surfxml_storage___type() -{ - /* Won't happen since is now removed since v3.27. */ -} - -void STag_surfxml_mount() -{ - xbt_die(" tag was removed in SimGrid v3.27. Please stop using it now."); -} - -void ETag_surfxml_mount() -{ - /* Won't happen since is now removed since v3.27. */ -} - -void STag_surfxml_include() -{ - xbt_die(" tag was removed in SimGrid v3.18. Please stop using it now."); -} - -void ETag_surfxml_include() -{ - /* Won't happen since is now removed since v3.18. */ -} - -/* Stag and Etag parse functions */ -void STag_surfxml_platform() { - double version = surf_parse_get_double(A_surfxml_platform_version); - - surf_parse_assert((version >= 1.0), "******* BIG FAT WARNING *********\n " - "You're using an ancient XML file.\n" - "Since SimGrid 3.1, units are Bytes, Flops, and seconds " - "instead of MBytes, MFlops and seconds.\n" - - "Use simgrid_update_xml to update your file automatically. " - "This program is installed automatically with SimGrid, or " - "available in the tools/ directory of the source archive.\n" - - "Please check also out the SURF section of the ChangeLog for " - "the 3.1 version for more information. \n" - - "Last, do not forget to also update your values for " - "the calls to MSG_task_create (if any)."); - surf_parse_assert((version >= 3.0), "******* BIG FAT WARNING *********\n " - "You're using an old XML file.\n" - "Use simgrid_update_xml to update your file automatically. " - "This program is installed automatically with SimGrid, or " - "available in the tools/ directory of the source archive."); - surf_parse_assert( - (version >= 4.0), - std::string("******* THIS FILE IS TOO OLD (v:") + std::to_string(version) + - ") *********\n " - "Changes introduced in SimGrid 3.13:\n" - " - 'power' attribute of hosts (and others) got renamed to 'speed'.\n" - " - In , attribute kind=\"POWER\" is now kind=\"SPEED\".\n" - " - DOCTYPE now point to the rignt URL.\n" - " - speed, bandwidth and latency attributes now MUST have an explicit unit (f, Bps, s by default)" - "\n\n" - "Use simgrid_update_xml to update your file automatically. " - "This program is installed automatically with SimGrid, or " - "available in the tools/ directory of the source archive."); - if (version < 4.1) { - XBT_INFO("You're using a v%.1f XML file (%s) while the current standard is v4.1 " - "That's fine, the new version is backward compatible. \n\n" - "Use simgrid_update_xml to update your file automatically to get rid of this warning. " - "This program is installed automatically with SimGrid, or " - "available in the tools/ directory of the source archive.", - version, surf_parsed_filename.c_str()); - } - surf_parse_assert(version <= 4.1, - std::string("******* THIS FILE COMES FROM THE FUTURE (v:")+std::to_string(version)+") *********\n " - "The most recent formalism that this version of SimGrid understands is v4.1.\n" - "Please update your code, or use another, more adapted, file."); -} -void ETag_surfxml_platform(){ - simgrid::s4u::Engine::on_platform_created(); -} - -void STag_surfxml_prop() -{ - property_sets.back().try_emplace(A_surfxml_prop_id, A_surfxml_prop_value); - XBT_DEBUG("add prop %s=%s into current property set %p", A_surfxml_prop_id, A_surfxml_prop_value, - &(property_sets.back())); -} - -void STag_surfxml_host() -{ - simgrid::kernel::routing::HostCreationArgs host; - property_sets.emplace_back(); - host.id = A_surfxml_host_id; - - host.speed_per_pstate = xbt_parse_get_all_speeds(surf_parsed_filename, surf_parse_lineno, A_surfxml_host_speed, - "speed of host " + host.id); - - XBT_DEBUG("pstate: %s", A_surfxml_host_pstate); - host.core_amount = surf_parse_get_int(A_surfxml_host_core); - - if (A_surfxml_host_availability___file[0] != '\0') { - XBT_WARN("The availability_file attribute in is now deprecated. Please, use 'speed_file' instead."); - host.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_host_availability___file); - } - if (A_surfxml_host_speed___file[0] != '\0') - host.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_host_speed___file); - host.state_trace = A_surfxml_host_state___file[0] - ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_host_state___file) - : nullptr; - host.coord = A_surfxml_host_coordinates; - - sg_platf_new_host_begin(&host); -} - -void ETag_surfxml_host() -{ - sg_platf_new_host_set_properties(property_sets.back()); - property_sets.pop_back(); - - sg_platf_new_host_seal(surf_parse_get_int(A_surfxml_host_pstate)); -} - -void STag_surfxml_disk() { - property_sets.emplace_back(); -} - -void ETag_surfxml_disk() { - simgrid::kernel::routing::DiskCreationArgs disk; - disk.properties = property_sets.back(); - property_sets.pop_back(); - - disk.id = A_surfxml_disk_id; - disk.read_bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_disk_read___bw, - "read_bw of disk " + disk.id); - disk.write_bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_disk_write___bw, - "write_bw of disk " + disk.id); - - sg_platf_new_disk(&disk); -} - -void STag_surfxml_host___link(){ - XBT_DEBUG("Create a Host_link for %s",A_surfxml_host___link_id); - simgrid::kernel::routing::HostLinkCreationArgs host_link; - - host_link.id = A_surfxml_host___link_id; - host_link.link_up = A_surfxml_host___link_up; - host_link.link_down = A_surfxml_host___link_down; - sg_platf_new_hostlink(&host_link); -} - -void STag_surfxml_router(){ - sg_platf_new_router(A_surfxml_router_id, A_surfxml_router_coordinates); -} - -void ETag_surfxml_cluster(){ - simgrid::kernel::routing::ClusterCreationArgs cluster; - cluster.properties = property_sets.back(); - property_sets.pop_back(); - - cluster.id = A_surfxml_cluster_id; - cluster.prefix = A_surfxml_cluster_prefix; - cluster.suffix = A_surfxml_cluster_suffix; - explodesRadical(A_surfxml_cluster_radical, &cluster.radicals); - - cluster.speeds = xbt_parse_get_all_speeds(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_speed, - "speed of cluster " + cluster.id); - cluster.core_amount = surf_parse_get_int(A_surfxml_cluster_core); - cluster.bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_bw, - "bw of cluster " + cluster.id); - cluster.lat = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_lat, - "lat of cluster " + cluster.id); - if(strcmp(A_surfxml_cluster_bb___bw,"")) - cluster.bb_bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_bb___bw, - "bb_bw of cluster " + cluster.id); - if(strcmp(A_surfxml_cluster_bb___lat,"")) - cluster.bb_lat = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_bb___lat, - "bb_lat of cluster " + cluster.id); - if(strcmp(A_surfxml_cluster_limiter___link,"")) - cluster.limiter_link = - xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_limiter___link, - "limiter_link of cluster " + cluster.id); - if(strcmp(A_surfxml_cluster_loopback___bw,"")) - cluster.loopback_bw = - xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_loopback___bw, - "loopback_bw of cluster " + cluster.id); - if(strcmp(A_surfxml_cluster_loopback___lat,"")) - cluster.loopback_lat = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_cluster_loopback___lat, - "loopback_lat of cluster " + cluster.id); - - switch(AX_surfxml_cluster_topology){ - case A_surfxml_cluster_topology_FLAT: - cluster.topology = simgrid::kernel::routing::ClusterTopology::FLAT; - break; - case A_surfxml_cluster_topology_TORUS: - cluster.topology = simgrid::kernel::routing::ClusterTopology::TORUS; - break; - case A_surfxml_cluster_topology_FAT___TREE: - cluster.topology = simgrid::kernel::routing::ClusterTopology::FAT_TREE; - break; - case A_surfxml_cluster_topology_DRAGONFLY: - cluster.topology = simgrid::kernel::routing::ClusterTopology::DRAGONFLY; - break; - default: - surf_parse_error(std::string("Invalid cluster topology for cluster ") + cluster.id); - } - cluster.topo_parameters = A_surfxml_cluster_topo___parameters; - cluster.router_id = A_surfxml_cluster_router___id; - - switch (AX_surfxml_cluster_sharing___policy) { - case A_surfxml_cluster_sharing___policy_SHARED: - cluster.sharing_policy = simgrid::s4u::Link::SharingPolicy::SHARED; - break; - case A_surfxml_cluster_sharing___policy_FULLDUPLEX: - XBT_WARN("FULLDUPLEX is now deprecated. Please update your platform file to use SPLITDUPLEX instead."); - cluster.sharing_policy = simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX; - break; - case A_surfxml_cluster_sharing___policy_SPLITDUPLEX: - cluster.sharing_policy = simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX; - break; - case A_surfxml_cluster_sharing___policy_FATPIPE: - cluster.sharing_policy = simgrid::s4u::Link::SharingPolicy::FATPIPE; - break; - default: - surf_parse_error(std::string("Invalid cluster sharing policy for cluster ") + cluster.id); - } - switch (AX_surfxml_cluster_bb___sharing___policy) { - case A_surfxml_cluster_bb___sharing___policy_FATPIPE: - cluster.bb_sharing_policy = simgrid::s4u::Link::SharingPolicy::FATPIPE; - break; - case A_surfxml_cluster_bb___sharing___policy_SHARED: - cluster.bb_sharing_policy = simgrid::s4u::Link::SharingPolicy::SHARED; - break; - default: - surf_parse_error(std::string("Invalid bb sharing policy in cluster ") + cluster.id); - } - - sg_platf_new_tag_cluster(&cluster); -} - -void STag_surfxml_cluster(){ - property_sets.emplace_back(); -} - -void STag_surfxml_cabinet(){ - simgrid::kernel::routing::CabinetCreationArgs cabinet; - cabinet.id = A_surfxml_cabinet_id; - cabinet.prefix = A_surfxml_cabinet_prefix; - cabinet.suffix = A_surfxml_cabinet_suffix; - cabinet.speed = xbt_parse_get_speed(surf_parsed_filename, surf_parse_lineno, A_surfxml_cabinet_speed, - "speed of cabinet " + cabinet.id); - cabinet.bw = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_cabinet_bw, - "bw of cabinet " + cabinet.id); - cabinet.lat = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_cabinet_lat, - "lat of cabinet " + cabinet.id); - explodesRadical(A_surfxml_cabinet_radical, &cabinet.radicals); - - sg_platf_new_cabinet(&cabinet); -} - -void STag_surfxml_peer(){ - simgrid::kernel::routing::PeerCreationArgs peer; - - peer.id = std::string(A_surfxml_peer_id); - peer.speed = - xbt_parse_get_speed(surf_parsed_filename, surf_parse_lineno, A_surfxml_peer_speed, "speed of peer " + peer.id); - peer.bw_in = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_peer_bw___in, - "bw_in of peer " + peer.id); - peer.bw_out = xbt_parse_get_bandwidth(surf_parsed_filename, surf_parse_lineno, A_surfxml_peer_bw___out, - "bw_out of peer " + peer.id); - peer.coord = A_surfxml_peer_coordinates; - peer.speed_trace = nullptr; - if (A_surfxml_peer_availability___file[0] != '\0') { - XBT_WARN("The availability_file attribute in is now deprecated. Please, use 'speed_file' instead."); - peer.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_peer_availability___file); - } - if (A_surfxml_peer_speed___file[0] != '\0') - peer.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_peer_speed___file); - peer.state_trace = A_surfxml_peer_state___file[0] - ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_peer_state___file) - : nullptr; - - if (A_surfxml_peer_lat[0] != '\0') - XBT_WARN("The latency attribute in is now deprecated. Use the z coordinate instead of '%s'.", - A_surfxml_peer_lat); - - sg_platf_new_peer(&peer); -} - -void STag_surfxml_link(){ - property_sets.emplace_back(); -} - -void ETag_surfxml_link(){ - simgrid::kernel::routing::LinkCreationArgs link; - - link.properties = property_sets.back(); - property_sets.pop_back(); - - link.id = std::string(A_surfxml_link_id); - link.bandwidths = xbt_parse_get_bandwidths(surf_parsed_filename, surf_parse_lineno, A_surfxml_link_bandwidth, - "bandwidth of link " + link.id); - link.bandwidth_trace = A_surfxml_link_bandwidth___file[0] - ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_link_bandwidth___file) - : nullptr; - link.latency = - xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_link_latency, "latency of link " + link.id); - link.latency_trace = A_surfxml_link_latency___file[0] - ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_link_latency___file) - : nullptr; - link.state_trace = A_surfxml_link_state___file[0] - ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_link_state___file) - : nullptr; - - switch (A_surfxml_link_sharing___policy) { - case A_surfxml_link_sharing___policy_SHARED: - link.policy = simgrid::s4u::Link::SharingPolicy::SHARED; - break; - case A_surfxml_link_sharing___policy_FATPIPE: - link.policy = simgrid::s4u::Link::SharingPolicy::FATPIPE; - break; - case A_surfxml_link_sharing___policy_FULLDUPLEX: - XBT_WARN("FULLDUPLEX is now deprecated. Please update your platform file to use SPLITDUPLEX instead."); - link.policy = simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX; - break; - case A_surfxml_link_sharing___policy_SPLITDUPLEX: - link.policy = simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX; - break; - case A_surfxml_link_sharing___policy_WIFI: - link.policy = simgrid::s4u::Link::SharingPolicy::WIFI; - break; - default: - surf_parse_error(std::string("Invalid sharing policy in link ") + link.id); - } - - sg_platf_new_link(&link); -} - -void STag_surfxml_link___ctn() -{ - const auto engine = simgrid::s4u::Engine::get_instance(); - const simgrid::s4u::Link* link; - simgrid::s4u::LinkInRoute::Direction direction = simgrid::s4u::LinkInRoute::Direction::NONE; - switch (A_surfxml_link___ctn_direction) { - case AU_surfxml_link___ctn_direction: - case A_surfxml_link___ctn_direction_NONE: - link = engine->link_by_name(std::string(A_surfxml_link___ctn_id)); - break; - case A_surfxml_link___ctn_direction_UP: - link = engine->split_duplex_link_by_name(std::string(A_surfxml_link___ctn_id)); - direction = simgrid::s4u::LinkInRoute::Direction::UP; - break; - case A_surfxml_link___ctn_direction_DOWN: - link = engine->split_duplex_link_by_name(std::string(A_surfxml_link___ctn_id)); - direction = simgrid::s4u::LinkInRoute::Direction::DOWN; - break; - default: - surf_parse_error(std::string("Invalid direction for link ") + A_surfxml_link___ctn_id); - } - - const char* dirname; - switch (A_surfxml_link___ctn_direction) { - case A_surfxml_link___ctn_direction_UP: - dirname = " (upward)"; - break; - case A_surfxml_link___ctn_direction_DOWN: - dirname = " (downward)"; - break; - default: - dirname = ""; - } - surf_parse_assert(link != nullptr, std::string("No such link: '") + A_surfxml_link___ctn_id + "'" + dirname); - parsed_link_list.emplace_back(link, direction); -} - -void ETag_surfxml_backbone() -{ - auto link = std::make_unique(); - - link->id = std::string(A_surfxml_backbone_id); - link->bandwidths.push_back(xbt_parse_get_bandwidth( - surf_parsed_filename, surf_parse_lineno, A_surfxml_backbone_bandwidth, "bandwidth of backbone " + link->id)); - link->latency = xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_backbone_latency, - "latency of backbone " + link->id); - link->policy = simgrid::s4u::Link::SharingPolicy::SHARED; - - routing_cluster_add_backbone(std::move(link)); -} - -void STag_surfxml_route(){ - surf_parse_assert_netpoint(A_surfxml_route_src, "Route src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_route_dst, "Route dst='", "' does name a node."); -} - -void STag_surfxml_ASroute(){ - surf_parse_assert_netpoint(A_surfxml_ASroute_src, "ASroute src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_ASroute_dst, "ASroute dst='", "' does name a node."); - - surf_parse_assert_netpoint(A_surfxml_ASroute_gw___src, "ASroute gw_src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_ASroute_gw___dst, "ASroute gw_dst='", "' does name a node."); -} -void STag_surfxml_zoneRoute(){ - surf_parse_assert_netpoint(A_surfxml_zoneRoute_src, "zoneRoute src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_zoneRoute_dst, "zoneRoute dst='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_zoneRoute_gw___src, "zoneRoute gw_src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_zoneRoute_gw___dst, "zoneRoute gw_dst='", "' does name a node."); -} - -void STag_surfxml_bypassRoute(){ - surf_parse_assert_netpoint(A_surfxml_bypassRoute_src, "bypassRoute src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_bypassRoute_dst, "bypassRoute dst='", "' does name a node."); -} - -void STag_surfxml_bypassASroute(){ - surf_parse_assert_netpoint(A_surfxml_bypassASroute_src, "bypassASroute src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_bypassASroute_dst, "bypassASroute dst='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_bypassASroute_gw___src, "bypassASroute gw_src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_bypassASroute_gw___dst, "bypassASroute gw_dst='", "' does name a node."); -} -void STag_surfxml_bypassZoneRoute(){ - surf_parse_assert_netpoint(A_surfxml_bypassZoneRoute_src, "bypassZoneRoute src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_bypassZoneRoute_dst, "bypassZoneRoute dst='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_bypassZoneRoute_gw___src, "bypassZoneRoute gw_src='", "' does name a node."); - surf_parse_assert_netpoint(A_surfxml_bypassZoneRoute_gw___dst, "bypassZoneRoute gw_dst='", "' does name a node."); -} - -void ETag_surfxml_route(){ - simgrid::kernel::routing::RouteCreationArgs route; - - route.src = sg_netpoint_by_name_or_null(A_surfxml_route_src); // tested to not be nullptr in start tag - route.dst = sg_netpoint_by_name_or_null(A_surfxml_route_dst); // tested to not be nullptr in start tag - route.symmetrical = (A_surfxml_route_symmetrical == AU_surfxml_route_symmetrical || - A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES || - A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_yes); - - route.link_list.swap(parsed_link_list); - - sg_platf_new_route(&route); -} - -void ETag_surfxml_ASroute() -{ - AX_surfxml_zoneRoute_src = AX_surfxml_ASroute_src; - AX_surfxml_zoneRoute_dst = AX_surfxml_ASroute_dst; - AX_surfxml_zoneRoute_gw___src = AX_surfxml_ASroute_gw___src; - AX_surfxml_zoneRoute_gw___dst = AX_surfxml_ASroute_gw___dst; - AX_surfxml_zoneRoute_symmetrical = (AT_surfxml_zoneRoute_symmetrical)AX_surfxml_ASroute_symmetrical; - ETag_surfxml_zoneRoute(); -} -void ETag_surfxml_zoneRoute() -{ - simgrid::kernel::routing::RouteCreationArgs ASroute; - - ASroute.src = sg_netpoint_by_name_or_null(A_surfxml_zoneRoute_src); // tested to not be nullptr in start tag - ASroute.dst = sg_netpoint_by_name_or_null(A_surfxml_zoneRoute_dst); // tested to not be nullptr in start tag - - ASroute.gw_src = sg_netpoint_by_name_or_null(A_surfxml_zoneRoute_gw___src); // tested to not be nullptr in start tag - ASroute.gw_dst = sg_netpoint_by_name_or_null(A_surfxml_zoneRoute_gw___dst); // tested to not be nullptr in start tag - - ASroute.link_list.swap(parsed_link_list); - - ASroute.symmetrical = (A_surfxml_zoneRoute_symmetrical == AU_surfxml_zoneRoute_symmetrical || - A_surfxml_zoneRoute_symmetrical == A_surfxml_zoneRoute_symmetrical_YES || - A_surfxml_zoneRoute_symmetrical == A_surfxml_zoneRoute_symmetrical_yes); - - sg_platf_new_route(&ASroute); -} - -void ETag_surfxml_bypassRoute(){ - simgrid::kernel::routing::RouteCreationArgs route; - - route.src = sg_netpoint_by_name_or_null(A_surfxml_bypassRoute_src); // tested to not be nullptr in start tag - route.dst = sg_netpoint_by_name_or_null(A_surfxml_bypassRoute_dst); // tested to not be nullptr in start tag - route.symmetrical = false; - - route.link_list.swap(parsed_link_list); - - sg_platf_new_bypass_route(&route); -} - -void ETag_surfxml_bypassASroute() -{ - AX_surfxml_bypassZoneRoute_src = AX_surfxml_bypassASroute_src; - AX_surfxml_bypassZoneRoute_dst = AX_surfxml_bypassASroute_dst; - AX_surfxml_bypassZoneRoute_gw___src = AX_surfxml_bypassASroute_gw___src; - AX_surfxml_bypassZoneRoute_gw___dst = AX_surfxml_bypassASroute_gw___dst; - ETag_surfxml_bypassZoneRoute(); -} -void ETag_surfxml_bypassZoneRoute() -{ - simgrid::kernel::routing::RouteCreationArgs ASroute; - - ASroute.src = sg_netpoint_by_name_or_null(A_surfxml_bypassZoneRoute_src); - ASroute.dst = sg_netpoint_by_name_or_null(A_surfxml_bypassZoneRoute_dst); - ASroute.link_list.swap(parsed_link_list); - - ASroute.symmetrical = false; - - ASroute.gw_src = sg_netpoint_by_name_or_null(A_surfxml_bypassZoneRoute_gw___src); - ASroute.gw_dst = sg_netpoint_by_name_or_null(A_surfxml_bypassZoneRoute_gw___dst); - - sg_platf_new_bypass_route(&ASroute); -} - -void ETag_surfxml_trace(){ - simgrid::kernel::routing::ProfileCreationArgs trace; - - trace.id = A_surfxml_trace_id; - trace.file = A_surfxml_trace_file; - trace.periodicity = surf_parse_get_double(A_surfxml_trace_periodicity); - trace.pc_data = surfxml_pcdata; - - sg_platf_new_trace(&trace); -} - -void STag_surfxml_trace___connect() -{ - simgrid::kernel::routing::TraceConnectCreationArgs trace_connect; - - trace_connect.element = A_surfxml_trace___connect_element; - trace_connect.trace = A_surfxml_trace___connect_trace; - - switch (A_surfxml_trace___connect_kind) { - case AU_surfxml_trace___connect_kind: - case A_surfxml_trace___connect_kind_SPEED: - trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::SPEED; - break; - case A_surfxml_trace___connect_kind_BANDWIDTH: - trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::BANDWIDTH; - break; - case A_surfxml_trace___connect_kind_HOST___AVAIL: - trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::HOST_AVAIL; - break; - case A_surfxml_trace___connect_kind_LATENCY: - trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::LATENCY; - break; - case A_surfxml_trace___connect_kind_LINK___AVAIL: - trace_connect.kind = simgrid::kernel::routing::TraceConnectKind::LINK_AVAIL; - break; - default: - surf_parse_error("Invalid trace kind"); - } - sg_platf_trace_connect(&trace_connect); -} - -void STag_surfxml_AS() -{ - AX_surfxml_zone_id = AX_surfxml_AS_id; - AX_surfxml_zone_routing = AX_surfxml_AS_routing; - STag_surfxml_zone(); -} - -void ETag_surfxml_AS() -{ - ETag_surfxml_zone(); -} - -void STag_surfxml_zone() -{ - property_sets.emplace_back(); - simgrid::kernel::routing::ZoneCreationArgs zone; - zone.id = A_surfxml_zone_id; - zone.routing = A_surfxml_zone_routing; - sg_platf_new_zone_begin(&zone); -} - -void ETag_surfxml_zone() -{ - sg_platf_new_zone_set_properties(property_sets.back()); - property_sets.pop_back(); - sg_platf_new_zone_seal(); -} - -void STag_surfxml_config() -{ - property_sets.emplace_back(); - XBT_DEBUG("START configuration name = %s",A_surfxml_config_id); - if (_sg_cfg_init_status == 2) { - surf_parse_error("All tags must be given before any platform elements (such as , , , " - ", etc)."); - } -} - -void ETag_surfxml_config() -{ - // Sort config elements before applying. - // That's a little waste of time, but not doing so would break the tests - auto current_property_set = property_sets.back(); - - std::vector keys; - for (auto const& [key, _] : current_property_set) { - keys.push_back(key); - } - std::sort(keys.begin(), keys.end()); - for (const std::string& key : keys) { - if (simgrid::config::is_default(key.c_str())) { - std::string cfg = key + ":" + current_property_set.at(key); - simgrid::config::set_parse(cfg); - } else - XBT_INFO("The custom configuration '%s' is already defined by user!", key.c_str()); - } - XBT_DEBUG("End configuration name = %s",A_surfxml_config_id); - - property_sets.pop_back(); -} - -static std::vector arguments; - -void STag_surfxml_process() -{ - AX_surfxml_actor_function = AX_surfxml_process_function; - STag_surfxml_actor(); -} - -void STag_surfxml_actor() -{ - property_sets.emplace_back(); - arguments.assign(1, A_surfxml_actor_function); -} - -void ETag_surfxml_process() -{ - AX_surfxml_actor_host = AX_surfxml_process_host; - AX_surfxml_actor_function = AX_surfxml_process_function; - AX_surfxml_actor_start___time = AX_surfxml_process_start___time; - AX_surfxml_actor_kill___time = AX_surfxml_process_kill___time; - AX_surfxml_actor_on___failure = (AT_surfxml_actor_on___failure)AX_surfxml_process_on___failure; - ETag_surfxml_actor(); -} - -void ETag_surfxml_actor() -{ - simgrid::kernel::routing::ActorCreationArgs actor; - - actor.properties = property_sets.back(); - property_sets.pop_back(); - - actor.args.swap(arguments); - actor.host = A_surfxml_actor_host; - actor.function = A_surfxml_actor_function; - actor.start_time = surf_parse_get_double(A_surfxml_actor_start___time); - actor.kill_time = surf_parse_get_double(A_surfxml_actor_kill___time); - - switch (A_surfxml_actor_on___failure) { - case AU_surfxml_actor_on___failure: - case A_surfxml_actor_on___failure_DIE: - actor.restart_on_failure = false; - break; - case A_surfxml_actor_on___failure_RESTART: - actor.restart_on_failure = true; - break; - default: - surf_parse_error("Invalid on failure behavior"); - } - - sg_platf_new_actor(&actor); -} - -void STag_surfxml_argument(){ - arguments.emplace_back(A_surfxml_argument_value); -} - -void STag_surfxml_model___prop(){ - XBT_INFO("Deprecated tag ignored"); -} - -void ETag_surfxml_prop(){/* Nothing to do */} -void STag_surfxml_random(){/* Nothing to do */} -void ETag_surfxml_random(){/* Nothing to do */} -void ETag_surfxml_trace___connect() -{ /* Nothing to do */ -} -void STag_surfxml_trace() -{ /* Nothing to do */ -} -void ETag_surfxml_router(){/*Nothing to do*/} -void ETag_surfxml_host___link(){/* Nothing to do */} -void ETag_surfxml_cabinet(){/* Nothing to do */} -void ETag_surfxml_peer(){/* Nothing to do */} -void STag_surfxml_backbone(){/* Nothing to do */} -void ETag_surfxml_link___ctn(){/* Nothing to do */} -void ETag_surfxml_argument(){/* Nothing to do */} -void ETag_surfxml_model___prop(){/* Nothing to do */} - -/* Open and Close parse file */ -YY_BUFFER_STATE surf_input_buffer; - -void surf_parse_open(const std::string& file) -{ - surf_parsed_filename = file; - std::string dir = simgrid::xbt::Path(file).get_dir_name(); - surf_path.push_back(dir); - - surf_file_to_parse = surf_fopen(file, "r"); - if (surf_file_to_parse == nullptr) - throw std::invalid_argument(std::string("Unable to open '") + file + "' from '" + simgrid::xbt::Path().get_name() + - "'. Does this file exist?"); - surf_input_buffer = surf_parse__create_buffer(surf_file_to_parse, YY_BUF_SIZE); - surf_parse__switch_to_buffer(surf_input_buffer); - surf_parse_lineno = 1; -} - -void surf_parse_close() -{ - surf_path.pop_back(); // remove the dirname of the opened file, that was added in surf_parse_open() - - if (surf_file_to_parse) { - surf_parse__delete_buffer(surf_input_buffer); - fclose(surf_file_to_parse); - surf_file_to_parse = nullptr; //Must be reset for Bypass - } -} - -/* Call the lexer to parse the currently opened file */ -void surf_parse() -{ - bool err = surf_parse_lex(); - surf_parse_assert(not err, "Flex returned an error code"); -} diff --git a/src/xbt/OsSemaphore.hpp b/src/xbt/OsSemaphore.hpp index 6582689d69..821075f6b0 100644 --- a/src/xbt/OsSemaphore.hpp +++ b/src/xbt/OsSemaphore.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -22,7 +22,7 @@ public: inline void release() { - std::unique_lock lock(mutex_); + const std::scoped_lock lock(mutex_); ++capa_; condition_.notify_one(); } diff --git a/src/xbt/PropertyHolder.cpp b/src/xbt/PropertyHolder.cpp index 958daa6782..945d4c9946 100644 --- a/src/xbt/PropertyHolder.cpp +++ b/src/xbt/PropertyHolder.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/src/xbt/automaton/automaton.c b/src/xbt/automaton/automaton.c deleted file mode 100644 index 06d5a27df6..0000000000 --- a/src/xbt/automaton/automaton.c +++ /dev/null @@ -1,417 +0,0 @@ -/* automaton - representation of büchi automaton */ - -/* Copyright (c) 2011-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "xbt/automaton.h" -#include /* printf */ -#include - -struct xbt_automaton_propositional_symbol{ - char* pred; - /** Callback used to evaluate the value of the symbol */ - int (*callback)(void*); - /** Additional data for the callback. - Alternatively it can be used as a pointer to the data. */ - void* data; - /** Optional callback used to free the data field */ - void (*free_function)(void*); -}; - -xbt_automaton_t xbt_automaton_new(void){ - xbt_automaton_t automaton = xbt_new0(struct xbt_automaton, 1); - automaton->states = xbt_dynar_new(sizeof(xbt_automaton_state_t), xbt_automaton_state_free_voidp); - automaton->transitions = xbt_dynar_new(sizeof(xbt_automaton_transition_t), xbt_automaton_transition_free_voidp); - automaton->propositional_symbols = xbt_dynar_new(sizeof(xbt_automaton_propositional_symbol_t), xbt_automaton_propositional_symbol_free_voidp); - return automaton; -} - -xbt_automaton_state_t xbt_automaton_state_new(const_xbt_automaton_t a, int type, const char* id) -{ - xbt_automaton_state_t state = xbt_new0(struct xbt_automaton_state, 1); - state->type = type; - state->id = xbt_strdup(id); - state->in = xbt_dynar_new(sizeof(xbt_automaton_transition_t), NULL); - state->out = xbt_dynar_new(sizeof(xbt_automaton_transition_t), NULL); - xbt_dynar_push(a->states, &state); - return state; -} - -xbt_automaton_transition_t xbt_automaton_transition_new(const_xbt_automaton_t a, xbt_automaton_state_t src, - xbt_automaton_state_t dst, xbt_automaton_exp_label_t label) -{ - xbt_automaton_transition_t transition = xbt_new0(struct xbt_automaton_transition, 1); - if(src != NULL){ - xbt_dynar_push(src->out, &transition); - transition->src = src; - } - if(dst != NULL){ - xbt_dynar_push(dst->in, &transition); - transition->dst = dst; - } - transition->label = label; - xbt_dynar_push(a->transitions, &transition); - return transition; -} - -xbt_automaton_exp_label_t xbt_automaton_exp_label_new_or(xbt_automaton_exp_label_t left, - xbt_automaton_exp_label_t right) -{ - xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1); - label->type = AUT_OR; - label->u.or_and.left_exp = left; - label->u.or_and.right_exp = right; - return label; -} - -xbt_automaton_exp_label_t xbt_automaton_exp_label_new_and(xbt_automaton_exp_label_t left, - xbt_automaton_exp_label_t right) -{ - xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1); - label->type = AUT_AND; - label->u.or_and.left_exp = left; - label->u.or_and.right_exp = right; - return label; -} - -xbt_automaton_exp_label_t xbt_automaton_exp_label_new_not(xbt_automaton_exp_label_t exp_not) -{ - xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1); - label->type = AUT_NOT; - label->u.exp_not = exp_not; - return label; -} - -xbt_automaton_exp_label_t xbt_automaton_exp_label_new_predicat(const char* p) -{ - xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1); - label->type = AUT_PREDICAT; - label->u.predicat = xbt_strdup(p); - return label; -} - -xbt_automaton_exp_label_t xbt_automaton_exp_label_new_one(void) -{ - xbt_automaton_exp_label_t label = xbt_new0(struct xbt_automaton_exp_label, 1); - label->type = AUT_ONE; - return label; -} - -xbt_dynar_t xbt_automaton_get_states(const_xbt_automaton_t a) -{ - return a->states; -} - -xbt_dynar_t xbt_automaton_get_transitions(const_xbt_automaton_t a) -{ - return a->transitions; -} - -xbt_automaton_transition_t xbt_automaton_get_transition(XBT_ATTRIB_UNUSED const_xbt_automaton_t a, - const_xbt_automaton_state_t src, - const_xbt_automaton_state_t dst) -{ - xbt_automaton_transition_t transition; - unsigned int cursor; - xbt_dynar_foreach(src->out, cursor, transition){ - if((transition->src == src) && (transition->dst == dst)) - return transition; - } - return NULL; -} - -xbt_automaton_state_t xbt_automaton_transition_get_source(const_xbt_automaton_transition_t t) -{ - return t->src; -} - -xbt_automaton_state_t xbt_automaton_transition_get_destination(const_xbt_automaton_transition_t t) -{ - return t->dst; -} - -void xbt_automaton_transition_set_source(xbt_automaton_transition_t t, xbt_automaton_state_t src){ - t->src = src; - xbt_dynar_push(src->out,&t); -} - -void xbt_automaton_transition_set_destination(xbt_automaton_transition_t t, xbt_automaton_state_t dst){ - t->dst = dst; - xbt_dynar_push(dst->in,&t); -} - -xbt_dynar_t xbt_automaton_state_get_out_transitions(const_xbt_automaton_state_t s) -{ - return s->out; -} - -xbt_dynar_t xbt_automaton_state_get_in_transitions(const_xbt_automaton_state_t s) -{ - return s->in; -} - -xbt_automaton_state_t xbt_automaton_state_exists(const_xbt_automaton_t a, const char* id) -{ - xbt_automaton_state_t state = NULL; - unsigned int cursor = 0; - xbt_dynar_foreach(a->states, cursor, state){ - if(strcmp(state->id, id)==0) - return state; - } - return NULL; -} - -void xbt_automaton_display(const_xbt_automaton_t a) -{ - unsigned int cursor; - xbt_automaton_state_t state = NULL; - - printf("\n\nCurrent state: %s\n", a->current_state->id); - - printf("\nStates' List: %lu\n\n", xbt_dynar_length(a->states)); - - xbt_dynar_foreach(a->states, cursor, state) - printf("ID: %s, type: %d\n", state->id, state->type); - - xbt_automaton_transition_t transition; - printf("\nTransitions: %lu\n\n", xbt_dynar_length(a->transitions)); - - xbt_dynar_foreach(a->transitions, cursor, transition){ - printf("label:"); - xbt_automaton_exp_label_display(transition->label); - printf(", %s -> %s\n", transition->src->id, transition->dst->id); - } -} - -void xbt_automaton_exp_label_display(const_xbt_automaton_exp_label_t label) -{ - printf("("); - switch(label->type){ - case 0: - xbt_automaton_exp_label_display(label->u.or_and.left_exp); - printf(" || "); - xbt_automaton_exp_label_display(label->u.or_and.right_exp); - break; - case 1: - xbt_automaton_exp_label_display(label->u.or_and.left_exp); - printf(" && "); - xbt_automaton_exp_label_display(label->u.or_and.right_exp); - break; - case 2: - printf("!"); - xbt_automaton_exp_label_display(label->u.exp_not); - break; - case 3: - printf("%s", label->u.predicat); - break; - case 4: - printf("1"); - break; - default: - break; - } - printf(")"); -} - -xbt_automaton_state_t xbt_automaton_get_current_state(const_xbt_automaton_t a) -{ - return a->current_state; -} - -static int call_simple_function(int function(void) ) -{ - return function(); -} - -xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new(const_xbt_automaton_t a, const char* id, - int (*fct)(void)) -{ - xbt_automaton_propositional_symbol_t prop_symb = xbt_new0(struct xbt_automaton_propositional_symbol, 1); - prop_symb->pred = xbt_strdup(id); - prop_symb->callback = ((int (*)(void *))&call_simple_function); - prop_symb->data = (void*)&fct; - prop_symb->free_function = NULL; - xbt_dynar_push(a->propositional_symbols, &prop_symb); - return prop_symb; -} - -XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new_pointer(const_xbt_automaton_t a, - const char* id, - int* value) -{ - xbt_automaton_propositional_symbol_t prop_symb = xbt_new0(struct xbt_automaton_propositional_symbol, 1); - prop_symb->pred = xbt_strdup(id); - prop_symb->callback = NULL; - prop_symb->data = value; - prop_symb->free_function = NULL; - xbt_dynar_push(a->propositional_symbols, &prop_symb); - return prop_symb; -} - -XBT_PUBLIC xbt_automaton_propositional_symbol_t xbt_automaton_propositional_symbol_new_callback( - const_xbt_automaton_t a, const char* id, xbt_automaton_propositional_symbol_callback_type callback, void* data, - xbt_automaton_propositional_symbol_free_function_type free_function) -{ - xbt_automaton_propositional_symbol_t prop_symb = xbt_new0(struct xbt_automaton_propositional_symbol, 1); - prop_symb->pred = xbt_strdup(id); - prop_symb->callback = callback; - prop_symb->data = data; - prop_symb->free_function = free_function; - xbt_dynar_push(a->propositional_symbols, &prop_symb); - return prop_symb; -} - -XBT_PUBLIC int xbt_automaton_propositional_symbol_evaluate(const_xbt_automaton_propositional_symbol_t symbol) -{ - if (symbol->callback) - return (symbol->callback)(symbol->data); - else - return *(int*) symbol->data; -} - -XBT_PUBLIC xbt_automaton_propositional_symbol_callback_type -xbt_automaton_propositional_symbol_get_callback(const_xbt_automaton_propositional_symbol_t symbol) -{ - return symbol->callback; -} - -XBT_PUBLIC void* xbt_automaton_propositional_symbol_get_data(const_xbt_automaton_propositional_symbol_t symbol) -{ - return symbol->data; -} - -XBT_PUBLIC const char* xbt_automaton_propositional_symbol_get_name(const_xbt_automaton_propositional_symbol_t symbol) -{ - return symbol->pred; -} - -int xbt_automaton_state_compare(const_xbt_automaton_state_t s1, const_xbt_automaton_state_t s2) -{ - /* single id for each state, id and type sufficient for comparison*/ - return (strcmp(s1->id, s2->id) != 0) || (s1->type != s2->type); -} - -int xbt_automaton_transition_compare(const_xbt_automaton_transition_t t1, const_xbt_automaton_transition_t t2) -{ - return xbt_automaton_state_compare(t1->src, t2->src) || xbt_automaton_state_compare(t1->dst, t2->dst) || - xbt_automaton_exp_label_compare(t1->label, t2->label); -} - -int xbt_automaton_exp_label_compare(const_xbt_automaton_exp_label_t l1, const_xbt_automaton_exp_label_t l2) -{ - if(l1->type != l2->type) - return 1; - - int res; - switch(l1->type){ - case 0 : // OR - case 1 : // AND - res = xbt_automaton_exp_label_compare(l1->u.or_and.left_exp, l2->u.or_and.left_exp) || - xbt_automaton_exp_label_compare(l1->u.or_and.right_exp, l2->u.or_and.right_exp); - break; - case 2 : // NOT - res = xbt_automaton_exp_label_compare(l1->u.exp_not, l2->u.exp_not); - break; - case 3 : // predicat - res = strcmp(l1->u.predicat, l2->u.predicat) != 0; - break; - case 4 : // 1 - res = 0; - break; - default : - res = -1; - break; - } - return res; -} - -int xbt_automaton_propositional_symbols_compare_value(const_xbt_dynar_t s1, const_xbt_dynar_t s2) -{ - unsigned long nb_elem = xbt_dynar_length(s1); - - for (unsigned long cursor = 0; cursor < nb_elem; cursor++) { - const int* iptr1 = xbt_dynar_get_ptr(s1, cursor); - const int* iptr2 = xbt_dynar_get_ptr(s2, cursor); - if(*iptr1 != *iptr2) - return 1; - } - - return 0; -} - -static void xbt_automaton_transition_free(xbt_automaton_transition_t t); -static void xbt_automaton_exp_label_free(xbt_automaton_exp_label_t e); -static void xbt_automaton_propositional_symbol_free(xbt_automaton_propositional_symbol_t ps); - -void xbt_automaton_state_free(xbt_automaton_state_t s){ - if (s == NULL) - return; - xbt_free(s->id); - xbt_dynar_free(&(s->in)); - xbt_dynar_free(&(s->out)); - xbt_free(s); -} - -void xbt_automaton_state_free_voidp(void *s){ - xbt_automaton_state_free((xbt_automaton_state_t) * (void **) s); -} - -static void xbt_automaton_transition_free(xbt_automaton_transition_t t){ - if (t == NULL) - return; - xbt_automaton_exp_label_free(t->label); - xbt_free(t); -} - -void xbt_automaton_transition_free_voidp(void *t){ - xbt_automaton_transition_free((xbt_automaton_transition_t) * (void **) t); -} - -static void xbt_automaton_exp_label_free(xbt_automaton_exp_label_t e){ - if (e == NULL) - return; - switch (e->type) { - case AUT_OR: - case AUT_AND: - xbt_automaton_exp_label_free(e->u.or_and.left_exp); - xbt_automaton_exp_label_free(e->u.or_and.right_exp); - break; - case AUT_NOT: - xbt_automaton_exp_label_free(e->u.exp_not); - break; - case AUT_PREDICAT: - xbt_free(e->u.predicat); - break; - default: - break; - } - xbt_free(e); -} - -void xbt_automaton_exp_label_free_voidp(void *e){ - xbt_automaton_exp_label_free((xbt_automaton_exp_label_t) * (void **) e); -} - -static void xbt_automaton_propositional_symbol_free(xbt_automaton_propositional_symbol_t ps){ - if (ps == NULL) - return; - if (ps->free_function) - ps->free_function(ps->data); - xbt_free(ps->pred); - xbt_free(ps); -} - -void xbt_automaton_propositional_symbol_free_voidp(void *ps){ - xbt_automaton_propositional_symbol_free((xbt_automaton_propositional_symbol_t) * (void**)ps); -} - -void xbt_automaton_free(xbt_automaton_t a){ - if (a == NULL) - return; - xbt_dynar_free(&(a->propositional_symbols)); - xbt_dynar_free(&(a->transitions)); - xbt_dynar_free(&(a->states)); - xbt_free(a); -} diff --git a/src/xbt/automaton/automaton_lexer.yy.c b/src/xbt/automaton/automaton_lexer.yy.c deleted file mode 100644 index 9286e7bc4f..0000000000 --- a/src/xbt/automaton/automaton_lexer.yy.c +++ /dev/null @@ -1,2184 +0,0 @@ -#line 2 "automaton_lexer.yy.c" - -#line 4 "automaton_lexer.yy.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define yy_create_buffer xbt_automaton_parser__create_buffer -#define yy_delete_buffer xbt_automaton_parser__delete_buffer -#define yy_scan_buffer xbt_automaton_parser__scan_buffer -#define yy_scan_string xbt_automaton_parser__scan_string -#define yy_scan_bytes xbt_automaton_parser__scan_bytes -#define yy_init_buffer xbt_automaton_parser__init_buffer -#define yy_flush_buffer xbt_automaton_parser__flush_buffer -#define yy_load_buffer_state xbt_automaton_parser__load_buffer_state -#define yy_switch_to_buffer xbt_automaton_parser__switch_to_buffer -#define yypush_buffer_state xbt_automaton_parser_push_buffer_state -#define yypop_buffer_state xbt_automaton_parser_pop_buffer_state -#define yyensure_buffer_stack xbt_automaton_parser_ensure_buffer_stack -#define yy_flex_debug xbt_automaton_parser__flex_debug -#define yyin xbt_automaton_parser_in -#define yyleng xbt_automaton_parser_leng -#define yylex xbt_automaton_parser_lex -#define yylineno xbt_automaton_parser_lineno -#define yyout xbt_automaton_parser_out -#define yyrestart xbt_automaton_parser_restart -#define yytext xbt_automaton_parser_text -#define yywrap xbt_automaton_parser_wrap -#define yyalloc xbt_automaton_parser_alloc -#define yyrealloc xbt_automaton_parser_realloc -#define yyfree xbt_automaton_parser_free - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 6 -#define YY_FLEX_SUBMINOR_VERSION 4 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -#ifdef yy_create_buffer -#define xbt_automaton_parser__create_buffer_ALREADY_DEFINED -#else -#define yy_create_buffer xbt_automaton_parser__create_buffer -#endif - -#ifdef yy_delete_buffer -#define xbt_automaton_parser__delete_buffer_ALREADY_DEFINED -#else -#define yy_delete_buffer xbt_automaton_parser__delete_buffer -#endif - -#ifdef yy_scan_buffer -#define xbt_automaton_parser__scan_buffer_ALREADY_DEFINED -#else -#define yy_scan_buffer xbt_automaton_parser__scan_buffer -#endif - -#ifdef yy_scan_string -#define xbt_automaton_parser__scan_string_ALREADY_DEFINED -#else -#define yy_scan_string xbt_automaton_parser__scan_string -#endif - -#ifdef yy_scan_bytes -#define xbt_automaton_parser__scan_bytes_ALREADY_DEFINED -#else -#define yy_scan_bytes xbt_automaton_parser__scan_bytes -#endif - -#ifdef yy_init_buffer -#define xbt_automaton_parser__init_buffer_ALREADY_DEFINED -#else -#define yy_init_buffer xbt_automaton_parser__init_buffer -#endif - -#ifdef yy_flush_buffer -#define xbt_automaton_parser__flush_buffer_ALREADY_DEFINED -#else -#define yy_flush_buffer xbt_automaton_parser__flush_buffer -#endif - -#ifdef yy_load_buffer_state -#define xbt_automaton_parser__load_buffer_state_ALREADY_DEFINED -#else -#define yy_load_buffer_state xbt_automaton_parser__load_buffer_state -#endif - -#ifdef yy_switch_to_buffer -#define xbt_automaton_parser__switch_to_buffer_ALREADY_DEFINED -#else -#define yy_switch_to_buffer xbt_automaton_parser__switch_to_buffer -#endif - -#ifdef yypush_buffer_state -#define xbt_automaton_parser_push_buffer_state_ALREADY_DEFINED -#else -#define yypush_buffer_state xbt_automaton_parser_push_buffer_state -#endif - -#ifdef yypop_buffer_state -#define xbt_automaton_parser_pop_buffer_state_ALREADY_DEFINED -#else -#define yypop_buffer_state xbt_automaton_parser_pop_buffer_state -#endif - -#ifdef yyensure_buffer_stack -#define xbt_automaton_parser_ensure_buffer_stack_ALREADY_DEFINED -#else -#define yyensure_buffer_stack xbt_automaton_parser_ensure_buffer_stack -#endif - -#ifdef yylex -#define xbt_automaton_parser_lex_ALREADY_DEFINED -#else -#define yylex xbt_automaton_parser_lex -#endif - -#ifdef yyrestart -#define xbt_automaton_parser_restart_ALREADY_DEFINED -#else -#define yyrestart xbt_automaton_parser_restart -#endif - -#ifdef yylex_init -#define xbt_automaton_parser_lex_init_ALREADY_DEFINED -#else -#define yylex_init xbt_automaton_parser_lex_init -#endif - -#ifdef yylex_init_extra -#define xbt_automaton_parser_lex_init_extra_ALREADY_DEFINED -#else -#define yylex_init_extra xbt_automaton_parser_lex_init_extra -#endif - -#ifdef yylex_destroy -#define xbt_automaton_parser_lex_destroy_ALREADY_DEFINED -#else -#define yylex_destroy xbt_automaton_parser_lex_destroy -#endif - -#ifdef yyget_debug -#define xbt_automaton_parser_get_debug_ALREADY_DEFINED -#else -#define yyget_debug xbt_automaton_parser_get_debug -#endif - -#ifdef yyset_debug -#define xbt_automaton_parser_set_debug_ALREADY_DEFINED -#else -#define yyset_debug xbt_automaton_parser_set_debug -#endif - -#ifdef yyget_extra -#define xbt_automaton_parser_get_extra_ALREADY_DEFINED -#else -#define yyget_extra xbt_automaton_parser_get_extra -#endif - -#ifdef yyset_extra -#define xbt_automaton_parser_set_extra_ALREADY_DEFINED -#else -#define yyset_extra xbt_automaton_parser_set_extra -#endif - -#ifdef yyget_in -#define xbt_automaton_parser_get_in_ALREADY_DEFINED -#else -#define yyget_in xbt_automaton_parser_get_in -#endif - -#ifdef yyset_in -#define xbt_automaton_parser_set_in_ALREADY_DEFINED -#else -#define yyset_in xbt_automaton_parser_set_in -#endif - -#ifdef yyget_out -#define xbt_automaton_parser_get_out_ALREADY_DEFINED -#else -#define yyget_out xbt_automaton_parser_get_out -#endif - -#ifdef yyset_out -#define xbt_automaton_parser_set_out_ALREADY_DEFINED -#else -#define yyset_out xbt_automaton_parser_set_out -#endif - -#ifdef yyget_leng -#define xbt_automaton_parser_get_leng_ALREADY_DEFINED -#else -#define yyget_leng xbt_automaton_parser_get_leng -#endif - -#ifdef yyget_text -#define xbt_automaton_parser_get_text_ALREADY_DEFINED -#else -#define yyget_text xbt_automaton_parser_get_text -#endif - -#ifdef yyget_lineno -#define xbt_automaton_parser_get_lineno_ALREADY_DEFINED -#else -#define yyget_lineno xbt_automaton_parser_get_lineno -#endif - -#ifdef yyset_lineno -#define xbt_automaton_parser_set_lineno_ALREADY_DEFINED -#else -#define yyset_lineno xbt_automaton_parser_set_lineno -#endif - -#ifdef yywrap -#define xbt_automaton_parser_wrap_ALREADY_DEFINED -#else -#define yywrap xbt_automaton_parser_wrap -#endif - -#ifdef yyalloc -#define xbt_automaton_parser_alloc_ALREADY_DEFINED -#else -#define yyalloc xbt_automaton_parser_alloc -#endif - -#ifdef yyrealloc -#define xbt_automaton_parser_realloc_ALREADY_DEFINED -#else -#define yyrealloc xbt_automaton_parser_realloc -#endif - -#ifdef yyfree -#define xbt_automaton_parser_free_ALREADY_DEFINED -#else -#define yyfree xbt_automaton_parser_free -#endif - -#ifdef yytext -#define xbt_automaton_parser_text_ALREADY_DEFINED -#else -#define yytext xbt_automaton_parser_text -#endif - -#ifdef yyleng -#define xbt_automaton_parser_leng_ALREADY_DEFINED -#else -#define yyleng xbt_automaton_parser_leng -#endif - -#ifdef yyin -#define xbt_automaton_parser_in_ALREADY_DEFINED -#else -#define yyin xbt_automaton_parser_in -#endif - -#ifdef yyout -#define xbt_automaton_parser_out_ALREADY_DEFINED -#else -#define yyout xbt_automaton_parser_out -#endif - -#ifdef yy_flex_debug -#define xbt_automaton_parser__flex_debug_ALREADY_DEFINED -#else -#define yy_flex_debug xbt_automaton_parser__flex_debug -#endif - -#ifdef yylineno -#define xbt_automaton_parser_lineno_ALREADY_DEFINED -#else -#define yylineno xbt_automaton_parser_lineno -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#ifndef SIZE_MAX -#define SIZE_MAX (~(size_t)0) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -/* begin standard C++ headers. */ - -/* TODO: this is always defined, so inline it */ -#define yyconst const - -#if defined(__GNUC__) && __GNUC__ >= 3 -#define yynoreturn __attribute__((__noreturn__)) -#else -#define yynoreturn -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an - * integer in range [0..255] for use as an array index. - */ -#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -extern int yyleng; - -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - #define YY_LINENO_REWIND_TO(ptr) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - int yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = NULL; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart ( FILE *input_file ); -void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); -void yy_delete_buffer ( YY_BUFFER_STATE b ); -void yy_flush_buffer ( YY_BUFFER_STATE b ); -void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state ( void ); - -static void yyensure_buffer_stack ( void ); -static void yy_load_buffer_state ( void ); -static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); -#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); -YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); - -void *yyalloc ( yy_size_t ); -void *yyrealloc ( void *, yy_size_t ); -void yyfree ( void * ); - -#define yy_new_buffer yy_create_buffer -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer( yyin, YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer( yyin, YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define xbt_automaton_parser_wrap() (/*CONSTCOND*/1) -#define YY_SKIP_YYWRAP -typedef flex_uint8_t YY_CHAR; - -FILE *yyin = NULL, *yyout = NULL; - -typedef int yy_state_type; - -extern int yylineno; -int yylineno = 1; - -extern char *yytext; -#ifdef yytext_ptr -#undef yytext_ptr -#endif -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state ( void ); -static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); -static int yy_get_next_buffer ( void ); -static void yynoreturn yy_fatal_error ( const char* msg ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 25 -#define YY_END_OF_BUFFER 26 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static const flex_int16_t yy_accept[54] = - { 0, - 0, 0, 26, 24, 18, 23, 8, 24, 24, 9, - 10, 24, 24, 20, 14, 12, 13, 22, 22, 22, - 22, 22, 15, 24, 16, 18, 0, 0, 21, 0, - 6, 4, 0, 0, 20, 11, 22, 3, 22, 2, - 22, 7, 0, 0, 0, 19, 22, 22, 17, 5, - 22, 1, 0 - } ; - -static const YY_CHAR yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 4, 5, 6, 1, 1, 1, 7, 1, 8, - 9, 10, 1, 1, 11, 12, 13, 14, 15, 14, - 14, 14, 14, 14, 14, 14, 14, 16, 17, 1, - 1, 18, 1, 1, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 1, 20, 1, 1, 21, 1, 19, 19, 19, 19, - - 22, 23, 24, 19, 25, 19, 19, 19, 19, 26, - 27, 19, 19, 28, 19, 29, 19, 30, 19, 19, - 19, 19, 31, 32, 33, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static const YY_CHAR yy_meta[34] = - { 0, - 1, 1, 2, 2, 1, 2, 1, 1, 1, 1, - 1, 1, 3, 4, 4, 1, 1, 1, 4, 2, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 1, 1, 1 - } ; - -static const flex_int16_t yy_base[57] = - { 0, - 0, 0, 89, 90, 32, 90, 90, 34, 81, 90, - 90, 69, 76, 27, 31, 69, 90, 0, 59, 56, - 58, 55, 90, 42, 90, 45, 47, 0, 0, 0, - 90, 90, 52, 43, 49, 90, 0, 0, 44, 0, - 42, 90, 56, 65, 52, 56, 25, 26, 90, 0, - 16, 0, 90, 74, 31, 78 - } ; - -static const flex_int16_t yy_def[57] = - { 0, - 53, 1, 53, 53, 53, 53, 53, 54, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 55, 55, 55, - 55, 55, 53, 53, 53, 53, 54, 27, 27, 27, - 53, 53, 56, 53, 53, 53, 55, 55, 55, 55, - 55, 53, 56, 56, 53, 53, 55, 55, 53, 55, - 55, 55, 0, 53, 53, 53 - } ; - -static const flex_int16_t yy_nxt[124] = - { 0, - 4, 5, 6, 5, 7, 8, 9, 10, 11, 4, - 12, 4, 13, 14, 15, 16, 17, 4, 18, 4, - 4, 18, 19, 20, 21, 22, 18, 18, 18, 18, - 23, 24, 25, 26, 37, 26, 27, 28, 34, 29, - 35, 35, 34, 52, 35, 35, 26, 51, 26, 27, - 28, 50, 29, 27, 44, 44, 46, 46, 44, 44, - 34, 45, 35, 35, 49, 45, 27, 44, 44, 46, - 46, 48, 47, 42, 45, 30, 41, 30, 43, 43, - 40, 43, 39, 38, 36, 33, 32, 31, 53, 3, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53 - } ; - -static const flex_int16_t yy_chk[124] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 5, 55, 5, 8, 8, 14, 8, - 14, 14, 15, 51, 15, 15, 26, 48, 26, 27, - 27, 47, 27, 8, 33, 33, 34, 34, 43, 43, - 35, 33, 35, 35, 45, 43, 27, 44, 44, 46, - 46, 41, 39, 24, 44, 54, 22, 54, 56, 56, - 21, 56, 20, 19, 16, 13, 12, 9, 3, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -extern int yy_flex_debug; -int yy_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "parserPromela.lex" -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ -#line 10 "parserPromela.lex" - -#include "simgrid/config.h" -#if !HAVE_UNISTD_H -#define YY_NO_UNISTD_H /* hello Windows */ -#endif - -#include -#include "parserPromela.tab.hacc" - - extern YYSTYPE yylval; - -#line 764 "automaton_lexer.yy.c" -#line 765 "automaton_lexer.yy.c" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -static int yy_init_globals ( void ); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy ( void ); - -int yyget_debug ( void ); - -void yyset_debug ( int debug_flag ); - -YY_EXTRA_TYPE yyget_extra ( void ); - -void yyset_extra ( YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in ( void ); - -void yyset_in ( FILE * _in_str ); - -FILE *yyget_out ( void ); - -void yyset_out ( FILE * _out_str ); - - int yyget_leng ( void ); - -char *yyget_text ( void ); - -int yyget_lineno ( void ); - -void yyset_lineno ( int _line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap ( void ); -#else -extern int yywrap ( void ); -#endif -#endif - -#ifndef YY_NO_UNPUT - - static void yyunput ( int c, char *buf_ptr ); - -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy ( char *, const char *, int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen ( const char * ); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput ( void ); -#else -static int input ( void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - int n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex (void); - -#define YY_DECL int yylex (void) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK /*LINTED*/break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - yy_state_type yy_current_state; - char *yy_cp, *yy_bp; - int yy_act; - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer( yyin, YY_BUF_SIZE ); - } - - yy_load_buffer_state( ); - } - - { -#line 38 "parserPromela.lex" - - -#line 985 "automaton_lexer.yy.c" - - while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - do - { - YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 54 ) - yy_c = yy_meta[yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 90 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 40 "parserPromela.lex" -{ return (NEVER); } - YY_BREAK -case 2: -YY_RULE_SETUP -#line 41 "parserPromela.lex" -{ return (IF); } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 42 "parserPromela.lex" -{ return (FI); } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 43 "parserPromela.lex" -{ return (IMPLIES); } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 44 "parserPromela.lex" -{ return (GOTO); } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 45 "parserPromela.lex" -{ return (AND); } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 46 "parserPromela.lex" -{ return (OR); } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 47 "parserPromela.lex" -{ return (NOT); } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 48 "parserPromela.lex" -{ return (LEFT_PAR); } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 49 "parserPromela.lex" -{ return (RIGHT_PAR); } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 50 "parserPromela.lex" -{ return (CASE); } - YY_BREAK -case 12: -YY_RULE_SETUP -#line 51 "parserPromela.lex" -{ return (COLON); } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 52 "parserPromela.lex" -{ return (SEMI_COLON); } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 53 "parserPromela.lex" -{ return (CASE_TRUE); } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 54 "parserPromela.lex" -{ return (LEFT_BRACE); } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 55 "parserPromela.lex" -{ return (RIGHT_BRACE); } - YY_BREAK -case 17: -/* rule 17 can match eol */ -YY_RULE_SETUP -#line 58 "parserPromela.lex" -{ } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 60 "parserPromela.lex" -{ } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 63 "parserPromela.lex" -{ sscanf(yytext,"%lf",&yylval.real); - return (LITT_REEL); } - YY_BREAK -case 20: -YY_RULE_SETUP -#line 66 "parserPromela.lex" -{ sscanf(yytext,"%d",&yylval.integer); - return (LITT_ENT); } - YY_BREAK -case 21: -/* rule 21 can match eol */ -YY_RULE_SETUP -#line 69 "parserPromela.lex" -{ yylval.string=(char *)malloc(strlen(yytext)+1); - sscanf(yytext,"%s",yylval.string); - return (LITT_CHAINE); } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 73 "parserPromela.lex" -{ yylval.string=(char *)malloc(strlen(yytext)+1); - sscanf(yytext,"%s",yylval.string); - return (ID); } - YY_BREAK -case 23: -/* rule 23 can match eol */ -YY_RULE_SETUP -#line 77 "parserPromela.lex" -{ } - YY_BREAK -case 24: -YY_RULE_SETUP -#line 79 "parserPromela.lex" -{ } - YY_BREAK -case 25: -YY_RULE_SETUP -#line 81 "parserPromela.lex" -ECHO; - YY_BREAK -#line 1176 "automaton_lexer.yy.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of user's declarations */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - char *source = (yytext_ptr); - int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc( (void *) b->yy_ch_buf, - (yy_size_t) (b->yy_buf_size + 2) ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = NULL; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( - (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - /* "- 2" to take care of EOB's */ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - yy_state_type yy_current_state; - char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 54 ) - yy_c = yy_meta[yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - int yy_is_jam; - char *yy_cp = (yy_c_buf_p); - - YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 54 ) - yy_c = yy_meta[yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 53); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_UNPUT - - static void yyunput (int c, char * yy_bp ) -{ - char *yy_cp; - - yy_cp = (yy_c_buf_p); - - /* undo effects of setting up yytext */ - *yy_cp = (yy_hold_char); - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - int number_to_move = (yy_n_chars) + 2; - char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - (yytext_ptr) = yy_bp; - (yy_hold_char) = *yy_cp; - (yy_c_buf_p) = yy_cp; -} - -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) - return 0; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve yytext */ - (yy_hold_char) = *++(yy_c_buf_p); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer( yyin, YY_BUF_SIZE ); - } - - yy_init_buffer( YY_CURRENT_BUFFER, input_file ); - yy_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void yy_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * - */ - void yy_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree( (void *) b->yy_ch_buf ); - - yyfree( (void *) b ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void yy_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void yypop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (void) -{ - yy_size_t num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - yy_size_t grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return NULL; - - b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = NULL; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (const char * yystr ) -{ - - return yy_scan_bytes( yystr, (int) strlen(yystr) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = (yy_size_t) (_yybytes_len + 2); - buf = (char *) yyalloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yynoreturn yy_fatal_error (const char* msg ) -{ - fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = (yy_hold_char); \ - (yy_c_buf_p) = yytext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int yyget_lineno (void) -{ - - return yylineno; -} - -/** Get the input stream. - * - */ -FILE *yyget_in (void) -{ - return yyin; -} - -/** Get the output stream. - * - */ -FILE *yyget_out (void) -{ - return yyout; -} - -/** Get the length of the current token. - * - */ -int yyget_leng (void) -{ - return yyleng; -} - -/** Get the current token. - * - */ - -char *yyget_text (void) -{ - return yytext; -} - -/** Set the current line number. - * @param _line_number line number - * - */ -void yyset_lineno (int _line_number ) -{ - - yylineno = _line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param _in_str A readable stream. - * - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * _in_str ) -{ - yyin = _in_str ; -} - -void yyset_out (FILE * _out_str ) -{ - yyout = _out_str ; -} - -int yyget_debug (void) -{ - return yy_flex_debug; -} - -void yyset_debug (int _bdebug ) -{ - yy_flex_debug = _bdebug ; -} - -static int yy_init_globals (void) -{ - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - (yy_buffer_stack) = NULL; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = NULL; - (yy_init) = 0; - (yy_start) = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = NULL; - yyout = NULL; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer( YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(); - } - - /* Destroy the stack itself. */ - yyfree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( ); - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, const char * s2, int n ) -{ - - int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (const char * s ) -{ - int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size ) -{ - return malloc(size); -} - -void *yyrealloc (void * ptr, yy_size_t size ) -{ - - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return realloc(ptr, size); -} - -void yyfree (void * ptr ) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 81 "parserPromela.lex" - - - - diff --git a/src/xbt/automaton/automatonparse_promela.c b/src/xbt/automaton/automatonparse_promela.c deleted file mode 100644 index 37dd4bd6d2..0000000000 --- a/src/xbt/automaton/automatonparse_promela.c +++ /dev/null @@ -1,70 +0,0 @@ -/* methods for implementation of automaton from promela description */ - -/* Copyright (c) 2011-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "src/internal_config.h" -#include "xbt/automaton.h" -#include -#include /* strerror */ -#if HAVE_UNISTD_H -# include /* isatty */ -#endif -#include - -#include "parserPromela.tab.cacc" - -static xbt_automaton_t parsed_automaton; -char* state_id_src; - -static void new_state(const char* id, int src) -{ - char* saveptr = NULL; // for strtok_r() - char* id_copy = xbt_strdup(id); - const char* first_part = strtok_r(id_copy, "_", &saveptr); - int type = 0 ; // -1=initial state; 0=intermediate state; 1=final state - - if(strcmp(first_part,"accept")==0){ - type = 1; - }else{ - const char* second_part = strtok_r(NULL, "_", &saveptr); - if(strcmp(second_part,"init")==0){ - type = -1; - } - } - xbt_free(id_copy); - - xbt_automaton_state_t state = xbt_automaton_state_exists(parsed_automaton, id); - if(state == NULL){ - state = xbt_automaton_state_new(parsed_automaton, type, id); - } - - if(type==-1) - parsed_automaton->current_state = state; - - if(src) { - xbt_free(state_id_src); - state_id_src = xbt_strdup(id); - } -} - -static void new_transition(const char* id, xbt_automaton_exp_label_t label) -{ - new_state(id, 0); - xbt_automaton_state_t state_dst = xbt_automaton_state_exists(parsed_automaton, id); - xbt_automaton_state_t state_src = xbt_automaton_state_exists(parsed_automaton, state_id_src); - - xbt_automaton_transition_new(parsed_automaton, state_src, state_dst, label); - -} - -void xbt_automaton_load(xbt_automaton_t a, const char *file) -{ - parsed_automaton = a; - xbt_automaton_parser_in = fopen(file, "r"); - xbt_assert(xbt_automaton_parser_in != NULL, "Failed to open automaton file `%s': %s", file, strerror(errno)); - xbt_automaton_parser_parse(); - fclose(xbt_automaton_parser_in); -} diff --git a/src/xbt/automaton/parserPromela.lex b/src/xbt/automaton/parserPromela.lex deleted file mode 100644 index 2207f74f63..0000000000 --- a/src/xbt/automaton/parserPromela.lex +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -%option noyywrap - -%{ - -#include "simgrid/config.h" -#if !HAVE_UNISTD_H -#define YY_NO_UNISTD_H /* hello Windows */ -#endif - -#include -#include "parserPromela.tab.hacc" - - extern YYSTYPE yylval; - -%} - -blancs [ \t]+ -espace [ ]+ -nouv_ligne [ \n] - -chiffre [0-9] -entier {chiffre}+ -reel {entier}("."{entier}) -caractere [a-zA-Z0-9_] - -numl \n - -chaine \"({caractere}*|\n|\\|\"|{espace}*)*\" - -commentaire "/*"([^\*\/]*{nouv_ligne}*[^\*\/]*)*"*/" - -%% - -"never" { return (NEVER); } -"if" { return (IF); } -"fi" { return (FI); } -"->" { return (IMPLIES); } -"goto" { return (GOTO); } -"&&" { return (AND); } -"||" { return (OR); } -"!" { return (NOT); } -"(" { return (LEFT_PAR); } -")" { return (RIGHT_PAR); } -"::" { return (CASE); } -":" { return (COLON); } -";" { return (SEMI_COLON); } -"1" { return (CASE_TRUE); } -"{" { return (LEFT_BRACE); } -"}" { return (RIGHT_BRACE); } - - -{commentaire} { } - -{blancs} { } - - -{reel} { sscanf(yytext,"%lf",&yylval.real); - return (LITT_REEL); } - -{entier} { sscanf(yytext,"%d",&yylval.integer); - return (LITT_ENT); } - -{chaine} { yylval.string=(char *)malloc(strlen(yytext)+1); - sscanf(yytext,"%s",yylval.string); - return (LITT_CHAINE); } - -[a-zA-Z]{caractere}* { yylval.string=(char *)malloc(strlen(yytext)+1); - sscanf(yytext,"%s",yylval.string); - return (ID); } - -{numl} { } - -. { } - -%% - - diff --git a/src/xbt/automaton/parserPromela.tab.cacc b/src/xbt/automaton/parserPromela.tab.cacc deleted file mode 100644 index 57a86d335c..0000000000 --- a/src/xbt/automaton/parserPromela.tab.cacc +++ /dev/null @@ -1,1374 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.7.6. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output, and Bison version. */ -#define YYBISON 30706 - -/* Bison version string. */ -#define YYBISON_VERSION "3.7.6" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - -/* Substitute the variable and function names. */ -#define yyparse xbt_automaton_parser_parse -#define yylex xbt_automaton_parser_lex -#define yyerror xbt_automaton_parser_error -#define yydebug xbt_automaton_parser_debug -#define yynerrs xbt_automaton_parser_nerrs -#define yylval xbt_automaton_parser_lval -#define yychar xbt_automaton_parser_char - -/* First part of user prologue. */ -#line 7 "parserPromela.yacc" - -#include "simgrid/config.h" -#if !HAVE_UNISTD_H -#define YY_NO_UNISTD_H /* hello Windows */ -#endif - -#include "automaton_lexer.yy.c" -#include - -void yyerror(const char *s); - -static void new_state(const char* id, int src); -static void new_transition(const char* id, xbt_automaton_exp_label_t label); - - -#line 94 "parserPromela.tab.cacc" - -# ifndef YY_CAST -# ifdef __cplusplus -# define YY_CAST(Type, Val) static_cast (Val) -# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) -# else -# define YY_CAST(Type, Val) ((Type) (Val)) -# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) -# endif -# endif -# ifndef YY_NULLPTR -# if defined __cplusplus -# if 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# else -# define YY_NULLPTR ((void*)0) -# endif -# endif - -#include "parserPromela.tab.hacc" -/* Symbol kind. */ -enum yysymbol_kind_t -{ - YYSYMBOL_YYEMPTY = -2, - YYSYMBOL_YYEOF = 0, /* "end of file" */ - YYSYMBOL_YYerror = 1, /* error */ - YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ - YYSYMBOL_NEVER = 3, /* NEVER */ - YYSYMBOL_IF = 4, /* IF */ - YYSYMBOL_FI = 5, /* FI */ - YYSYMBOL_IMPLIES = 6, /* IMPLIES */ - YYSYMBOL_GOTO = 7, /* GOTO */ - YYSYMBOL_AND = 8, /* AND */ - YYSYMBOL_OR = 9, /* OR */ - YYSYMBOL_NOT = 10, /* NOT */ - YYSYMBOL_LEFT_PAR = 11, /* LEFT_PAR */ - YYSYMBOL_RIGHT_PAR = 12, /* RIGHT_PAR */ - YYSYMBOL_CASE = 13, /* CASE */ - YYSYMBOL_COLON = 14, /* COLON */ - YYSYMBOL_SEMI_COLON = 15, /* SEMI_COLON */ - YYSYMBOL_CASE_TRUE = 16, /* CASE_TRUE */ - YYSYMBOL_LEFT_BRACE = 17, /* LEFT_BRACE */ - YYSYMBOL_RIGHT_BRACE = 18, /* RIGHT_BRACE */ - YYSYMBOL_LITT_ENT = 19, /* LITT_ENT */ - YYSYMBOL_LITT_CHAINE = 20, /* LITT_CHAINE */ - YYSYMBOL_LITT_REEL = 21, /* LITT_REEL */ - YYSYMBOL_ID = 22, /* ID */ - YYSYMBOL_YYACCEPT = 23, /* $accept */ - YYSYMBOL_automaton = 24, /* automaton */ - YYSYMBOL_stateseq = 25, /* stateseq */ - YYSYMBOL_26_1 = 26, /* $@1 */ - YYSYMBOL_option = 27, /* option */ - YYSYMBOL_exp = 28 /* exp */ -}; -typedef enum yysymbol_kind_t yysymbol_kind_t; - - - - -#ifdef short -# undef short -#endif - -/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure - and (if available) are included - so that the code can choose integer types of a good width. */ - -#ifndef __PTRDIFF_MAX__ -# include /* INFRINGES ON USER NAME SPACE */ -# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_STDINT_H -# endif -#endif - -/* Narrow types that promote to a signed type and that can represent a - signed or unsigned integer of at least N bits. In tables they can - save space and decrease cache pressure. Promoting to a signed type - helps avoid bugs in integer arithmetic. */ - -#ifdef __INT_LEAST8_MAX__ -typedef __INT_LEAST8_TYPE__ yytype_int8; -#elif defined YY_STDINT_H -typedef int_least8_t yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef __INT_LEAST16_MAX__ -typedef __INT_LEAST16_TYPE__ yytype_int16; -#elif defined YY_STDINT_H -typedef int_least16_t yytype_int16; -#else -typedef short yytype_int16; -#endif - -/* Work around bug in HP-UX 11.23, which defines these macros - incorrectly for preprocessor constants. This workaround can likely - be removed in 2023, as HPE has promised support for HP-UX 11.23 - (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of - . */ -#ifdef __hpux -# undef UINT_LEAST8_MAX -# undef UINT_LEAST16_MAX -# define UINT_LEAST8_MAX 255 -# define UINT_LEAST16_MAX 65535 -#endif - -#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST8_TYPE__ yytype_uint8; -#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST8_MAX <= INT_MAX) -typedef uint_least8_t yytype_uint8; -#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX -typedef unsigned char yytype_uint8; -#else -typedef short yytype_uint8; -#endif - -#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST16_TYPE__ yytype_uint16; -#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST16_MAX <= INT_MAX) -typedef uint_least16_t yytype_uint16; -#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX -typedef unsigned short yytype_uint16; -#else -typedef int yytype_uint16; -#endif - -#ifndef YYPTRDIFF_T -# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ -# define YYPTRDIFF_T __PTRDIFF_TYPE__ -# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ -# elif defined PTRDIFF_MAX -# ifndef ptrdiff_t -# include /* INFRINGES ON USER NAME SPACE */ -# endif -# define YYPTRDIFF_T ptrdiff_t -# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX -# else -# define YYPTRDIFF_T long -# define YYPTRDIFF_MAXIMUM LONG_MAX -# endif -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned -# endif -#endif - -#define YYSIZE_MAXIMUM \ - YY_CAST (YYPTRDIFF_T, \ - (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ - ? YYPTRDIFF_MAXIMUM \ - : YY_CAST (YYSIZE_T, -1))) - -#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) - - -/* Stored state numbers (used for stacks). */ -typedef yytype_int8 yy_state_t; - -/* State numbers in computations. */ -typedef int yy_state_fast_t; - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - - -#ifndef YY_ATTRIBUTE_PURE -# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) -# else -# define YY_ATTRIBUTE_PURE -# endif -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -# else -# define YY_ATTRIBUTE_UNUSED -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YY_USE(E) ((void) (E)) -#else -# define YY_USE(E) /* empty */ -#endif - -#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ -# define YY_IGNORE_USELESS_CAST_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") -# define YY_IGNORE_USELESS_CAST_END \ - _Pragma ("GCC diagnostic pop") -#endif -#ifndef YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_END -#endif - - -#define YY_ASSERT(E) ((void) (0 && (E))) - -#if !defined yyoverflow - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* !defined yyoverflow */ - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yy_state_t yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYPTRDIFF_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / YYSIZEOF (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYPTRDIFF_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 4 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 28 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 23 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 6 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 13 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 32 - -/* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 277 - - -/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, with out-of-bounds checking. */ -#define YYTRANSLATE(YYX) \ - (0 <= (YYX) && (YYX) <= YYMAXUTOK \ - ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ - : YYSYMBOL_YYUNDEF) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex. */ -static const yytype_int8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22 -}; - -#if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_int8 yyrline[] = -{ - 0, 60, 60, 63, 64, 64, 67, 68, 71, 72, - 73, 74, 75, 76 -}; -#endif - -/** Accessing symbol of state STATE. */ -#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) - -#if YYDEBUG || 0 -/* The user-facing name of the symbol whose (internal) number is - YYSYMBOL. No bounds checking. */ -static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; - -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "\"end of file\"", "error", "\"invalid token\"", "NEVER", "IF", "FI", - "IMPLIES", "GOTO", "AND", "OR", "NOT", "LEFT_PAR", "RIGHT_PAR", "CASE", - "COLON", "SEMI_COLON", "CASE_TRUE", "LEFT_BRACE", "RIGHT_BRACE", - "LITT_ENT", "LITT_CHAINE", "LITT_REEL", "ID", "$accept", "automaton", - "stateseq", "$@1", "option", "exp", YY_NULLPTR -}; - -static const char * -yysymbol_name (yysymbol_kind_t yysymbol) -{ - return yytname[yysymbol]; -} -#endif - -#ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_int16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277 -}; -#endif - -#define YYPACT_NINF (-16) - -#define yypact_value_is_default(Yyn) \ - ((Yyn) == YYPACT_NINF) - -#define YYTABLE_NINF (-1) - -#define yytable_value_is_error(Yyn) \ - 0 - - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int8 yypact[] = -{ - 0, -15, 10, -13, -16, 2, 1, -16, -16, 16, - 8, -10, 17, -10, -10, -16, -16, 9, 11, -16, - -1, 18, -10, -10, -13, -16, 5, -16, -16, -16, - 8, -16 -}; - - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_int8 yydefact[] = -{ - 0, 0, 0, 3, 1, 0, 0, 4, 2, 0, - 6, 0, 0, 0, 0, 12, 13, 0, 0, 11, - 0, 0, 0, 0, 3, 8, 0, 10, 9, 5, - 6, 7 -}; - - /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -16, -16, 4, -16, -7, -9 -}; - - /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - 0, 2, 6, 9, 12, 17 -}; - - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int8 yytable[] = -{ - 13, 14, 3, 1, 19, 20, 15, 22, 23, 5, - 4, 25, 16, 27, 28, 21, 7, 22, 23, 8, - 10, 11, 18, 31, 0, 26, 24, 30, 29 -}; - -static const yytype_int8 yycheck[] = -{ - 10, 11, 17, 3, 13, 14, 16, 8, 9, 22, - 0, 12, 22, 22, 23, 6, 14, 8, 9, 18, - 4, 13, 5, 30, -1, 7, 15, 22, 24 -}; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_int8 yystos[] = -{ - 0, 3, 24, 17, 0, 22, 25, 14, 18, 26, - 4, 13, 27, 10, 11, 16, 22, 28, 5, 28, - 28, 6, 8, 9, 15, 12, 7, 28, 28, 25, - 22, 27 -}; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_int8 yyr1[] = -{ - 0, 23, 24, 25, 26, 25, 27, 27, 28, 28, - 28, 28, 28, 28 -}; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_int8 yyr2[] = -{ - 0, 2, 4, 0, 0, 8, 0, 6, 3, 3, - 3, 2, 1, 1 -}; - - -enum { YYENOMEM = -2 }; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ - do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ - while (0) - -/* Backward compatibility with an undocumented macro. - Use YYerror or YYUNDEF. */ -#define YYERRCODE YYUNDEF - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -/* This macro is provided for backward compatibility. */ -# ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif - - -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Kind, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*-----------------------------------. -| Print this symbol's value on YYO. | -`-----------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - FILE *yyoutput = yyo; - YY_USE (yyoutput); - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yykind < YYNTOKENS) - YYPRINT (yyo, yytoknum[yykind], *yyvaluep); -# endif - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/*---------------------------. -| Print this symbol on YYO. | -`---------------------------*/ - -static void -yy_symbol_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - YYFPRINTF (yyo, "%s %s (", - yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - - yy_symbol_value_print (yyo, yykind, yyvaluep); - YYFPRINTF (yyo, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, - int yyrule) -{ - int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), - &yyvsp[(yyi + 1) - (yynrhs)]); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) ((void) 0) -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - - - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, - yysymbol_kind_t yykind, YYSTYPE *yyvaluep) -{ - YY_USE (yyvaluep); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/* Lookahead token kind. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; - - - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (void) -{ - yy_state_fast_t yystate = 0; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus = 0; - - /* Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* Their size. */ - YYPTRDIFF_T yystacksize = YYINITDEPTH; - - /* The state stack: array, bottom, top. */ - yy_state_t yyssa[YYINITDEPTH]; - yy_state_t *yyss = yyssa; - yy_state_t *yyssp = yyss; - - /* The semantic value stack: array, bottom, top. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp = yyvs; - - int yyn; - /* The return value of yyparse. */ - int yyresult; - /* Lookahead symbol kind. */ - yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yychar = YYEMPTY; /* Cause a token to be read. */ - goto yysetstate; - - -/*------------------------------------------------------------. -| yynewstate -- push a new state, which is found in yystate. | -`------------------------------------------------------------*/ -yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - -/*--------------------------------------------------------------------. -| yysetstate -- set current state (the top of the stack) to yystate. | -`--------------------------------------------------------------------*/ -yysetstate: - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - YY_ASSERT (0 <= yystate && yystate < YYNSTATES); - YY_IGNORE_USELESS_CAST_BEGIN - *yyssp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - YY_STACK_PRINT (yyss, yyssp); - - if (yyss + yystacksize - 1 <= yyssp) -#if !defined yyoverflow && !defined YYSTACK_RELOCATE - goto yyexhaustedlab; -#else - { - /* Get the current used size of the three stacks, in elements. */ - YYPTRDIFF_T yysize = yyssp - yyss + 1; - -# if defined yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - yy_state_t *yyss1 = yyss; - YYSTYPE *yyvs1 = yyvs; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * YYSIZEOF (*yyssp), - &yyvs1, yysize * YYSIZEOF (*yyvsp), - &yystacksize); - yyss = yyss1; - yyvs = yyvs1; - } -# else /* defined YYSTACK_RELOCATE */ - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yy_state_t *yyss1 = yyss; - union yyalloc *yyptr = - YY_CAST (union yyalloc *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YY_IGNORE_USELESS_CAST_BEGIN - YYDPRINTF ((stderr, "Stack size increased to %ld\n", - YY_CAST (long, yystacksize))); - YY_IGNORE_USELESS_CAST_END - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } -#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token\n")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = YYEOF; - yytoken = YYSYMBOL_YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else if (yychar == YYerror) - { - /* The scanner already issued an error message, process directly - to error recovery. But do not keep the error token as - lookahead, it is too special and may lead us to an endless - loop in error recovery. */ - yychar = YYUNDEF; - yytoken = YYSYMBOL_YYerror; - goto yyerrlab1; - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - /* Discard the shifted token. */ - yychar = YYEMPTY; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 4: /* $@1: %empty */ -#line 64 "parserPromela.yacc" - { new_state((yyvsp[-1].string), 1);} -#line 1125 "parserPromela.tab.cacc" - break; - - case 7: /* option: CASE exp IMPLIES GOTO ID option */ -#line 68 "parserPromela.yacc" - { new_transition((yyvsp[-1].string), (yyvsp[-4].label));} -#line 1131 "parserPromela.tab.cacc" - break; - - case 8: /* exp: LEFT_PAR exp RIGHT_PAR */ -#line 71 "parserPromela.yacc" - { (yyval.label) = (yyvsp[-1].label); } -#line 1137 "parserPromela.tab.cacc" - break; - - case 9: /* exp: exp OR exp */ -#line 72 "parserPromela.yacc" - { (yyval.label) = xbt_automaton_exp_label_new_or((yyvsp[-2].label), (yyvsp[0].label)); } -#line 1143 "parserPromela.tab.cacc" - break; - - case 10: /* exp: exp AND exp */ -#line 73 "parserPromela.yacc" - { (yyval.label) = xbt_automaton_exp_label_new_and((yyvsp[-2].label), (yyvsp[0].label)); } -#line 1149 "parserPromela.tab.cacc" - break; - - case 11: /* exp: NOT exp */ -#line 74 "parserPromela.yacc" - { (yyval.label) = xbt_automaton_exp_label_new_not((yyvsp[0].label)); } -#line 1155 "parserPromela.tab.cacc" - break; - - case 12: /* exp: CASE_TRUE */ -#line 75 "parserPromela.yacc" - { (yyval.label) = xbt_automaton_exp_label_new_one(); } -#line 1161 "parserPromela.tab.cacc" - break; - - case 13: /* exp: ID */ -#line 76 "parserPromela.yacc" - { (yyval.label) = xbt_automaton_exp_label_new_predicat((yyvsp[0].string)); } -#line 1167 "parserPromela.tab.cacc" - break; - - -#line 1171 "parserPromela.tab.cacc" - - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - - *++yyvsp = yyval; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - { - const int yylhs = yyr1[yyn] - YYNTOKENS; - const int yyi = yypgoto[yylhs] + *yyssp; - yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp - ? yytable[yyi] - : yydefgoto[yylhs]); - } - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - yyerror (YY_("syntax error")); - } - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - /* Pacify compilers when the user code never invokes YYERROR and the - label yyerrorlab therefore never appears in user code. */ - if (0) - YYERROR; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - /* Pop stack until we find a state that shifts the error token. */ - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYSYMBOL_YYerror; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - YY_ACCESSING_SYMBOL (yystate), yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - - -#if !defined yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - goto yyreturn; -#endif - - -/*-------------------------------------------------------. -| yyreturn -- parsing is finished, clean up and return. | -`-------------------------------------------------------*/ -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - - return yyresult; -} - -#line 79 "parserPromela.yacc" - - - - -void yyerror(const char *s){ - fprintf (stderr, "%s\n", s); -} - - - diff --git a/src/xbt/automaton/parserPromela.tab.hacc b/src/xbt/automaton/parserPromela.tab.hacc deleted file mode 100644 index 66ae1660cd..0000000000 --- a/src/xbt/automaton/parserPromela.tab.hacc +++ /dev/null @@ -1,105 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.7.6. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -#ifndef YY_XBT_AUTOMATON_PARSER_PARSERPROMELA_TAB_HACC_INCLUDED -# define YY_XBT_AUTOMATON_PARSER_PARSERPROMELA_TAB_HACC_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 1 -#endif -#if YYDEBUG -extern int xbt_automaton_parser_debug; -#endif - -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - YYEMPTY = -2, - YYEOF = 0, /* "end of file" */ - YYerror = 256, /* error */ - YYUNDEF = 257, /* "invalid token" */ - NEVER = 258, /* NEVER */ - IF = 259, /* IF */ - FI = 260, /* FI */ - IMPLIES = 261, /* IMPLIES */ - GOTO = 262, /* GOTO */ - AND = 263, /* AND */ - OR = 264, /* OR */ - NOT = 265, /* NOT */ - LEFT_PAR = 266, /* LEFT_PAR */ - RIGHT_PAR = 267, /* RIGHT_PAR */ - CASE = 268, /* CASE */ - COLON = 269, /* COLON */ - SEMI_COLON = 270, /* SEMI_COLON */ - CASE_TRUE = 271, /* CASE_TRUE */ - LEFT_BRACE = 272, /* LEFT_BRACE */ - RIGHT_BRACE = 273, /* RIGHT_BRACE */ - LITT_ENT = 274, /* LITT_ENT */ - LITT_CHAINE = 275, /* LITT_CHAINE */ - LITT_REEL = 276, /* LITT_REEL */ - ID = 277 /* ID */ - }; - typedef enum yytokentype yytoken_kind_t; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -union YYSTYPE -{ -#line 23 "parserPromela.yacc" - - double real; - int integer; - char* string; - xbt_automaton_exp_label_t label; - -#line 93 "parserPromela.tab.hacc" - -}; -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE xbt_automaton_parser_lval; - -int xbt_automaton_parser_parse (void); - -#endif /* !YY_XBT_AUTOMATON_PARSER_PARSERPROMELA_TAB_HACC_INCLUDED */ diff --git a/src/xbt/automaton/parserPromela.yacc b/src/xbt/automaton/parserPromela.yacc deleted file mode 100644 index 10f2edb5ca..0000000000 --- a/src/xbt/automaton/parserPromela.yacc +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. - * All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -%{ -#include "simgrid/config.h" -#if !HAVE_UNISTD_H -#define YY_NO_UNISTD_H /* hello Windows */ -#endif - -#include "automaton_lexer.yy.c" -#include - -void yyerror(const char *s); - -static void new_state(const char* id, int src); -static void new_transition(const char* id, xbt_automaton_exp_label_t label); - -%} - -%union{ - double real; - int integer; - char* string; - xbt_automaton_exp_label_t label; -} - -%token NEVER -%token IF -%token FI -%token IMPLIES -%token GOTO -%token AND -%token OR -%token NOT -%token LEFT_PAR -%token RIGHT_PAR -%token CASE -%token COLON -%token SEMI_COLON -%token CASE_TRUE -%token LEFT_BRACE -%token RIGHT_BRACE -%token LITT_ENT -%token LITT_CHAINE -%token LITT_REEL -%token ID - -%type > $ ${bindir:=.}/flatifier ./one_cluster_multicore.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> +> +> +> +> +> +> +> > -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -257,24 +257,24 @@ $ ${bindir:=.}/flatifier ./one_cluster_multicore.xml "--log=root.fmt:[%10.6r]%e[ > > > -> +> > $ ${bindir:=.}/flatifier ./host_attributes.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> +> +> +> +> +> +> > > > > -> -> +> +> > > > @@ -290,38 +290,38 @@ $ ${bindir:=.}/flatifier ./host_attributes.xml "--log=root.fmt:[%10.6r]%e[%i:%a@ > > > -> +> > $ ${bindir:=.}/flatifier ./link_attributes.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> > > > -> +> > $ ${bindir:=.}/flatifier ./three_hosts_non_symmetric_route.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> > > > @@ -349,32 +349,32 @@ $ ${bindir:=.}/flatifier ./three_hosts_non_symmetric_route.xml "--log=root.fmt:[ > > > -> +> > $ ${bindir:=.}/flatifier ./two_clusters.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> +> +> +> +> +> +> > > -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -477,20 +477,20 @@ $ ${bindir:=.}/flatifier ./two_clusters.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h] > > > -> +> > $ ${bindir:=.}/flatifier ./two_hosts_multi_hop.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> > > > @@ -503,18 +503,18 @@ $ ${bindir:=.}/flatifier ./two_hosts_multi_hop.xml "--log=root.fmt:[%10.6r]%e[%i > > > -> +> > $ ${bindir:=.}/flatifier ./two_hosts_one_link.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> +> +> +> +> +> +> > > > @@ -527,31 +527,31 @@ $ ${bindir:=.}/flatifier ./two_hosts_one_link.xml "--log=root.fmt:[%10.6r]%e[%i: > > > -> +> > $ ${bindir:=.}/flatifier ${srcdir:=.}/examples/platforms/bypassZoneRoute.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> +> +> +> +> +> > > > -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -651,111 +651,111 @@ $ ${bindir:=.}/flatifier ${srcdir:=.}/examples/platforms/bypassZoneRoute.xml "-- > > > -> +> > $ ${bindir:=.}/flatifier ${srcdir:=.}/examples/platforms/cluster_torus.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -1188,47 +1188,47 @@ $ ${bindir:=.}/flatifier ${srcdir:=.}/examples/platforms/cluster_torus.xml "--lo > > > -> +> > $ ${bindir:=.}/flatifier ./cluster_dragonfly_noncontiguous_rad.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -1277,55 +1277,55 @@ $ ${bindir:=.}/flatifier ./cluster_dragonfly_noncontiguous_rad.xml "--log=root.f > > > -> +> > $ ${bindir:=.}/flatifier ./cluster_fat_tree_noncontiguous_rad.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -1333,10 +1333,10 @@ $ ${bindir:=.}/flatifier ./cluster_fat_tree_noncontiguous_rad.xml "--log=root.fm > > > -> +> > > -> +> > > > @@ -1345,10 +1345,10 @@ $ ${bindir:=.}/flatifier ./cluster_fat_tree_noncontiguous_rad.xml "--log=root.fm > > > -> +> > > -> +> > > > @@ -1363,10 +1363,10 @@ $ ${bindir:=.}/flatifier ./cluster_fat_tree_noncontiguous_rad.xml "--log=root.fm > > > -> +> > > -> +> > > > @@ -1374,51 +1374,51 @@ $ ${bindir:=.}/flatifier ./cluster_fat_tree_noncontiguous_rad.xml "--log=root.fm > > > -> +> > $ ${bindir:=.}/flatifier ./cluster_torus_noncontiguous_rad.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> +> > > > @@ -1467,19 +1467,19 @@ $ ${bindir:=.}/flatifier ./cluster_torus_noncontiguous_rad.xml "--log=root.fmt:[ > > > -> +> > $ ${bindir:=.}/flatifier ./two_hosts_one_link_splitduplex.xml "--log=root.fmt:[%10.6r]%e[%i:%a@%h]%e%m%n" > > -> -> -> -> -> -> -> +> +> +> +> +> +> +> > > > @@ -1492,5 +1492,5 @@ $ ${bindir:=.}/flatifier ./two_hosts_one_link_splitduplex.xml "--log=root.fmt:[% > > > -> +> > diff --git a/teshsuite/platforms/properties.xml b/teshsuite/platforms/properties.xml index 50de5a4bf7..6f06059e68 100644 --- a/teshsuite/platforms/properties.xml +++ b/teshsuite/platforms/properties.xml @@ -2,9 +2,8 @@ - + - diff --git a/teshsuite/python/borken-context/borken-context.py b/teshsuite/python/borken-context/borken-context.py index cae1e5adb3..0e7aee58a8 100644 --- a/teshsuite/python/borken-context/borken-context.py +++ b/teshsuite/python/borken-context/borken-context.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/teshsuite/python/corrupt-stack/corrupt-stack.py b/teshsuite/python/corrupt-stack/corrupt-stack.py index f541d9a6be..5abb24f195 100644 --- a/teshsuite/python/corrupt-stack/corrupt-stack.py +++ b/teshsuite/python/corrupt-stack/corrupt-stack.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/teshsuite/python/platform-mix/platform-mix.py b/teshsuite/python/platform-mix/platform-mix.py index 618605b55a..9859b541ae 100644 --- a/teshsuite/python/platform-mix/platform-mix.py +++ b/teshsuite/python/platform-mix/platform-mix.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -59,12 +59,13 @@ def load_platform(): host1.create_disk("disk1", 1e5, 1e4).seal() host1.create_disk("disk2", "1MBps", "1Mbps").seal() host1.seal() + dijkstra.set_gateway(host1) host2 = dijkstra.create_host("host2", ["1Gf", "1Mf"]).seal() hosts.append(host2) link1 = dijkstra.create_link("link1_up", [1e9]).set_latency(1e-3).set_concurrency_limit(10).seal() link2 = dijkstra.create_link("link1_down", ["1GBps"]).set_latency("1ms").seal() - dijkstra.add_route(host1.netpoint, host2.netpoint, None, None, [LinkInRoute(link1)], False) - dijkstra.add_route(host2.netpoint, host1.netpoint, None, None, [LinkInRoute(link2)], False) + dijkstra.add_route(host1, host2, [LinkInRoute(link1)], False) + dijkstra.add_route(host2, host1, [LinkInRoute(link2)], False) dijkstra.seal() # vivaldi @@ -72,6 +73,7 @@ def load_platform(): this_actor.info(msg_base + vivaldi.name) vivaldi.set_parent(root) host3 = vivaldi.create_host("host3", 1e9).set_coordinates("1 1 1").seal() + vivaldi.set_gateway(host3) host4 = vivaldi.create_host("host4", "1Gf").set_coordinates("2 2 2").seal() hosts.append(host3) hosts.append(host4) @@ -81,6 +83,7 @@ def load_platform(): this_actor.info(msg_base + empty.name) empty.set_parent(root) host5 = empty.create_host("host5", 1e9) + empty.set_gateway(host5) hosts.append(host5) empty.seal() @@ -89,6 +92,7 @@ def load_platform(): this_actor.info(msg_base + wifi.name) wifi.set_parent(root) router = wifi.create_router("wifi_router") + wifi.set_gateway(router) wifi.set_property("access_point", "wifi_router") host6 = wifi.create_host( "host6", ["100.0Mf", "50.0Mf", "20.0Mf"]).seal() @@ -101,9 +105,9 @@ def load_platform(): link_a = vivaldi.create_link("linkA", 1e9).seal() link_b = vivaldi.create_link("linkB", "1GBps").seal() link_c = vivaldi.create_link("linkC", "1GBps").seal() - root.add_route(dijkstra.netpoint, vivaldi.netpoint, host1.netpoint, host3.netpoint, [LinkInRoute(link_a)], True) - root.add_route(vivaldi.netpoint, empty.netpoint, host3.netpoint, host5.netpoint, [LinkInRoute(link_b)], True) - root.add_route(empty.netpoint, wifi.netpoint, host5.netpoint, router, [LinkInRoute(link_c)], True) + root.add_route(dijkstra, vivaldi, [link_a]) + root.add_route(vivaldi, empty, [link_b]) + root.add_route(empty, wifi, [link_c]) # create actors Sender/Receiver Actor.create("sender", hosts[0], Sender(hosts)) diff --git a/teshsuite/s4u/CMakeLists.txt b/teshsuite/s4u/CMakeLists.txt index bc7a813c71..a21866a7e2 100644 --- a/teshsuite/s4u/CMakeLists.txt +++ b/teshsuite/s4u/CMakeLists.txt @@ -6,17 +6,18 @@ endforeach() foreach(x actor actor-autorestart actor-suspend activity-lifecycle - comm-get-sender comm-pt2pt comm-fault-scenarios wait-all-for wait-any-for + comm-get-sender comm-pt2pt comm-fault-scenarios cloud-interrupt-migration cloud-two-execs monkey-masterworkers monkey-semaphore concurrent_rw dag-incomplete-simulation dependencies - host-on-off host-on-off-actors host-on-off-recv host-multicore-speed-file io-set-bw + host-on-off host-on-off-actors host-on-off-recv host-multicore-speed-file + io-set-bw io-stream basic-link-test basic-parsing-test evaluate-get-route-time evaluate-parse-time is-router storage_client_server listen_async pid trace-integration seal-platform - vm-live-migration vm-suicide issue71) + vm-live-migration vm-suicide issue71) if(NOT DEFINED ${x}_sources) set(${x}_sources ${x}/${x}.cpp) @@ -38,8 +39,8 @@ set_property(TARGET activity-lifecycle APPEND PROPERTY INCLUDE_DIRECTORIES "${IN ## Add the tests. ## Some need to be run with all factories, some don't need tesh to run -foreach(x actor actor-autorestart actor-suspend activity-lifecycle comm-get-sender wait-all-for wait-any-for - cloud-interrupt-migration cloud-two-execs concurrent_rw dag-incomplete-simulation dependencies io-set-bw +foreach(x actor actor-autorestart actor-suspend activity-lifecycle comm-get-sender + cloud-interrupt-migration cloud-two-execs concurrent_rw dag-incomplete-simulation dependencies io-set-bw io-stream vm-live-migration vm-suicide) set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.tesh) ADD_TESH_FACTORIES(tesh-s4u-${x} "*" --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/s4u/${x} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_BINARY_DIR}/teshsuite/s4u/${x} ${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x}/${x}.tesh) @@ -104,7 +105,7 @@ if(SIMGRID_HAVE_NS3) add_executable (${x} EXCLUDE_FROM_ALL ${x}/${x}.cpp) target_link_libraries(${x} simgrid) set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x}) - add_dependencies(tests ${x}) + add_dependencies(tests-ns3 ${x}) ADD_TESH(tesh-s4u-${x} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_BINARY_DIR}/teshsuite/s4u/${x} ${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x}/${x}.tesh) endforeach() endif() @@ -143,7 +144,7 @@ ADD_TEST(tesh-parser-full-links01 ${CMAKE_BINARY_DIR}/teshsuite/s4u/basic-par ADD_TEST(tesh-parser-full-links02 ${CMAKE_BINARY_DIR}/teshsuite/s4u/basic-parsing-test/basic-parsing-test ${CMAKE_HOME_DIRECTORY}/teshsuite/platforms/two_clusters_one_name.xml FULL_LINK) ADD_TEST(tesh-parser-one-link-g5k ${CMAKE_BINARY_DIR}/teshsuite/s4u/basic-parsing-test/basic-parsing-test ${CMAKE_HOME_DIRECTORY}/examples/platforms/g5k.xml ONE_LINK) -set(teshsuite_src ${teshsuite_src} ${CMAKE_SOURCE_DIR}/src/include/catch_simgrid.hpp PARENT_SCOPE) +set(teshsuite_src ${teshsuite_src} ${CMAKE_SOURCE_DIR}/teshsuite/catch_simgrid.hpp PARENT_SCOPE) set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/basic-parsing-test/basic-parsing-test-sym-full.tesh ${CMAKE_CURRENT_SOURCE_DIR}/basic-parsing-test/basic-parsing-test-bypass.tesh PARENT_SCOPE) set(xml_files ${xml_files} ${CMAKE_CURRENT_SOURCE_DIR}/activity-lifecycle/testing_platform.xml diff --git a/teshsuite/s4u/activity-lifecycle/testing_comm.cpp b/teshsuite/s4u/activity-lifecycle/testing_comm.cpp index 7884ce3d47..f00b25bbd8 100644 --- a/teshsuite/s4u/activity-lifecycle/testing_comm.cpp +++ b/teshsuite/s4u/activity-lifecycle/testing_comm.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch_simgrid.hpp" +#include "teshsuite/catch_simgrid.hpp" #include static void test_link_off_helper(double delay) @@ -172,7 +172,7 @@ TEST_CASE("Activity lifecycle: comm activities") simgrid::s4u::this_actor::sleep_for(2); receiver_basic(recv_done, true, 1); - // Sleep long enough to let the test ends by itself. 1 + surf_precision should be enough. + // Sleep long enough to let the test ends by itself. 1 + precision_timing should be enough. simgrid::s4u::this_actor::sleep_for(4); INFO("Sender or receiver killed somehow. It shouldn't"); REQUIRE(dsend_done); @@ -191,7 +191,7 @@ TEST_CASE("Activity lifecycle: comm activities") simgrid::s4u::this_actor::sleep_for(2); sender_dtach(dsend_done, true, 0); - // Sleep long enough to let the test ends by itself. 3 + surf_precision should be enough. + // Sleep long enough to let the test ends by itself. 3 + precision_timing should be enough. simgrid::s4u::this_actor::sleep_for(4); INFO("Sender or receiver killed somehow. It shouldn't"); REQUIRE(dsend_done); @@ -219,7 +219,7 @@ TEST_CASE("Activity lifecycle: comm activities") simgrid::s4u::this_actor::sleep_for(2); sender->kill(); - // let the test ends by itself. waiting for surf_precision should be enough. + // let the test ends by itself. waiting for precision_timing should be enough. simgrid::s4u::this_actor::sleep_for(0.00001); INFO("Sender was not killed properly or receiver killed somehow. It shouldn't"); @@ -312,9 +312,9 @@ TEST_CASE("Activity lifecycle: comm activities") simgrid::s4u::ActorPtr receiver = simgrid::s4u::Actor::create("receiver", all_hosts[1], []() { assert_exit(true, 2); int* data; - simgrid::s4u::CommPtr comm = simgrid::s4u::Mailbox::by_name("mb")->get_async(&data); - std::vector pending_comms = {comm}; - REQUIRE_NETWORK_FAILURE(simgrid::s4u::Comm::wait_any(pending_comms)); + simgrid::s4u::CommPtr comm = simgrid::s4u::Mailbox::by_name("mb")->get_async(&data); + simgrid::s4u::ActivitySet pending_comms({comm}); + REQUIRE_NETWORK_FAILURE(pending_comms.wait_any()); }); simgrid::s4u::ActorPtr sender = simgrid::s4u::Actor::create("sender", all_hosts[2], []() { diff --git a/teshsuite/s4u/activity-lifecycle/testing_comm_direct.cpp b/teshsuite/s4u/activity-lifecycle/testing_comm_direct.cpp index 89fddfe148..769763b060 100644 --- a/teshsuite/s4u/activity-lifecycle/testing_comm_direct.cpp +++ b/teshsuite/s4u/activity-lifecycle/testing_comm_direct.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch_simgrid.hpp" +#include "teshsuite/catch_simgrid.hpp" TEST_CASE("Activity lifecycle: direct communication (sendto) activities") { @@ -123,7 +123,7 @@ TEST_CASE("Activity lifecycle: direct communication (sendto) activities") }); simgrid::s4u::this_actor::yield(); - auto link = simgrid::s4u::Engine::get_instance()->link_by_name("link1"); + auto* link = simgrid::s4u::Engine::get_instance()->link_by_name("link1"); link->turn_off(); link->turn_on(); @@ -139,7 +139,7 @@ TEST_CASE("Activity lifecycle: direct communication (sendto) activities") }); simgrid::s4u::this_actor::sleep_for(2); - auto link = simgrid::s4u::Engine::get_instance()->link_by_name("link1"); + auto* link = simgrid::s4u::Engine::get_instance()->link_by_name("link1"); link->turn_off(); link->turn_on(); @@ -160,7 +160,7 @@ TEST_CASE("Activity lifecycle: direct communication (sendto) activities") simgrid::s4u::Actor::create("killer", all_hosts[0], []() { simgrid::s4u::this_actor::sleep_for(5); XBT_VERB("Killer!"); - auto link = simgrid::s4u::Engine::get_instance()->link_by_name("link1"); + auto* link = simgrid::s4u::Engine::get_instance()->link_by_name("link1"); link->turn_off(); link->turn_on(); }); diff --git a/teshsuite/s4u/activity-lifecycle/testing_exec.cpp b/teshsuite/s4u/activity-lifecycle/testing_exec.cpp index 07d5a728f1..8e2930cf80 100644 --- a/teshsuite/s4u/activity-lifecycle/testing_exec.cpp +++ b/teshsuite/s4u/activity-lifecycle/testing_exec.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch_simgrid.hpp" +#include "teshsuite/catch_simgrid.hpp" TEST_CASE("Activity lifecycle: exec activities") { diff --git a/teshsuite/s4u/activity-lifecycle/testing_sleep.cpp b/teshsuite/s4u/activity-lifecycle/testing_sleep.cpp index 8dc8d3a848..362b3c0bc1 100644 --- a/teshsuite/s4u/activity-lifecycle/testing_sleep.cpp +++ b/teshsuite/s4u/activity-lifecycle/testing_sleep.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch_simgrid.hpp" +#include "teshsuite/catch_simgrid.hpp" TEST_CASE("Activity lifecycle: sleep activities") { diff --git a/teshsuite/s4u/activity-lifecycle/testing_test-wait.cpp b/teshsuite/s4u/activity-lifecycle/testing_test-wait.cpp index e2a3ab4252..855f56e772 100644 --- a/teshsuite/s4u/activity-lifecycle/testing_test-wait.cpp +++ b/teshsuite/s4u/activity-lifecycle/testing_test-wait.cpp @@ -1,9 +1,9 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ -#include "catch_simgrid.hpp" +#include "teshsuite/catch_simgrid.hpp" //========== Creators: create an async activity @@ -60,19 +60,21 @@ template bool tester_wait_any(const Activity& const double timeout = simgrid::s4u::Engine::get_clock() + duration; bool ret; try { - std::vector activities = {activity}; + simgrid::s4u::ActivitySet set; + set.push(activity); + XBT_DEBUG("calling wait_any_for(%f)", duration); - ssize_t index = Activity::element_type::wait_any_for(activities, duration); - if (index == -1) { - XBT_DEBUG("wait_any_for() timed out"); - INFO("wait_any_for() timeout should expire at expected date: " << timeout); - REQUIRE(simgrid::s4u::Engine::get_clock() == Approx(timeout)); - ret = false; - } else { - XBT_DEBUG("wait_any_for() returned index %zd", index); - REQUIRE(index == 0); - ret = true; - } + auto waited_activity = set.wait_any_for(duration); + + XBT_DEBUG("wait_any_for() returned activity %p", waited_activity.get()); + REQUIRE(waited_activity.get() == activity); + ret = true; + + } catch (const simgrid::TimeoutException& e) { + XBT_DEBUG("wait_any_for() timed out"); + INFO("wait_any_for() timeout should expire at expected date: " << timeout); + REQUIRE(simgrid::s4u::Engine::get_clock() == Approx(timeout)); + ret = false; } catch (const simgrid::Exception& e) { XBT_DEBUG("wait_any_for() threw an exception: %s", e.what()); ret = true; diff --git a/teshsuite/s4u/actor-autorestart/actor-autorestart.cpp b/teshsuite/s4u/actor-autorestart/actor-autorestart.cpp index f896ceebbb..9fb89acfc7 100644 --- a/teshsuite/s4u/actor-autorestart/actor-autorestart.cpp +++ b/teshsuite/s4u/actor-autorestart/actor-autorestart.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/actor-suspend/actor-suspend.cpp b/teshsuite/s4u/actor-suspend/actor-suspend.cpp index c39dccf604..91aad4daa1 100644 --- a/teshsuite/s4u/actor-suspend/actor-suspend.cpp +++ b/teshsuite/s4u/actor-suspend/actor-suspend.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2020-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2020-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -14,21 +14,23 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(mwe, "Minimum Working Example"); -simgrid::s4u::ActorPtr receiver; - class Receiver { public: void operator()() const { XBT_INFO("Starting."); - auto mailbox = simgrid::s4u::Mailbox::by_name("receiver"); + auto* mailbox = simgrid::s4u::Mailbox::by_name("receiver"); int data = *mailbox->get(); XBT_INFO("Got %d at the end", data); } }; class Suspender { + const simgrid::s4u::ActorPtr& receiver; + public: + explicit Suspender(const simgrid::s4u::ActorPtr& receiver) : receiver(receiver) {} + void operator()() const { XBT_INFO("Suspend the receiver..."); @@ -40,7 +42,7 @@ public: simgrid::s4u::this_actor::sleep_for(10); XBT_INFO("Sending a message to the receiver..."); - auto mailbox = simgrid::s4u::Mailbox::by_name("receiver"); + auto* mailbox = simgrid::s4u::Mailbox::by_name("receiver"); static int data = 42; mailbox->put(&data, 4); @@ -55,7 +57,8 @@ int main(int argc, char** argv) engine.load_platform(argv[1]); simgrid::s4u::Host* host = engine.host_by_name("Tremblay"); - simgrid::s4u::Actor::create("Suspender", host, Suspender()); + simgrid::s4u::ActorPtr receiver; + simgrid::s4u::Actor::create("Suspender", host, Suspender(receiver)); receiver = simgrid::s4u::Actor::create("Receiver", host, Receiver()); engine.run(); diff --git a/teshsuite/s4u/actor/actor.cpp b/teshsuite/s4u/actor/actor.cpp index 4421a0d153..37548fb614 100644 --- a/teshsuite/s4u/actor/actor.cpp +++ b/teshsuite/s4u/actor/actor.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/basic-link-test/basic-link-test.cpp b/teshsuite/s4u/basic-link-test/basic-link-test.cpp index bf6013a7a5..8466f44e67 100644 --- a/teshsuite/s4u/basic-link-test/basic-link-test.cpp +++ b/teshsuite/s4u/basic-link-test/basic-link-test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. +/* Copyright (c) 2008-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/s4u/basic-parsing-test/basic-parsing-test.cpp b/teshsuite/s4u/basic-parsing-test/basic-parsing-test.cpp index fedd092b52..b69c4578ca 100644 --- a/teshsuite/s4u/basic-parsing-test/basic-parsing-test.cpp +++ b/teshsuite/s4u/basic-parsing-test/basic-parsing-test.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. +/* Copyright (c) 2008-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/s4u/basic-parsing-test/basic-parsing-test.tesh b/teshsuite/s4u/basic-parsing-test/basic-parsing-test.tesh index ddcabb8112..5fdbb080a6 100644 --- a/teshsuite/s4u/basic-parsing-test/basic-parsing-test.tesh +++ b/teshsuite/s4u/basic-parsing-test/basic-parsing-test.tesh @@ -1,49 +1,49 @@ ! output sort -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/one_cluster.xml --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms one_cluster.xml --log=root.fmt=%m%n > Workstation number: 5, link number: 12 ! output sort -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/host_attributes.xml --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms host_attributes.xml --log=root.fmt=%m%n > Workstation number: 5, link number: 1 ! output sort -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/link_attributes.xml --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms link_attributes.xml --log=root.fmt=%m%n > Workstation number: 1, link number: 5 ! output sort -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/three_hosts_non_symmetric_route.xml --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms three_hosts_non_symmetric_route.xml --log=root.fmt=%m%n > Workstation number: 3, link number: 4 ! output sort -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/two_clusters.xml --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms two_clusters.xml --log=root.fmt=%m%n > Workstation number: 4, link number: 12 ! output sort -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/two_hosts_multi_hop.xml --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms two_hosts_multi_hop.xml --log=root.fmt=%m%n > Workstation number: 2, link number: 4 ! output sort -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/two_hosts_one_link.xml --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms two_hosts_one_link.xml --log=root.fmt=%m%n > Workstation number: 2, link number: 2 ! output sort -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/four_hosts_floyd.xml --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms four_hosts_floyd.xml --log=root.fmt=%m%n > Workstation number: 4, link number: 5 ! output sort $ ${bindir:=.}/basic-parsing-test ${platfdir:=.}/cloud.xml --log=root.fmt=%m%n > Workstation number: 510, link number: 1056 -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/properties.xml --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms properties.xml --log=root.fmt=%m%n > Configuration change: Set 'cpu/optim' to 'TI' -> Configuration change: Set 'host/model' to 'compound' -> Configuration change: Set 'maxmin/precision' to '0.000010' +> The custom configuration 'path' is already defined by user! +> Configuration change: Set 'precision/work-amount' to '0.000010' > Workstation number: 1, link number: 1 -$ ${bindir:=.}/basic-parsing-test ${srcdir:=.}/../../platforms/properties.xml --cfg=cpu/optim:TI --log=root.fmt=%m%n +$ ${bindir:=.}/basic-parsing-test --cfg=path:${srcdir:=.}/../../platforms properties.xml --cfg=cpu/optim:TI --log=root.fmt=%m%n > Configuration change: Set 'cpu/optim' to 'TI' > The custom configuration 'cpu/optim' is already defined by user! -> Configuration change: Set 'host/model' to 'compound' -> Configuration change: Set 'maxmin/precision' to '0.000010' +> The custom configuration 'path' is already defined by user! +> Configuration change: Set 'precision/work-amount' to '0.000010' > Workstation number: 1, link number: 1 diff --git a/teshsuite/s4u/cloud-interrupt-migration/cloud-interrupt-migration.cpp b/teshsuite/s4u/cloud-interrupt-migration/cloud-interrupt-migration.cpp index 925191d3c0..2f7bdd36dd 100644 --- a/teshsuite/s4u/cloud-interrupt-migration/cloud-interrupt-migration.cpp +++ b/teshsuite/s4u/cloud-interrupt-migration/cloud-interrupt-migration.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/cloud-two-execs/cloud-two-execs.cpp b/teshsuite/s4u/cloud-two-execs/cloud-two-execs.cpp index adfd0f4657..1f5f198dea 100644 --- a/teshsuite/s4u/cloud-two-execs/cloud-two-execs.cpp +++ b/teshsuite/s4u/cloud-two-execs/cloud-two-execs.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2014-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -7,9 +7,7 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this example"); -simgrid::s4u::ExecPtr exec; - -static void computation_fun() +static void computation_fun(simgrid::s4u::ExecPtr& exec) { const char* pr_name = simgrid::s4u::this_actor::get_cname(); const char* host_name = simgrid::s4u::Host::current()->get_cname(); @@ -37,7 +35,8 @@ static void master_main() auto* vm0 = pm0->create_vm("VM0", 1); vm0->start(); - simgrid::s4u::Actor::create("compute", vm0, computation_fun); + simgrid::s4u::ExecPtr exec; + simgrid::s4u::Actor::create("compute", vm0, computation_fun, std::ref(exec)); while (simgrid::s4u::Engine::get_clock() < 100) { if (exec) diff --git a/teshsuite/s4u/comm-fault-scenarios/comm-fault-scenarios.cpp b/teshsuite/s4u/comm-fault-scenarios/comm-fault-scenarios.cpp index 6f674fa073..b996076738 100644 --- a/teshsuite/s4u/comm-fault-scenarios/comm-fault-scenarios.cpp +++ b/teshsuite/s4u/comm-fault-scenarios/comm-fault-scenarios.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -159,21 +159,23 @@ class SendAgent { // Make sure we have a clean slate xbt_assert(not mbox_.eager->listen(), "Eager mailbox should be empty when starting a test"); xbt_assert(not mbox_.rdv->listen(), "RDV mailbox should be empty when starting a test"); - for (; step_index < s.steps.size(); step_index++) { - const Step& step = s.steps[step_index]; - if (step.entity != Step::Entity::SND || step.type != Step::Type::ACTION) - continue; - try { + + Action current_action; + try { + for (; step_index < s.steps.size(); step_index++) { + const Step& step = s.steps[step_index]; + if (step.entity != Step::Entity::SND || step.type != Step::Type::ACTION) + continue; + + current_action = Action::SLEEP; sg4::this_actor::sleep_until(s.start_time + step.rel_time); - } catch (const simgrid::Exception& e) { - XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what()); - break; - } - // Check if the other host is still OK. - if (not other_host_->is_on()) - break; - // Perform the action - try { + + // Check if the other host is still OK. + if (not other_host_->is_on()) + break; + + // Perform the action + current_action = step.action_type; switch (step.action_type) { case Action::PUT: comm = do_put(s.type, send_value); @@ -187,11 +189,10 @@ class SendAgent { default: xbt_die("Not a valid action for SND"); } - } catch (const simgrid::Exception& e) { - XBT_DEBUG("During %s, failed to send message because of a %s exception (%s)", to_c_str(step.action_type), - typeid(e).name(), e.what()); - break; } + } catch (const simgrid::Exception& e) { + XBT_DEBUG("During %s, failed to send message because of a %s exception (%s)", to_c_str(current_action), + typeid(e).name(), e.what()); } try { sg4::this_actor::sleep_until(end_time); @@ -283,21 +284,21 @@ class ReceiveAgent { // Make sure we have a clean slate xbt_assert(not mbox_.eager->listen(), "Eager mailbox should be empty when starting a test"); xbt_assert(not mbox_.rdv->listen(), "RDV mailbox should be empty when starting a test"); - for (; step_index < s.steps.size(); step_index++) { - const Step& step = s.steps[step_index]; - if (step.entity != Step::Entity::RCV || step.type != Step::Type::ACTION) - continue; - try { + + Action current_action; + try { + for (; step_index < s.steps.size(); step_index++) { + const Step& step = s.steps[step_index]; + if (step.entity != Step::Entity::RCV || step.type != Step::Type::ACTION) + continue; + + current_action = Action::SLEEP; sg4::this_actor::sleep_until(s.start_time + step.rel_time); - } catch (const simgrid::Exception& e) { - XBT_DEBUG("During Sleep, failed to receive message because of a %s exception (%s)", typeid(e).name(), e.what()); - break; - } - // Check if the other host is still OK. - if (not other_host_->is_on()) - break; - // Perform the action - try { + + // Check if the other host is still OK. + if (not other_host_->is_on()) + break; + // Perform the action switch (step.action_type) { case Action::GET: comm = do_get(type, receive_ptr); @@ -311,11 +312,10 @@ class ReceiveAgent { default: xbt_die("Not a valid action for RCV"); } - } catch (const simgrid::Exception& e) { - XBT_DEBUG("During %s, failed to receive message because of a %s exception (%s)", to_c_str(step.action_type), - typeid(e).name(), e.what()); - break; } + } catch (const simgrid::Exception& e) { + XBT_DEBUG("During %s, failed to receive message because of a %s exception (%s)", to_c_str(current_action), + typeid(e).name(), e.what()); } try { sg4::this_actor::sleep_until(end_time - .1); @@ -409,11 +409,10 @@ int main(int argc, char* argv[]) pr::Profile* profile_link = pr::ProfileBuilder::from_string("link_profile", ctx.link_profile.str(), 0); sg4::Link const* link = zone->create_link("link", LinkBandwidth)->set_latency(LinkLatency)->set_state_profile(profile_link)->seal(); - zone->add_route(sender_host->get_netpoint(), receiver_host->get_netpoint(), nullptr, nullptr, - {sg4::LinkInRoute{link}}, false); + zone->add_route(sender_host, receiver_host, {link}); zone->seal(); - sg4::Host::on_state_change_cb([mbox](sg4::Host const& host) { + sg4::Host::on_onoff_cb([mbox](sg4::Host const& host) { XBT_DEBUG("Host %s is now %s", host.get_cname(), host.is_on() ? "ON " : "OFF"); if (not host.is_on()) { mbox.eager->clear(); @@ -421,7 +420,7 @@ int main(int argc, char* argv[]) } }); - sg4::Link::on_state_change_cb( + sg4::Link::on_onoff_cb( [](sg4::Link const& lnk) { XBT_DEBUG("Link %s is now %s", lnk.get_cname(), lnk.is_on() ? "ON " : "OFF"); }); e.run_until(end_time); @@ -457,7 +456,8 @@ static void prepareScenario(ScenarioContext& ctx, CommType type, double duration DIE_IMPOSSIBLE; } } - ctx.scenarios.push_back({type, ctx.start_time, duration, sender_expected, receiver_expected, steps, ctx.index}); + Scenario scen{type, ctx.start_time, duration, sender_expected, receiver_expected, steps, ctx.index}; + ctx.scenarios.push_back(scen); ctx.active++; } ctx.index++; diff --git a/teshsuite/s4u/comm-get-sender/comm-get-sender.cpp b/teshsuite/s4u/comm-get-sender/comm-get-sender.cpp index 15effb7b63..68b3481e06 100644 --- a/teshsuite/s4u/comm-get-sender/comm-get-sender.cpp +++ b/teshsuite/s4u/comm-get-sender/comm-get-sender.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/s4u/comm-pt2pt/comm-pt2pt.cpp b/teshsuite/s4u/comm-pt2pt/comm-pt2pt.cpp index ccd4dc0769..21ce33d38a 100644 --- a/teshsuite/s4u/comm-pt2pt/comm-pt2pt.cpp +++ b/teshsuite/s4u/comm-pt2pt/comm-pt2pt.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/concurrent_rw/concurrent_rw.cpp b/teshsuite/s4u/concurrent_rw/concurrent_rw.cpp index 83759d3c56..1e8e89097d 100644 --- a/teshsuite/s4u/concurrent_rw/concurrent_rw.cpp +++ b/teshsuite/s4u/concurrent_rw/concurrent_rw.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/dag-incomplete-simulation/dag-incomplete-simulation.cpp b/teshsuite/s4u/dag-incomplete-simulation/dag-incomplete-simulation.cpp index db9983aacc..140d969b3f 100644 --- a/teshsuite/s4u/dag-incomplete-simulation/dag-incomplete-simulation.cpp +++ b/teshsuite/s4u/dag-incomplete-simulation/dag-incomplete-simulation.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -23,13 +23,13 @@ int main(int argc, char** argv) simgrid::s4u::Engine e(&argc, argv); e.load_platform(argv[1]); - auto host = e.host_by_name("cpu0"); + auto* host = e.host_by_name("cpu0"); /* creation of the tasks and their dependencies */ - simgrid::s4u::ExecPtr Init = simgrid::s4u::Exec::init()->set_name("Init")->set_flops_amount(0)->vetoable_start(); - simgrid::s4u::CommPtr A = simgrid::s4u::Comm::sendto_init()->set_name("A")->set_payload_size(1e9)->vetoable_start(); - simgrid::s4u::CommPtr B = simgrid::s4u::Comm::sendto_init()->set_name("B")->vetoable_start(); - simgrid::s4u::ExecPtr C = simgrid::s4u::Exec::init()->set_name("C")->vetoable_start(); - simgrid::s4u::CommPtr D = simgrid::s4u::Comm::sendto_init()->set_name("D")->set_payload_size(1e9)->vetoable_start(); + simgrid::s4u::ExecPtr Init = simgrid::s4u::Exec::init()->set_name("Init")->set_flops_amount(0)->start(); + simgrid::s4u::CommPtr A = simgrid::s4u::Comm::sendto_init()->set_name("A")->set_payload_size(1e9)->start(); + simgrid::s4u::CommPtr B = simgrid::s4u::Comm::sendto_init()->set_name("B")->start(); + simgrid::s4u::ExecPtr C = simgrid::s4u::Exec::init()->set_name("C")->start(); + simgrid::s4u::CommPtr D = simgrid::s4u::Comm::sendto_init()->set_name("D")->set_payload_size(1e9)->start(); std::vector activities = {Init, A, B, C, D}; Init->add_successor(A); diff --git a/teshsuite/s4u/dependencies/dependencies.cpp b/teshsuite/s4u/dependencies/dependencies.cpp index d367dd78aa..fa1e49dcd4 100644 --- a/teshsuite/s4u/dependencies/dependencies.cpp +++ b/teshsuite/s4u/dependencies/dependencies.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -13,19 +13,16 @@ int main(int argc, char** argv) xbt_assert(argc > 1, "Usage: %s platform_file\n\nExample: %s two_clusters.xml", argv[0], argv[0]); engine.load_platform(argv[1]); - simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) { - const auto* exec = dynamic_cast(&activity); - if (exec == nullptr) // Only Execs are concerned here - return; - XBT_INFO("Exec '%s' start time: %f, finish time: %f", exec->get_cname(), exec->get_start_time(), - exec->get_finish_time()); + simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) { + XBT_INFO("Exec '%s' start time: %f, finish time: %f", exec.get_cname(), exec.get_start_time(), + exec.get_finish_time()); }); /* creation of the activities and their dependencies */ - simgrid::s4u::ExecPtr A = simgrid::s4u::Exec::init()->set_name("A")->vetoable_start(); - simgrid::s4u::ExecPtr B = simgrid::s4u::Exec::init()->set_name("B")->vetoable_start(); - simgrid::s4u::ExecPtr C = simgrid::s4u::Exec::init()->set_name("C")->vetoable_start(); - simgrid::s4u::ExecPtr D = simgrid::s4u::Exec::init()->set_name("D")->vetoable_start(); + simgrid::s4u::ExecPtr A = simgrid::s4u::Exec::init()->set_name("A")->start(); + simgrid::s4u::ExecPtr B = simgrid::s4u::Exec::init()->set_name("B")->start(); + simgrid::s4u::ExecPtr C = simgrid::s4u::Exec::init()->set_name("C")->start(); + simgrid::s4u::ExecPtr D = simgrid::s4u::Exec::init()->set_name("D")->start(); B->add_successor(A); C->add_successor(A); diff --git a/teshsuite/s4u/evaluate-get-route-time/evaluate-get-route-time.cpp b/teshsuite/s4u/evaluate-get-route-time/evaluate-get-route-time.cpp index fc9106c84b..4481bf134b 100644 --- a/teshsuite/s4u/evaluate-get-route-time/evaluate-get-route-time.cpp +++ b/teshsuite/s4u/evaluate-get-route-time/evaluate-get-route-time.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. +/* Copyright (c) 2008-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/s4u/evaluate-parse-time/evaluate-parse-time.cpp b/teshsuite/s4u/evaluate-parse-time/evaluate-parse-time.cpp index 5c962a4420..5397d38989 100644 --- a/teshsuite/s4u/evaluate-parse-time/evaluate-parse-time.cpp +++ b/teshsuite/s4u/evaluate-parse-time/evaluate-parse-time.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/host-multicore-speed-file/host-multicore-speed-file.cpp b/teshsuite/s4u/host-multicore-speed-file/host-multicore-speed-file.cpp index e2f65a541e..3a5c94e3c9 100644 --- a/teshsuite/s4u/host-multicore-speed-file/host-multicore-speed-file.cpp +++ b/teshsuite/s4u/host-multicore-speed-file/host-multicore-speed-file.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/s4u/host-on-off-actors/host-on-off-actors.cpp b/teshsuite/s4u/host-on-off-actors/host-on-off-actors.cpp index f4e9cd8c94..fcc42cb94b 100644 --- a/teshsuite/s4u/host-on-off-actors/host-on-off-actors.cpp +++ b/teshsuite/s4u/host-on-off-actors/host-on-off-actors.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -8,9 +8,7 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example"); -int tasks_done = 0; - -XBT_ATTRIB_NORETURN static void actor_daemon() +XBT_ATTRIB_NORETURN static void actor_daemon(int& tasks_done) { const simgrid::s4u::Host* host = simgrid::s4u::Host::current(); XBT_INFO(" Start daemon on %s (%f)", host->get_cname(), host->get_speed()); @@ -41,7 +39,7 @@ static void commRX() { XBT_INFO(" Start RX"); try { - auto payload = simgrid::s4u::Mailbox::by_name("comm")->get(); + const auto* payload = simgrid::s4u::Mailbox::by_name("comm")->get(); XBT_INFO(" Receive message: %s", payload->c_str()); } catch (const simgrid::HostFailureException&) { XBT_INFO(" Receive message: HOST_FAILURE"); @@ -57,13 +55,14 @@ static void test_launcher(int test_number) simgrid::s4u::Host* jupiter = simgrid::s4u::Host::by_name("Jupiter"); simgrid::s4u::ActorPtr daemon; simgrid::s4u::VirtualMachine* vm0 = nullptr; + int tasks_done = 0; switch (test_number) { case 1: // Create a process running a simple task on a host and turn the host off during the execution of the actor. XBT_INFO("Test 1:"); XBT_INFO(" Create an actor on Jupiter"); - simgrid::s4u::Actor::create("actor_daemon", jupiter, actor_daemon); + simgrid::s4u::Actor::create("actor_daemon", jupiter, actor_daemon, std::ref(tasks_done)); simgrid::s4u::this_actor::sleep_for(3); XBT_INFO(" Turn off Jupiter"); jupiter->turn_off(); @@ -79,7 +78,7 @@ static void test_launcher(int test_number) // adsein: This can be one additional test, to check that you cannot shutdown twice a host jupiter->turn_off(); try { - simgrid::s4u::Actor::create("actor_daemon", jupiter, actor_daemon); + simgrid::s4u::Actor::create("actor_daemon", jupiter, actor_daemon, std::ref(tasks_done)); simgrid::s4u::this_actor::sleep_for(10); XBT_INFO(" Test 2 does crash as it should. This message will not be displayed."); } catch (const simgrid::HostFailureException&) { @@ -128,8 +127,8 @@ static void test_launcher(int test_number) vm0 = jupiter->create_vm("vm0", 1); vm0->start(); - daemon = simgrid::s4u::Actor::create("actor_daemon", vm0, actor_daemon); - simgrid::s4u::Actor::create("actor_daemonJUPI", jupiter, actor_daemon); + daemon = simgrid::s4u::Actor::create("actor_daemon", vm0, actor_daemon, std::ref(tasks_done)); + simgrid::s4u::Actor::create("actor_daemonJUPI", jupiter, actor_daemon, std::ref(tasks_done)); daemon->suspend(); vm0->set_bound(90); diff --git a/teshsuite/s4u/host-on-off-recv/host-on-off-recv.cpp b/teshsuite/s4u/host-on-off-recv/host-on-off-recv.cpp index 1952fa69d6..7c36e1bbcb 100644 --- a/teshsuite/s4u/host-on-off-recv/host-on-off-recv.cpp +++ b/teshsuite/s4u/host-on-off-recv/host-on-off-recv.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/s4u/host-on-off/host-on-off.cpp b/teshsuite/s4u/host-on-off/host-on-off.cpp index 69e4b2593b..c4ccf9d81c 100644 --- a/teshsuite/s4u/host-on-off/host-on-off.cpp +++ b/teshsuite/s4u/host-on-off/host-on-off.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/s4u/io-set-bw/io-set-bw.cpp b/teshsuite/s4u/io-set-bw/io-set-bw.cpp index 7c21d313bb..6a1b305d4e 100644 --- a/teshsuite/s4u/io-set-bw/io-set-bw.cpp +++ b/teshsuite/s4u/io-set-bw/io-set-bw.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/io-stream/io-stream.cpp b/teshsuite/s4u/io-stream/io-stream.cpp new file mode 100644 index 0000000000..6977fbc139 --- /dev/null +++ b/teshsuite/s4u/io-stream/io-stream.cpp @@ -0,0 +1,124 @@ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include + +namespace sg4 = simgrid::s4u; + +XBT_LOG_NEW_DEFAULT_CATEGORY(io_stream, "Messages specific for this simulation"); + +static void streamer(size_t size) +{ + auto* bob = sg4::Host::by_name("bob"); + auto* alice = sg4::Host::by_name("alice"); + const auto* bob_disk = bob->get_disks().front(); + const auto* alice_disk = alice->get_disks().front(); + double clock = sg4::Engine::get_clock(); + + XBT_INFO("[Bob -> Alice] Store and Forward (1 block)"); + bob_disk->read(size); + XBT_INFO(" Read : %.6f seconds", sg4::Engine::get_clock() - clock); + clock = sg4::Engine::get_clock(); + sg4::Comm::sendto(bob, alice, size); + XBT_INFO(" Send : %.6f seconds", sg4::Engine::get_clock() - clock); + clock = sg4::Engine::get_clock(); + alice_disk->write(size); + XBT_INFO(" Write : %.6f seconds", sg4::Engine::get_clock() - clock); + XBT_INFO(" Total : %.6f seconds", sg4::Engine::get_clock()); + + XBT_INFO("[Bob -> Alice] Store and Forward (100 blocks)"); + size_t block_size = size / 100; + sg4::IoPtr read = bob_disk->read_async(block_size); + sg4::CommPtr transfer = sg4::Comm::sendto_async(bob, alice, block_size); + sg4::IoPtr write = alice_disk->write_async(block_size); + + clock = sg4::Engine::get_clock(); + + for (int i = 0; i < 99; i++){ + read->wait(); + read = bob_disk->read_async(block_size); + transfer->wait(); + transfer = sg4::Comm::sendto_async(bob, alice, block_size); + write->wait(); + write = alice_disk->write_async(block_size); + } + + read->wait(); + transfer->wait(); + write->wait(); + XBT_INFO(" Total : %.6f seconds", sg4::Engine::get_clock() - clock); + + XBT_INFO("[Bob -> Alice] Streaming (Read bottleneck)"); + clock = sg4::Engine::get_clock(); + sg4::Io::streamto(bob, bob_disk, alice, alice_disk, size); + XBT_INFO(" Total : %.6f seconds", sg4::Engine::get_clock() - clock); + + XBT_INFO("[Alice -> Bob] Streaming (Write bottleneck)"); + clock = sg4::Engine::get_clock(); + sg4::Io::streamto(alice, alice_disk, bob, bob_disk, size); + XBT_INFO(" Total : %.6f seconds", sg4::Engine::get_clock() - clock); + + XBT_INFO("Start two 10-second background traffic between Bob and Alice"); + sg4::CommPtr bt1 = sg4::Comm::sendto_async(bob, alice, 2e7); + XBT_INFO("[Bob -> Alice] Streaming (Transfer bottleneck)"); + clock = sg4::Engine::get_clock(); + sg4::Io::streamto(bob, bob_disk, alice, alice_disk, size); + XBT_INFO(" Total : %.6f seconds", sg4::Engine::get_clock() - clock); + bt1->wait(); + + XBT_INFO("[Bob -> Alice] Streaming \"from disk to memory\" (no write)"); + clock = sg4::Engine::get_clock(); + sg4::Io::streamto(bob, bob_disk, alice, nullptr, size); + XBT_INFO(" Total : %.6f seconds", sg4::Engine::get_clock() - clock); + + XBT_INFO("[Bob -> Alice] Streaming \"from memory to disk\" (no read)"); + clock = sg4::Engine::get_clock(); + sg4::Io::streamto(bob, nullptr, alice, alice_disk, size); + XBT_INFO(" Total : %.6f seconds", sg4::Engine::get_clock() - clock); + + XBT_INFO("[Bob -> Bob] Disk to disk (no transfer)"); + clock = sg4::Engine::get_clock(); + sg4::Io::streamto(bob, bob_disk, bob, bob_disk, size); + XBT_INFO(" Total : %.6f seconds", sg4::Engine::get_clock() - clock); +} + +static void background_send() { + sg4::this_actor::sleep_for(23.000150); + sg4::Mailbox::by_name("mbox")->put(new double(1), 2e7); +} + +static void background_recv() { + double* res; + sg4::CommPtr comm = sg4::Mailbox::by_name("mbox")->get_async(&res); + sg4::this_actor::sleep_for(33.1); + comm->wait(); + delete res; +} + +int main(int argc, char** argv) +{ + sg4::Engine e(&argc, argv); + + /* simple platform containing 2 hosts and 2 disks */ + auto* zone = sg4::create_full_zone(""); + auto* bob = zone->create_host("bob", 1e6); + auto* alice = zone->create_host("alice", 1e6); + + auto* link = zone->create_link("link", "2MBps")->set_latency("50us"); + zone->add_route(bob, alice, {link}); + + bob->create_disk("bob_disk", "1MBps", "500kBps"); + alice->create_disk("alice_disk", "4MBps", "4MBps"); + + zone->seal(); + + sg4::Actor::create("streamer", bob, streamer, 4e6); + sg4::Actor::create("background send", bob, background_send); + sg4::Actor::create("background recv", alice, background_recv); + + e.run(); + + return 0; +} diff --git a/teshsuite/s4u/io-stream/io-stream.tesh b/teshsuite/s4u/io-stream/io-stream.tesh new file mode 100644 index 0000000000..62caef5f35 --- /dev/null +++ b/teshsuite/s4u/io-stream/io-stream.tesh @@ -0,0 +1,47 @@ +#!/usr/bin/env tesh + +$ ${bindir:=.}/io-stream --cfg=network/model:CM02 --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e%m%n" +> [ 0.000000] Configuration change: Set 'network/model' to 'CM02' +> [ 0.000000] Configuration change: Set 'network/crosstraffic' to '0' +> [ 0.000000] [Bob -> Alice] Store and Forward (1 block) +> [ 4.000000] Read : 4.000000 seconds +> [ 6.000050] Send : 2.000050 seconds +> [ 7.000050] Write : 1.000000 seconds +> [ 7.000050] Total : 7.000050 seconds +> [ 7.000050] [Bob -> Alice] Store and Forward (100 blocks) +> [ 11.000050] Total : 4.000000 seconds +> [ 11.000050] [Bob -> Alice] Streaming (Read bottleneck) +> [ 15.000100] Total : 4.000050 seconds +> [ 15.000100] [Alice -> Bob] Streaming (Write bottleneck) +> [ 23.000150] Total : 8.000050 seconds +> [ 23.000150] Start two 10-second background traffic between Bob and Alice +> [ 23.000150] [Bob -> Alice] Streaming (Transfer bottleneck) +> [ 29.000200] Total : 6.000050 seconds +> [ 45.000200] [Bob -> Alice] Streaming "from disk to memory" (no write) +> [ 49.000250] Total : 4.000050 seconds +> [ 49.000250] [Bob -> Alice] Streaming "from memory to disk" (no read) +> [ 51.000300] Total : 2.000050 seconds +> [ 51.000300] [Bob -> Bob] Disk to disk (no transfer) +> [ 59.000300] Total : 8.000000 seconds + +$ ${bindir:=.}/io-stream "--log=root.fmt:[%10.6r]%e%m%n" +> [ 0.000000] [Bob -> Alice] Store and Forward (1 block) +> [ 4.000000] Read : 4.000000 seconds +> [ 6.165599] Send : 2.165599 seconds +> [ 7.165599] Write : 1.000000 seconds +> [ 7.165599] Total : 7.165599 seconds +> [ 7.165599] [Bob -> Alice] Store and Forward (100 blocks) +> [ 11.165518] Total : 3.999919 seconds +> [ 11.165518] [Bob -> Alice] Streaming (Read bottleneck) +> [ 15.166169] Total : 4.000651 seconds +> [ 15.166169] [Alice -> Bob] Streaming (Write bottleneck) +> [ 23.166819] Total : 8.000651 seconds +> [ 23.166819] Start two 10-second background traffic between Bob and Alice +> [ 23.166819] [Bob -> Alice] Streaming (Transfer bottleneck) +> [ 29.662315] Total : 6.495496 seconds +> [ 46.860161] [Bob -> Alice] Streaming "from disk to memory" (no write) +> [ 50.860812] Total : 4.000650 seconds +> [ 50.860812] [Bob -> Alice] Streaming "from memory to disk" (no read) +> [ 53.026411] Total : 2.165599 seconds +> [ 53.026411] [Bob -> Bob] Disk to disk (no transfer) +> [ 61.026411] Total : 8.000000 seconds diff --git a/teshsuite/s4u/is-router/is-router.cpp b/teshsuite/s4u/is-router/is-router.cpp index 2c1e96d810..9e35b77fde 100644 --- a/teshsuite/s4u/is-router/is-router.cpp +++ b/teshsuite/s4u/is-router/is-router.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/issue71/issue71.cpp b/teshsuite/s4u/issue71/issue71.cpp index 6333844281..7983e49f66 100644 --- a/teshsuite/s4u/issue71/issue71.cpp +++ b/teshsuite/s4u/issue71/issue71.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2021-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,7 +9,7 @@ static void runner() { - auto e = simgrid::s4u::Engine::get_instance(); + const auto* e = simgrid::s4u::Engine::get_instance(); simgrid::s4u::Host* host0 = e->host_by_name("c1_0"); simgrid::s4u::Host* host1 = e->host_by_name("c2_0"); diff --git a/teshsuite/s4u/listen_async/listen_async.cpp b/teshsuite/s4u/listen_async/listen_async.cpp index 00e3182877..778232ee5f 100644 --- a/teshsuite/s4u/listen_async/listen_async.cpp +++ b/teshsuite/s4u/listen_async/listen_async.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,7 +6,7 @@ /* Bug report: https://github.com/simgrid/simgrid/issues/40 * * Task.listen used to be on async mailboxes as it always returned false. - * This occurs in Java and C, but is only tested here in C. + * This occurred in Java and C, but only C remains. */ #include "simgrid/s4u.hpp" diff --git a/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.cpp b/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.cpp index b6334cf3b3..4a4fca3b71 100644 --- a/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.cpp +++ b/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,7 +9,7 @@ * It is not written to be pleasant to read, but instead to resist the aggressions of the monkey: * - Workers keep going until after a global variable `todo` reaches 0. * - The master is a daemon that just sends infinitely tasks - * (simgrid simulations stop as soon as all non-daemon actors are done). + * (SimGrid simulations stop as soon as all non-daemon actors are done). * - The platform is created programmatically to remove path issues and control the problem size. * * Command-line configuration items: @@ -33,10 +33,7 @@ static simgrid::config::Flag cfg_deadline{"deadline", "When to fail the 120}; static simgrid::config::Flag cfg_task_count{"task-count", "Amount of tasks that must be executed to succeed", 1}; -int todo; // remaining amount of tasks to execute, a global variable -sg4::Mailbox* mailbox; // as a global to reduce the amount of simcalls during actor reboot - -XBT_ATTRIB_NORETURN static void master() +XBT_ATTRIB_NORETURN static void master(sg4::Mailbox* mailbox) { double comp_size = 1e6; long comm_size = 1e6; @@ -66,7 +63,7 @@ XBT_ATTRIB_NORETURN static void master() THROW_IMPOSSIBLE; } -static void worker(int id) +static void worker(int id, sg4::Mailbox* mailbox, int& todo) { bool rebooting = sg4::Actor::self()->get_restart_count() > 0; @@ -104,29 +101,32 @@ int main(int argc, char* argv[]) auto* rootzone = sg4::create_full_zone("root"); std::vector worker_hosts; + int todo = cfg_task_count; // remaining amount of tasks to execute, a shared variable + xbt_assert(todo > 0, "Please give more than %d tasks to run", todo); + xbt_assert(cfg_host_count > 2, "You need at least 2 workers (i.e., 3 hosts) or the master will be auto-killed when " "the only worker gets killed."); + + // get it once for all, to reduce the amount of simcalls during actor reboot + sg4::Mailbox* mailbox = sg4::Mailbox::by_name("mailbox"); + sg4::Host* master_host = rootzone->create_host("lilibeth 0", 1e9); // Host where the master will stay for (int i = 1; i < cfg_host_count; i++) { - auto hostname = std::string("lilibeth ") + std::to_string(i); + auto hostname = "lilibeth " + std::to_string(i); auto* host = rootzone->create_host(hostname, 1e9); - sg4::LinkInRoute link(rootzone->create_link(hostname, "1MBps")->set_latency("24us")->seal()); - rootzone->add_route(master_host->get_netpoint(), host->get_netpoint(), nullptr, nullptr, {link}, true); + auto* link = rootzone->create_link(hostname, "1MBps")->set_latency("24us")->seal(); + rootzone->add_route(master_host, host, {link}); worker_hosts.push_back(host); } rootzone->seal(); - sg4::Actor::create("master", master_host, master)->daemonize()->set_auto_restart(true); + sg4::Actor::create("master", master_host, master, mailbox)->daemonize()->set_auto_restart(true); int id = 0; for (auto* h : worker_hosts) { - sg4::Actor::create("worker", h, worker, id)->set_auto_restart(true); + sg4::Actor::create("worker", h, worker, id, mailbox, std::ref(todo))->set_auto_restart(true); id++; } - todo = cfg_task_count; - xbt_assert(todo > 0, "Please give more than %d tasks to run", todo); - mailbox = sg4::Mailbox::by_name("mailbox"); - e.run(); XBT_INFO("WE SURVIVED!"); diff --git a/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.py b/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.py index c9e92c7a8c..863b39244e 100644 --- a/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.py +++ b/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -10,7 +10,7 @@ It is not written to be pleasant to read, but instead to resist the aggressions of the monkey: - Workers keep going until after a global variable `todo` reaches 0. - The master is a daemon that just sends infinitely tasks - (simgrid simulations stop as soon as all non-daemon actors are done). + (SimGrid simulations stop as soon as all non-daemon actors are done). - The platform is created programmatically to remove path issues and control the problem size. See the simgrid-monkey script for more information. @@ -63,7 +63,7 @@ def worker(my_id): assert Engine.clock < deadline, f"Failed to run all tasks in less than {deadline} seconds. Is this an infinite loop?" try: - this_actor.info(f"Waiting a message on mailbox") + this_actor.info("Waiting a message on mailbox") compute_cost = mailbox.get() this_actor.info("Start execution...") @@ -92,7 +92,7 @@ if __name__ == '__main__': for i in range(1, host_count): link = rootzone.create_split_duplex_link(f"link {i}", "1MBps").set_latency("24us") host = rootzone.create_host(f"lilibeth {i}", 1e9) - rootzone.add_route(main.netpoint, host.netpoint, None, None, [LinkInRoute(link, LinkInRoute.Direction.UP)], True) + rootzone.add_route(main, host, [link]) Actor.create("worker", host, worker, i).set_auto_restart(True) e.netzone_root.seal() diff --git a/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.py.tesh b/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.py.tesh index eb92ddeb03..66292c17d2 100644 --- a/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.py.tesh +++ b/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.py.tesh @@ -3,7 +3,7 @@ p Smoke test: do one arbitrary run of the monkey, just to make sure that *someth $ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/monkey-masterworkers.py --cfg=plugin:cmonkey --cfg=cmonkey/time:1 --cfg=cmonkey/host:1 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'plugin' to 'cmonkey' -> [0.000000] [cmonkey/INFO] Initializing the chaos monkey +> [0.000000] [cmonkey/INFO] Initializing the chaos monkey. > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cmonkey/time' to '1' > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cmonkey/host' to '1' > [lilibeth 0:master:(1) 0.000000] [python/INFO] Master booting diff --git a/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.tesh b/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.tesh index e7f9e553ce..db6fb4f108 100644 --- a/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.tesh +++ b/teshsuite/s4u/monkey-masterworkers/monkey-masterworkers.tesh @@ -3,7 +3,7 @@ p Smoke test: do one arbitrary run of the monkey, just to make sure that *someth $ ${bindir:=.}/monkey-masterworkers --cfg=plugin:cmonkey --cfg=cmonkey/time:1 --cfg=cmonkey/host:1 --cfg=task-count:2 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'plugin' to 'cmonkey' -> [0.000000] [cmonkey/INFO] Initializing the chaos monkey +> [0.000000] [cmonkey/INFO] Initializing the chaos monkey. > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cmonkey/time' to '1' > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cmonkey/host' to '1' > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'task-count' to '2' diff --git a/teshsuite/s4u/monkey-semaphore/monkey-semaphore.cpp b/teshsuite/s4u/monkey-semaphore/monkey-semaphore.cpp index b9dea1199e..6e73575767 100644 --- a/teshsuite/s4u/monkey-semaphore/monkey-semaphore.cpp +++ b/teshsuite/s4u/monkey-semaphore/monkey-semaphore.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -116,8 +116,8 @@ int main(int argc, char** argv) auto* rootzone = sg4::create_full_zone("root"); auto* paul = rootzone->create_host("Paul", 1e9); auto* carol = rootzone->create_host("Carol", 1e9); - sg4::LinkInRoute link(rootzone->create_link("link", "1MBps")->set_latency("24us")->seal()); - rootzone->add_route(paul->get_netpoint(), carol->get_netpoint(), nullptr, nullptr, {link}, true); + auto* link = rootzone->create_link("link", "1MBps")->set_latency("24us")->seal(); + rootzone->add_route(paul, carol, {link}); SharedBuffer buffer; sg4::Actor::create("producer", paul, producer, std::ref(buffer))->set_auto_restart(); diff --git a/teshsuite/s4u/monkey-semaphore/monkey-semaphore.tesh b/teshsuite/s4u/monkey-semaphore/monkey-semaphore.tesh index 5a36de0235..d1808cccff 100644 --- a/teshsuite/s4u/monkey-semaphore/monkey-semaphore.tesh +++ b/teshsuite/s4u/monkey-semaphore/monkey-semaphore.tesh @@ -3,7 +3,7 @@ p Smoke test: do one arbitrary run of the monkey, just to make sure that *someth $ ${bindir:=.}/monkey-semaphore --cfg=plugin:cmonkey --cfg=cmonkey/time:1 --cfg=cmonkey/host:1 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'plugin' to 'cmonkey' -> [0.000000] [cmonkey/INFO] Initializing the chaos monkey +> [0.000000] [cmonkey/INFO] Initializing the chaos monkey. > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cmonkey/time' to '1' > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cmonkey/host' to '1' > [Paul:producer:(1) 0.000000] [sem_monkey/INFO] Producer booting diff --git a/teshsuite/s4u/ns3-from-src-to-itself/ns3-from-src-to-itself.cpp b/teshsuite/s4u/ns3-from-src-to-itself/ns3-from-src-to-itself.cpp index 49e4c3963f..713508e938 100644 --- a/teshsuite/s4u/ns3-from-src-to-itself/ns3-from-src-to-itself.cpp +++ b/teshsuite/s4u/ns3-from-src-to-itself/ns3-from-src-to-itself.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/ns3-from-src-to-itself/ns3-from-src-to-itself.tesh b/teshsuite/s4u/ns3-from-src-to-itself/ns3-from-src-to-itself.tesh index ff4e558d78..b6f9251049 100644 --- a/teshsuite/s4u/ns3-from-src-to-itself/ns3-from-src-to-itself.tesh +++ b/teshsuite/s4u/ns3-from-src-to-itself/ns3-from-src-to-itself.tesh @@ -3,6 +3,6 @@ p We just want to check that the ns-3 bindings of SimGrid are working correctly, $ ./ns3-from-src-to-itself ${platfdir}/ns3-big-cluster.xml --cfg=network/model:ns-3 "--log=root.fmt:[%h:%a(%i)]%e[%c/%p]%e%m%n" > [:maestro(0)] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3' -> [:maestro(0)] [res_ns3/WARNING] Sending from a host c-01.rennes to itself is not supported by ns-3. Every such communication finishes immediately upon startup. +> [:maestro(0)] [res_ns3/WARNING] Sending from a host c-01.rennes to itself is not supported by ns-3. Every such communication finishes immediately upon startup in the SimGrid+ns-3 system. > [c-01.rennes:receiver(1)] [s4u_test/INFO] Done receiving from 2 senders, each of them sending 5 messages diff --git a/teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.cpp b/teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.cpp index 241f74d379..47f7b0ea05 100644 --- a/teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.cpp +++ b/teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/pid/pid.cpp b/teshsuite/s4u/pid/pid.cpp index 6e18870e5d..5d0c7f1fb6 100644 --- a/teshsuite/s4u/pid/pid.cpp +++ b/teshsuite/s4u/pid/pid.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/s4u/seal-platform/seal-platform.cpp b/teshsuite/s4u/seal-platform/seal-platform.cpp index e8b775bb34..d32d2d92f3 100644 --- a/teshsuite/s4u/seal-platform/seal-platform.cpp +++ b/teshsuite/s4u/seal-platform/seal-platform.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,7 +6,7 @@ #include "simgrid/s4u.hpp" namespace sg4 = simgrid::s4u; -XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_torus_multicpu, "Messages specific for this s4u example"); +XBT_LOG_NEW_DEFAULT_CATEGORY(seal_platform, "Messages specific for this s4u example"); class Sender { long msg_size = 1e6; /* message size in bytes */ @@ -17,25 +17,24 @@ public: void operator()() const { /* Vector in which we store all ongoing communications */ - std::vector pending_comms; + sg4::ActivitySet pending_comms; /* Make a vector of the mailboxes to use */ std::vector mboxes; - std::string msg_content = - std::string("Hello, I'm alive and running on ") + std::string(sg4::this_actor::get_host()->get_name()); + std::string msg_content = "Hello, I'm alive and running on " + sg4::this_actor::get_host()->get_name(); for (const auto* host : hosts_) { auto* payload = new std::string(msg_content); /* Create a communication representing the ongoing communication, and store it in pending_comms */ - auto mbox = sg4::Mailbox::by_name(host->get_name()); + auto* mbox = sg4::Mailbox::by_name(host->get_name()); mboxes.push_back(mbox); sg4::CommPtr comm = mbox->put_async(payload, msg_size); - pending_comms.push_back(comm); + pending_comms.push(comm); } XBT_INFO("Done dispatching all messages"); /* Now that all message exchanges were initiated, wait for their completion in one single call */ - sg4::Comm::wait_all(pending_comms); + pending_comms.wait_all(); XBT_INFO("Goodbye now!"); } @@ -46,7 +45,7 @@ class Receiver { public: void operator()() const { - auto mbox = sg4::Mailbox::by_name(sg4::this_actor::get_host()->get_name()); + auto* mbox = sg4::Mailbox::by_name(sg4::this_actor::get_host()->get_name()); auto received = mbox->get_unique(); XBT_INFO("I got a '%s'.", received->c_str()); @@ -59,17 +58,16 @@ public: /*************************************************************************************************/ static sg4::NetZone* create_zone(const sg4::NetZone* root, const std::string& id) { - auto* zone = sg4::create_floyd_zone(id); - zone->set_parent(root); + auto* zone = sg4::create_star_zone(id)->set_parent(root); constexpr int n_host = 2; - auto* router = zone->create_router("router" + id); + zone->set_gateway(zone->create_router("router" + id)); for (int i = 0; i < n_host; i++) { std::string hostname = id + "-cpu-" + std::to_string(i); auto* host = zone->create_host(hostname, 1e9); host->create_disk("disk-" + hostname, 1e9, 1e6); const auto* link = zone->create_link("link-" + hostname, 1e9); - zone->add_route(host->get_netpoint(), router, nullptr, nullptr, {sg4::LinkInRoute(link)}); + zone->add_route(host, nullptr, {link}); } return zone; } @@ -85,15 +83,14 @@ int main(int argc, char* argv[]) auto* zoneA = create_zone(root, "A"); auto* zoneB = create_zone(root, "B"); const auto* link = root->create_link("root-link", 1e10); - root->add_route(zoneA->get_netpoint(), zoneB->get_netpoint(), e.netpoint_by_name("routerA"), - e.netpoint_by_name("routerB"), {sg4::LinkInRoute(link)}); + root->add_route(zoneA, zoneB, {sg4::LinkInRoute(link)}, true); std::vector host_list = e.get_all_hosts(); /* create the sender actor running on first host */ sg4::Actor::create("sender", host_list[0], Sender(host_list)); /* create receiver in every host */ for (auto* host : host_list) { - sg4::Actor::create(std::string("receiver-") + std::string(host->get_name()), host, Receiver()); + sg4::Actor::create("receiver-" + host->get_name(), host, Receiver()); } /* runs the simulation */ diff --git a/teshsuite/s4u/seal-platform/seal-platform.tesh b/teshsuite/s4u/seal-platform/seal-platform.tesh index 11ea6df7b7..187501ccac 100644 --- a/teshsuite/s4u/seal-platform/seal-platform.tesh +++ b/teshsuite/s4u/seal-platform/seal-platform.tesh @@ -1,11 +1,11 @@ $ ./seal-platform -> [A-cpu-0:sender:(1) 0.000000] [s4u_torus_multicpu/INFO] Done dispatching all messages -> [A-cpu-0:receiver-A-cpu-0:(2) 0.000103] [s4u_torus_multicpu/INFO] I got a 'Hello, I'm alive and running on A-cpu-0'. -> [B-cpu-1:receiver-B-cpu-1:(5) 0.003247] [s4u_torus_multicpu/INFO] I got a 'Hello, I'm alive and running on A-cpu-0'. -> [B-cpu-0:receiver-B-cpu-0:(4) 0.003247] [s4u_torus_multicpu/INFO] I got a 'Hello, I'm alive and running on A-cpu-0'. -> [A-cpu-1:receiver-A-cpu-1:(3) 0.003247] [s4u_torus_multicpu/INFO] I got a 'Hello, I'm alive and running on A-cpu-0'. -> [A-cpu-0:sender:(1) 0.003247] [s4u_torus_multicpu/INFO] Goodbye now! -> [A-cpu-0:receiver-A-cpu-0:(2) 4.000103] [s4u_torus_multicpu/INFO] Wrote 4000000 bytes on 'disk-A-cpu-0' -> [B-cpu-1:receiver-B-cpu-1:(5) 4.003247] [s4u_torus_multicpu/INFO] Wrote 4000000 bytes on 'disk-B-cpu-1' -> [B-cpu-0:receiver-B-cpu-0:(4) 4.003247] [s4u_torus_multicpu/INFO] Wrote 4000000 bytes on 'disk-B-cpu-0' -> [A-cpu-1:receiver-A-cpu-1:(3) 4.003247] [s4u_torus_multicpu/INFO] Wrote 4000000 bytes on 'disk-A-cpu-1' +> [A-cpu-0:sender:(1) 0.000000] [seal_platform/INFO] Done dispatching all messages +> [B-cpu-1:receiver-B-cpu-1:(5) 0.004330] [seal_platform/INFO] I got a 'Hello, I'm alive and running on A-cpu-0'. +> [B-cpu-0:receiver-B-cpu-0:(4) 0.004330] [seal_platform/INFO] I got a 'Hello, I'm alive and running on A-cpu-0'. +> [A-cpu-1:receiver-A-cpu-1:(3) 0.004330] [seal_platform/INFO] I got a 'Hello, I'm alive and running on A-cpu-0'. +> [A-cpu-0:receiver-A-cpu-0:(2) 0.004330] [seal_platform/INFO] I got a 'Hello, I'm alive and running on A-cpu-0'. +> [A-cpu-0:sender:(1) 0.004330] [seal_platform/INFO] Goodbye now! +> [B-cpu-1:receiver-B-cpu-1:(5) 4.004330] [seal_platform/INFO] Wrote 4000000 bytes on 'disk-B-cpu-1' +> [B-cpu-0:receiver-B-cpu-0:(4) 4.004330] [seal_platform/INFO] Wrote 4000000 bytes on 'disk-B-cpu-0' +> [A-cpu-1:receiver-A-cpu-1:(3) 4.004330] [seal_platform/INFO] Wrote 4000000 bytes on 'disk-A-cpu-1' +> [A-cpu-0:receiver-A-cpu-0:(2) 4.004330] [seal_platform/INFO] Wrote 4000000 bytes on 'disk-A-cpu-0' \ No newline at end of file diff --git a/teshsuite/s4u/storage_client_server/storage_client_server.cpp b/teshsuite/s4u/storage_client_server/storage_client_server.cpp index f8ee407a0c..8170ff0f83 100644 --- a/teshsuite/s4u/storage_client_server/storage_client_server.cpp +++ b/teshsuite/s4u/storage_client_server/storage_client_server.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2013-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -76,18 +76,17 @@ static void get_set_disk_data(simgrid::s4u::Disk* disk) { XBT_INFO("*** GET/SET DATA for disk: %s ***", disk->get_cname()); - const std::string* data = disk->get_data(); + auto data = disk->get_unique_data(); XBT_INFO("Get data: '%s'", data ? data->c_str() : "No User Data"); disk->set_data(new std::string("Some data")); - data = disk->get_data(); + data = disk->get_unique_data(); XBT_INFO(" Set and get data: '%s'", data->c_str()); - delete data; } static void dump_platform_disks() { - for (auto const& h : simgrid::s4u::Engine::get_instance()->get_all_hosts()) - for (auto const& d : h->get_disks()) { + for (auto const* h : simgrid::s4u::Engine::get_instance()->get_all_hosts()) + for (auto* d : h->get_disks()) { if (h == d->get_host()) XBT_INFO("%s is attached to %s", d->get_cname(), d->get_host()->get_cname()); d->set_property("other usage", "gpfs"); @@ -98,7 +97,7 @@ static void disk_info(const simgrid::s4u::Host* host) { XBT_INFO("*** Disk info on %s ***", host->get_cname()); - for (auto const& disk : host->get_disks()) { + for (auto const* disk : host->get_disks()) { const char* mount_name = sg_disk_get_mount_point(disk); XBT_INFO(" Disk name: %s, mount name: %s", disk->get_cname(), mount_name); diff --git a/teshsuite/s4u/storage_client_server/storage_client_server.tesh b/teshsuite/s4u/storage_client_server/storage_client_server.tesh index f724c4d616..10822fe557 100644 --- a/teshsuite/s4u/storage_client_server/storage_client_server.tesh +++ b/teshsuite/s4u/storage_client_server/storage_client_server.tesh @@ -32,9 +32,9 @@ $ ./storage_client_server ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%10. > [ 0.000000] (server@alice) /include/mc/modelchecker.h size: 96 bytes > [ 0.000000] (server@alice) /include/msg/datatypes.h size: 4635 bytes > [ 0.000000] (server@alice) /include/simdag/simdag.h size: 10325 bytes +> [ 0.000000] (server@alice) /include/simgrid_dtd.h size: 23583 bytes > [ 0.000000] (server@alice) /include/simix/simix.h size: 13003 bytes > [ 0.000000] (server@alice) /include/smpi/mpif.h size: 4826 bytes -> [ 0.000000] (server@alice) /include/surf/simgrid_dtd.h size: 23583 bytes > [ 0.000000] (server@alice) /include/xbt/fifo.h size: 3626 bytes > [ 0.000000] (server@alice) /lib/libsimgrid.so.3.6.2 size: 12710497 bytes > [ 0.000000] (server@alice) Server waiting for transfers ... @@ -80,18 +80,18 @@ $ ./storage_client_server ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%10. > [ 1.207952] (server@alice) /include/mc/modelchecker.h size: 96 bytes > [ 1.207952] (server@alice) /include/msg/datatypes.h size: 4635 bytes > [ 1.207952] (server@alice) /include/simdag/simdag.h size: 10325 bytes +> [ 1.207952] (server@alice) /include/simgrid_dtd.h size: 23583 bytes > [ 1.207952] (server@alice) /include/simix/simix.h size: 13003 bytes > [ 1.207952] (server@alice) /include/smpi/mpif.h size: 4826 bytes -> [ 1.207952] (server@alice) /include/surf/simgrid_dtd.h size: 23583 bytes > [ 1.207952] (server@alice) /include/xbt/fifo.h size: 3626 bytes > [ 1.207952] (server@alice) /lib/libsimgrid.so.3.6.2 size: 12710497 bytes > [ 1.207952] (server@alice) /tmp/tata.c size: 6217 bytes > [ 1.207952] (server@alice) /tmp/titi.xml size: 654 bytes > [ 1.207952] (server@alice) /tmp/toto.xml size: 972 bytes > [ 1.207952] (server@alice) Disk1 is attached to alice +> [ 1.207952] (server@alice) Disk1 is attached to bob +> [ 1.207952] (server@alice) Disk2 is attached to bob > [ 1.207952] (client@bob) *** GET/SET DATA for disk: Disk1 *** > [ 1.207952] (client@bob) Get data: 'No User Data' > [ 1.207952] (client@bob) Set and get data: 'Some data' -> [ 1.207952] (server@alice) Disk1 is attached to bob -> [ 1.207952] (server@alice) Disk2 is attached to bob > [ 1.207952] (maestro@) Simulated time: 1.20795 diff --git a/teshsuite/s4u/trace-integration/trace-integration.cpp b/teshsuite/s4u/trace-integration/trace-integration.cpp index 0c7e384bc6..a61b498ca4 100644 --- a/teshsuite/s4u/trace-integration/trace-integration.cpp +++ b/teshsuite/s4u/trace-integration/trace-integration.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/s4u/trace-integration/trace-integration.tesh b/teshsuite/s4u/trace-integration/trace-integration.tesh index 6899622175..41e6267ccf 100644 --- a/teshsuite/s4u/trace-integration/trace-integration.tesh +++ b/teshsuite/s4u/trace-integration/trace-integration.tesh @@ -4,8 +4,7 @@ p c=cycle s=step p=priority h=host p Testing trace integration using trace_B.txt and test-hbp1-c0s0-c0s1.xml, test_trace:start == trace_cycle_0_step_0, test_trace:end < trace_cycle_0_step_1 ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s0-c0s1.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s0-c0s1.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 0.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -16,8 +15,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1-c0s1-c0s2.xml, test_trace:start == trace_cycle_0_step_1, test_trace:end < trace_cycle_0_step_2 ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s1-c0s2.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s1-c0s2.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 10.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -28,8 +26,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1-c0s2-c1s0.xml, test_trace:start == trace_cycle_0_step_2, test_trace:end < trace_cycle_1_step_0 ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s2-c1s0.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s2-c1s0.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 20.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -40,8 +37,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1-c0s0-c1s0.xml, test_trace:start == trace_cycle_0_step_0, test_trace:end < trace_cycle_1_step_0 ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s0-c1s0.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s0-c1s0.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 0.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -52,8 +48,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1-c0s2-c1s1.xml, test_trace:start == trace_cycle_0_step_2, test_trace:end < trace_cycle_1_step_1 ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s2-c1s1.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s2-c1s1.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 20.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -64,8 +59,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1-c0s1-c2s2.xml, test_trace:start == trace_cycle_0_step_1, test_trace:end < trace_cycle_2_step_2 ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s1-c2s2.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c0s1-c2s2.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 10.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -76,8 +70,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1-c1s1-c1s2.xml, test_trace:start == trace_cycle_1_step_1, test_trace:end < trace_cycle_1_step_2 ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c1s1-c1s2.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c1s1-c1s2.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 40.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -88,8 +81,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1-c1s1-c3s2.xml, test_trace:start == trace_cycle_1_step_1, test_trace:end < trace_cycle_3_step_2 ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c1s1-c3s2.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1-c1s1-c3s2.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 40.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -100,8 +92,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1.5-hbp1.5.xml, two process with same priority ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1.5-hbp1.5.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1.5-hbp1.5.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 10.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -116,8 +107,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp2.5-hbp1.5.xml, two process with different priority ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp2.5-hbp1.5.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp2.5-hbp1.5.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 10.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -132,8 +122,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp2 p Testing trace integration using trace_B.txt and test-hbp2.5-hbp1.5.xml, two process with different priority (included) ! output sort -$ ./trace-integration ${platfdir}/two_hosts_platform_with_availability_included.xml ${srcdir:=.}/test-hbp2.5-hbp1.5.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_platform_with_availability_included.xml ${srcdir:=.}/test-hbp2.5-hbp1.5.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 10.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -148,8 +137,7 @@ $ ./trace-integration ${platfdir}/two_hosts_platform_with_availability_included. p Testing trace integration using trace_B.txt and test-hbp1.0-hbp1.0-hbp1.0.xml, three process with same priority ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1.0-hbp1.0-hbp1.0.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1.0-hbp1.0-hbp1.0.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 0.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -168,8 +156,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1.0-hbp3.0-hbp4.0.xml, three process with different priority ! output sort -$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1.0-hbp3.0-hbp4.0.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1.0-hbp3.0-hbp4.0.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 10.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI @@ -188,8 +175,7 @@ $ ./trace-integration ${platfdir}/two_hosts_profiles.xml ${srcdir:=.}/test-hbp1 p Testing trace integration using trace_B.txt and test-hbp1.0-hbp3.0-hbp4.0.xml, three process with different priority (included) ! output sort -$ ./trace-integration ${platfdir}/two_hosts_platform_with_availability_included.xml ${srcdir:=.}/test-hbp1.0-hbp3.0-hbp4.0.xml --cfg=host/model:compound --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'compound' +$ ./trace-integration ${platfdir}/two_hosts_platform_with_availability_included.xml ${srcdir:=.}/test-hbp1.0-hbp3.0-hbp4.0.xml --cfg=network/model:CM02 --cfg=cpu/optim:TI "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" > [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02' > [ 0.000000] (0:maestro@) Configuration change: Set 'cpu/optim' to 'TI' > [ 10.000000] (1:test_trace@Cpu B) Testing the trace integration cpu model: CpuTI diff --git a/teshsuite/s4u/vm-live-migration/vm-live-migration.cpp b/teshsuite/s4u/vm-live-migration/vm-live-migration.cpp index 62570bb606..9b7352304d 100644 --- a/teshsuite/s4u/vm-live-migration/vm-live-migration.cpp +++ b/teshsuite/s4u/vm-live-migration/vm-live-migration.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/s4u/vm-suicide/vm-suicide.cpp b/teshsuite/s4u/vm-suicide/vm-suicide.cpp index 12c0faf876..69cdf8623e 100644 --- a/teshsuite/s4u/vm-suicide/vm-suicide.cpp +++ b/teshsuite/s4u/vm-suicide/vm-suicide.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2021-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2021-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -27,14 +27,14 @@ static void print_status(const std::vector& hosts) { XBT_INFO("---- HOSTS and VMS STATUS ----"); XBT_INFO("--- HOSTS ---"); - for (auto const& host : hosts) { + for (auto const* host : hosts) { XBT_INFO("+ Name:%s Load:%f", host->get_cname(), host->get_load()); for (auto const& actor : host->get_all_actors()) XBT_INFO("++ actor: %s", actor->get_cname()); } XBT_INFO("--- VMS ---"); - for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) { - if (auto vm = dynamic_cast(host)) { + for (auto const* host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) { + if (auto const* vm = dynamic_cast(host)) { XBT_INFO("+ Name:%s Host:%s Load:%f State: %s", vm->get_cname(), vm->get_pm()->get_cname(), vm->get_load(), simgrid::s4u::VirtualMachine::to_c_str(vm->get_state())); for (auto const& actor : host->get_all_actors()) diff --git a/teshsuite/s4u/wait-all-for/wait-all-for.cpp b/teshsuite/s4u/wait-all-for/wait-all-for.cpp deleted file mode 100644 index 371936a2a0..0000000000 --- a/teshsuite/s4u/wait-all-for/wait-all-for.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include -#include - -XBT_LOG_NEW_DEFAULT_CATEGORY(meh, "meh"); - -static void worker() -{ - auto mbox = simgrid::s4u::Mailbox::by_name("meh"); - int input1 = 42; - int input2 = 51; - - XBT_INFO("Sending and receiving %d and %d asynchronously", input1, input2); - - auto put1 = mbox->put_async(&input1, 1000 * 1000 * 500); - auto put2 = mbox->put_async(&input2, 1000 * 1000 * 1000); - - int* out1; - auto get1 = mbox->get_async(&out1); - - int* out2; - auto get2 = mbox->get_async(&out2); - - XBT_INFO("All comms have started"); - std::vector comms = {put1, put2, get1, get2}; - - while (not comms.empty()) { - size_t index = simgrid::s4u::Comm::wait_all_for(comms, 0.5); - if (index < comms.size()) - XBT_INFO("wait_all_for: Timeout reached"); - XBT_INFO("wait_all_for: %zu comms finished (#comms=%zu)", index, comms.size()); - comms.erase(comms.begin(), comms.begin() + index); - } - - XBT_INFO("All comms have finished"); - XBT_INFO("Got %d and %d", *out1, *out2); -} - -int main(int argc, char* argv[]) - -{ - simgrid::s4u::Engine e(&argc, argv); - e.load_platform(argv[1]); - simgrid::s4u::Actor::create("worker", e.host_by_name("Tremblay"), worker); - e.run(); - return 0; -} diff --git a/teshsuite/s4u/wait-all-for/wait-all-for.tesh b/teshsuite/s4u/wait-all-for/wait-all-for.tesh deleted file mode 100644 index c7b30a9f9a..0000000000 --- a/teshsuite/s4u/wait-all-for/wait-all-for.tesh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env tesh - -p Testing the wait_all_for feature of S4U - -! output sort 19 -$ ${bindir:=.}/wait-all-for ${platfdir:=.}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (1:worker@Tremblay) Sending and receiving 42 and 51 asynchronously -> [ 0.000000] (1:worker@Tremblay) All comms have started -> [ 0.500000] (1:worker@Tremblay) wait_all_for: Timeout reached -> [ 0.500000] (1:worker@Tremblay) wait_all_for: 0 comms finished (#comms=4) -> [ 1.000000] (1:worker@Tremblay) wait_all_for: Timeout reached -> [ 1.000000] (1:worker@Tremblay) wait_all_for: 0 comms finished (#comms=4) -> [ 1.500000] (1:worker@Tremblay) wait_all_for: Timeout reached -> [ 1.500000] (1:worker@Tremblay) wait_all_for: 1 comms finished (#comms=4) -> [ 2.000000] (1:worker@Tremblay) wait_all_for: Timeout reached -> [ 2.000000] (1:worker@Tremblay) wait_all_for: 0 comms finished (#comms=3) -> [ 2.070331] (1:worker@Tremblay) wait_all_for: 3 comms finished (#comms=3) -> [ 2.070331] (1:worker@Tremblay) All comms have finished -> [ 2.070331] (1:worker@Tremblay) Got 42 and 51 diff --git a/teshsuite/s4u/wait-any-for/wait-any-for.cpp b/teshsuite/s4u/wait-any-for/wait-any-for.cpp deleted file mode 100644 index 5190d4a29a..0000000000 --- a/teshsuite/s4u/wait-any-for/wait-any-for.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include -#include -#include -#include - -XBT_LOG_NEW_DEFAULT_CATEGORY(meh, "meh"); - -static void worker() -{ - auto mbox = simgrid::s4u::Mailbox::by_name("meh"); - int input1 = 42; - int input2 = 51; - - XBT_INFO("Sending and receiving %d and %d asynchronously", input1, input2); - - auto put1 = mbox->put_async(&input1, 1000 * 1000 * 500); - auto put2 = mbox->put_async(&input2, 1000 * 1000 * 1000); - - int* out1; - auto get1 = mbox->get_async(&out1); - - int* out2; - auto get2 = mbox->get_async(&out2); - - XBT_INFO("All comms have started"); - std::vector comms = {put1, put2, get1, get2}; - - while (not comms.empty()) { - ssize_t index = simgrid::s4u::Comm::wait_any_for(comms, 0.5); - if (index < 0) - XBT_INFO("wait_any_for: Timeout reached"); - else { - XBT_INFO("wait_any_for: A comm finished (index=%zd, #comms=%zu)", index, comms.size()); - comms.erase(comms.begin() + index); - } - } - - XBT_INFO("All comms have finished"); - XBT_INFO("Got %d and %d", *out1, *out2); -} - -int main(int argc, char* argv[]) - -{ - simgrid::s4u::Engine e(&argc, argv); - e.load_platform(argv[1]); - simgrid::s4u::Actor::create("worker", e.host_by_name("Tremblay"), worker); - e.run(); - return 0; -} diff --git a/teshsuite/s4u/wait-any-for/wait-any-for.tesh b/teshsuite/s4u/wait-any-for/wait-any-for.tesh deleted file mode 100644 index 87ae347dce..0000000000 --- a/teshsuite/s4u/wait-any-for/wait-any-for.tesh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env tesh - -p Testing the wait_any_for feature of S4U - -! output sort 19 -$ ${bindir:=.}/wait-any-for ${platfdir:=.}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" -> [ 0.000000] (1:worker@Tremblay) Sending and receiving 42 and 51 asynchronously -> [ 0.000000] (1:worker@Tremblay) All comms have started -> [ 0.500000] (1:worker@Tremblay) wait_any_for: Timeout reached -> [ 1.000000] (1:worker@Tremblay) wait_any_for: Timeout reached -> [ 1.035263] (1:worker@Tremblay) wait_any_for: A comm finished (index=0, #comms=4) -> [ 1.035263] (1:worker@Tremblay) wait_any_for: A comm finished (index=1, #comms=3) -> [ 1.535263] (1:worker@Tremblay) wait_any_for: Timeout reached -> [ 2.035263] (1:worker@Tremblay) wait_any_for: Timeout reached -> [ 2.070331] (1:worker@Tremblay) wait_any_for: A comm finished (index=0, #comms=2) -> [ 2.070331] (1:worker@Tremblay) wait_any_for: A comm finished (index=0, #comms=1) -> [ 2.070331] (1:worker@Tremblay) All comms have finished -> [ 2.070331] (1:worker@Tremblay) Got 42 and 51 diff --git a/teshsuite/smpi/CMakeLists.txt b/teshsuite/smpi/CMakeLists.txt index 0b5bab84da..25b8ce35f8 100644 --- a/teshsuite/smpi/CMakeLists.txt +++ b/teshsuite/smpi/CMakeLists.txt @@ -1,9 +1,5 @@ if(enable_smpi) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - endif() + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") foreach(x coll-allgather coll-allgatherv coll-allreduce coll-allreduce-with-leaks coll-alltoall coll-alltoallv coll-barrier coll-bcast @@ -16,14 +12,12 @@ if(enable_smpi) add_dependencies(tests ${x}) endforeach() - if(NOT WIN32) - foreach(x macro-shared auto-shared macro-partial-shared macro-partial-shared-communication ) - add_executable (${x} EXCLUDE_FROM_ALL ${x}/${x}.c) - target_link_libraries(${x} simgrid) - set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x}) - add_dependencies(tests ${x}) - endforeach() - endif() + foreach(x macro-shared auto-shared macro-partial-shared macro-partial-shared-communication ) + add_executable (${x} EXCLUDE_FROM_ALL ${x}/${x}.c) + target_link_libraries(${x} simgrid) + set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x}) + add_dependencies(tests ${x}) + endforeach() if(enable_smpi AND SMPI_FORTRAN) set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") @@ -50,7 +44,6 @@ set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/coll-allreduce/c ${CMAKE_CURRENT_SOURCE_DIR}/coll-allreduce/coll-allreduce-papi.tesh ${CMAKE_CURRENT_SOURCE_DIR}/coll-allreduce-with-leaks/mc-coll-allreduce-with-leaks.tesh ${CMAKE_CURRENT_SOURCE_DIR}/coll-alltoall/clusters.tesh - ${CMAKE_CURRENT_SOURCE_DIR}/coll-alltoall/griffon.tesh ${CMAKE_CURRENT_SOURCE_DIR}/pt2pt-pingpong/broken_hostfiles.tesh ${CMAKE_CURRENT_SOURCE_DIR}/pt2pt-pingpong/TI_output.tesh ${CMAKE_CURRENT_SOURCE_DIR}/fort_args/fort_args.tesh PARENT_SCOPE) @@ -64,12 +57,12 @@ set(bin_files ${bin_files} ${CMAKE_CURRENT_SOURCE_DIR}/hostfile if(enable_smpi) - if(NOT WIN32) - ADD_TESH_FACTORIES(tesh-smpi-macro-shared "*" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-shared --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-shared ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/macro-shared/macro-shared.tesh) - ADD_TESH_FACTORIES(tesh-smpi-auto-shared "*" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/auto-shared --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/auto-shared ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/auto-shared/auto-shared.tesh) - ADD_TESH_FACTORIES(tesh-smpi-macro-partial-shared "*" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-partial-shared --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-partial-shared ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/macro-partial-shared/macro-partial-shared.tesh) - ADD_TESH_FACTORIES(tesh-smpi-macro-partial-shared-communication "*" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-partial-shared-communication --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-partial-shared-communication ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/macro-partial-shared-communication/macro-partial-shared-communication.tesh) - endif() + ADD_TEST(test-smpi-help-coll ${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -wrapper "${VALGRIND_WRAPPER_NO_LEAK_CHECK}" --help-coll) + + ADD_TESH_FACTORIES(tesh-smpi-macro-shared "*" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-shared --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-shared ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/macro-shared/macro-shared.tesh) + ADD_TESH_FACTORIES(tesh-smpi-auto-shared "*" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/auto-shared --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/auto-shared ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/auto-shared/auto-shared.tesh) + ADD_TESH_FACTORIES(tesh-smpi-macro-partial-shared "*" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-partial-shared --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-partial-shared ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/macro-partial-shared/macro-partial-shared.tesh) + ADD_TESH_FACTORIES(tesh-smpi-macro-partial-shared-communication "*" --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-partial-shared-communication --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/macro-partial-shared-communication ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/macro-partial-shared-communication/macro-partial-shared-communication.tesh) foreach(x coll-allgather coll-allgatherv coll-allreduce coll-alltoall coll-alltoallv coll-barrier coll-bcast coll-gather coll-reduce coll-reduce-scatter coll-scatter macro-sample pt2pt-dsend pt2pt-pingpong @@ -150,7 +143,7 @@ if(enable_smpi) if (NOT HAVE_SANITIZER_ADDRESS) ADD_TESH(tesh-smpi-coll-allreduce-with-leaks --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/coll-allreduce-with-leaks --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/coll-allreduce-with-leaks ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/coll-allreduce-with-leaks/coll-allreduce-with-leaks.tesh) set_target_properties(coll-allreduce-with-leaks PROPERTIES COMPILE_FLAGS "-trace-call-location") - if(enable_model-checking) + if(SIMGRID_HAVE_MC) add_dependencies(tests-mc coll-allreduce-with-leaks) ADD_TESH(tesh-mc-smpi-coll-allreduce-with-leaks --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/smpi/coll-allreduce-with-leaks --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi/coll-allreduce-with-leaks ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/coll-allreduce-with-leaks/mc-coll-allreduce-with-leaks.tesh) endif() diff --git a/teshsuite/smpi/MBI/CMakeLists.txt b/teshsuite/smpi/MBI/CMakeLists.txt index 06cec65c1e..9ea75baf7d 100644 --- a/teshsuite/smpi/MBI/CMakeLists.txt +++ b/teshsuite/smpi/MBI/CMakeLists.txt @@ -1,42 +1,18 @@ -# Copyright 2021-2022. The SimGrid Team. All rights reserved. +# Copyright 2021-2023. The SimGrid Team. All rights reserved. # Integrates the MBI tests into the SimGrid build chain when asked to # Only the python scripts are embeeded in the archive, and the C test files are generated at config time using these scripts. # These python scripts are copied over from the MBI repository with as little changes as possible. -set(generator_scripts - CollArgGenerator.py - CollComGenerator.py - CollLocalConcurrencyGenerator.py - CollMatchingGenerator.py - CollP2PMatchingGenerator.py - CollP2PMessageRaceGenerator.py - CollTopoGenerator.py - MissingWaitandStartGenerator.py - P2PArgGenerator.py - P2PComGenerator.py - P2PInvalidComGenerator.py - P2PLocalConcurrencyGenerator.py - P2PMatchingANYSRCGenerator.py - P2PMatchingGenerator.py - P2PProbeGenerator.py - ResleakGenerator.py - RMAArgGenerator.py - RMAInvalidArgGenerator.py - RMALocalLocalConcurrencyGenerator.py - RMAP2PGlobalConcurrencyGenerator.py - RMARemoteLocalConcurrencyGenerator.py - RMARemoteRemoteConcurrencyGenerator.py - RMAReqLifecycleGenerator.py - RMAWinBufferGenerator.py) +file(GLOB generator_scripts *Generator.py) -if (enable_smpi_MBI_testsuite) +if (enable_testsuite_smpi_MBI) if (NOT enable_smpi) - message(FATAL_ERROR "MBI test suite cannot be enabled without SMPI. Please change either setting.") + message(FATAL_ERROR "The MBI test suite cannot be enabled without SMPI. Please change either setting.") endif() - if (NOT enable_model-checking) - message(FATAL_ERROR "MBI test suite cannot be enabled without the Mc SimGrid model-checker. Please change either setting.") + if (NOT SIMGRID_HAVE_MC) + message(FATAL_ERROR "The MBI test suite cannot be enabled without the model-checker. Please change either setting.") endif() message(STATUS "Generating the MBI test cases") @@ -45,7 +21,7 @@ if (enable_smpi_MBI_testsuite) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/generator_utils.py DESTINATION ${CMAKE_BINARY_DIR}/MBI/tmp) foreach (script ${generator_scripts}) message(STATUS " $ ${CMAKE_CURRENT_SOURCE_DIR}/${script}") - execute_process(COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${script} + execute_process(COMMAND ${PYTHON_EXECUTABLE} ${script} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/MBI/tmp RESULT_VARIABLE status) if (NOT status EQUAL 0) @@ -60,6 +36,19 @@ if (enable_smpi_MBI_testsuite) # Connect the MBI tests to the other tests add_custom_target(tests-mbi COMMENT "Recompiling the MBI tests and tools.") add_dependencies(tests tests-mbi) + add_dependencies(tests-mbi simgrid-mc smpimain) + + # Remove Concurrency tests that are out of reach because SimGrid does not intercept local modifications yet + # An idea could be to use ASan on the verified application, along with https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning + # But currently, ASan is not usable at all, since the Checker dislikes this trick when it tries to read the memory of the app. + # We should change the checker to not read the app when verifying safty properties + file(GLOB cfiles ${CMAKE_BINARY_DIR}/MBI/tmp/LocalConcurrency*.c ${CMAKE_BINARY_DIR}/MBI/tmp/GlobalConcurrency*.c ) + foreach(cfile ${cfiles}) + file(REMOVE ${cfile}) + endforeach() + list(LENGTH cfiles len) + message(STATUS "Removed ${len} concurrency tests that would fail because we cannot intercept modifications of local variables.") + unset(len) file(GLOB cfiles RELATIVE ${CMAKE_BINARY_DIR}/MBI/tmp ${CMAKE_BINARY_DIR}/MBI/tmp/*.c ) foreach(cfile ${cfiles}) @@ -75,6 +64,7 @@ if (enable_smpi_MBI_testsuite) add_executable(mbi_${basefile} EXCLUDE_FROM_ALL ${CMAKE_BINARY_DIR}/MBI/${cfile}) target_link_libraries(mbi_${basefile} simgrid) target_compile_options(mbi_${basefile} PRIVATE "-Wno-unused-variable") + target_compile_options(mbi_${basefile} PRIVATE "-Wno-unused-but-set-variable") set_target_properties(mbi_${basefile} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/MBI) add_dependencies(tests-mbi mbi_${basefile}) @@ -91,33 +81,11 @@ if (enable_smpi_MBI_testsuite) else() file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/MBIutils.py DESTINATION ${CMAKE_BINARY_DIR}/MBI) endif() - - # The following tests are known to fail because simgrid does not intercept local modifications yet - # An idea could be to use ASan on the verified application, along with https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning - # But currently, ASan is not usable at all, since the Checker dislikes this trick when it tries to read the memory of the app. - # We should change the checker to not read the app when verifying safty properties - foreach(localmodif - LocalConcurrency_Iallgather_nok LocalConcurrency_Iallgatherv_nok LocalConcurrency_Iallreduce_nok LocalConcurrency_Ialltoall_nok - LocalConcurrency_Ialltoallv_nok LocalConcurrency_Ibcast_nok LocalConcurrency_Iexscan_nok LocalConcurrency_Igather_nok - LocalConcurrency_Irecv_Isend_nok LocalConcurrency_Irecv_Send_init_nok LocalConcurrency_Irecv_Send_nok LocalConcurrency_Ireduce_nok - LocalConcurrency_Iscan_nok LocalConcurrency_Iscatter_nok LocalConcurrency_Recv_Isend_nok LocalConcurrency_Recv_Send_init_nok - LocalConcurrency_Recv_init_Isend_nok LocalConcurrency_Recv_init_Send_nok LocalConcurrency_Recv_init_Send_init_nok - - GlobalConcurrency_Get_Isend_Irecv_nok GlobalConcurrency_Get_Isend_Recv_nok GlobalConcurrency_Get_Send_Irecv_nok GlobalConcurrency_Get_Send_Recv_nok - GlobalConcurrency_Put_Isend_Irecv_nok GlobalConcurrency_Put_Isend_Recv_nok GlobalConcurrency_Put_Send_Irecv_nok GlobalConcurrency_Put_Send_Recv_nok - - GlobalConcurrency_rl_Win_fence_Get_rload_nok GlobalConcurrency_rl_Win_fence_Get_rstore_nok - GlobalConcurrency_rl_Win_fence_Put_rload_nok GlobalConcurrency_rl_Win_fence_Put_rstore_nok - GlobalConcurrency_rl_Win_lock_all_Get_rload_nok GlobalConcurrency_rl_Win_lock_all_Get_rstore_nok - GlobalConcurrency_rl_Win_lock_all_Put_rload_nok GlobalConcurrency_rl_Win_lock_all_Put_rstore_nok - ) - set_tests_properties(mbi-${localmodif} PROPERTIES WILL_FAIL true) - endforeach(localmodif ) endif() # Add the needed files to the distribution foreach(script ${generator_scripts}) - set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/${script}) + set(teshsuite_src ${teshsuite_src} ${script}) endforeach() set(teshsuite_src ${teshsuite_src} diff --git a/teshsuite/smpi/MBI/CollArgGenerator.py b/teshsuite/smpi/MBI/CollArgGenerator.py index 42a655db37..e269309bdf 100755 --- a/teshsuite/smpi/MBI/CollArgGenerator.py +++ b/teshsuite/smpi/MBI/CollArgGenerator.py @@ -42,7 +42,7 @@ int main(int argc, char **argv) { int rank = -1; int root = 0; int size = 1; - int j = 0; + int j=0; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); @@ -195,7 +195,7 @@ for c in gen.coll4op + gen.icoll4op: patterns = {} patterns = {'c': c} patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' - patterns['collfeature'] = 'Yes' if c in gen.coll4op else 'Lacking' + patterns['collfeature'] = 'Yes' if c in gen.coll4op else 'Lacking' patterns['icollfeature'] = 'Yes' if c in gen.icoll4op else 'Lacking' patterns['toolfeature'] = 'Lacking' patterns['c'] = c diff --git a/teshsuite/smpi/MBI/CollP2PMatchingGenerator.py b/teshsuite/smpi/MBI/CollP2PMatchingGenerator.py index 6a184f1fc1..edf030576f 100755 --- a/teshsuite/smpi/MBI/CollP2PMatchingGenerator.py +++ b/teshsuite/smpi/MBI/CollP2PMatchingGenerator.py @@ -124,10 +124,10 @@ for s in gen.send + gen.isend: # replace['longdesc'] = 'Point to point @{s}@ is matched with @{c}@ which causes a deadlock depending on the buffering mode.' # replace['outcome'] = 'ERROR: BufferingHazard' # replace['errormsg'] = 'P2P & Collective mistmatch. @{s}@ at @{filename}@:@{line:MBIERROR2}@ is matched with @{c}@ at @{filename}@:@{line:MBIERROR1}@ wich causes a deadlock.' - # replace['init1'] = init[s]("1") - # replace['init2'] = init[r]("2") - # replace['operation1'] = operation[r]("2") - # replace['operation2'] = operation[s]("1") - # replace['fini1'] = fini[r]("2") - # replace['fini2'] = fini[s]("1") + # replace['init1'] = gen.init[s]("1") + # replace['init2'] = gen.init[r]("2") + # replace['operation1'] = gen.operation[r]("2") + # replace['operation2'] = gen.operation[s]("1") + # replace['fini1'] = gen.fini[r]("2") + # replace['fini2'] = gen.fini[s]("1") # gen.make_file(template, f'CollP2PBuffering_{r}_{s}_{c}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/CollP2PMessageRaceGenerator.py b/teshsuite/smpi/MBI/CollP2PMessageRaceGenerator.py index 2c3233b442..4ca22b9d0d 100755 --- a/teshsuite/smpi/MBI/CollP2PMessageRaceGenerator.py +++ b/teshsuite/smpi/MBI/CollP2PMessageRaceGenerator.py @@ -40,6 +40,7 @@ int main(int argc, char **argv) { int nprocs = -1; int rank = -1; int dest, src; + int i=0; int root = 0; int stag = 0, rtag = 0; int buff_size = 1; @@ -80,7 +81,7 @@ int main(int argc, char **argv) { @{operation3}@ /* MBIERROR1 */ @{operation1}@ @{fini1}@ - src = 0; + @{changesrc}@ @{operation4}@ /* MBIERROR2 */ @{fini3}@ @{fini4}@ @@ -129,6 +130,16 @@ for s in gen.send + gen.isend: patterns['operation2'] = gen.operation[s]("2") patterns['operation3'] = gen.operation[r]("3") patterns['operation4'] = gen.operation[r]("4") + patterns['changesrc'] = '' + + # Generate the correct matching because of the conditional + replace = patterns.copy() + replace['shortdesc'] = 'Message race' + replace['longdesc'] = 'Message race without problem in @{r}@ with @{c}@.' + replace['outcome'] = 'OK' + replace['errormsg'] = 'OK' + replace['changesrc'] = '' + gen.make_file(template, f'MessageRace_{c}_{s}_{r}_ok.c', replace) # Generate the incorrect matching because of the conditional replace = patterns.copy() @@ -136,4 +147,5 @@ for s in gen.send + gen.isend: replace['longdesc'] = 'Message race in @{r}@ with @{c}@.' replace['outcome'] = 'ERROR: MessageRace' replace['errormsg'] = 'Message race. The use of wildcard receive calls (@{r}@ at @{filename}@:@{line:MBIERROR1}@ and @{r}@ at @{filename}@:@{line:MBIERROR2}@) leads to nondeterministic matching.' + replace['changesrc'] = 'src = 0;' gen.make_file(template, f'MessageRace_{c}_{s}_{r}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/InputHazardGenerator.py b/teshsuite/smpi/MBI/InputHazardGenerator.py new file mode 100755 index 0000000000..d9f8a5141c --- /dev/null +++ b/teshsuite/smpi/MBI/InputHazardGenerator.py @@ -0,0 +1,196 @@ +#! /usr/bin/python3 +import os +import sys +import generator_utils as gen + +template = """// @{generatedby}@ +/* ///////////////////////// The MPI Bugs Initiative //////////////////////// + + Origin: MBI + + Description: @{shortdesc}@ + @{longdesc}@ + + Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation + +BEGIN_MPI_FEATURES + P2P!basic: @{p2pfeature}@ + P2P!nonblocking: @{ip2pfeature}@ + P2P!persistent: Lacking + COLL!basic: @{collfeature}@ + COLL!nonblocking: @{icollfeature}@ + COLL!persistent: Lacking + COLL!tools: Lacking + RMA: Lacking +END_MPI_FEATURES + +BEGIN_MBI_TESTS + $ mpirun -np 2 ${EXE} 1 + | @{outcome1}@ + | @{errormsg1}@ + $ mpirun -np 2 ${EXE} 2 + | @{outcome2}@ + | @{errormsg2}@ +END_MBI_TESTS +////////////////////// End of MBI headers /////////////////// */ + +#include +#include +#include + +#define N 10 + +int main(int argc, char **argv) { + int nprocs = -1; + int rank = -1; + MPI_Status sta; + int i=0; + int root = 0; + int stag=0; + int rtag=0; + int buff_size = N; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + printf("Hello from rank %d \\n", rank); + + if (nprocs < 2) + printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n"); + + if (argc < 2) + printf("MBI ERROR: This test needs at least 1 argument to produce a bug!\\n"); + + int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */ + MPI_Comm newcom = MPI_COMM_WORLD; + MPI_Datatype type = MPI_INT; + MPI_Op op = MPI_SUM; + + int n = atoi(argv[1]); + int buffer[N] = {42}; + + @{init1}@ + @{init2}@ + + if (rank == 0) { + if ((n % 2) == 0) { @{errorcond}@ + @{operation1b}@ + @{fini1b}@ + } else { + @{operation1a}@ + @{fini1a}@ + } + } else @{addcond}@ { + @{operation2}@ + @{fini2}@ + } + + @{free1}@ + @{free2}@ + + MPI_Finalize(); + + printf("Rank %d finished normally\\n", rank); + return 0; +} +""" + +# P2P +for s in gen.send + gen.isend: + for r in gen.recv + gen.irecv: + patterns = {} + patterns = {'s': s, 'r': r} + patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' + patterns['p2pfeature'] = 'Yes' if s in gen.send or r in gen.recv else 'Lacking' + patterns['ip2pfeature'] = 'Yes' if s in gen.isend or r in gen.irecv else 'Lacking' + patterns['collfeature'] = 'Lacking' + patterns['icollfeature'] = 'Lacking' + patterns['s'] = s + patterns['r'] = r + + patterns['init1'] = gen.init[s]("1") + patterns['operation1a'] = gen.operation[s]("1").replace("buf1", "buffer").replace("dest", "1") + patterns['operation1b'] = gen.operation[s]("1").replace("buf1", "buffer").replace("dest", "1") + patterns['fini1a'] = gen.fini[s]("1") + patterns['fini1b'] = gen.fini[s]("1") + patterns['free1'] = gen.free[s]("1") + + patterns['init2'] = gen.init[r]("2") + patterns['operation2'] = gen.operation[r]("2").replace("buf2", "buffer").replace("src", "0") + patterns['fini2'] = gen.fini[r]("2") + patterns['free2'] = gen.free[r]("2") + + patterns['errorcond'] = '' + patterns['addcond'] = 'if (rank == 1)' + + # Generate a correct matching + replace = patterns.copy() + replace['shortdesc'] = 'Correct call ordering.' + replace['longdesc'] = 'Correct call ordering.' + replace['outcome1'] = 'OK' + replace['errormsg1'] = 'OK' + replace['outcome2'] = 'OK' + replace['errormsg2'] = 'OK' + gen.make_file(template, f'InputHazardCallOrdering_{r}_{s}_ok.c', replace) + + # Generate the incorrect matching + replace = patterns.copy() + replace['shortdesc'] = 'Missing Send function.' + replace['longdesc'] = 'Missing Send function call for a path depending to input, a deadlock is created.' + replace['outcome1'] = 'OK' + replace['errormsg1'] = 'OK' + replace['outcome2'] = 'ERROR: IHCallMatching' + replace['errormsg2'] = 'P2P mistmatch. Missing @{r}@ at @{filename}@:@{line:MBIERROR}@.' + replace['errorcond'] = '/* MBIERROR */' + replace['operation1b'] = '' + replace['fini1b'] = '' + gen.make_file(template, f'InputHazardCallOrdering_{r}_{s}_nok.c', replace) + +# COLLECTIVE +for c in gen.coll: + patterns = {} + patterns = {'c': c} + patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' + patterns['p2pfeature'] = 'Lacking' + patterns['ip2pfeature'] = 'Lacking' + patterns['collfeature'] = 'Yes' if c in gen.coll else 'Lacking' + patterns['icollfeature'] = 'Yes' if c in gen.icoll else 'Lacking' + patterns['c'] = c + + patterns['init1'] = gen.init[c]("1") + patterns['operation1a'] = gen.operation[c]("1") + patterns['operation1b'] = gen.operation[c]("1") + patterns['fini1a'] = gen.fini[c]("1") + patterns['fini1b'] = gen.fini[c]("1") + patterns['free1'] = gen.free[c]("1") + + patterns['init2'] = gen.init[c]("2") + patterns['operation2'] = gen.operation[c]("2") + patterns['fini2'] = gen.fini[c]("2") + patterns['free2'] = gen.free[c]("2") + + patterns['errorcond'] = '' + patterns['addcond'] = '' + + # Generate a correct matching + replace = patterns.copy() + replace['shortdesc'] = 'Correct call ordering.' + replace['longdesc'] = 'Correct call ordering.' + replace['outcome1'] = 'OK' + replace['errormsg1'] = 'OK' + replace['outcome2'] = 'OK' + replace['errormsg2'] = 'OK' + gen.make_file(template, f'InputHazardCallOrdering_{c}_ok.c', replace) + + # Generate the incorrect matching + replace = patterns.copy() + replace['shortdesc'] = 'Missing collective function call.' + replace['longdesc'] = 'Missing collective function call for a path depending to input, a deadlock is created.' + replace['outcome1'] = 'OK' + replace['errormsg1'] = 'OK' + replace['outcome2'] = 'ERROR: IHCallMatching' + replace['errormsg2'] = 'P2P mistmatch. Missing @{c}@ at @{filename}@:@{line:MBIERROR}@.' + replace['errorcond'] = '/* MBIERROR */' + replace['operation1b'] = '' + replace['fini1b'] = '' + gen.make_file(template, f'InputHazardCallOrdering_{c}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/MBI.py b/teshsuite/smpi/MBI/MBI.py index 9e2f904370..6484a0b545 100755 --- a/teshsuite/smpi/MBI/MBI.py +++ b/teshsuite/smpi/MBI/MBI.py @@ -1,6 +1,6 @@ #! /usr/bin/env python3 -# Copyright 2021-2022. The SimGrid Team. All rights reserved. +# Copyright 2021-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -30,7 +30,7 @@ simgrid = sg.Tool() (name, path, binary, filename) = sys.argv for test in mbi.parse_one_code(filename): - execcmd = test['cmd'].replace("mpirun", f"{path}/smpi_script/bin/smpirun -wrapper '{path}/bin/simgrid-mc --log=mc_safety.t:info' -platform ./cluster.xml -analyze --cfg=smpi/finalization-barrier:on --cfg=smpi/list-leaks:10 --cfg=model-check/max-depth:10000") + execcmd = test['cmd'].replace("mpirun", f"{path}/smpi_script/bin/smpirun -wrapper '{path}/bin/simgrid-mc --cfg=model-check/reduction:odpor --log=mc_safety.t:info' -platform ./cluster.xml -analyze --cfg=smpi/barrier-finalization:on --cfg=smpi/list-leaks:10 --cfg=model-check/max-depth:10000") execcmd = execcmd.replace('${EXE}', binary) execcmd = execcmd.replace('$zero_buffer', "--cfg=smpi/buffering:zero") execcmd = execcmd.replace('$infty_buffer', "--cfg=smpi/buffering:infty") @@ -43,5 +43,5 @@ for test in mbi.parse_one_code(filename): if res_category != "TRUE_NEG" and res_category != "TRUE_POS": print("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n") - print(f"SimGrid gave the wrong result ({outcome} instead of {test['expect']}).") + print(f"SimGrid gave the wrong result on {binary} ({outcome} instead of {test['detail']}).\nExpected diagnostic: {test['diagnostic']}") sys.exit(1) diff --git a/teshsuite/smpi/MBI/MBIutils.py b/teshsuite/smpi/MBI/MBIutils.py index 9eedad5240..9a7d837293 100644 --- a/teshsuite/smpi/MBI/MBIutils.py +++ b/teshsuite/smpi/MBI/MBIutils.py @@ -57,6 +57,7 @@ possible_details = { # 'OutOfInitFini':'BInitFini', 'CommunicatorLeak':'BResLeak', 'DatatypeLeak':'BResLeak', 'GroupLeak':'BResLeak', 'OperatorLeak':'BResLeak', 'TypeLeak':'BResLeak', 'RequestLeak':'BResLeak', 'MissingStart':'BReqLifecycle', 'MissingWait':'BReqLifecycle', + 'MissingEpoch':'BEpochLifecycle','DoubleEpoch':'BEpochLifecycle', 'LocalConcurrency':'BLocalConcurrency', # scope: communicator 'CallMatching':'DMatch', @@ -66,6 +67,9 @@ possible_details = { 'GlobalConcurrency':'DGlobalConcurrency', # larger scope 'BufferingHazard':'EBufferingHazard', + # Input Hazard + 'IHCallMatching':'InputHazard', + 'OK':'FOK'} error_scope = { @@ -73,6 +77,7 @@ error_scope = { 'BResLeak':'single process', # 'BInitFini':'single process', 'BReqLifecycle':'single process', + 'BEpochLifecycle':'single process', 'BLocalConcurrency':'single process', 'CMatch':'multi-processes', 'DRace':'multi-processes', @@ -136,7 +141,14 @@ def parse_one_code(filename): if detail not in possible_details: raise ValueError( f"\n{filename}:{line_num}: MBI parse error: Detailled outcome {detail} is not one of the allowed ones.") - test = {'filename': filename, 'id': test_num, 'cmd': cmd, 'expect': expect, 'detail': detail} + + nextline = next(input_file) + m = re.match('[ |]*(.*)', nextline) + if not m: + raise ValueError(f"\n{filename}:{line_num}: MBI parse error: Expected diagnostic of the test not found.\n") + diagnostic = m.group(1) + + test = {'filename': filename, 'id': test_num, 'cmd': cmd, 'expect': expect, 'detail': detail, 'diagnostic': diagnostic} res.append(test.copy()) test_num += 1 line_num += 1 diff --git a/teshsuite/smpi/MBI/P2PBufferingGenerator.py b/teshsuite/smpi/MBI/P2PBufferingGenerator.py new file mode 100755 index 0000000000..663a548a32 --- /dev/null +++ b/teshsuite/smpi/MBI/P2PBufferingGenerator.py @@ -0,0 +1,205 @@ +#! /usr/bin/python3 + +import os +import sys +import generator_utils as gen + +template = """// @{generatedby}@ +/* ///////////////////////// The MPI Bugs Initiative //////////////////////// + + Origin: @{origin}@ + + Description: @{shortdesc}@ + @{longdesc}@ + +BEGIN_MPI_FEATURES + P2P!basic: @{p2pfeature}@ + P2P!nonblocking: @{ip2pfeature}@ + P2P!persistent: Lacking + COLL!basic: Lacking + COLL!nonblocking: Lacking + COLL!persistent: Lacking + COLL!tools: Lacking + RMA: Lacking +END_MPI_FEATURES + +BEGIN_MBI_TESTS + $ mpirun -np 4 $zero_buffer ${EXE} + | @{outcome_zerob}@ + | @{errormsg_zerob}@ + $ mpirun -np 4 $infty_buffer ${EXE} + | @{outcome_infty}@ + | @{errormsg_infty}@ +END_MBI_TESTS +////////////////////// End of MBI headers /////////////////// */ + +#include +#include +#include + + +int main(int argc, char **argv) { + int nprocs = -1; + int rank = -1; + int dest, src; + int stag = 0, rtag = 0; + int buff_size = 1; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + printf("Hello from rank %d \\n", rank); + + if (nprocs < 4) + printf("MBI ERROR: This test needs at least 4 processes to produce a bug!\\n"); + + MPI_Comm newcom = MPI_COMM_WORLD; + MPI_Datatype type = MPI_INT; + + @{init1}@ + @{init2}@ + if (rank == 0) { + src=@{src1}@,dest=@{dest1}@; + @{operation1a}@ /* MBIERROR1 */ + @{fini1a}@ + @{operation2a}@ + @{fini2a}@ + }else if (rank == 1) { + src=@{src2}@,dest=@{dest2}@; + @{operation1b}@ /* MBIERROR2 */ + @{fini1b}@ + @{operation2b}@ + @{fini2b}@ + }else{ + src=@{src3}@,dest=@{dest3}@; + @{operation1c}@ + @{fini1c}@ + @{operation2c}@ + @{fini2c}@ + } + @{free1}@ + @{free2}@ + + MPI_Finalize(); + printf("Rank %d finished normally\\n", rank); + return 0; +} +""" + +for s in gen.send + gen.isend: + for r in gen.recv + gen.irecv: + patterns = {} + patterns = {'s': s, 'r': r} + patterns['origin'] = 'MBI' + patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' + patterns['p2pfeature'] = 'Yes' if s in gen.send or r in gen.recv else 'Lacking' + patterns['ip2pfeature'] = 'Yes' if s in gen.isend or r in gen.irecv else 'Lacking' + patterns['s'] = s + patterns['r'] = r + patterns['src1'] = '1' + patterns['dest1'] = '1' + patterns['src2'] = '0' + patterns['dest2'] = '0' + patterns['src3'] = '0' + patterns['dest3'] = '0' + patterns['init1'] = gen.init[s]("1") + patterns['init2'] = gen.init[r]("2") + patterns['fini1a'] = gen.fini[s]("1") + patterns['fini1b'] = gen.fini[s]("1") + patterns['fini1c'] = '' + patterns['fini2a'] = gen.fini[r]("2") + patterns['fini2b'] = gen.fini[r]("2") + patterns['fini2c'] = '' + patterns['free1'] = gen.free[s]("1") + patterns['free2'] = gen.free[r]("2") + patterns['operation1a'] = gen.operation[s]("1") + patterns['operation2a'] = gen.operation[r]("2") + patterns['operation1b'] = gen.operation[s]("1") + patterns['operation2b'] = gen.operation[r]("2") + patterns['operation1c'] = '' + patterns['operation2c'] = '' + + # Generate the incorrect matching depending on the buffering mode (send + recv) + replace = patterns.copy() + replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ may not be matched' + replace['longdesc'] = 'Processes 0 and 1 both call @{s}@ and @{r}@. This results in a deadlock depending on the buffering mode' + replace['outcome_zerob'] = 'ERROR: BufferingHazard' + replace['errormsg_zerob'] = f'Buffering Hazard. Possible deadlock depending the buffer size of MPI implementation and system environment cause by two processes call {s} before {r}.' + replace['outcome_infty'] = 'OK' + replace['errormsg_infty'] = 'OK' + gen.make_file(template, f'P2PBuffering_{s}_{r}_{s}_{r}_nok.c', replace) + + # Generate the incorrect matching with send message to the same process depending on the buffering mode (send + recv) + replace = patterns.copy().copy() + replace['origin'] = 'RTED' + replace['src1'] = '0' + replace['dest1'] = '0' + replace['src2'] = '1' + replace['dest2'] = '1' + replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ may not be matched' + replace['longdesc'] = 'Processes 0 and 1 both call @{s}@ and @{r}@. This results in a deadlock depending on the buffering mode' + replace['outcome_zerob'] = 'ERROR: BufferingHazard' + replace['errormsg_zerob'] = f'Buffering Hazard. Possible deadlock depending the buffer size of MPI implementation and system environment cause Send message to the same process.' + replace['outcome_infty'] = 'OK' + replace['errormsg_infty'] = 'OK' + gen.make_file(template, f'P2PBuffering_SameProcess_{s}_{r}_nok.c', replace) + + # Generate the incorrect matching with circular send message depending on the buffering mode (send + recv) + replace = patterns.copy().copy() + replace['origin'] = 'RTED' + replace['src1'] = '(nprocs - 1)' + replace['dest1'] = '1' + replace['src2'] = '0' + replace['dest2'] = '2' + replace['src3'] = '(rank - 1)' + replace['dest3'] = '((rank + 1) % nprocs)' + replace['fini1c'] = gen.fini[s]("1") + replace['fini2c'] = gen.fini[r]("2") + replace['operation1c'] = gen.operation[s]("1") + ' /* MBIERROR3 */' + replace['operation2c'] = gen.operation[r]("2") + replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ may not be matched' + replace['longdesc'] = 'Processes 0 and 1 both call @{s}@ and @{r}@. This results in a deadlock depending on the buffering mode' + replace['outcome_zerob'] = 'ERROR: BufferingHazard' + replace['errormsg_zerob'] = f'Buffering Hazard. Possible deadlock depending the buffer size of MPI implementation and system environment cause circular send message.' + replace['outcome_infty'] = 'OK' + replace['errormsg_infty'] = 'OK' + gen.make_file(template, f'P2PBuffering_Circular_{s}_{r}_nok.c', replace) + + # Generate the incorrect matching depending on the buffering mode (recv + send) + replace = patterns.copy() + replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ are not matched' + replace['longdesc'] = 'Processes 0 and 1 both call @{r}@ and @{s}@. This results in a deadlock' + replace['outcome_zerob'] = 'ERROR: CallMatching' + replace['errormsg_zerob'] = 'ERROR: CallMatching' + replace['outcome_infty'] = 'ERROR: CallMatching' + replace['errormsg_infty'] = 'ERROR: CallMatching' + replace['operation1a'] = gen.operation[r]("2") + replace['fini1a'] = gen.fini[r]("2") + replace['operation2a'] = gen.operation[s]("1") + replace['fini2a'] = gen.fini[s]("1") + replace['operation1b'] = gen.operation[r]("2") + replace['fini1b'] = gen.fini[r]("2") + replace['operation2b'] = gen.operation[s]("1") + replace['fini2b'] = gen.fini[s]("1") + gen.make_file(template, f'P2PCallMatching_{r}_{s}_{r}_{s}_nok.c', replace) + + # Generate the correct matching + replace = patterns.copy() + replace['shortdesc'] = 'Point to point @{s}@ and @{r}@ are correctly matched' + replace['longdesc'] = 'Process 0 calls @{s}@ and process 1 calls @{r}@.' + replace['outcome_zerob'] = 'OK' + replace['errormsg_zerob'] = 'OK' + replace['outcome_infty'] = 'OK' + replace['errormsg_infty'] = 'OK' + patterns['init1'] = gen.init[s]("1") + replace['operation1a'] = gen.operation[s]("1") + replace['fini1a'] = gen.fini[s]("1") + replace['operation2a'] = '' + replace['fini2a'] = '' + + patterns['init2'] = gen.init[r]("2") + replace['operation1b'] = gen.operation[r]("2") + replace['fini1b'] = gen.fini[r]("2") + replace['operation2b'] = '' + replace['fini2b'] = '' + gen.make_file(template, f'P2PCallMatching_{s}_{r}_{r}_{s}_ok.c', replace) diff --git a/teshsuite/smpi/MBI/P2PLocalConcurrencyGenerator.py b/teshsuite/smpi/MBI/P2PLocalConcurrencyGenerator.py index 0f1812783b..072817b5a5 100755 --- a/teshsuite/smpi/MBI/P2PLocalConcurrencyGenerator.py +++ b/teshsuite/smpi/MBI/P2PLocalConcurrencyGenerator.py @@ -103,7 +103,7 @@ for s in gen.send + gen.isend + gen.psend: patterns['free2'] = gen.free[r]("2") shortdesc = ' Local Concurrency with a P2P' - # Gtenerate a message race + # Generate a message race if s in gen.send and r in gen.irecv + gen.precv: replace = patterns.copy() replace['shortdesc'] = shortdesc diff --git a/teshsuite/smpi/MBI/P2PMatchingGenerator.py b/teshsuite/smpi/MBI/P2PMatchingGenerator.py index f449148db8..a675d335cb 100755 --- a/teshsuite/smpi/MBI/P2PMatchingGenerator.py +++ b/teshsuite/smpi/MBI/P2PMatchingGenerator.py @@ -16,7 +16,7 @@ template = """// @{generatedby}@ BEGIN_MPI_FEATURES P2P!basic: @{p2pfeature}@ P2P!nonblocking: @{ip2pfeature}@ - P2P!persistent: @{persfeature}0@ + P2P!persistent: @{persfeature}@ COLL!basic: Lacking COLL!nonblocking: Lacking COLL!persistent: Lacking @@ -57,6 +57,7 @@ int main(int argc, char **argv) { @{init1}@ @{init2}@ + if (rank == 0) { @{operation1}@ /* MBIERROR1 */ @{fini1}@ @@ -65,6 +66,9 @@ int main(int argc, char **argv) { @{fini2}@ } + @{free1}@ + @{free2}@ + MPI_Finalize(); printf("Rank %d finished normally\\n", rank); return 0; @@ -79,12 +83,14 @@ for p in gen.send + gen.ssend + gen.bsend + gen.recv + gen.irecv + gen.isend: patterns['p2pfeature'] = 'Yes' if p in gen.send + gen.bsend + gen.ssend + gen.recv else 'Lacking' patterns['ip2pfeature'] = 'Yes' if p in gen.isend + gen.irecv else 'Lacking' patterns['persfeature'] = 'Lacking' - #patterns['persfeature'] = 'Yes' if p in psend + precv else 'Lacking' + # patterns['persfeature'] = 'Yes' if p in gen.psend + gen.precv else 'Lacking' patterns['p'] = p patterns['init1'] = gen.init[p]("1") patterns['init2'] = '' #gen.init[p2]("2") patterns['fini1'] = gen.fini[p]("1") patterns['fini2'] = '' #gen.fini[p2]("2") + patterns['free1'] = gen.free[p]("1") + patterns['free2'] = '' #gen.free[p]("2") patterns['operation1'] = gen.operation[p]("1") patterns['operation2'] = '' #gen.operation[p2]("2") patterns['change_cond'] = 'rank == 1' @@ -105,6 +111,7 @@ for p in gen.send + gen.ssend + gen.bsend + gen.recv + gen.irecv + gen.isend: replace['errormsg'] = 'P2P mismatch. @{p}@ at @{filename}@:@{line:MBIERROR1}@ and @{p}@ at @{filename}@:@{line:MBIERROR2}@ are not matched.' replace['operation2'] = gen.operation[p]("1") replace['fini2'] = gen.fini[p]("1") + #replace['free2'] = gen.free[p]("2") gen.make_file(template, f'CallOrdering_{p}_{p}_nok.c', replace) for s in gen.send + gen.isend + gen.ssend + gen.bsend: @@ -114,12 +121,15 @@ for s in gen.send + gen.isend + gen.ssend + gen.bsend: patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' patterns['p2pfeature'] = 'Yes' if s in gen.send or r in gen.recv else 'Lacking' patterns['ip2pfeature'] = 'Yes' if s in gen.isend or r in gen.irecv else 'Lacking' + patterns['persfeature'] = 'Lacking' patterns['s'] = s patterns['r'] = r patterns['init1'] = gen.init[s]("1") patterns['init2'] = gen.init[r]("2") patterns['fini1'] = gen.fini[s]("1") patterns['fini2'] = gen.fini[r]("2") + patterns['free1'] = gen.free[s]("1") + patterns['free2'] = gen.free[r]("2") patterns['operation1'] = gen.operation[s]("1") patterns['operation2'] = gen.operation[r]("2") patterns['change_cond'] = '(rank == 1) && (its_raining)' diff --git a/teshsuite/smpi/MBI/P2PMessageRaceGenerator.py b/teshsuite/smpi/MBI/P2PMessageRaceGenerator.py new file mode 100644 index 0000000000..8003d58782 --- /dev/null +++ b/teshsuite/smpi/MBI/P2PMessageRaceGenerator.py @@ -0,0 +1,189 @@ +#! /usr/bin/python3 +import os +import sys +import generator_utils as gen + +template = """// @{generatedby}@ +/* ///////////////////////// The MPI Bugs Initiative //////////////////////// + + Origin: MBI + + Description: @{shortdesc}@ + @{longdesc}@ + + Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation + +BEGIN_MPI_FEATURES + P2P!basic: @{p2pfeature}@ + P2P!nonblocking: @{ip2pfeature}@ + P2P!persistent: Lacking + COLL!basic: Lacking + COLL!nonblocking: Lacking + COLL!persistent: Lacking + COLL!tools: Lacking + RMA: Lacking +END_MPI_FEATURES + +BEGIN_MBI_TESTS + $ mpirun -np 4 ${EXE} + | @{outcome}@ + | @{errormsg}@ +END_MBI_TESTS +////////////////////// End of MBI headers /////////////////// */ + +#include +#include +#include + +#define N 2 + +int main(int argc, char **argv) { + int nprocs = -1; + int rank = -1; + int dest, src; + int i=0; + int root = 0; + int stag = 0, rtag = 0; + int buff_size = 1; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + printf("Hello from rank %d \\n", rank); + + if (nprocs != 4) + printf("MBI ERROR: This test needs 4 processes to produce a bug!\\n"); + + int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */ + MPI_Comm newcom = MPI_COMM_WORLD; + MPI_Datatype type = MPI_INT; + MPI_Op op = MPI_SUM; + + @{init0a}@ + @{init0b}@ + @{init0c}@ + @{init1a}@ + @{init1b}@ + @{init3a}@ + @{init3b}@ + @{init3c}@ + @{init3d}@ + + if (rank == 0) { + src = MPI_ANY_SOURCE; rtag = @{tag}@; + for (int i = 0; i < 2 * N; i++) { + @{operation0a}@ /* MBIERROR1 */ + @{fini0a}@ + } + src = 3; rtag = 0; + @{operation0b}@ /* MBIERROR2 */ + @{fini0b}@ + @{operation0c}@ + @{fini0c}@ + } else if (rank == 1 || rank == 2) { + dest = 0; stag = @{tag}@; + for (int i = 0; i < N; i++) { + @{operation1a}@ + @{fini1a}@ + } + dest = 3; stag = 0; + @{operation1b}@ + @{fini1b}@ + } else if (rank == 3) { + dest = 0; src = 1; rtag= 0; stag = 0; + @{operation3a}@ + @{fini3a}@ + @{operation3b}@ /* MBIERROR3 */ + @{fini3b}@ + src = 2; + @{operation3c}@ + @{fini3c}@ + @{operation3d}@ + @{fini3d}@ + } + + @{free0a}@ + @{free0b}@ + @{free0c}@ + @{free1a}@ + @{free1b}@ + @{free3a}@ + @{free3b}@ + @{free3c}@ + @{free3d}@ + + MPI_Finalize(); + printf("Rank %d finished normally\\n", rank); + return 0; +} +""" + +basedesc = 'We have 4 processes (p0, p1, p2 and p3). p1 and p2 send N messages to p0 and send a last message to p3. Process p0 recv 2*N messages from p1 and p2 using MPI_ANY_SOURCE and wait messages from p3. p3 wait a message from p1 and send message to p0, before doing the same for p2.' + +for s in gen.send + gen.isend: + for r in gen.recv + gen.irecv: + patterns = {} + patterns = {'s': s, 'r': r} + patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' + patterns['p2pfeature'] = 'Yes' if s in gen.send or r in gen.recv else 'Lacking' + patterns['ip2pfeature'] = 'Yes' if s in gen.isend or r in gen.irecv else 'Lacking' + patterns['s'] = s + patterns['r'] = r + + patterns['init0a'] = gen.init[r]("0a") + patterns['init0b'] = gen.init[r]("0b") + patterns['init0c'] = gen.init[r]("0c") + patterns['operation0a'] = gen.operation[r]("0a") + patterns['operation0b'] = gen.operation[r]("0b") + patterns['operation0c'] = gen.operation[r]("0c") + patterns['fini0a'] = gen.fini[r]("0a") + patterns['fini0b'] = gen.fini[r]("0b") + patterns['fini0c'] = gen.fini[r]("0c") + patterns['free0a'] = gen.free[r]("0a") + patterns['free0b'] = gen.free[r]("0b") + patterns['free0c'] = gen.free[r]("0c") + + patterns['init1a'] = gen.init[s]("1a") + patterns['init1b'] = gen.init[s]("1b") + patterns['operation1a'] = gen.operation[s]("1a") + patterns['operation1b'] = gen.operation[s]("1b") + patterns['fini1a'] = gen.fini[s]("1a") + patterns['fini1b'] = gen.fini[s]("1b") + patterns['free1a'] = gen.free[s]("1a") + patterns['free1b'] = gen.free[s]("1b") + + patterns['init3a'] = gen.init[r]("3a") + patterns['init3b'] = gen.init[s]("3b") + patterns['init3c'] = gen.init[r]("3c") + patterns['init3d'] = gen.init[s]("3d") + patterns['operation3a'] = gen.operation[r]("3a") + patterns['operation3b'] = gen.operation[s]("3b") + patterns['operation3c'] = gen.operation[r]("3c") + patterns['operation3d'] = gen.operation[s]("3d") + patterns['fini3a'] = gen.fini[r]("3a") + patterns['fini3b'] = gen.fini[s]("3b") + patterns['fini3c'] = gen.fini[r]("3c") + patterns['fini3d'] = gen.fini[s]("3d") + patterns['free3a'] = gen.free[r]("3a") + patterns['free3b'] = gen.free[s]("3b") + patterns['free3c'] = gen.free[r]("3c") + patterns['free3d'] = gen.free[s]("3d") + + patterns['tag'] = '1' + + # Generate the correct matching because of the conditional + replace = patterns.copy() + replace['shortdesc'] = 'Message race' + replace['longdesc'] = basedesc + ' In this file, different message tag are used to avoid involuntary message race.' + replace['outcome'] = 'OK' + replace['errormsg'] = 'OK' + gen.make_file(template, f'MessageRace_Loop_{s}_{r}_ok.c', replace) + + # Generate the incorrect matching because of the conditional + replace = patterns.copy() + replace['shortdesc'] = 'Message race' + replace['longdesc'] = basedesc + ' If the loop of p1 ending before the loop of p2, p0 could recv a message from process p3 into recv loop destined to message from p1 and p2. In this case, the program deadlock cause by message race at recv at line @{line:MBIERROR2}@.' + replace['outcome'] = 'ERROR: MessageRace' + replace['errormsg'] = 'Message race. The use of wildcard receive calls @{r}@ at @{filename}@:@{line:MBIERROR1}@ from @{r}@ at @{filename}@:@{line:MBIERROR3}@ and @{r}@ without wildcard at @{filename}@:@{line:MBIERROR2}@) leads to nondeterministic matching.' + replace['tag'] = '0' + gen.make_file(template, f'MessageRace_Loop_{s}_{r}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/P2PMessageRaceTagsGenerator.py b/teshsuite/smpi/MBI/P2PMessageRaceTagsGenerator.py new file mode 100644 index 0000000000..78e3e24e96 --- /dev/null +++ b/teshsuite/smpi/MBI/P2PMessageRaceTagsGenerator.py @@ -0,0 +1,161 @@ +#! /usr/bin/python3 +import os +import sys +import generator_utils as gen + +template = """// @{generatedby}@ +/* ///////////////////////// The MPI Bugs Initiative //////////////////////// + + Origin: MBI + + Description: @{shortdesc}@ + @{longdesc}@ + + Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation + +BEGIN_MPI_FEATURES + P2P!basic: @{p2pfeature}@ + P2P!nonblocking: @{ip2pfeature}@ + P2P!persistent: Lacking + COLL!basic: Lacking + COLL!nonblocking: Lacking + COLL!persistent: Lacking + COLL!tools: Lacking + RMA: Lacking +END_MPI_FEATURES + +BEGIN_MBI_TESTS + $ mpirun -np 3 ${EXE} + | @{outcome}@ + | @{errormsg}@ +END_MBI_TESTS +////////////////////// End of MBI headers /////////////////// */ + +#include +#include +#include + +#define N 10 + +int main(int argc, char **argv) { + int nprocs = -1; + int rank = -1; + int dest, src; + int i=0; + int root = 0; + int stag = 0, rtag = 0; + int buff_size = 1; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + printf("Hello from rank %d \\n", rank); + + if (nprocs < 3) + printf("MBI ERROR: This test needs at least 3 processes to produce a bug!\\n"); + + int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */ + MPI_Comm newcom = MPI_COMM_WORLD; + MPI_Datatype type = MPI_INT; + MPI_Op op = MPI_SUM; + + @{init0}@ + @{init1a}@ + @{init1b}@ + @{init2}@ + + if (rank == 0) { + dest = 1; stag = 1; + @{operation0}@ + @{fini0}@ + } else if (rank == 1) { + src = MPI_ANY_SOURCE; + rtag = @{tag1}@; + @{operation1a}@ + @{fini1a}@ + rtag = @{tag2}@; + @{operation1b}@ @{tagerror}@ + @{fini1b}@ + } else if (rank == 2) { + dest = 1; stag = 2; + @{operation2}@ + @{fini2}@ + } + + @{free0}@ + @{free1a}@ + @{free1b}@ + @{free2}@ + + MPI_Finalize(); + printf("Rank %d finished normally\\n", rank); + return 0; +} +""" + +# To be correct, this benchmark must be use wildcard on second recv +# tag, or no wildcard on first recv tag and second recv tag must be +# different. +# +# |-----+-----+----+----| +# | x\y | ANY | 1 | 2 | +# |-----+-----+----+----| +# | ANY | OK | - | - | +# | 1 | OK | - | OK | +# | 2 | OK | OK | - | +# |-----+-----+----+----| + +for s in gen.send: + for r in gen.recv: + for x, y in [('MPI_ANY_TAG', 'MPI_ANY_TAG'), # OK + ('MPI_ANY_TAG', '1'), # NOK + ('1', 'MPI_ANY_TAG'), # OK + ('1', '2'), # OK + ('2', '2')]: # NOK + patterns = {} + patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' + patterns['p2pfeature'] = 'Yes' if s in gen.send or r in gen.recv else 'Lacking' + patterns['ip2pfeature'] = 'Yes' if s in gen.isend or r in gen.irecv else 'Lacking' + patterns['s'] = s + patterns['r'] = r + + patterns['tag1'] = x + patterns['tag2'] = y + + patterns['init0'] = gen.init[s]("0") + patterns['operation0'] = gen.operation[s]("0") + patterns['fini0'] = gen.fini[s]("0") + patterns['free0'] = gen.free[s]("0") + + patterns['init1a'] = gen.init[r]("1a") + patterns['init1b'] = gen.init[r]("1b") + patterns['operation1a'] = gen.operation[r]("1a") + patterns['operation1b'] = gen.operation[r]("1b") + patterns['fini1a'] = gen.fini[r]("1a") + patterns['fini1b'] = gen.fini[r]("1b") + patterns['free1a'] = gen.free[r]("1a") + patterns['free1b'] = gen.free[r]("1b") + + patterns['init2'] = gen.init[s]("2") + patterns['operation2'] = gen.operation[s]("2") + patterns['fini2'] = gen.fini[s]("2") + patterns['free2'] = gen.free[s]("2") + patterns['tagerror'] = '/* MBIERROR */' + + if y == 'MPI_ANY_TAG' or (x != 'MPI_ANY_TAG' and x != y): + # Generate the correct matching because of the conditional + replace = patterns.copy() + replace['shortdesc'] = 'Message race' + replace['longdesc'] = 'Correct code without message race.' + replace['outcome'] = 'OK' + replace['errormsg'] = 'OK' + replace['tagerror'] = '' + gen.make_file(template, f'MessageRace_tag_{x}_{y}_{s}_{r}_ok.c', replace) + else: + # Generate the incorrect matching because of the conditional + replace = patterns.copy() + replace['shortdesc'] = 'Message race' + replace['longdesc'] = 'Message race in @{r}@ with @{s}@.' + replace['outcome'] = 'ERROR: MessageRace' + replace['errormsg'] = 'Message race. The use of wildcard receive calls @{r}@ at @{filename}@:@{line:MBIERROR}@ and incorrect tag matching.' + gen.make_file(template, f'MessageRace_tag_{x}_{y}_{s}_{r}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/P2PSendrecvArgGenerator.py b/teshsuite/smpi/MBI/P2PSendrecvArgGenerator.py new file mode 100644 index 0000000000..ef6fb16e42 --- /dev/null +++ b/teshsuite/smpi/MBI/P2PSendrecvArgGenerator.py @@ -0,0 +1,134 @@ +#! /usr/bin/python3 +import os +import sys +import generator_utils as gen + +template = """// @{generatedby}@ +/* ///////////////////////// The MPI Bugs Initiative //////////////////////// + + Origin: @{origin}@ + + Description: @{shortdesc}@ + @{longdesc}@ + + Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation + +BEGIN_MPI_FEATURES + P2P!basic: Yes + P2P!nonblocking: Lacking + P2P!persistent: Lacking + COLL!basic: Lacking + COLL!nonblocking: Lacking + COLL!persistent: Lacking + COLL!tools: Lacking + RMA: Lacking +END_MPI_FEATURES + +BEGIN_MBI_TESTS + $ mpirun -np 3 ${EXE} + | @{outcome}@ + | @{errormsg}@ +END_MBI_TESTS +////////////////////// End of MBI headers /////////////////// */ + +#include +#include +#include + +#define N 10 + +int main(int argc, char **argv) { + int nprocs = -1 , rank = -1; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + if (nprocs < 3) + printf("MBI ERROR: This test needs at least 3 processes to produce a bug!\\n"); + + MPI_Comm newcom = MPI_COMM_WORLD; + MPI_Datatype type = MPI_INT; + + int src = 0; int dest = 0; + int stag = 1; int rtag = 1; + int buff_size = N; + + @{init1}@ + @{init2}@ + @{init3}@ + + if (rank == 0) { + src = 1; + @{start1}@ + @{operation1}@ + @{fini1}@ + } else if (rank == 1) { + src = 2; dest = 0; + @{start2}@ + @{change_arg}@ + @{operation2}@ + @{fini2}@ + } else if (rank == 2) { + dest = 1; + @{start3}@ + @{operation3}@ + @{fini3}@ + } + + @{free1}@ + @{free2}@ + @{free3}@ + + MPI_Finalize(); + printf("Rank %d finished normally\\n", rank); + return 0; +} +""" + +for s in gen.send: + for r in gen.recv: + for sr in gen.sendrecv: + patterns = {} + patterns = {'s': s, 'r': r, 'sr': sr} + patterns['origin'] = "RTED" + patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' + + patterns['init1'] = gen.init[r]("1").replace("buf1=-1", "buf1[N]={-1}") + patterns['start1'] = gen.start[r]("1") + patterns['operation1'] = gen.operation[r]("1") + patterns['fini1'] = gen.fini[r]("1") + patterns['free1'] = gen.free[r]("1") + + patterns['init2'] = gen.init[sr]("2") + patterns['start2'] = gen.start[sr]("2") + patterns['operation2'] = gen.operation[sr]("2") + patterns['fini2'] = gen.fini[sr]("2") + patterns['free2'] = gen.free[sr]("2") + + patterns['init3'] = gen.init[s]("3").replace("buf3=rank", "buf3[N]={rank}") + patterns['start3'] = gen.start[s]("3") + patterns['operation3'] = gen.operation[s]("3") + patterns['fini3'] = gen.fini[s]("3") + patterns['free3'] = gen.free[s]("3") + + patterns['change_arg'] = '' + + # Generate a code with distinct buffer + replace = patterns.copy() + replace['origin'] = 'MBI' + replace['shortdesc'] = 'Correct usage of Sendrecv function.' + replace['longdesc'] = 'Correct usage of Sendrecv function.' + replace['outcome'] = 'OK' + replace['errormsg'] = 'OK' + gen.make_file(template, f'InvalidParam_Buffer_{s}_{sr}_{r}_ok.c', replace) + + # Generate a code with non distinct buffer + replace = patterns.copy() + replace['shortdesc'] = 'Invalid buffer on Sendrecv function.' + replace['longdesc'] = 'Invalid buffer on Sendrecv, the two buffers must be distinct.' + replace['outcome'] = 'ERROR: InvalidBuffer' + replace['errormsg'] = '@{sr}@ at @{filename}@:@{line:MBIERROR}@ send buffer and recv buffer must be distinct.' + replace['change_arg'] = gen.write[sr]("2") + replace['operation2'] = gen.operation[sr]("2") + " /* MBIERROR */" + gen.make_file(template, f'InvalidParam_Buffer_{s}_{sr}_{r}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/RMAArgGenerator.py b/teshsuite/smpi/MBI/RMAArgGenerator.py index 5cab47b30a..04cef56feb 100755 --- a/teshsuite/smpi/MBI/RMAArgGenerator.py +++ b/teshsuite/smpi/MBI/RMAArgGenerator.py @@ -44,7 +44,7 @@ int main(int argc, char **argv) { MPI_Comm_size(MPI_COMM_WORLD, &numProcs); MPI_Comm_rank(MPI_COMM_WORLD, &rank); - int *winbuf = malloc(N * sizeof(int)); + int *winbuf = (int *)malloc(N * sizeof(int)); MPI_Win win; MPI_Win_create(&winbuf, N * sizeof(int), 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win); diff --git a/teshsuite/smpi/MBI/RMAInvalidArgGenerator.py b/teshsuite/smpi/MBI/RMAInvalidArgGenerator.py index afe656c3c7..2ba7cf9add 100755 --- a/teshsuite/smpi/MBI/RMAInvalidArgGenerator.py +++ b/teshsuite/smpi/MBI/RMAInvalidArgGenerator.py @@ -40,7 +40,7 @@ END_MBI_TESTS int main(int argc, char **argv) { int nprocs = -1 , rank = -1; MPI_Win win; - int *winbuf = @{malloc}@ // Window buffer + int *winbuf = (int *)@{malloc}@ // Window buffer MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); @@ -104,7 +104,7 @@ for e in gen.epoch: # replace['shortdesc'] = 'nullptr is invalid in one-sided operation.' # replace['longdesc'] = 'A one-sided operation has an invalid buffer.' # replace['outcome'] = 'ERROR: InvalidBuffer' - # replace['init'] = 'int * localbuf1 = malloc(sizeof(int));' + # replace['init'] = 'int * localbuf1 = (int *)malloc(sizeof(int));' # replace['change_arg'] = 'localbuf1 = NULL;' # replace['operation'] = gen.operation[p]("1").replace('&localbuf1', 'localbuf1') # replace['errormsg'] = '@{p}@ at @{filename}@:@{line:MBIERROR}@ has an invalid buffer' diff --git a/teshsuite/smpi/MBI/RMAP2PGlobalConcurrencyGenerator.py b/teshsuite/smpi/MBI/RMAP2PGlobalConcurrencyGenerator.py index fee996db2c..a6723fac19 100755 --- a/teshsuite/smpi/MBI/RMAP2PGlobalConcurrencyGenerator.py +++ b/teshsuite/smpi/MBI/RMAP2PGlobalConcurrencyGenerator.py @@ -41,7 +41,7 @@ int main(int argc, char **argv) { int nprocs = -1; int rank = -1; MPI_Win win; - int * winbuf = malloc(N * sizeof(int)); // Window buffer + int * winbuf = (int *)malloc(N * sizeof(int)); // Window buffer int buff_size = 1; MPI_Init(&argc, &argv); diff --git a/teshsuite/smpi/MBI/RMAP2PLocalConcurrencyGenerator.py b/teshsuite/smpi/MBI/RMAP2PLocalConcurrencyGenerator.py new file mode 100644 index 0000000000..0f9f92e1f4 --- /dev/null +++ b/teshsuite/smpi/MBI/RMAP2PLocalConcurrencyGenerator.py @@ -0,0 +1,134 @@ +#! /usr/bin/python3 +import os +import sys +import generator_utils as gen + +template = """// @{generatedby}@ +/* ///////////////////////// The MPI Bugs Initiative //////////////////////// + + Origin: @{origin}@ + + Description: @{shortdesc}@ + @{longdesc}@ + + Version of MPI: Conforms to MPI 2, does not require MPI 3 implementation + +BEGIN_MPI_FEATURES + P2P!basic: @{p2pfeature}@ + P2P!nonblocking: @{ip2pfeature}@ + P2P!persistent: Lacking + COLL!basic: Lacking + COLL!nonblocking: Lacking + COLL!persistent: Lacking + COLL!tools: Lacking + RMA: @{rmafeature}@ +END_MPI_FEATURES + +BEGIN_MBI_TESTS + $ mpirun -np 3 ${EXE} + | @{outcome}@ + | @{errormsg}@ +END_MBI_TESTS +////////////////////// End of MBI headers /////////////////// */ + +#include +#include +#include + +#define N 1 + +int main(int argc, char **argv) { + int nprocs = -1; + int rank = -1; + MPI_Win win; + int * winbuf = (int *)malloc(N * sizeof(int)); // Window buffer + int buff_size = N; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + printf("Hello from rank %d \\n", rank); + + if (nprocs < 3) + printf("MBI ERROR: This test needs at least 3 processes to produce a bug!\\n"); + + MPI_Comm newcom = MPI_COMM_WORLD; + MPI_Datatype type = MPI_INT; + int stag=0, rtag=0; + winbuf[0] = nprocs; + + MPI_Win_create(winbuf, N*sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win); + + + @{init1}@ + @{init2}@ + @{init3}@ + + @{comment_fence}@MPI_Win_fence(0, win); + + if (rank == 0) { + int target=1, dest=2; + + @{comment_lock}@MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 1, 0, win); + @{operation1}@ + @{operation2}@ /* MBIERROR */ + @{comment_lock}@MPI_Win_unlock(1, win); + + @{fini2}@ + }else if (rank == 2){ + int src=0; + @{operation3}@ + @{fini3}@ + } + + @{comment_fence}@MPI_Win_fence(0, win); + + MPI_Win_free(&win); + free(winbuf); + + MPI_Finalize(); + printf("Rank %d finished normally\\n", rank); + return 0; +} +""" + + +for p in gen.get: + for s in gen.send + gen.isend: + for r in gen.recv + gen.irecv: + patterns = {} + patterns = {'p': p, 's': s, 'r': r} + patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' + patterns['origin'] = 'RTED' + patterns['shortdesc'] = 'Local Concurrency error.' + patterns['longdesc'] = 'Local Concurrency error. Concurrent access of variable localbuf1 by @{p}@ (write) and @{s}@ (read)' + patterns['rmafeature'] = 'Yes' + patterns['p2pfeature'] = 'Yes' if s in gen.send or r in gen.recv else 'Lacking' + patterns['ip2pfeature'] = 'Yes' if s in gen.isend or r in gen.irecv else 'Lacking' + patterns['p'] = p + patterns['s'] = s + patterns['r'] = r + patterns['init1'] = gen.init[p]("1") + patterns['init2'] = gen.init[s]("2") + patterns['init3'] = gen.init[r]("3") + patterns['fini2'] = gen.fini[s]("2") + patterns['fini3'] = gen.fini[r]("3") + patterns['operation1'] = gen.operation[p]("1") + patterns['operation2'] = gen.operation[s]("2").replace("buf2", "localbuf1") + patterns['operation3'] = gen.operation[r]("3") + patterns['comment_lock'] = '' + patterns['comment_fence'] = '' + + # Use fence epoch + replace = patterns.copy() + replace['outcome'] = 'ERROR: LocalConcurrency' + replace['errormsg'] = 'Local Concurrency error. @{p}@ at @{filename}@:@{line:MBIERROR}@ .' + replace['comment_lock'] = '// ' + gen.make_file(template, f'LocalConcurrency_fence_{p}_{s}_{r}_nok.c', replace) + + # Use lock epoch + replace = patterns.copy() + replace['outcome'] = 'ERROR: LocalConcurrency' + replace['errormsg'] = 'Local Concurrency error. @{p}@ at @{filename}@:@{line:MBIERROR}@ .' + replace['comment_fence'] = '// ' + gen.make_file(template, f'LocalConcurrency_lock_{p}_{s}_{r}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/RMARemoteLocalConcurrencyGenerator.py b/teshsuite/smpi/MBI/RMARemoteLocalConcurrencyGenerator.py index 5f201343f4..5df6ef3607 100755 --- a/teshsuite/smpi/MBI/RMARemoteLocalConcurrencyGenerator.py +++ b/teshsuite/smpi/MBI/RMARemoteLocalConcurrencyGenerator.py @@ -35,7 +35,7 @@ END_MBI_TESTS #include #include -#define N 1 +#define N 10 int main(int argc, char **argv) { int nprocs = -1; @@ -52,11 +52,12 @@ int main(int argc, char **argv) { printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n"); MPI_Datatype type = MPI_INT; - int target = 1; + int target = 1 - rank; MPI_Win_create(&winbuf, 100 * sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win); @{init1}@ + @{init2}@ @{epoch}@ @@ -64,7 +65,6 @@ int main(int argc, char **argv) { @{operation1}@ /* MBIERROR1 */ } if(rank == 1){ - target = 0; @{operation2}@ /* MBIERROR2 */ } @@ -80,7 +80,7 @@ int main(int argc, char **argv) { for e in gen.epoch: for p1 in gen.get: - for p2 in gen.put + gen.rstore + gen.rload + gen.get: + for p2 in gen.put + gen.rstore + gen.rload + gen.get : patterns = {} patterns = {'e': e, 'p1': p1, 'p2': p2} patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' @@ -92,7 +92,8 @@ for e in gen.epoch: patterns['finEpoch'] = gen.finEpoch[e]("1") patterns['init1'] = gen.init[p1]("1") patterns['operation1'] = gen.operation[p1]("1") - patterns['operation2'] = gen.operation[p2]("1") + patterns['init2'] = gen.init[p2]("2") + patterns['operation2'] = gen.operation[p2]("2") # Generate a data race (Get + Get/load/store/Put) replace = patterns.copy() @@ -103,16 +104,22 @@ for e in gen.epoch: # Replace Put and Get first argument if p2 in gen.put: - replace['operation2'] = 'MPI_Put(&winbuf[20], N, MPI_INT, target, 0, N, type, win);' - if p2 in gen.get: - replace['operation2'] = 'MPI_Get(&winbuf[20], N, MPI_INT, target, 0, N, type, win);' + replace['operation2'] = 'MPI_Put(&winbuf[5], N, MPI_INT, target, 0, N, type, win);' + replace['outcome'] = 'OK' + replace['errormsg'] = 'OK' + elif p2 in gen.get: + replace['operation2'] = 'MPI_Get(&winbuf[5], N, MPI_INT, target, 0, N, type, win);' + elif p2 in gen.rload: + replace['outcome'] = 'OK' + replace['errormsg'] = 'OK' - gen.make_file(template, f'GlobalConcurrency_rl_{e}_{p1}_{p2}_nok.c', replace) + ok = 'ok' if replace['outcome'] == 'OK' else 'nok' + gen.make_file(template, f'GlobalConcurrency_rl_{e}_{p1}_{p2}_{ok}.c', replace) for e in gen.epoch: for p1 in gen.put: - for p2 in gen.rstore + gen.rload + gen.put: + for p2 in gen.rstore + gen.rload + gen.put + gen.get: patterns = {} patterns = {'e': e, 'p1': p1, 'p2': p2} patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' @@ -124,7 +131,8 @@ for e in gen.epoch: patterns['finEpoch'] = gen.finEpoch[e]("1") patterns['init1'] = gen.init[p1]("1") patterns['operation1'] = gen.operation[p1]("1") - patterns['operation2'] = gen.operation[p2]("1") + patterns['init2'] = gen.init[p2]("2") + patterns['operation2'] = gen.operation[p2]("2") # Generate a data race (Put + store) replace = patterns.copy() @@ -133,8 +141,10 @@ for e in gen.epoch: replace['outcome'] = 'ERROR: GlobalConcurrency' replace['errormsg'] = 'Global Concurrency error. @{p2}@ at @{filename}@:@{line:MBIERROR2}@ conflicts with @{p1}@ line @{line:MBIERROR1}@' - # Replace Put first argument + # Replace Put/Get first argument if p2 in gen.put: - replace['operation2'] = 'MPI_Put(&winbuf[20], N, MPI_INT, target, 0, N, type, win);' + replace['operation2'] = 'MPI_Put(&winbuf[5], N, MPI_INT, target, 0, N, type, win);' + elif p2 in gen.get: + replace['operation2'] = 'MPI_Get(&winbuf[5], N, MPI_INT, target, 0, N, type, win);' gen.make_file(template, f'GlobalConcurrency_rl_{e}_{p1}_{p2}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/RMARemoteRemoteConcurrencyGenerator.py b/teshsuite/smpi/MBI/RMARemoteRemoteConcurrencyGenerator.py index 7a9f77aa39..9361187b41 100755 --- a/teshsuite/smpi/MBI/RMARemoteRemoteConcurrencyGenerator.py +++ b/teshsuite/smpi/MBI/RMARemoteRemoteConcurrencyGenerator.py @@ -25,7 +25,7 @@ BEGIN_MPI_FEATURES END_MPI_FEATURES BEGIN_MBI_TESTS - $ mpirun -np 2 ${EXE} + $ mpirun -np 3 ${EXE} | @{outcome}@ | @{errormsg}@ END_MBI_TESTS @@ -57,12 +57,16 @@ int main(int argc, char **argv) { MPI_Win_create(&winbuf, 100 * sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win); @{init1}@ + @{init2}@ @{epoch}@ - if (rank == 0 || rank == 2) { + if (rank == 0) { @{operation1}@ /* MBIERROR1 */ } + else if (rank == 2) { + @{operation2}@ /* MBIERROR2 */ + } @{finEpoch}@ @@ -76,21 +80,25 @@ int main(int argc, char **argv) { for e in gen.epoch: for p1 in gen.get + gen.put: - patterns = {} - patterns = {'e': e, 'p1': p1} - patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' - patterns['rmafeature'] = 'Yes' - patterns['p1'] = p1 - patterns['e'] = e - patterns['epoch'] = gen.epoch[e]("1") - patterns['finEpoch'] = gen.finEpoch[e]("1") - patterns['init1'] = gen.init[p1]("1") - patterns['operation1'] = gen.operation[p1]("1") - - # Generate a data race (Get + Get/load/store/Put) - replace = patterns.copy() - replace['shortdesc'] = 'Global Concurrency error.' - replace['longdesc'] = 'Global Concurrency error. Both processes 0 and 2 access the window in process 1 with @{p1}@' - replace['outcome'] = 'ERROR: GlobalConcurrency' - replace['errormsg'] = 'Global Concurrency error. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ conflicts in process 1' - gen.make_file(template, f'GlobalConcurrency_rr_{e}_{p1}_nok.c', replace) + for p2 in gen.put: + patterns = {} + patterns = {'e': e, 'p1': p1, 'p2': p2} + patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.' + patterns['rmafeature'] = 'Yes' + patterns['p1'] = p1 + patterns['p2'] = p2 + patterns['e'] = e + patterns['epoch'] = gen.epoch[e]("1") + patterns['finEpoch'] = gen.finEpoch[e]("1") + patterns['init1'] = gen.init[p1]("1") + patterns['operation1'] = gen.operation[p1]("1") + patterns['init2'] = gen.init[p2]("2") + patterns['operation2'] = gen.operation[p2]("2") + + # Generate a data race + replace = patterns.copy() + replace['shortdesc'] = 'Global Concurrency error.' + replace['longdesc'] = 'Global Concurrency error. Both processes 0 and 2 access the window in process 1 with @{p1}@' + replace['outcome'] = 'ERROR: GlobalConcurrency' + replace['errormsg'] = 'Global Concurrency error. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ and @{p2}@ at @{filename}@:@{line:MBIERROR2}@ conflicts in process 1' + gen.make_file(template, f'GlobalConcurrency_rr_{e}_{p1}_{p2}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/RMAReqLifecycleGenerator.py b/teshsuite/smpi/MBI/RMAReqLifecycleGenerator.py index b946f97103..82ee3fd99d 100755 --- a/teshsuite/smpi/MBI/RMAReqLifecycleGenerator.py +++ b/teshsuite/smpi/MBI/RMAReqLifecycleGenerator.py @@ -47,7 +47,7 @@ int main(int argc, char **argv) { if (numProcs < 2) printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n"); - int *winbuf = malloc(N * sizeof(int)); + int *winbuf = (int *)malloc(N * sizeof(int)); MPI_Win win; MPI_Win_create(winbuf, N * sizeof(int), 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win); @@ -102,26 +102,26 @@ for e1 in gen.epoch: replace['longdesc'] = 'Correct code' replace['outcome'] = 'OK' replace['errormsg'] = 'OK' - gen.make_file(template, f'ReqLifecycle_RMA_{e1}_{p}_ok.c', replace) + gen.make_file(template, f'EpochLifecycle_RMA_{e1}_{p}_ok.c', replace) # Generate a code with missing open epoch replace = patterns.copy() replace['shortdesc'] = f"Request lifecycle, missing open {e1} epoch" replace['longdesc'] = f"Request lifecycle, missing open {e1} epoch" - replace['outcome'] = 'ERROR: MissingStart' + replace['outcome'] = 'ERROR: MissingEpoch' replace['errormsg'] = '@{e1}@ at @{filename}@:@{line:MBIERROR}@ has missing' replace['epoch'] = f"/* MBIERROR MISSING: {gen.epoch[e1]('1')} */" - gen.make_file(template, f'ReqLifecycle_RMA_MissingOpen_{e1}_{p}_nok.c', replace) + gen.make_file(template, f'EpochLifecycle_RMA_MissingOpen_{e1}_{p}_nok.c', replace) # Generate a code with missing close epoch replace = patterns.copy() replace['shortdesc'] = f"Request lifecycle, missing close {e1} epoch" replace['longdesc'] = f"Request lifecycle, missing close {e1} epoch" - replace['outcome'] = 'ERROR: MissingWait' + replace['outcome'] = 'ERROR: MissingEpoch' replace['errormsg'] = '@{e1}@ at @{filename}@:@{line:MBIERROR}@ has missing' replace['epoch'] = gen.epoch[e1]("1") replace['finEpoch'] = f"/* MBIERROR MISSING: {gen.finEpoch[e1]('1')} */" - gen.make_file(template, f'ReqLifecycle_RMA_MissingClose_{e1}_{p}_nok.c', replace) + gen.make_file(template, f'EpochLifecycle_RMA_MissingClose_{e1}_{p}_nok.c', replace) for e1 in gen.epoch: for e2 in gen.epoch: @@ -145,6 +145,6 @@ for e1 in gen.epoch: replace = patterns.copy() replace['shortdesc'] = f"Request lifecycle, {e2} epoch into {e1} epoch" replace['longdesc'] = f"Request lifecycle, {e2} epoch into {e1} epoch" - replace['outcome'] = 'ERROR: MissingWait' #FIXME: New type of error + replace['outcome'] = 'ERROR: DoubleEpoch' replace['errormsg'] = '@{e2}@ at @{filename}@:@{line:MBIERROR}@ has in an other epoch' - gen.make_file(template, f'ReqLifecycle_RMA_TwoEpoch_{e1}_{e2}_{p}_nok.c', replace) + gen.make_file(template, f'EpochLifecycle_RMA_doubleEpoch_{e1}_{e2}_{p}_nok.c', replace) diff --git a/teshsuite/smpi/MBI/RMAWinBufferGenerator.py b/teshsuite/smpi/MBI/RMAWinBufferGenerator.py index bae8efa9f5..8ad4a4f501 100755 --- a/teshsuite/smpi/MBI/RMAWinBufferGenerator.py +++ b/teshsuite/smpi/MBI/RMAWinBufferGenerator.py @@ -65,8 +65,7 @@ int main(int argc, char *argv[]) { MPI_Win_fence(0, win); if (rank == 0) { - int localbuf[N] = {0}; - localbuf[0] = 12345; + int localbuf[N] = {12345}; MPI_Put(&localbuf, N, MPI_INT, 1, 0, N, MPI_INT, win); } @@ -84,7 +83,7 @@ int main(int argc, char *argv[]) { """ -for b in ['missing', 'null', 'malloc', 'bufferSize']: +for b in ['missing', 'null', 'malloc', 'bufferSize']: patterns = {} patterns = {'b': b} patterns['origin'] = "MPI-CorrBench" @@ -108,11 +107,11 @@ for b in ['missing', 'null', 'malloc', 'bufferSize']: replace['bufferalloc'] = 'buffer = NULL; /* MBIERROR1 */' replace['longdesc'] = 'Use NULL buffer in window creation.' elif b == 'bufferSize': - replace['bufferalloc'] = 'buffer = malloc((N/2) * sizeof(int)); /* MBIERROR1 */' + replace['bufferalloc'] = 'buffer = (int *)malloc((N/2) * sizeof(int)); /* MBIERROR1 */' replace['bufferfree'] = 'free(buffer);' replace['longdesc'] = 'Unmatched size of buffer in window creation.' else: - replace['bufferalloc'] = 'buffer = malloc(N * sizeof(int));' + replace['bufferalloc'] = 'buffer = (int *)malloc(N * sizeof(int));' replace['bufferfree'] = 'free(buffer);' replace['longdesc'] = 'Correct initialized buffer in window creation.' replace['outcome'] = 'OK' diff --git a/teshsuite/smpi/MBI/ResleakGenerator.py b/teshsuite/smpi/MBI/ResleakGenerator.py index a9ff22fd3b..c33d1978fb 100755 --- a/teshsuite/smpi/MBI/ResleakGenerator.py +++ b/teshsuite/smpi/MBI/ResleakGenerator.py @@ -50,8 +50,9 @@ static void myOp(int *invec, int *inoutvec, int *len, MPI_Datatype *dtype) { int main(int argc, char **argv) { int nprocs = -1; int rank = -1; - int size = 1; - int j = 0; + int i=1; + int j=0; + int size=1; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); @@ -118,7 +119,7 @@ for call in gen.tcoll: replace['outcome'] = f'ERROR: {gen.error[call]}' replace['errormsg'] = 'Resleak. @{call}@ at @{filename}@:@{line:MBIERROR}@ lacks several free.' replace['change_size'] = 'size=PARAM_PER_ITERATION;' - replace['loop'] = 'for (int i = 0; i < ITERATIONS; i++) {\n for (j = 0; j < PARAM_PER_ITERATION; j++) {' + replace['loop'] = 'for (i = 0; i < ITERATIONS; i++) {\n for (j = 0; j < PARAM_PER_ITERATION; j++) {' replace['cond'] = ' if (j < PARAM_PER_ITERATION - PARAM_LOST_PER_ITERATION) {' replace['fini'] = gen.fini[call]("1") + ' /* MBIERROR */' replace['end'] = ' }\n }\n }' diff --git a/teshsuite/smpi/MBI/generator_utils.py b/teshsuite/smpi/MBI/generator_utils.py index 78f5b5e4a0..af5750bbd5 100644 --- a/teshsuite/smpi/MBI/generator_utils.py +++ b/teshsuite/smpi/MBI/generator_utils.py @@ -9,10 +9,11 @@ import re # Collectives coll = ['MPI_Barrier', 'MPI_Bcast', 'MPI_Reduce', 'MPI_Gather', 'MPI_Scatter', 'MPI_Scan', 'MPI_Exscan', 'MPI_Allgather', 'MPI_Allreduce', 'MPI_Allgatherv', 'MPI_Alltoall', 'MPI_Alltoallv'] icoll = ['MPI_Ibcast', 'MPI_Ireduce', 'MPI_Igather', 'MPI_Iscatter', 'MPI_Iscan', 'MPI_Iexscan', 'MPI_Iallgather', 'MPI_Iallreduce', 'MPI_Iallgatherv', 'MPI_Ialltoall', 'MPI_Ialltoallv'] +barrier = ['MPI_Barrier'] ibarrier = ['MPI_Ibarrier'] coll4op = ['MPI_Reduce', 'MPI_Allreduce'] icoll4op = ['MPI_Ireduce', 'MPI_Iallreduce'] -coll4root = ['MPI_Reduce', 'MPI_Bcast', 'MPI_Gather', 'MPI_Scatter'] +coll4root = ['MPI_Reduce', 'MPI_Bcast', 'MPI_Gather', 'MPI_Scatter'] icoll4root = ['MPI_Ireduce', 'MPI_Ibcast', 'MPI_Igather', 'MPI_Iscatter'] pcoll = [] tcoll = ['MPI_Comm_split', 'MPI_Op_create', 'MPI_Comm_dup', 'MPI_Type_contiguous', 'MPI_Comm_create', 'MPI_Group_excl'] # MPI_Comm_dup removed @@ -31,8 +32,10 @@ recv = ['MPI_Recv'] irecv = ['MPI_Irecv'] precv = ['MPI_Recv_init'] probe = ['MPI_Probe'] +sendrecv = ['MPI_Sendrecv'] # RMA +epoch = ['MPI_Win_fence', 'MPI_Win_lock', 'MPI_Win_lock_all'] rma = ['MPI_Get', 'MPI_Put'] get = ['MPI_Get'] put = ['MPI_Put'] @@ -350,6 +353,12 @@ fini['MPI_Probe'] = lambda n: "" free['MPI_Probe'] = lambda n: "" write['MPI_Probe'] = lambda n: "" +init['MPI_Sendrecv'] = lambda n: f'int sbuf{n}[N+2]={{rank}}; int rbuf{n}[N]={{rank}}; int * psbuf{n} = &sbuf{n}[0]; int * prbuf{n} = &rbuf{n}[0]; MPI_Status sta{n};' +start['MPI_Sendrecv'] = lambda n: "" +operation['MPI_Sendrecv'] = lambda n: f'MPI_Sendrecv(psbuf{n}, buff_size, type, dest, stag, prbuf{n}, buff_size, type, src, rtag, newcom, &sta{n});' +fini['MPI_Sendrecv'] = lambda n: "" +free['MPI_Sendrecv'] = lambda n: "" +write['MPI_Sendrecv'] = lambda n: f"prbuf{n} = &sbuf{n}[0];" ### P2P:nonblocking @@ -393,23 +402,23 @@ finEpoch['MPI_Win_lock'] = lambda n: 'MPI_Win_unlock(target, win);' epoch['MPI_Win_lock_all'] = lambda n: 'MPI_Win_lock_all(0,win);' finEpoch['MPI_Win_lock_all'] = lambda n: 'MPI_Win_unlock_all(win);' -init['MPI_Put'] = lambda n: f'int localbuf{n}[N] = {{0}};\n localbuf{n}[0] = 12345;' +init['MPI_Put'] = lambda n: f'int localbuf{n}[N] = {{12345}};' operation['MPI_Put'] = lambda n: f'MPI_Put(&localbuf{n}, N, MPI_INT, target, 0, N, type, win);' -init['MPI_Get'] = lambda n: f'int localbuf{n}[N] = {{0}};\n localbuf{n}[0] = 54321;' +init['MPI_Get'] = lambda n: f'int localbuf{n}[N] = {{54321}};' operation['MPI_Get'] = lambda n: f'MPI_Get(&localbuf{n}, N, MPI_INT, target, 0, N, type, win);' init['store'] = lambda n: f'int localbuf{n}[N] = {{0}};' operation['store'] = lambda n: f'localbuf{n}[0] = 8;' init['rstore'] = lambda n: "" -operation['rstore'] = lambda n: 'winbuf[20] = 12346;' +operation['rstore'] = lambda n: f'winbuf[5] = 12346;' init['load'] = lambda n: f'int localbuf{n}[N] = {{0}};' operation['load'] = lambda n: f'int load = localbuf{n}[0];' init['rload'] = lambda n: "" -operation['rload'] = lambda n: "int load = winbuf[20];" +operation['rload'] = lambda n: "int load = winbuf[5];" init['loadstore'] = lambda n: f'int localbuf{n}[N] = {{0}};' operation['loadstore'] = lambda n: f'if (localbuf{n}[0] % 2 == 0) localbuf{n}[0]++; ' diff --git a/teshsuite/smpi/MBI/simgrid.py b/teshsuite/smpi/MBI/simgrid.py index 2119d40f8e..907abc880b 100644 --- a/teshsuite/smpi/MBI/simgrid.py +++ b/teshsuite/smpi/MBI/simgrid.py @@ -49,13 +49,13 @@ class Tool(mbi.AbstractTool): outfile.write(' \n') outfile.write('\n') - execcmd = execcmd.replace("mpirun", "smpirun -wrapper simgrid-mc -platform ./cluster.xml -analyze --cfg=smpi/finalization-barrier:on --cfg=smpi/list-leaks:10 --cfg=model-check/max-depth:10000") + execcmd = execcmd.replace("mpirun", "smpirun -wrapper simgrid-mc -platform ./cluster.xml -analyze --cfg=smpi/barrier-finalization:on --cfg=smpi/list-leaks:10 --cfg=model-check/max-depth:10000") execcmd = execcmd.replace('${EXE}', binary) execcmd = execcmd.replace('$zero_buffer', "--cfg=smpi/buffering:zero") execcmd = execcmd.replace('$infty_buffer', "--cfg=smpi/buffering:infty") mbi.run_cmd( - buildcmd=f"smpicc {filename} -trace-call-location -g -Wl,-znorelro -Wl,-znoseparate-code -o {binary}", + buildcmd=f"smpicc {filename} -trace-call-location -g -o {binary}", execcmd=execcmd, cachefile=cachefile, filename=filename, diff --git a/teshsuite/smpi/auto-shared/auto-shared.c b/teshsuite/smpi/auto-shared/auto-shared.c index 4c6718f1f7..2af5a4210b 100644 --- a/teshsuite/smpi/auto-shared/auto-shared.c +++ b/teshsuite/smpi/auto-shared/auto-shared.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/bug-17132/bug-17132.c b/teshsuite/smpi/bug-17132/bug-17132.c index 4e3f6fdf49..158eeef74d 100644 --- a/teshsuite/smpi/bug-17132/bug-17132.c +++ b/teshsuite/smpi/bug-17132/bug-17132.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2022. The SimGrid Team. +/* Copyright (c) 2014-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-allgather/coll-allgather.c b/teshsuite/smpi/coll-allgather/coll-allgather.c index a6600f83f9..2ca914cc9c 100644 --- a/teshsuite/smpi/coll-allgather/coll-allgather.c +++ b/teshsuite/smpi/coll-allgather/coll-allgather.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/coll-allgatherv/coll-allgatherv.c b/teshsuite/smpi/coll-allgatherv/coll-allgatherv.c index 5b857e4b9e..c2358fd3f0 100644 --- a/teshsuite/smpi/coll-allgatherv/coll-allgatherv.c +++ b/teshsuite/smpi/coll-allgatherv/coll-allgatherv.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-allreduce-with-leaks/coll-allreduce-with-leaks.c b/teshsuite/smpi/coll-allreduce-with-leaks/coll-allreduce-with-leaks.c index bc28bf101b..f4dac7dd55 100644 --- a/teshsuite/smpi/coll-allreduce-with-leaks/coll-allreduce-with-leaks.c +++ b/teshsuite/smpi/coll-allreduce-with-leaks/coll-allreduce-with-leaks.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-allreduce-with-leaks/mc-coll-allreduce-with-leaks.tesh b/teshsuite/smpi/coll-allreduce-with-leaks/mc-coll-allreduce-with-leaks.tesh index 4ffce51371..ecdacc4b36 100644 --- a/teshsuite/smpi/coll-allreduce-with-leaks/mc-coll-allreduce-with-leaks.tesh +++ b/teshsuite/smpi/coll-allreduce-with-leaks/mc-coll-allreduce-with-leaks.tesh @@ -1,12 +1,56 @@ # Smpi Allreduce collectives tests p Test allreduce -$ $VALGRIND_NO_LEAK_CHECK ${bindir:=.}/../../../smpi_script/bin/smpirun -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -map -hostfile ../hostfile_coll -platform ${platfdir:=.}/small_platform.xml -np 4 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-allreduce-with-leaks --log=smpi_config.thres:warning --cfg=smpi/display-allocs:yes --cfg=smpi/simulate-computation:no --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error --cfg=smpi/list-leaks:10 --log=no_loc -> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. +$ $VALGRIND_NO_LEAK_CHECK ${bindir:=.}/../../../smpi_script/bin/smpirun -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -map -hostfile ../hostfile_coll -platform ${platfdir:=.}/small_platform.xml -np 4 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-allreduce-with-leaks --log=smpi_config.thres:warning --cfg=smpi/display-allocs:yes --cfg=smpi/simulate-computation:no --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --cfg=smpi/list-leaks:10 --log=no_loc > [0.000000] [smpi/INFO] [rank 0] -> Tremblay > [0.000000] [smpi/INFO] [rank 1] -> Tremblay > [0.000000] [smpi/INFO] [rank 2] -> Tremblay > [0.000000] [smpi/INFO] [rank 3] -> Tremblay +> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor. +> [0.000000] [smpi_utils/INFO] Probable memory leaks in your code: SMPI detected 8 unfreed MPI handles: +> [0.000000] [smpi_utils/WARNING] To get more information (location of allocations), compile your code with -trace-call-location flag of smpicc/f90 +> [0.000000] [smpi_utils/INFO] 4 leaked handles of type MPI_Comm +> [0.000000] [smpi_utils/INFO] 4 leaked handles of type MPI_Group +> [0.000000] [smpi_utils/INFO] Probable memory leaks in your code: SMPI detected 8 unfreed buffers: +> [0.000000] [smpi_utils/INFO] leaked allocations of total size 152, called 8 times, with minimum size 16 and maximum size 28 +> [0.000000] [smpi_utils/INFO] Memory Usage: Simulated application allocated 152 bytes during its lifetime through malloc/calloc calls. +> Largest allocation at once from a single process was 28 bytes, at coll-allreduce-with-leaks.c:28. It was called 1 times during the whole simulation. +> If this is too much, consider sharing allocations for computation buffers. +> This can be done automatically by setting --cfg=smpi/auto-shared-malloc-thresh to the minimum size wanted size (this can alter execution if data content is necessary) +> +> [0.000000] [smpi_utils/INFO] Probable memory leaks in your code: SMPI detected 8 unfreed MPI handles: +> [0.000000] [smpi_utils/WARNING] To get more information (location of allocations), compile your code with -trace-call-location flag of smpicc/f90 +> [0.000000] [smpi_utils/INFO] 4 leaked handles of type MPI_Comm +> [0.000000] [smpi_utils/INFO] 4 leaked handles of type MPI_Group +> [0.000000] [smpi_utils/INFO] Probable memory leaks in your code: SMPI detected 8 unfreed buffers: +> [0.000000] [smpi_utils/INFO] leaked allocations of total size 152, called 8 times, with minimum size 16 and maximum size 28 +> [0.000000] [smpi_utils/INFO] Memory Usage: Simulated application allocated 152 bytes during its lifetime through malloc/calloc calls. +> Largest allocation at once from a single process was 28 bytes, at coll-allreduce-with-leaks.c:28. It was called 1 times during the whole simulation. +> If this is too much, consider sharing allocations for computation buffers. +> This can be done automatically by setting --cfg=smpi/auto-shared-malloc-thresh to the minimum size wanted size (this can alter execution if data content is necessary) +> +> [0.000000] [smpi_utils/INFO] Probable memory leaks in your code: SMPI detected 8 unfreed MPI handles: +> [0.000000] [smpi_utils/WARNING] To get more information (location of allocations), compile your code with -trace-call-location flag of smpicc/f90 +> [0.000000] [smpi_utils/INFO] 4 leaked handles of type MPI_Comm +> [0.000000] [smpi_utils/INFO] 4 leaked handles of type MPI_Group +> [0.000000] [smpi_utils/INFO] Probable memory leaks in your code: SMPI detected 8 unfreed buffers: +> [0.000000] [smpi_utils/INFO] leaked allocations of total size 152, called 8 times, with minimum size 16 and maximum size 28 +> [0.000000] [smpi_utils/INFO] Memory Usage: Simulated application allocated 152 bytes during its lifetime through malloc/calloc calls. +> Largest allocation at once from a single process was 28 bytes, at coll-allreduce-with-leaks.c:28. It was called 1 times during the whole simulation. +> If this is too much, consider sharing allocations for computation buffers. +> This can be done automatically by setting --cfg=smpi/auto-shared-malloc-thresh to the minimum size wanted size (this can alter execution if data content is necessary) +> +> [0.000000] [smpi_utils/INFO] Probable memory leaks in your code: SMPI detected 8 unfreed MPI handles: +> [0.000000] [smpi_utils/WARNING] To get more information (location of allocations), compile your code with -trace-call-location flag of smpicc/f90 +> [0.000000] [smpi_utils/INFO] 4 leaked handles of type MPI_Comm +> [0.000000] [smpi_utils/INFO] 4 leaked handles of type MPI_Group +> [0.000000] [smpi_utils/INFO] Probable memory leaks in your code: SMPI detected 8 unfreed buffers: +> [0.000000] [smpi_utils/INFO] leaked allocations of total size 152, called 8 times, with minimum size 16 and maximum size 28 +> [0.000000] [smpi_utils/INFO] Memory Usage: Simulated application allocated 152 bytes during its lifetime through malloc/calloc calls. +> Largest allocation at once from a single process was 28 bytes, at coll-allreduce-with-leaks.c:28. It was called 1 times during the whole simulation. +> If this is too much, consider sharing allocations for computation buffers. +> This can be done automatically by setting --cfg=smpi/auto-shared-malloc-thresh to the minimum size wanted size (this can alter execution if data content is necessary) +> > [0.000000] [smpi_utils/INFO] Probable memory leaks in your code: SMPI detected 8 unfreed MPI handles: > [0.000000] [smpi_utils/WARNING] To get more information (location of allocations), compile your code with -trace-call-location flag of smpicc/f90 > [0.000000] [smpi_utils/INFO] 4 leaked handles of type MPI_Comm @@ -29,4 +73,4 @@ $ $VALGRIND_NO_LEAK_CHECK ${bindir:=.}/../../../smpi_script/bin/smpirun -wrapper > If this is too much, consider sharing allocations for computation buffers. > This can be done automatically by setting --cfg=smpi/auto-shared-malloc-thresh to the minimum size wanted size (this can alter execution if data content is necessary) > -> [0.000000] [mc_dfs/INFO] DFS exploration ended. 33 unique states visited; 7 backtracks (140 transition replays, 101 states visited overall) +> [0.000000] [mc_dfs/INFO] DFS exploration ended. 211 unique states visited; 50 backtracks (837 transition replays, 1098 states visited overall) diff --git a/teshsuite/smpi/coll-allreduce/coll-allreduce-automatic.tesh b/teshsuite/smpi/coll-allreduce/coll-allreduce-automatic.tesh index 940489f77a..fff9336f24 100644 --- a/teshsuite/smpi/coll-allreduce/coll-allreduce-automatic.tesh +++ b/teshsuite/smpi/coll-allreduce/coll-allreduce-automatic.tesh @@ -2,7 +2,7 @@ p Test allreduce ! output sort -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_coll -platform ${platfdir:=.}/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-allreduce --log=smpi_config.thres:warning --log=smpi_coll.thres:error --cfg=smpi/allreduce:automatic --cfg=smpi/async-small-thresh:65536 --cfg=smpi/send-is-detached-thresh:128000 --cfg=smpi/simulate-computation:no "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_coll -platform ${platfdir:=.}/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-allreduce --log=smpi_config.thres:warning --log=smpi_coll.thres:error --cfg=smpi/allreduce:automatic --cfg=smpi/async-small-thresh:65536 --cfg=smpi/send-is-detached-thresh:128000 --cfg=smpi/simulate-computation:no "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error --log=root.app:stdout > [ 0.000000] (0:maestro@) [rank 0] -> Tremblay > [ 0.000000] (0:maestro@) [rank 1] -> Tremblay > [ 0.000000] (0:maestro@) [rank 2] -> Tremblay diff --git a/teshsuite/smpi/coll-allreduce/coll-allreduce-papi.tesh b/teshsuite/smpi/coll-allreduce/coll-allreduce-papi.tesh index d47dba95c8..099247533f 100644 --- a/teshsuite/smpi/coll-allreduce/coll-allreduce-papi.tesh +++ b/teshsuite/smpi/coll-allreduce/coll-allreduce-papi.tesh @@ -1,7 +1,7 @@ # Smpi Allreduce collectives tests ! output sort -p Test allreduce with papi events activated - needs papi installed, simgrid compiled with it, and sudo or sudo sh -c "echo 0 > /proc/sys/kernel/perf_event_paranoid" +p Test allreduce with papi events activated - needs papi installed, SimGrid compiled with it, and sudo or sudo sh -c "echo 0 > /proc/sys/kernel/perf_event_paranoid" $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_coll -platform ${platfdir:=.}/small_platform.xml -np 16 -trace --log=xbt_cfg.thres:critical ${bindir:=.}/coll-allreduce --log=smpi_config.thres:warning --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error --cfg=smpi/papi-events:default:PAPI_L1_TCM:PAPI_TOT_CYC > [0.000000] [smpi/INFO] [rank 0] -> Tremblay > [0.000000] [smpi/INFO] [rank 1] -> Tremblay diff --git a/teshsuite/smpi/coll-allreduce/coll-allreduce.c b/teshsuite/smpi/coll-allreduce/coll-allreduce.c index 0d03353bc7..c7b3fd56a0 100644 --- a/teshsuite/smpi/coll-allreduce/coll-allreduce.c +++ b/teshsuite/smpi/coll-allreduce/coll-allreduce.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-alltoall/coll-alltoall.c b/teshsuite/smpi/coll-alltoall/coll-alltoall.c index 0c5b652993..cf979c7898 100644 --- a/teshsuite/smpi/coll-alltoall/coll-alltoall.c +++ b/teshsuite/smpi/coll-alltoall/coll-alltoall.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-alltoall/griffon.tesh b/teshsuite/smpi/coll-alltoall/griffon.tesh deleted file mode 100644 index 46aec20979..0000000000 --- a/teshsuite/smpi/coll-alltoall/griffon.tesh +++ /dev/null @@ -1,521 +0,0 @@ -# Smpi Alltoall on various cluster files, with several routings -! output sort - -p Test classic - backbone -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ${bindir}/../hostfile_cluster -platform ${platfdir:=.}/cluster_backbone.xml -np 12 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-alltoall -q --log=smpi_config.thres:warning --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error -> [0.000000] [smpi/INFO] [rank 0] -> node-0.simgrid.org -> [0.000000] [smpi/INFO] [rank 1] -> node-1.simgrid.org -> [0.000000] [smpi/INFO] [rank 2] -> node-2.simgrid.org -> [0.000000] [smpi/INFO] [rank 3] -> node-3.simgrid.org -> [0.000000] [smpi/INFO] [rank 4] -> node-4.simgrid.org -> [0.000000] [smpi/INFO] [rank 5] -> node-5.simgrid.org -> [0.000000] [smpi/INFO] [rank 6] -> node-6.simgrid.org -> [0.000000] [smpi/INFO] [rank 7] -> node-7.simgrid.org -> [0.000000] [smpi/INFO] [rank 8] -> node-8.simgrid.org -> [0.000000] [smpi/INFO] [rank 9] -> node-9.simgrid.org -> [0.000000] [smpi/INFO] [rank 10] -> node-10.simgrid.org -> [0.000000] [smpi/INFO] [rank 11] -> node-11.simgrid.org -> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 ] -> [1] sndbuf=[12 13 14 15 16 17 18 19 20 21 22 23 ] -> [2] sndbuf=[24 25 26 27 28 29 30 31 32 33 34 35 ] -> [3] sndbuf=[36 37 38 39 40 41 42 43 44 45 46 47 ] -> [4] sndbuf=[48 49 50 51 52 53 54 55 56 57 58 59 ] -> [5] sndbuf=[60 61 62 63 64 65 66 67 68 69 70 71 ] -> [6] sndbuf=[72 73 74 75 76 77 78 79 80 81 82 83 ] -> [7] sndbuf=[84 85 86 87 88 89 90 91 92 93 94 95 ] -> [8] sndbuf=[96 97 98 99 100 101 102 103 104 105 106 107 ] -> [9] sndbuf=[108 109 110 111 112 113 114 115 116 117 118 119 ] -> [10] sndbuf=[120 121 122 123 124 125 126 127 128 129 130 131 ] -> [11] sndbuf=[132 133 134 135 136 137 138 139 140 141 142 143 ] -> [0] rcvbuf=[0 12 24 36 48 60 72 84 96 108 120 132 ] -> [10] rcvbuf=[10 22 34 46 58 70 82 94 106 118 130 142 ] -> [11] rcvbuf=[11 23 35 47 59 71 83 95 107 119 131 143 ] -> [8] rcvbuf=[8 20 32 44 56 68 80 92 104 116 128 140 ] -> [3] rcvbuf=[3 15 27 39 51 63 75 87 99 111 123 135 ] -> [2] rcvbuf=[2 14 26 38 50 62 74 86 98 110 122 134 ] -> [6] rcvbuf=[6 18 30 42 54 66 78 90 102 114 126 138 ] -> [7] rcvbuf=[7 19 31 43 55 67 79 91 103 115 127 139 ] -> [4] rcvbuf=[4 16 28 40 52 64 76 88 100 112 124 136 ] -> [9] rcvbuf=[9 21 33 45 57 69 81 93 105 117 129 141 ] -> [5] rcvbuf=[5 17 29 41 53 65 77 89 101 113 125 137 ] -> [1] rcvbuf=[1 13 25 37 49 61 73 85 97 109 121 133 ] - -! output sort -p Test separate clusters -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -platform ${platfdir:=.}/cluster_multi.xml -np 12 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-alltoall -q --log=smpi_config.thres:warning --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error -> [0.000000] [smpi/INFO] [rank 0] -> node-0.1core.org -> [0.000000] [smpi/INFO] [rank 1] -> node-1.1core.org -> [0.000000] [smpi/INFO] [rank 2] -> node-2.1core.org -> [0.000000] [smpi/INFO] [rank 3] -> node-3.1core.org -> [0.000000] [smpi/INFO] [rank 4] -> node-4.1core.org -> [0.000000] [smpi/INFO] [rank 5] -> node-5.1core.org -> [0.000000] [smpi/INFO] [rank 6] -> node-6.1core.org -> [0.000000] [smpi/INFO] [rank 7] -> node-0.2cores.org -> [0.000000] [smpi/INFO] [rank 8] -> node-1.2cores.org -> [0.000000] [smpi/INFO] [rank 9] -> node-2.2cores.org -> [0.000000] [smpi/INFO] [rank 10] -> node-3.2cores.org -> [0.000000] [smpi/INFO] [rank 11] -> node-4.2cores.org -> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 ] -> [1] sndbuf=[12 13 14 15 16 17 18 19 20 21 22 23 ] -> [2] sndbuf=[24 25 26 27 28 29 30 31 32 33 34 35 ] -> [3] sndbuf=[36 37 38 39 40 41 42 43 44 45 46 47 ] -> [4] sndbuf=[48 49 50 51 52 53 54 55 56 57 58 59 ] -> [5] sndbuf=[60 61 62 63 64 65 66 67 68 69 70 71 ] -> [6] sndbuf=[72 73 74 75 76 77 78 79 80 81 82 83 ] -> [7] sndbuf=[84 85 86 87 88 89 90 91 92 93 94 95 ] -> [8] sndbuf=[96 97 98 99 100 101 102 103 104 105 106 107 ] -> [9] sndbuf=[108 109 110 111 112 113 114 115 116 117 118 119 ] -> [10] sndbuf=[120 121 122 123 124 125 126 127 128 129 130 131 ] -> [11] sndbuf=[132 133 134 135 136 137 138 139 140 141 142 143 ] -> [0] rcvbuf=[0 12 24 36 48 60 72 84 96 108 120 132 ] -> [10] rcvbuf=[10 22 34 46 58 70 82 94 106 118 130 142 ] -> [11] rcvbuf=[11 23 35 47 59 71 83 95 107 119 131 143 ] -> [8] rcvbuf=[8 20 32 44 56 68 80 92 104 116 128 140 ] -> [3] rcvbuf=[3 15 27 39 51 63 75 87 99 111 123 135 ] -> [2] rcvbuf=[2 14 26 38 50 62 74 86 98 110 122 134 ] -> [6] rcvbuf=[6 18 30 42 54 66 78 90 102 114 126 138 ] -> [7] rcvbuf=[7 19 31 43 55 67 79 91 103 115 127 139 ] -> [4] rcvbuf=[4 16 28 40 52 64 76 88 100 112 124 136 ] -> [9] rcvbuf=[9 21 33 45 57 69 81 93 105 117 129 141 ] -> [5] rcvbuf=[5 17 29 41 53 65 77 89 101 113 125 137 ] -> [1] rcvbuf=[1 13 25 37 49 61 73 85 97 109 121 133 ] - -! output sort -p Test torus -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_cluster -platform ${platfdir:=.}/cluster_torus.xml -np 12 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-alltoall -q --log=smpi_config.thres:warning --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error -> [0.000000] [smpi/INFO] [rank 0] -> node-0.simgrid.org -> [0.000000] [smpi/INFO] [rank 1] -> node-1.simgrid.org -> [0.000000] [smpi/INFO] [rank 2] -> node-2.simgrid.org -> [0.000000] [smpi/INFO] [rank 3] -> node-3.simgrid.org -> [0.000000] [smpi/INFO] [rank 4] -> node-4.simgrid.org -> [0.000000] [smpi/INFO] [rank 5] -> node-5.simgrid.org -> [0.000000] [smpi/INFO] [rank 6] -> node-6.simgrid.org -> [0.000000] [smpi/INFO] [rank 7] -> node-7.simgrid.org -> [0.000000] [smpi/INFO] [rank 8] -> node-8.simgrid.org -> [0.000000] [smpi/INFO] [rank 9] -> node-9.simgrid.org -> [0.000000] [smpi/INFO] [rank 10] -> node-10.simgrid.org -> [0.000000] [smpi/INFO] [rank 11] -> node-11.simgrid.org -> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 ] -> [1] sndbuf=[12 13 14 15 16 17 18 19 20 21 22 23 ] -> [2] sndbuf=[24 25 26 27 28 29 30 31 32 33 34 35 ] -> [3] sndbuf=[36 37 38 39 40 41 42 43 44 45 46 47 ] -> [4] sndbuf=[48 49 50 51 52 53 54 55 56 57 58 59 ] -> [5] sndbuf=[60 61 62 63 64 65 66 67 68 69 70 71 ] -> [6] sndbuf=[72 73 74 75 76 77 78 79 80 81 82 83 ] -> [7] sndbuf=[84 85 86 87 88 89 90 91 92 93 94 95 ] -> [8] sndbuf=[96 97 98 99 100 101 102 103 104 105 106 107 ] -> [9] sndbuf=[108 109 110 111 112 113 114 115 116 117 118 119 ] -> [10] sndbuf=[120 121 122 123 124 125 126 127 128 129 130 131 ] -> [11] sndbuf=[132 133 134 135 136 137 138 139 140 141 142 143 ] -> [0] rcvbuf=[0 12 24 36 48 60 72 84 96 108 120 132 ] -> [10] rcvbuf=[10 22 34 46 58 70 82 94 106 118 130 142 ] -> [11] rcvbuf=[11 23 35 47 59 71 83 95 107 119 131 143 ] -> [8] rcvbuf=[8 20 32 44 56 68 80 92 104 116 128 140 ] -> [3] rcvbuf=[3 15 27 39 51 63 75 87 99 111 123 135 ] -> [2] rcvbuf=[2 14 26 38 50 62 74 86 98 110 122 134 ] -> [6] rcvbuf=[6 18 30 42 54 66 78 90 102 114 126 138 ] -> [7] rcvbuf=[7 19 31 43 55 67 79 91 103 115 127 139 ] -> [4] rcvbuf=[4 16 28 40 52 64 76 88 100 112 124 136 ] -> [9] rcvbuf=[9 21 33 45 57 69 81 93 105 117 129 141 ] -> [5] rcvbuf=[5 17 29 41 53 65 77 89 101 113 125 137 ] -> [1] rcvbuf=[1 13 25 37 49 61 73 85 97 109 121 133 ] - -! output sort -p Test fat tree -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_cluster -platform ${platfdir:=.}/cluster_fat_tree.xml -np 12 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-alltoall -q --log=smpi_config.thres:warning --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error -> [0.000000] [smpi/INFO] [rank 0] -> node-0.simgrid.org -> [0.000000] [smpi/INFO] [rank 1] -> node-1.simgrid.org -> [0.000000] [smpi/INFO] [rank 2] -> node-2.simgrid.org -> [0.000000] [smpi/INFO] [rank 3] -> node-3.simgrid.org -> [0.000000] [smpi/INFO] [rank 4] -> node-4.simgrid.org -> [0.000000] [smpi/INFO] [rank 5] -> node-5.simgrid.org -> [0.000000] [smpi/INFO] [rank 6] -> node-6.simgrid.org -> [0.000000] [smpi/INFO] [rank 7] -> node-7.simgrid.org -> [0.000000] [smpi/INFO] [rank 8] -> node-8.simgrid.org -> [0.000000] [smpi/INFO] [rank 9] -> node-9.simgrid.org -> [0.000000] [smpi/INFO] [rank 10] -> node-10.simgrid.org -> [0.000000] [smpi/INFO] [rank 11] -> node-11.simgrid.org -> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 ] -> [1] sndbuf=[12 13 14 15 16 17 18 19 20 21 22 23 ] -> [2] sndbuf=[24 25 26 27 28 29 30 31 32 33 34 35 ] -> [3] sndbuf=[36 37 38 39 40 41 42 43 44 45 46 47 ] -> [4] sndbuf=[48 49 50 51 52 53 54 55 56 57 58 59 ] -> [5] sndbuf=[60 61 62 63 64 65 66 67 68 69 70 71 ] -> [6] sndbuf=[72 73 74 75 76 77 78 79 80 81 82 83 ] -> [7] sndbuf=[84 85 86 87 88 89 90 91 92 93 94 95 ] -> [8] sndbuf=[96 97 98 99 100 101 102 103 104 105 106 107 ] -> [9] sndbuf=[108 109 110 111 112 113 114 115 116 117 118 119 ] -> [10] sndbuf=[120 121 122 123 124 125 126 127 128 129 130 131 ] -> [11] sndbuf=[132 133 134 135 136 137 138 139 140 141 142 143 ] -> [0] rcvbuf=[0 12 24 36 48 60 72 84 96 108 120 132 ] -> [10] rcvbuf=[10 22 34 46 58 70 82 94 106 118 130 142 ] -> [11] rcvbuf=[11 23 35 47 59 71 83 95 107 119 131 143 ] -> [8] rcvbuf=[8 20 32 44 56 68 80 92 104 116 128 140 ] -> [3] rcvbuf=[3 15 27 39 51 63 75 87 99 111 123 135 ] -> [2] rcvbuf=[2 14 26 38 50 62 74 86 98 110 122 134 ] -> [6] rcvbuf=[6 18 30 42 54 66 78 90 102 114 126 138 ] -> [7] rcvbuf=[7 19 31 43 55 67 79 91 103 115 127 139 ] -> [4] rcvbuf=[4 16 28 40 52 64 76 88 100 112 124 136 ] -> [9] rcvbuf=[9 21 33 45 57 69 81 93 105 117 129 141 ] -> [5] rcvbuf=[5 17 29 41 53 65 77 89 101 113 125 137 ] -> [1] rcvbuf=[1 13 25 37 49 61 73 85 97 109 121 133 ] - -! output sort -p Test fat tree IB -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_cluster -platform ${platfdir:=.}/cluster_fat_tree.xml -np 12 --cfg=network/model:IB --log=xbt_cfg.thres:critical ${bindir:=.}/coll-alltoall -q --log=smpi_config.thres:warning --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error -> [0.000000] [smpi/INFO] [rank 0] -> node-0.simgrid.org -> [0.000000] [smpi/INFO] [rank 1] -> node-1.simgrid.org -> [0.000000] [smpi/INFO] [rank 2] -> node-2.simgrid.org -> [0.000000] [smpi/INFO] [rank 3] -> node-3.simgrid.org -> [0.000000] [smpi/INFO] [rank 4] -> node-4.simgrid.org -> [0.000000] [smpi/INFO] [rank 5] -> node-5.simgrid.org -> [0.000000] [smpi/INFO] [rank 6] -> node-6.simgrid.org -> [0.000000] [smpi/INFO] [rank 7] -> node-7.simgrid.org -> [0.000000] [smpi/INFO] [rank 8] -> node-8.simgrid.org -> [0.000000] [smpi/INFO] [rank 9] -> node-9.simgrid.org -> [0.000000] [smpi/INFO] [rank 10] -> node-10.simgrid.org -> [0.000000] [smpi/INFO] [rank 11] -> node-11.simgrid.org -> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 ] -> [1] sndbuf=[12 13 14 15 16 17 18 19 20 21 22 23 ] -> [2] sndbuf=[24 25 26 27 28 29 30 31 32 33 34 35 ] -> [3] sndbuf=[36 37 38 39 40 41 42 43 44 45 46 47 ] -> [4] sndbuf=[48 49 50 51 52 53 54 55 56 57 58 59 ] -> [5] sndbuf=[60 61 62 63 64 65 66 67 68 69 70 71 ] -> [6] sndbuf=[72 73 74 75 76 77 78 79 80 81 82 83 ] -> [7] sndbuf=[84 85 86 87 88 89 90 91 92 93 94 95 ] -> [8] sndbuf=[96 97 98 99 100 101 102 103 104 105 106 107 ] -> [9] sndbuf=[108 109 110 111 112 113 114 115 116 117 118 119 ] -> [10] sndbuf=[120 121 122 123 124 125 126 127 128 129 130 131 ] -> [11] sndbuf=[132 133 134 135 136 137 138 139 140 141 142 143 ] -> [0] rcvbuf=[0 12 24 36 48 60 72 84 96 108 120 132 ] -> [10] rcvbuf=[10 22 34 46 58 70 82 94 106 118 130 142 ] -> [11] rcvbuf=[11 23 35 47 59 71 83 95 107 119 131 143 ] -> [8] rcvbuf=[8 20 32 44 56 68 80 92 104 116 128 140 ] -> [3] rcvbuf=[3 15 27 39 51 63 75 87 99 111 123 135 ] -> [2] rcvbuf=[2 14 26 38 50 62 74 86 98 110 122 134 ] -> [6] rcvbuf=[6 18 30 42 54 66 78 90 102 114 126 138 ] -> [7] rcvbuf=[7 19 31 43 55 67 79 91 103 115 127 139 ] -> [4] rcvbuf=[4 16 28 40 52 64 76 88 100 112 124 136 ] -> [9] rcvbuf=[9 21 33 45 57 69 81 93 105 117 129 141 ] -> [5] rcvbuf=[5 17 29 41 53 65 77 89 101 113 125 137 ] -> [1] rcvbuf=[1 13 25 37 49 61 73 85 97 109 121 133 ] - -! output sort -p Test Dragonfly -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_cluster -platform ${platfdir:=.}/cluster_dragonfly.xml -np 12 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-alltoall -q --log=smpi_config.thres:warning --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error -> [0.000000] [smpi/INFO] [rank 0] -> node-0.simgrid.org -> [0.000000] [smpi/INFO] [rank 1] -> node-1.simgrid.org -> [0.000000] [smpi/INFO] [rank 2] -> node-2.simgrid.org -> [0.000000] [smpi/INFO] [rank 3] -> node-3.simgrid.org -> [0.000000] [smpi/INFO] [rank 4] -> node-4.simgrid.org -> [0.000000] [smpi/INFO] [rank 5] -> node-5.simgrid.org -> [0.000000] [smpi/INFO] [rank 6] -> node-6.simgrid.org -> [0.000000] [smpi/INFO] [rank 7] -> node-7.simgrid.org -> [0.000000] [smpi/INFO] [rank 8] -> node-8.simgrid.org -> [0.000000] [smpi/INFO] [rank 9] -> node-9.simgrid.org -> [0.000000] [smpi/INFO] [rank 10] -> node-10.simgrid.org -> [0.000000] [smpi/INFO] [rank 11] -> node-11.simgrid.org -> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 ] -> [1] sndbuf=[12 13 14 15 16 17 18 19 20 21 22 23 ] -> [2] sndbuf=[24 25 26 27 28 29 30 31 32 33 34 35 ] -> [3] sndbuf=[36 37 38 39 40 41 42 43 44 45 46 47 ] -> [4] sndbuf=[48 49 50 51 52 53 54 55 56 57 58 59 ] -> [5] sndbuf=[60 61 62 63 64 65 66 67 68 69 70 71 ] -> [6] sndbuf=[72 73 74 75 76 77 78 79 80 81 82 83 ] -> [7] sndbuf=[84 85 86 87 88 89 90 91 92 93 94 95 ] -> [8] sndbuf=[96 97 98 99 100 101 102 103 104 105 106 107 ] -> [9] sndbuf=[108 109 110 111 112 113 114 115 116 117 118 119 ] -> [10] sndbuf=[120 121 122 123 124 125 126 127 128 129 130 131 ] -> [11] sndbuf=[132 133 134 135 136 137 138 139 140 141 142 143 ] -> [0] rcvbuf=[0 12 24 36 48 60 72 84 96 108 120 132 ] -> [10] rcvbuf=[10 22 34 46 58 70 82 94 106 118 130 142 ] -> [11] rcvbuf=[11 23 35 47 59 71 83 95 107 119 131 143 ] -> [8] rcvbuf=[8 20 32 44 56 68 80 92 104 116 128 140 ] -> [3] rcvbuf=[3 15 27 39 51 63 75 87 99 111 123 135 ] -> [2] rcvbuf=[2 14 26 38 50 62 74 86 98 110 122 134 ] -> [6] rcvbuf=[6 18 30 42 54 66 78 90 102 114 126 138 ] -> [7] rcvbuf=[7 19 31 43 55 67 79 91 103 115 127 139 ] -> [4] rcvbuf=[4 16 28 40 52 64 76 88 100 112 124 136 ] -> [9] rcvbuf=[9 21 33 45 57 69 81 93 105 117 129 141 ] -> [5] rcvbuf=[5 17 29 41 53 65 77 89 101 113 125 137 ] -> [1] rcvbuf=[1 13 25 37 49 61 73 85 97 109 121 133 ] - -! output sort -p Test Griffon -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_griffon -platform ${platfdir:=.}/griffon.xml -np 92 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-alltoall -q --log=smpi_config.thres:warning --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error -> [0.000000] [smpi/INFO] [rank 0] -> griffon-1.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 1] -> griffon-2.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 2] -> griffon-3.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 3] -> griffon-4.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 4] -> griffon-5.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 5] -> griffon-6.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 6] -> griffon-7.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 7] -> griffon-8.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 8] -> griffon-9.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 9] -> griffon-10.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 10] -> griffon-11.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 11] -> griffon-12.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 12] -> griffon-13.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 13] -> griffon-14.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 14] -> griffon-15.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 15] -> griffon-16.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 16] -> griffon-17.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 17] -> griffon-18.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 18] -> griffon-19.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 19] -> griffon-20.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 20] -> griffon-21.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 21] -> griffon-22.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 22] -> griffon-23.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 23] -> griffon-24.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 24] -> griffon-25.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 25] -> griffon-26.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 26] -> griffon-27.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 27] -> griffon-28.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 28] -> griffon-29.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 29] -> griffon-30.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 30] -> griffon-31.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 31] -> griffon-32.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 32] -> griffon-33.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 33] -> griffon-34.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 34] -> griffon-35.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 35] -> griffon-36.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 36] -> griffon-37.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 37] -> griffon-38.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 38] -> griffon-39.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 39] -> griffon-40.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 40] -> griffon-41.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 41] -> griffon-42.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 42] -> griffon-43.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 43] -> griffon-44.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 44] -> griffon-45.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 45] -> griffon-46.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 46] -> griffon-47.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 47] -> griffon-48.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 48] -> griffon-49.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 49] -> griffon-50.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 50] -> griffon-51.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 51] -> griffon-52.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 52] -> griffon-53.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 53] -> griffon-54.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 54] -> griffon-55.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 55] -> griffon-56.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 56] -> griffon-57.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 57] -> griffon-58.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 58] -> griffon-59.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 59] -> griffon-60.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 60] -> griffon-61.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 61] -> griffon-62.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 62] -> griffon-63.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 63] -> griffon-64.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 64] -> griffon-65.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 65] -> griffon-66.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 66] -> griffon-67.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 67] -> griffon-68.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 68] -> griffon-69.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 69] -> griffon-70.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 70] -> griffon-71.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 71] -> griffon-72.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 72] -> griffon-73.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 73] -> griffon-74.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 74] -> griffon-75.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 75] -> griffon-76.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 76] -> griffon-77.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 77] -> griffon-78.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 78] -> griffon-79.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 79] -> griffon-80.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 80] -> griffon-81.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 81] -> griffon-82.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 82] -> griffon-83.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 83] -> griffon-84.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 84] -> griffon-85.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 85] -> griffon-86.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 86] -> griffon-87.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 87] -> griffon-88.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 88] -> griffon-89.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 89] -> griffon-90.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 90] -> griffon-91.nancy.grid5000.fr -> [0.000000] [smpi/INFO] [rank 91] -> griffon-92.nancy.grid5000.fr -> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 ] -> [1] sndbuf=[92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 ] -> [2] sndbuf=[184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 ] -> [3] sndbuf=[276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 ] -> [4] sndbuf=[368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 ] -> [5] sndbuf=[460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 ] -> [6] sndbuf=[552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 ] -> [7] sndbuf=[644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 ] -> [8] sndbuf=[736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 ] -> [9] sndbuf=[828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 ] -> [10] sndbuf=[920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 ] -> [11] sndbuf=[1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 ] -> [12] sndbuf=[1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 ] -> [13] sndbuf=[1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 ] -> [14] sndbuf=[1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 ] -> [15] sndbuf=[1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 ] -> [16] sndbuf=[1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 ] -> [17] sndbuf=[1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 ] -> [18] sndbuf=[1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 ] -> [19] sndbuf=[1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 ] -> [20] sndbuf=[1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 ] -> [21] sndbuf=[1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 ] -> [22] sndbuf=[2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 ] -> [23] sndbuf=[2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 ] -> [24] sndbuf=[2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 ] -> [25] sndbuf=[2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 ] -> [26] sndbuf=[2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 ] -> [27] sndbuf=[2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 ] -> [28] sndbuf=[2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 ] -> [29] sndbuf=[2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 ] -> [30] sndbuf=[2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 ] -> [31] sndbuf=[2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 ] -> [32] sndbuf=[2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 ] -> [33] sndbuf=[3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 ] -> [34] sndbuf=[3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 ] -> [35] sndbuf=[3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 ] -> [36] sndbuf=[3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 ] -> [37] sndbuf=[3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 ] -> [38] sndbuf=[3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 ] -> [39] sndbuf=[3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 ] -> [40] sndbuf=[3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 ] -> [41] sndbuf=[3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 ] -> [42] sndbuf=[3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 ] -> [43] sndbuf=[3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 ] -> [44] sndbuf=[4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 ] -> [45] sndbuf=[4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 ] -> [46] sndbuf=[4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 ] -> [47] sndbuf=[4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 ] -> [48] sndbuf=[4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 ] -> [49] sndbuf=[4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 ] -> [50] sndbuf=[4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 ] -> [51] sndbuf=[4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 ] -> [52] sndbuf=[4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 ] -> [53] sndbuf=[4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 ] -> [54] sndbuf=[4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 ] -> [55] sndbuf=[5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 ] -> [56] sndbuf=[5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 ] -> [57] sndbuf=[5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 ] -> [58] sndbuf=[5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 ] -> [59] sndbuf=[5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 ] -> [60] sndbuf=[5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 ] -> [61] sndbuf=[5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 ] -> [62] sndbuf=[5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 ] -> [63] sndbuf=[5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 ] -> [64] sndbuf=[5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 ] -> [65] sndbuf=[5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 ] -> [66] sndbuf=[6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 ] -> [67] sndbuf=[6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 ] -> [68] sndbuf=[6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 ] -> [69] sndbuf=[6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 ] -> [70] sndbuf=[6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 ] -> [71] sndbuf=[6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 ] -> [72] sndbuf=[6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 ] -> [73] sndbuf=[6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 ] -> [74] sndbuf=[6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 ] -> [75] sndbuf=[6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 ] -> [76] sndbuf=[6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 ] -> [77] sndbuf=[7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 ] -> [78] sndbuf=[7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 ] -> [79] sndbuf=[7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 ] -> [80] sndbuf=[7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 ] -> [81] sndbuf=[7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 ] -> [82] sndbuf=[7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 ] -> [83] sndbuf=[7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 ] -> [84] sndbuf=[7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 ] -> [85] sndbuf=[7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 ] -> [86] sndbuf=[7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 ] -> [87] sndbuf=[8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 ] -> [88] sndbuf=[8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 ] -> [89] sndbuf=[8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 ] -> [90] sndbuf=[8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 ] -> [91] sndbuf=[8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 ] -> [19] rcvbuf=[19 111 203 295 387 479 571 663 755 847 939 1031 1123 1215 1307 1399 1491 1583 1675 1767 1859 1951 2043 2135 2227 2319 2411 2503 2595 2687 2779 2871 2963 3055 3147 3239 3331 3423 3515 3607 3699 3791 3883 3975 4067 4159 4251 4343 4435 4527 4619 4711 4803 4895 4987 5079 5171 5263 5355 5447 5539 5631 5723 5815 5907 5999 6091 6183 6275 6367 6459 6551 6643 6735 6827 6919 7011 7103 7195 7287 7379 7471 7563 7655 7747 7839 7931 8023 8115 8207 8299 8391 ] -> [17] rcvbuf=[17 109 201 293 385 477 569 661 753 845 937 1029 1121 1213 1305 1397 1489 1581 1673 1765 1857 1949 2041 2133 2225 2317 2409 2501 2593 2685 2777 2869 2961 3053 3145 3237 3329 3421 3513 3605 3697 3789 3881 3973 4065 4157 4249 4341 4433 4525 4617 4709 4801 4893 4985 5077 5169 5261 5353 5445 5537 5629 5721 5813 5905 5997 6089 6181 6273 6365 6457 6549 6641 6733 6825 6917 7009 7101 7193 7285 7377 7469 7561 7653 7745 7837 7929 8021 8113 8205 8297 8389 ] -> [3] rcvbuf=[3 95 187 279 371 463 555 647 739 831 923 1015 1107 1199 1291 1383 1475 1567 1659 1751 1843 1935 2027 2119 2211 2303 2395 2487 2579 2671 2763 2855 2947 3039 3131 3223 3315 3407 3499 3591 3683 3775 3867 3959 4051 4143 4235 4327 4419 4511 4603 4695 4787 4879 4971 5063 5155 5247 5339 5431 5523 5615 5707 5799 5891 5983 6075 6167 6259 6351 6443 6535 6627 6719 6811 6903 6995 7087 7179 7271 7363 7455 7547 7639 7731 7823 7915 8007 8099 8191 8283 8375 ] -> [1] rcvbuf=[1 93 185 277 369 461 553 645 737 829 921 1013 1105 1197 1289 1381 1473 1565 1657 1749 1841 1933 2025 2117 2209 2301 2393 2485 2577 2669 2761 2853 2945 3037 3129 3221 3313 3405 3497 3589 3681 3773 3865 3957 4049 4141 4233 4325 4417 4509 4601 4693 4785 4877 4969 5061 5153 5245 5337 5429 5521 5613 5705 5797 5889 5981 6073 6165 6257 6349 6441 6533 6625 6717 6809 6901 6993 7085 7177 7269 7361 7453 7545 7637 7729 7821 7913 8005 8097 8189 8281 8373 ] -> [27] rcvbuf=[27 119 211 303 395 487 579 671 763 855 947 1039 1131 1223 1315 1407 1499 1591 1683 1775 1867 1959 2051 2143 2235 2327 2419 2511 2603 2695 2787 2879 2971 3063 3155 3247 3339 3431 3523 3615 3707 3799 3891 3983 4075 4167 4259 4351 4443 4535 4627 4719 4811 4903 4995 5087 5179 5271 5363 5455 5547 5639 5731 5823 5915 6007 6099 6191 6283 6375 6467 6559 6651 6743 6835 6927 7019 7111 7203 7295 7387 7479 7571 7663 7755 7847 7939 8031 8123 8215 8307 8399 ] -> [25] rcvbuf=[25 117 209 301 393 485 577 669 761 853 945 1037 1129 1221 1313 1405 1497 1589 1681 1773 1865 1957 2049 2141 2233 2325 2417 2509 2601 2693 2785 2877 2969 3061 3153 3245 3337 3429 3521 3613 3705 3797 3889 3981 4073 4165 4257 4349 4441 4533 4625 4717 4809 4901 4993 5085 5177 5269 5361 5453 5545 5637 5729 5821 5913 6005 6097 6189 6281 6373 6465 6557 6649 6741 6833 6925 7017 7109 7201 7293 7385 7477 7569 7661 7753 7845 7937 8029 8121 8213 8305 8397 ] -> [26] rcvbuf=[26 118 210 302 394 486 578 670 762 854 946 1038 1130 1222 1314 1406 1498 1590 1682 1774 1866 1958 2050 2142 2234 2326 2418 2510 2602 2694 2786 2878 2970 3062 3154 3246 3338 3430 3522 3614 3706 3798 3890 3982 4074 4166 4258 4350 4442 4534 4626 4718 4810 4902 4994 5086 5178 5270 5362 5454 5546 5638 5730 5822 5914 6006 6098 6190 6282 6374 6466 6558 6650 6742 6834 6926 7018 7110 7202 7294 7386 7478 7570 7662 7754 7846 7938 8030 8122 8214 8306 8398 ] -> [16] rcvbuf=[16 108 200 292 384 476 568 660 752 844 936 1028 1120 1212 1304 1396 1488 1580 1672 1764 1856 1948 2040 2132 2224 2316 2408 2500 2592 2684 2776 2868 2960 3052 3144 3236 3328 3420 3512 3604 3696 3788 3880 3972 4064 4156 4248 4340 4432 4524 4616 4708 4800 4892 4984 5076 5168 5260 5352 5444 5536 5628 5720 5812 5904 5996 6088 6180 6272 6364 6456 6548 6640 6732 6824 6916 7008 7100 7192 7284 7376 7468 7560 7652 7744 7836 7928 8020 8112 8204 8296 8388 ] -> [24] rcvbuf=[24 116 208 300 392 484 576 668 760 852 944 1036 1128 1220 1312 1404 1496 1588 1680 1772 1864 1956 2048 2140 2232 2324 2416 2508 2600 2692 2784 2876 2968 3060 3152 3244 3336 3428 3520 3612 3704 3796 3888 3980 4072 4164 4256 4348 4440 4532 4624 4716 4808 4900 4992 5084 5176 5268 5360 5452 5544 5636 5728 5820 5912 6004 6096 6188 6280 6372 6464 6556 6648 6740 6832 6924 7016 7108 7200 7292 7384 7476 7568 7660 7752 7844 7936 8028 8120 8212 8304 8396 ] -> [0] rcvbuf=[0 92 184 276 368 460 552 644 736 828 920 1012 1104 1196 1288 1380 1472 1564 1656 1748 1840 1932 2024 2116 2208 2300 2392 2484 2576 2668 2760 2852 2944 3036 3128 3220 3312 3404 3496 3588 3680 3772 3864 3956 4048 4140 4232 4324 4416 4508 4600 4692 4784 4876 4968 5060 5152 5244 5336 5428 5520 5612 5704 5796 5888 5980 6072 6164 6256 6348 6440 6532 6624 6716 6808 6900 6992 7084 7176 7268 7360 7452 7544 7636 7728 7820 7912 8004 8096 8188 8280 8372 ] -> [8] rcvbuf=[8 100 192 284 376 468 560 652 744 836 928 1020 1112 1204 1296 1388 1480 1572 1664 1756 1848 1940 2032 2124 2216 2308 2400 2492 2584 2676 2768 2860 2952 3044 3136 3228 3320 3412 3504 3596 3688 3780 3872 3964 4056 4148 4240 4332 4424 4516 4608 4700 4792 4884 4976 5068 5160 5252 5344 5436 5528 5620 5712 5804 5896 5988 6080 6172 6264 6356 6448 6540 6632 6724 6816 6908 7000 7092 7184 7276 7368 7460 7552 7644 7736 7828 7920 8012 8104 8196 8288 8380 ] -> [23] rcvbuf=[23 115 207 299 391 483 575 667 759 851 943 1035 1127 1219 1311 1403 1495 1587 1679 1771 1863 1955 2047 2139 2231 2323 2415 2507 2599 2691 2783 2875 2967 3059 3151 3243 3335 3427 3519 3611 3703 3795 3887 3979 4071 4163 4255 4347 4439 4531 4623 4715 4807 4899 4991 5083 5175 5267 5359 5451 5543 5635 5727 5819 5911 6003 6095 6187 6279 6371 6463 6555 6647 6739 6831 6923 7015 7107 7199 7291 7383 7475 7567 7659 7751 7843 7935 8027 8119 8211 8303 8395 ] -> [21] rcvbuf=[21 113 205 297 389 481 573 665 757 849 941 1033 1125 1217 1309 1401 1493 1585 1677 1769 1861 1953 2045 2137 2229 2321 2413 2505 2597 2689 2781 2873 2965 3057 3149 3241 3333 3425 3517 3609 3701 3793 3885 3977 4069 4161 4253 4345 4437 4529 4621 4713 4805 4897 4989 5081 5173 5265 5357 5449 5541 5633 5725 5817 5909 6001 6093 6185 6277 6369 6461 6553 6645 6737 6829 6921 7013 7105 7197 7289 7381 7473 7565 7657 7749 7841 7933 8025 8117 8209 8301 8393 ] -> [7] rcvbuf=[7 99 191 283 375 467 559 651 743 835 927 1019 1111 1203 1295 1387 1479 1571 1663 1755 1847 1939 2031 2123 2215 2307 2399 2491 2583 2675 2767 2859 2951 3043 3135 3227 3319 3411 3503 3595 3687 3779 3871 3963 4055 4147 4239 4331 4423 4515 4607 4699 4791 4883 4975 5067 5159 5251 5343 5435 5527 5619 5711 5803 5895 5987 6079 6171 6263 6355 6447 6539 6631 6723 6815 6907 6999 7091 7183 7275 7367 7459 7551 7643 7735 7827 7919 8011 8103 8195 8287 8379 ] -> [5] rcvbuf=[5 97 189 281 373 465 557 649 741 833 925 1017 1109 1201 1293 1385 1477 1569 1661 1753 1845 1937 2029 2121 2213 2305 2397 2489 2581 2673 2765 2857 2949 3041 3133 3225 3317 3409 3501 3593 3685 3777 3869 3961 4053 4145 4237 4329 4421 4513 4605 4697 4789 4881 4973 5065 5157 5249 5341 5433 5525 5617 5709 5801 5893 5985 6077 6169 6261 6353 6445 6537 6629 6721 6813 6905 6997 7089 7181 7273 7365 7457 7549 7641 7733 7825 7917 8009 8101 8193 8285 8377 ] -> [18] rcvbuf=[18 110 202 294 386 478 570 662 754 846 938 1030 1122 1214 1306 1398 1490 1582 1674 1766 1858 1950 2042 2134 2226 2318 2410 2502 2594 2686 2778 2870 2962 3054 3146 3238 3330 3422 3514 3606 3698 3790 3882 3974 4066 4158 4250 4342 4434 4526 4618 4710 4802 4894 4986 5078 5170 5262 5354 5446 5538 5630 5722 5814 5906 5998 6090 6182 6274 6366 6458 6550 6642 6734 6826 6918 7010 7102 7194 7286 7378 7470 7562 7654 7746 7838 7930 8022 8114 8206 8298 8390 ] -> [2] rcvbuf=[2 94 186 278 370 462 554 646 738 830 922 1014 1106 1198 1290 1382 1474 1566 1658 1750 1842 1934 2026 2118 2210 2302 2394 2486 2578 2670 2762 2854 2946 3038 3130 3222 3314 3406 3498 3590 3682 3774 3866 3958 4050 4142 4234 4326 4418 4510 4602 4694 4786 4878 4970 5062 5154 5246 5338 5430 5522 5614 5706 5798 5890 5982 6074 6166 6258 6350 6442 6534 6626 6718 6810 6902 6994 7086 7178 7270 7362 7454 7546 7638 7730 7822 7914 8006 8098 8190 8282 8374 ] -> [11] rcvbuf=[11 103 195 287 379 471 563 655 747 839 931 1023 1115 1207 1299 1391 1483 1575 1667 1759 1851 1943 2035 2127 2219 2311 2403 2495 2587 2679 2771 2863 2955 3047 3139 3231 3323 3415 3507 3599 3691 3783 3875 3967 4059 4151 4243 4335 4427 4519 4611 4703 4795 4887 4979 5071 5163 5255 5347 5439 5531 5623 5715 5807 5899 5991 6083 6175 6267 6359 6451 6543 6635 6727 6819 6911 7003 7095 7187 7279 7371 7463 7555 7647 7739 7831 7923 8015 8107 8199 8291 8383 ] -> [9] rcvbuf=[9 101 193 285 377 469 561 653 745 837 929 1021 1113 1205 1297 1389 1481 1573 1665 1757 1849 1941 2033 2125 2217 2309 2401 2493 2585 2677 2769 2861 2953 3045 3137 3229 3321 3413 3505 3597 3689 3781 3873 3965 4057 4149 4241 4333 4425 4517 4609 4701 4793 4885 4977 5069 5161 5253 5345 5437 5529 5621 5713 5805 5897 5989 6081 6173 6265 6357 6449 6541 6633 6725 6817 6909 7001 7093 7185 7277 7369 7461 7553 7645 7737 7829 7921 8013 8105 8197 8289 8381 ] -> [15] rcvbuf=[15 107 199 291 383 475 567 659 751 843 935 1027 1119 1211 1303 1395 1487 1579 1671 1763 1855 1947 2039 2131 2223 2315 2407 2499 2591 2683 2775 2867 2959 3051 3143 3235 3327 3419 3511 3603 3695 3787 3879 3971 4063 4155 4247 4339 4431 4523 4615 4707 4799 4891 4983 5075 5167 5259 5351 5443 5535 5627 5719 5811 5903 5995 6087 6179 6271 6363 6455 6547 6639 6731 6823 6915 7007 7099 7191 7283 7375 7467 7559 7651 7743 7835 7927 8019 8111 8203 8295 8387 ] -> [13] rcvbuf=[13 105 197 289 381 473 565 657 749 841 933 1025 1117 1209 1301 1393 1485 1577 1669 1761 1853 1945 2037 2129 2221 2313 2405 2497 2589 2681 2773 2865 2957 3049 3141 3233 3325 3417 3509 3601 3693 3785 3877 3969 4061 4153 4245 4337 4429 4521 4613 4705 4797 4889 4981 5073 5165 5257 5349 5441 5533 5625 5717 5809 5901 5993 6085 6177 6269 6361 6453 6545 6637 6729 6821 6913 7005 7097 7189 7281 7373 7465 7557 7649 7741 7833 7925 8017 8109 8201 8293 8385 ] -> [22] rcvbuf=[22 114 206 298 390 482 574 666 758 850 942 1034 1126 1218 1310 1402 1494 1586 1678 1770 1862 1954 2046 2138 2230 2322 2414 2506 2598 2690 2782 2874 2966 3058 3150 3242 3334 3426 3518 3610 3702 3794 3886 3978 4070 4162 4254 4346 4438 4530 4622 4714 4806 4898 4990 5082 5174 5266 5358 5450 5542 5634 5726 5818 5910 6002 6094 6186 6278 6370 6462 6554 6646 6738 6830 6922 7014 7106 7198 7290 7382 7474 7566 7658 7750 7842 7934 8026 8118 8210 8302 8394 ] -> [20] rcvbuf=[20 112 204 296 388 480 572 664 756 848 940 1032 1124 1216 1308 1400 1492 1584 1676 1768 1860 1952 2044 2136 2228 2320 2412 2504 2596 2688 2780 2872 2964 3056 3148 3240 3332 3424 3516 3608 3700 3792 3884 3976 4068 4160 4252 4344 4436 4528 4620 4712 4804 4896 4988 5080 5172 5264 5356 5448 5540 5632 5724 5816 5908 6000 6092 6184 6276 6368 6460 6552 6644 6736 6828 6920 7012 7104 7196 7288 7380 7472 7564 7656 7748 7840 7932 8024 8116 8208 8300 8392 ] -> [6] rcvbuf=[6 98 190 282 374 466 558 650 742 834 926 1018 1110 1202 1294 1386 1478 1570 1662 1754 1846 1938 2030 2122 2214 2306 2398 2490 2582 2674 2766 2858 2950 3042 3134 3226 3318 3410 3502 3594 3686 3778 3870 3962 4054 4146 4238 4330 4422 4514 4606 4698 4790 4882 4974 5066 5158 5250 5342 5434 5526 5618 5710 5802 5894 5986 6078 6170 6262 6354 6446 6538 6630 6722 6814 6906 6998 7090 7182 7274 7366 7458 7550 7642 7734 7826 7918 8010 8102 8194 8286 8378 ] -> [4] rcvbuf=[4 96 188 280 372 464 556 648 740 832 924 1016 1108 1200 1292 1384 1476 1568 1660 1752 1844 1936 2028 2120 2212 2304 2396 2488 2580 2672 2764 2856 2948 3040 3132 3224 3316 3408 3500 3592 3684 3776 3868 3960 4052 4144 4236 4328 4420 4512 4604 4696 4788 4880 4972 5064 5156 5248 5340 5432 5524 5616 5708 5800 5892 5984 6076 6168 6260 6352 6444 6536 6628 6720 6812 6904 6996 7088 7180 7272 7364 7456 7548 7640 7732 7824 7916 8008 8100 8192 8284 8376 ] -> [10] rcvbuf=[10 102 194 286 378 470 562 654 746 838 930 1022 1114 1206 1298 1390 1482 1574 1666 1758 1850 1942 2034 2126 2218 2310 2402 2494 2586 2678 2770 2862 2954 3046 3138 3230 3322 3414 3506 3598 3690 3782 3874 3966 4058 4150 4242 4334 4426 4518 4610 4702 4794 4886 4978 5070 5162 5254 5346 5438 5530 5622 5714 5806 5898 5990 6082 6174 6266 6358 6450 6542 6634 6726 6818 6910 7002 7094 7186 7278 7370 7462 7554 7646 7738 7830 7922 8014 8106 8198 8290 8382 ] -> [14] rcvbuf=[14 106 198 290 382 474 566 658 750 842 934 1026 1118 1210 1302 1394 1486 1578 1670 1762 1854 1946 2038 2130 2222 2314 2406 2498 2590 2682 2774 2866 2958 3050 3142 3234 3326 3418 3510 3602 3694 3786 3878 3970 4062 4154 4246 4338 4430 4522 4614 4706 4798 4890 4982 5074 5166 5258 5350 5442 5534 5626 5718 5810 5902 5994 6086 6178 6270 6362 6454 6546 6638 6730 6822 6914 7006 7098 7190 7282 7374 7466 7558 7650 7742 7834 7926 8018 8110 8202 8294 8386 ] -> [12] rcvbuf=[12 104 196 288 380 472 564 656 748 840 932 1024 1116 1208 1300 1392 1484 1576 1668 1760 1852 1944 2036 2128 2220 2312 2404 2496 2588 2680 2772 2864 2956 3048 3140 3232 3324 3416 3508 3600 3692 3784 3876 3968 4060 4152 4244 4336 4428 4520 4612 4704 4796 4888 4980 5072 5164 5256 5348 5440 5532 5624 5716 5808 5900 5992 6084 6176 6268 6360 6452 6544 6636 6728 6820 6912 7004 7096 7188 7280 7372 7464 7556 7648 7740 7832 7924 8016 8108 8200 8292 8384 ] -> [83] rcvbuf=[83 175 267 359 451 543 635 727 819 911 1003 1095 1187 1279 1371 1463 1555 1647 1739 1831 1923 2015 2107 2199 2291 2383 2475 2567 2659 2751 2843 2935 3027 3119 3211 3303 3395 3487 3579 3671 3763 3855 3947 4039 4131 4223 4315 4407 4499 4591 4683 4775 4867 4959 5051 5143 5235 5327 5419 5511 5603 5695 5787 5879 5971 6063 6155 6247 6339 6431 6523 6615 6707 6799 6891 6983 7075 7167 7259 7351 7443 7535 7627 7719 7811 7903 7995 8087 8179 8271 8363 8455 ] -> [81] rcvbuf=[81 173 265 357 449 541 633 725 817 909 1001 1093 1185 1277 1369 1461 1553 1645 1737 1829 1921 2013 2105 2197 2289 2381 2473 2565 2657 2749 2841 2933 3025 3117 3209 3301 3393 3485 3577 3669 3761 3853 3945 4037 4129 4221 4313 4405 4497 4589 4681 4773 4865 4957 5049 5141 5233 5325 5417 5509 5601 5693 5785 5877 5969 6061 6153 6245 6337 6429 6521 6613 6705 6797 6889 6981 7073 7165 7257 7349 7441 7533 7625 7717 7809 7901 7993 8085 8177 8269 8361 8453 ] -> [67] rcvbuf=[67 159 251 343 435 527 619 711 803 895 987 1079 1171 1263 1355 1447 1539 1631 1723 1815 1907 1999 2091 2183 2275 2367 2459 2551 2643 2735 2827 2919 3011 3103 3195 3287 3379 3471 3563 3655 3747 3839 3931 4023 4115 4207 4299 4391 4483 4575 4667 4759 4851 4943 5035 5127 5219 5311 5403 5495 5587 5679 5771 5863 5955 6047 6139 6231 6323 6415 6507 6599 6691 6783 6875 6967 7059 7151 7243 7335 7427 7519 7611 7703 7795 7887 7979 8071 8163 8255 8347 8439 ] -> [65] rcvbuf=[65 157 249 341 433 525 617 709 801 893 985 1077 1169 1261 1353 1445 1537 1629 1721 1813 1905 1997 2089 2181 2273 2365 2457 2549 2641 2733 2825 2917 3009 3101 3193 3285 3377 3469 3561 3653 3745 3837 3929 4021 4113 4205 4297 4389 4481 4573 4665 4757 4849 4941 5033 5125 5217 5309 5401 5493 5585 5677 5769 5861 5953 6045 6137 6229 6321 6413 6505 6597 6689 6781 6873 6965 7057 7149 7241 7333 7425 7517 7609 7701 7793 7885 7977 8069 8161 8253 8345 8437 ] -> [57] rcvbuf=[57 149 241 333 425 517 609 701 793 885 977 1069 1161 1253 1345 1437 1529 1621 1713 1805 1897 1989 2081 2173 2265 2357 2449 2541 2633 2725 2817 2909 3001 3093 3185 3277 3369 3461 3553 3645 3737 3829 3921 4013 4105 4197 4289 4381 4473 4565 4657 4749 4841 4933 5025 5117 5209 5301 5393 5485 5577 5669 5761 5853 5945 6037 6129 6221 6313 6405 6497 6589 6681 6773 6865 6957 7049 7141 7233 7325 7417 7509 7601 7693 7785 7877 7969 8061 8153 8245 8337 8429 ] -> [59] rcvbuf=[59 151 243 335 427 519 611 703 795 887 979 1071 1163 1255 1347 1439 1531 1623 1715 1807 1899 1991 2083 2175 2267 2359 2451 2543 2635 2727 2819 2911 3003 3095 3187 3279 3371 3463 3555 3647 3739 3831 3923 4015 4107 4199 4291 4383 4475 4567 4659 4751 4843 4935 5027 5119 5211 5303 5395 5487 5579 5671 5763 5855 5947 6039 6131 6223 6315 6407 6499 6591 6683 6775 6867 6959 7051 7143 7235 7327 7419 7511 7603 7695 7787 7879 7971 8063 8155 8247 8339 8431 ] -> [33] rcvbuf=[33 125 217 309 401 493 585 677 769 861 953 1045 1137 1229 1321 1413 1505 1597 1689 1781 1873 1965 2057 2149 2241 2333 2425 2517 2609 2701 2793 2885 2977 3069 3161 3253 3345 3437 3529 3621 3713 3805 3897 3989 4081 4173 4265 4357 4449 4541 4633 4725 4817 4909 5001 5093 5185 5277 5369 5461 5553 5645 5737 5829 5921 6013 6105 6197 6289 6381 6473 6565 6657 6749 6841 6933 7025 7117 7209 7301 7393 7485 7577 7669 7761 7853 7945 8037 8129 8221 8313 8405 ] -> [35] rcvbuf=[35 127 219 311 403 495 587 679 771 863 955 1047 1139 1231 1323 1415 1507 1599 1691 1783 1875 1967 2059 2151 2243 2335 2427 2519 2611 2703 2795 2887 2979 3071 3163 3255 3347 3439 3531 3623 3715 3807 3899 3991 4083 4175 4267 4359 4451 4543 4635 4727 4819 4911 5003 5095 5187 5279 5371 5463 5555 5647 5739 5831 5923 6015 6107 6199 6291 6383 6475 6567 6659 6751 6843 6935 7027 7119 7211 7303 7395 7487 7579 7671 7763 7855 7947 8039 8131 8223 8315 8407 ] -> [49] rcvbuf=[49 141 233 325 417 509 601 693 785 877 969 1061 1153 1245 1337 1429 1521 1613 1705 1797 1889 1981 2073 2165 2257 2349 2441 2533 2625 2717 2809 2901 2993 3085 3177 3269 3361 3453 3545 3637 3729 3821 3913 4005 4097 4189 4281 4373 4465 4557 4649 4741 4833 4925 5017 5109 5201 5293 5385 5477 5569 5661 5753 5845 5937 6029 6121 6213 6305 6397 6489 6581 6673 6765 6857 6949 7041 7133 7225 7317 7409 7501 7593 7685 7777 7869 7961 8053 8145 8237 8329 8421 ] -> [51] rcvbuf=[51 143 235 327 419 511 603 695 787 879 971 1063 1155 1247 1339 1431 1523 1615 1707 1799 1891 1983 2075 2167 2259 2351 2443 2535 2627 2719 2811 2903 2995 3087 3179 3271 3363 3455 3547 3639 3731 3823 3915 4007 4099 4191 4283 4375 4467 4559 4651 4743 4835 4927 5019 5111 5203 5295 5387 5479 5571 5663 5755 5847 5939 6031 6123 6215 6307 6399 6491 6583 6675 6767 6859 6951 7043 7135 7227 7319 7411 7503 7595 7687 7779 7871 7963 8055 8147 8239 8331 8423 ] -> [58] rcvbuf=[58 150 242 334 426 518 610 702 794 886 978 1070 1162 1254 1346 1438 1530 1622 1714 1806 1898 1990 2082 2174 2266 2358 2450 2542 2634 2726 2818 2910 3002 3094 3186 3278 3370 3462 3554 3646 3738 3830 3922 4014 4106 4198 4290 4382 4474 4566 4658 4750 4842 4934 5026 5118 5210 5302 5394 5486 5578 5670 5762 5854 5946 6038 6130 6222 6314 6406 6498 6590 6682 6774 6866 6958 7050 7142 7234 7326 7418 7510 7602 7694 7786 7878 7970 8062 8154 8246 8338 8430 ] -> [91] rcvbuf=[91 183 275 367 459 551 643 735 827 919 1011 1103 1195 1287 1379 1471 1563 1655 1747 1839 1931 2023 2115 2207 2299 2391 2483 2575 2667 2759 2851 2943 3035 3127 3219 3311 3403 3495 3587 3679 3771 3863 3955 4047 4139 4231 4323 4415 4507 4599 4691 4783 4875 4967 5059 5151 5243 5335 5427 5519 5611 5703 5795 5887 5979 6071 6163 6255 6347 6439 6531 6623 6715 6807 6899 6991 7083 7175 7267 7359 7451 7543 7635 7727 7819 7911 8003 8095 8187 8279 8371 8463 ] -> [89] rcvbuf=[89 181 273 365 457 549 641 733 825 917 1009 1101 1193 1285 1377 1469 1561 1653 1745 1837 1929 2021 2113 2205 2297 2389 2481 2573 2665 2757 2849 2941 3033 3125 3217 3309 3401 3493 3585 3677 3769 3861 3953 4045 4137 4229 4321 4413 4505 4597 4689 4781 4873 4965 5057 5149 5241 5333 5425 5517 5609 5701 5793 5885 5977 6069 6161 6253 6345 6437 6529 6621 6713 6805 6897 6989 7081 7173 7265 7357 7449 7541 7633 7725 7817 7909 8001 8093 8185 8277 8369 8461 ] -> [40] rcvbuf=[40 132 224 316 408 500 592 684 776 868 960 1052 1144 1236 1328 1420 1512 1604 1696 1788 1880 1972 2064 2156 2248 2340 2432 2524 2616 2708 2800 2892 2984 3076 3168 3260 3352 3444 3536 3628 3720 3812 3904 3996 4088 4180 4272 4364 4456 4548 4640 4732 4824 4916 5008 5100 5192 5284 5376 5468 5560 5652 5744 5836 5928 6020 6112 6204 6296 6388 6480 6572 6664 6756 6848 6940 7032 7124 7216 7308 7400 7492 7584 7676 7768 7860 7952 8044 8136 8228 8320 8412 ] -> [32] rcvbuf=[32 124 216 308 400 492 584 676 768 860 952 1044 1136 1228 1320 1412 1504 1596 1688 1780 1872 1964 2056 2148 2240 2332 2424 2516 2608 2700 2792 2884 2976 3068 3160 3252 3344 3436 3528 3620 3712 3804 3896 3988 4080 4172 4264 4356 4448 4540 4632 4724 4816 4908 5000 5092 5184 5276 5368 5460 5552 5644 5736 5828 5920 6012 6104 6196 6288 6380 6472 6564 6656 6748 6840 6932 7024 7116 7208 7300 7392 7484 7576 7668 7760 7852 7944 8036 8128 8220 8312 8404 ] -> [56] rcvbuf=[56 148 240 332 424 516 608 700 792 884 976 1068 1160 1252 1344 1436 1528 1620 1712 1804 1896 1988 2080 2172 2264 2356 2448 2540 2632 2724 2816 2908 3000 3092 3184 3276 3368 3460 3552 3644 3736 3828 3920 4012 4104 4196 4288 4380 4472 4564 4656 4748 4840 4932 5024 5116 5208 5300 5392 5484 5576 5668 5760 5852 5944 6036 6128 6220 6312 6404 6496 6588 6680 6772 6864 6956 7048 7140 7232 7324 7416 7508 7600 7692 7784 7876 7968 8060 8152 8244 8336 8428 ] -> [48] rcvbuf=[48 140 232 324 416 508 600 692 784 876 968 1060 1152 1244 1336 1428 1520 1612 1704 1796 1888 1980 2072 2164 2256 2348 2440 2532 2624 2716 2808 2900 2992 3084 3176 3268 3360 3452 3544 3636 3728 3820 3912 4004 4096 4188 4280 4372 4464 4556 4648 4740 4832 4924 5016 5108 5200 5292 5384 5476 5568 5660 5752 5844 5936 6028 6120 6212 6304 6396 6488 6580 6672 6764 6856 6948 7040 7132 7224 7316 7408 7500 7592 7684 7776 7868 7960 8052 8144 8236 8328 8420 ] -> [90] rcvbuf=[90 182 274 366 458 550 642 734 826 918 1010 1102 1194 1286 1378 1470 1562 1654 1746 1838 1930 2022 2114 2206 2298 2390 2482 2574 2666 2758 2850 2942 3034 3126 3218 3310 3402 3494 3586 3678 3770 3862 3954 4046 4138 4230 4322 4414 4506 4598 4690 4782 4874 4966 5058 5150 5242 5334 5426 5518 5610 5702 5794 5886 5978 6070 6162 6254 6346 6438 6530 6622 6714 6806 6898 6990 7082 7174 7266 7358 7450 7542 7634 7726 7818 7910 8002 8094 8186 8278 8370 8462 ] -> [37] rcvbuf=[37 129 221 313 405 497 589 681 773 865 957 1049 1141 1233 1325 1417 1509 1601 1693 1785 1877 1969 2061 2153 2245 2337 2429 2521 2613 2705 2797 2889 2981 3073 3165 3257 3349 3441 3533 3625 3717 3809 3901 3993 4085 4177 4269 4361 4453 4545 4637 4729 4821 4913 5005 5097 5189 5281 5373 5465 5557 5649 5741 5833 5925 6017 6109 6201 6293 6385 6477 6569 6661 6753 6845 6937 7029 7121 7213 7305 7397 7489 7581 7673 7765 7857 7949 8041 8133 8225 8317 8409 ] -> [39] rcvbuf=[39 131 223 315 407 499 591 683 775 867 959 1051 1143 1235 1327 1419 1511 1603 1695 1787 1879 1971 2063 2155 2247 2339 2431 2523 2615 2707 2799 2891 2983 3075 3167 3259 3351 3443 3535 3627 3719 3811 3903 3995 4087 4179 4271 4363 4455 4547 4639 4731 4823 4915 5007 5099 5191 5283 5375 5467 5559 5651 5743 5835 5927 6019 6111 6203 6295 6387 6479 6571 6663 6755 6847 6939 7031 7123 7215 7307 7399 7491 7583 7675 7767 7859 7951 8043 8135 8227 8319 8411 ] -> [53] rcvbuf=[53 145 237 329 421 513 605 697 789 881 973 1065 1157 1249 1341 1433 1525 1617 1709 1801 1893 1985 2077 2169 2261 2353 2445 2537 2629 2721 2813 2905 2997 3089 3181 3273 3365 3457 3549 3641 3733 3825 3917 4009 4101 4193 4285 4377 4469 4561 4653 4745 4837 4929 5021 5113 5205 5297 5389 5481 5573 5665 5757 5849 5941 6033 6125 6217 6309 6401 6493 6585 6677 6769 6861 6953 7045 7137 7229 7321 7413 7505 7597 7689 7781 7873 7965 8057 8149 8241 8333 8425 ] -> [55] rcvbuf=[55 147 239 331 423 515 607 699 791 883 975 1067 1159 1251 1343 1435 1527 1619 1711 1803 1895 1987 2079 2171 2263 2355 2447 2539 2631 2723 2815 2907 2999 3091 3183 3275 3367 3459 3551 3643 3735 3827 3919 4011 4103 4195 4287 4379 4471 4563 4655 4747 4839 4931 5023 5115 5207 5299 5391 5483 5575 5667 5759 5851 5943 6035 6127 6219 6311 6403 6495 6587 6679 6771 6863 6955 7047 7139 7231 7323 7415 7507 7599 7691 7783 7875 7967 8059 8151 8243 8335 8427 ] -> [80] rcvbuf=[80 172 264 356 448 540 632 724 816 908 1000 1092 1184 1276 1368 1460 1552 1644 1736 1828 1920 2012 2104 2196 2288 2380 2472 2564 2656 2748 2840 2932 3024 3116 3208 3300 3392 3484 3576 3668 3760 3852 3944 4036 4128 4220 4312 4404 4496 4588 4680 4772 4864 4956 5048 5140 5232 5324 5416 5508 5600 5692 5784 5876 5968 6060 6152 6244 6336 6428 6520 6612 6704 6796 6888 6980 7072 7164 7256 7348 7440 7532 7624 7716 7808 7900 7992 8084 8176 8268 8360 8452 ] -> [88] rcvbuf=[88 180 272 364 456 548 640 732 824 916 1008 1100 1192 1284 1376 1468 1560 1652 1744 1836 1928 2020 2112 2204 2296 2388 2480 2572 2664 2756 2848 2940 3032 3124 3216 3308 3400 3492 3584 3676 3768 3860 3952 4044 4136 4228 4320 4412 4504 4596 4688 4780 4872 4964 5056 5148 5240 5332 5424 5516 5608 5700 5792 5884 5976 6068 6160 6252 6344 6436 6528 6620 6712 6804 6896 6988 7080 7172 7264 7356 7448 7540 7632 7724 7816 7908 8000 8092 8184 8276 8368 8460 ] -> [64] rcvbuf=[64 156 248 340 432 524 616 708 800 892 984 1076 1168 1260 1352 1444 1536 1628 1720 1812 1904 1996 2088 2180 2272 2364 2456 2548 2640 2732 2824 2916 3008 3100 3192 3284 3376 3468 3560 3652 3744 3836 3928 4020 4112 4204 4296 4388 4480 4572 4664 4756 4848 4940 5032 5124 5216 5308 5400 5492 5584 5676 5768 5860 5952 6044 6136 6228 6320 6412 6504 6596 6688 6780 6872 6964 7056 7148 7240 7332 7424 7516 7608 7700 7792 7884 7976 8068 8160 8252 8344 8436 ] -> [72] rcvbuf=[72 164 256 348 440 532 624 716 808 900 992 1084 1176 1268 1360 1452 1544 1636 1728 1820 1912 2004 2096 2188 2280 2372 2464 2556 2648 2740 2832 2924 3016 3108 3200 3292 3384 3476 3568 3660 3752 3844 3936 4028 4120 4212 4304 4396 4488 4580 4672 4764 4856 4948 5040 5132 5224 5316 5408 5500 5592 5684 5776 5868 5960 6052 6144 6236 6328 6420 6512 6604 6696 6788 6880 6972 7064 7156 7248 7340 7432 7524 7616 7708 7800 7892 7984 8076 8168 8260 8352 8444 ] -> [28] rcvbuf=[28 120 212 304 396 488 580 672 764 856 948 1040 1132 1224 1316 1408 1500 1592 1684 1776 1868 1960 2052 2144 2236 2328 2420 2512 2604 2696 2788 2880 2972 3064 3156 3248 3340 3432 3524 3616 3708 3800 3892 3984 4076 4168 4260 4352 4444 4536 4628 4720 4812 4904 4996 5088 5180 5272 5364 5456 5548 5640 5732 5824 5916 6008 6100 6192 6284 6376 6468 6560 6652 6744 6836 6928 7020 7112 7204 7296 7388 7480 7572 7664 7756 7848 7940 8032 8124 8216 8308 8400 ] -> [87] rcvbuf=[87 179 271 363 455 547 639 731 823 915 1007 1099 1191 1283 1375 1467 1559 1651 1743 1835 1927 2019 2111 2203 2295 2387 2479 2571 2663 2755 2847 2939 3031 3123 3215 3307 3399 3491 3583 3675 3767 3859 3951 4043 4135 4227 4319 4411 4503 4595 4687 4779 4871 4963 5055 5147 5239 5331 5423 5515 5607 5699 5791 5883 5975 6067 6159 6251 6343 6435 6527 6619 6711 6803 6895 6987 7079 7171 7263 7355 7447 7539 7631 7723 7815 7907 7999 8091 8183 8275 8367 8459 ] -> [85] rcvbuf=[85 177 269 361 453 545 637 729 821 913 1005 1097 1189 1281 1373 1465 1557 1649 1741 1833 1925 2017 2109 2201 2293 2385 2477 2569 2661 2753 2845 2937 3029 3121 3213 3305 3397 3489 3581 3673 3765 3857 3949 4041 4133 4225 4317 4409 4501 4593 4685 4777 4869 4961 5053 5145 5237 5329 5421 5513 5605 5697 5789 5881 5973 6065 6157 6249 6341 6433 6525 6617 6709 6801 6893 6985 7077 7169 7261 7353 7445 7537 7629 7721 7813 7905 7997 8089 8181 8273 8365 8457 ] -> [71] rcvbuf=[71 163 255 347 439 531 623 715 807 899 991 1083 1175 1267 1359 1451 1543 1635 1727 1819 1911 2003 2095 2187 2279 2371 2463 2555 2647 2739 2831 2923 3015 3107 3199 3291 3383 3475 3567 3659 3751 3843 3935 4027 4119 4211 4303 4395 4487 4579 4671 4763 4855 4947 5039 5131 5223 5315 5407 5499 5591 5683 5775 5867 5959 6051 6143 6235 6327 6419 6511 6603 6695 6787 6879 6971 7063 7155 7247 7339 7431 7523 7615 7707 7799 7891 7983 8075 8167 8259 8351 8443 ] -> [69] rcvbuf=[69 161 253 345 437 529 621 713 805 897 989 1081 1173 1265 1357 1449 1541 1633 1725 1817 1909 2001 2093 2185 2277 2369 2461 2553 2645 2737 2829 2921 3013 3105 3197 3289 3381 3473 3565 3657 3749 3841 3933 4025 4117 4209 4301 4393 4485 4577 4669 4761 4853 4945 5037 5129 5221 5313 5405 5497 5589 5681 5773 5865 5957 6049 6141 6233 6325 6417 6509 6601 6693 6785 6877 6969 7061 7153 7245 7337 7429 7521 7613 7705 7797 7889 7981 8073 8165 8257 8349 8441 ] -> [82] rcvbuf=[82 174 266 358 450 542 634 726 818 910 1002 1094 1186 1278 1370 1462 1554 1646 1738 1830 1922 2014 2106 2198 2290 2382 2474 2566 2658 2750 2842 2934 3026 3118 3210 3302 3394 3486 3578 3670 3762 3854 3946 4038 4130 4222 4314 4406 4498 4590 4682 4774 4866 4958 5050 5142 5234 5326 5418 5510 5602 5694 5786 5878 5970 6062 6154 6246 6338 6430 6522 6614 6706 6798 6890 6982 7074 7166 7258 7350 7442 7534 7626 7718 7810 7902 7994 8086 8178 8270 8362 8454 ] -> [66] rcvbuf=[66 158 250 342 434 526 618 710 802 894 986 1078 1170 1262 1354 1446 1538 1630 1722 1814 1906 1998 2090 2182 2274 2366 2458 2550 2642 2734 2826 2918 3010 3102 3194 3286 3378 3470 3562 3654 3746 3838 3930 4022 4114 4206 4298 4390 4482 4574 4666 4758 4850 4942 5034 5126 5218 5310 5402 5494 5586 5678 5770 5862 5954 6046 6138 6230 6322 6414 6506 6598 6690 6782 6874 6966 7058 7150 7242 7334 7426 7518 7610 7702 7794 7886 7978 8070 8162 8254 8346 8438 ] -> [75] rcvbuf=[75 167 259 351 443 535 627 719 811 903 995 1087 1179 1271 1363 1455 1547 1639 1731 1823 1915 2007 2099 2191 2283 2375 2467 2559 2651 2743 2835 2927 3019 3111 3203 3295 3387 3479 3571 3663 3755 3847 3939 4031 4123 4215 4307 4399 4491 4583 4675 4767 4859 4951 5043 5135 5227 5319 5411 5503 5595 5687 5779 5871 5963 6055 6147 6239 6331 6423 6515 6607 6699 6791 6883 6975 7067 7159 7251 7343 7435 7527 7619 7711 7803 7895 7987 8079 8171 8263 8355 8447 ] -> [73] rcvbuf=[73 165 257 349 441 533 625 717 809 901 993 1085 1177 1269 1361 1453 1545 1637 1729 1821 1913 2005 2097 2189 2281 2373 2465 2557 2649 2741 2833 2925 3017 3109 3201 3293 3385 3477 3569 3661 3753 3845 3937 4029 4121 4213 4305 4397 4489 4581 4673 4765 4857 4949 5041 5133 5225 5317 5409 5501 5593 5685 5777 5869 5961 6053 6145 6237 6329 6421 6513 6605 6697 6789 6881 6973 7065 7157 7249 7341 7433 7525 7617 7709 7801 7893 7985 8077 8169 8261 8353 8445 ] -> [79] rcvbuf=[79 171 263 355 447 539 631 723 815 907 999 1091 1183 1275 1367 1459 1551 1643 1735 1827 1919 2011 2103 2195 2287 2379 2471 2563 2655 2747 2839 2931 3023 3115 3207 3299 3391 3483 3575 3667 3759 3851 3943 4035 4127 4219 4311 4403 4495 4587 4679 4771 4863 4955 5047 5139 5231 5323 5415 5507 5599 5691 5783 5875 5967 6059 6151 6243 6335 6427 6519 6611 6703 6795 6887 6979 7071 7163 7255 7347 7439 7531 7623 7715 7807 7899 7991 8083 8175 8267 8359 8451 ] -> [77] rcvbuf=[77 169 261 353 445 537 629 721 813 905 997 1089 1181 1273 1365 1457 1549 1641 1733 1825 1917 2009 2101 2193 2285 2377 2469 2561 2653 2745 2837 2929 3021 3113 3205 3297 3389 3481 3573 3665 3757 3849 3941 4033 4125 4217 4309 4401 4493 4585 4677 4769 4861 4953 5045 5137 5229 5321 5413 5505 5597 5689 5781 5873 5965 6057 6149 6241 6333 6425 6517 6609 6701 6793 6885 6977 7069 7161 7253 7345 7437 7529 7621 7713 7805 7897 7989 8081 8173 8265 8357 8449 ] -> [86] rcvbuf=[86 178 270 362 454 546 638 730 822 914 1006 1098 1190 1282 1374 1466 1558 1650 1742 1834 1926 2018 2110 2202 2294 2386 2478 2570 2662 2754 2846 2938 3030 3122 3214 3306 3398 3490 3582 3674 3766 3858 3950 4042 4134 4226 4318 4410 4502 4594 4686 4778 4870 4962 5054 5146 5238 5330 5422 5514 5606 5698 5790 5882 5974 6066 6158 6250 6342 6434 6526 6618 6710 6802 6894 6986 7078 7170 7262 7354 7446 7538 7630 7722 7814 7906 7998 8090 8182 8274 8366 8458 ] -> [84] rcvbuf=[84 176 268 360 452 544 636 728 820 912 1004 1096 1188 1280 1372 1464 1556 1648 1740 1832 1924 2016 2108 2200 2292 2384 2476 2568 2660 2752 2844 2936 3028 3120 3212 3304 3396 3488 3580 3672 3764 3856 3948 4040 4132 4224 4316 4408 4500 4592 4684 4776 4868 4960 5052 5144 5236 5328 5420 5512 5604 5696 5788 5880 5972 6064 6156 6248 6340 6432 6524 6616 6708 6800 6892 6984 7076 7168 7260 7352 7444 7536 7628 7720 7812 7904 7996 8088 8180 8272 8364 8456 ] -> [70] rcvbuf=[70 162 254 346 438 530 622 714 806 898 990 1082 1174 1266 1358 1450 1542 1634 1726 1818 1910 2002 2094 2186 2278 2370 2462 2554 2646 2738 2830 2922 3014 3106 3198 3290 3382 3474 3566 3658 3750 3842 3934 4026 4118 4210 4302 4394 4486 4578 4670 4762 4854 4946 5038 5130 5222 5314 5406 5498 5590 5682 5774 5866 5958 6050 6142 6234 6326 6418 6510 6602 6694 6786 6878 6970 7062 7154 7246 7338 7430 7522 7614 7706 7798 7890 7982 8074 8166 8258 8350 8442 ] -> [68] rcvbuf=[68 160 252 344 436 528 620 712 804 896 988 1080 1172 1264 1356 1448 1540 1632 1724 1816 1908 2000 2092 2184 2276 2368 2460 2552 2644 2736 2828 2920 3012 3104 3196 3288 3380 3472 3564 3656 3748 3840 3932 4024 4116 4208 4300 4392 4484 4576 4668 4760 4852 4944 5036 5128 5220 5312 5404 5496 5588 5680 5772 5864 5956 6048 6140 6232 6324 6416 6508 6600 6692 6784 6876 6968 7060 7152 7244 7336 7428 7520 7612 7704 7796 7888 7980 8072 8164 8256 8348 8440 ] -> [34] rcvbuf=[34 126 218 310 402 494 586 678 770 862 954 1046 1138 1230 1322 1414 1506 1598 1690 1782 1874 1966 2058 2150 2242 2334 2426 2518 2610 2702 2794 2886 2978 3070 3162 3254 3346 3438 3530 3622 3714 3806 3898 3990 4082 4174 4266 4358 4450 4542 4634 4726 4818 4910 5002 5094 5186 5278 5370 5462 5554 5646 5738 5830 5922 6014 6106 6198 6290 6382 6474 6566 6658 6750 6842 6934 7026 7118 7210 7302 7394 7486 7578 7670 7762 7854 7946 8038 8130 8222 8314 8406 ] -> [50] rcvbuf=[50 142 234 326 418 510 602 694 786 878 970 1062 1154 1246 1338 1430 1522 1614 1706 1798 1890 1982 2074 2166 2258 2350 2442 2534 2626 2718 2810 2902 2994 3086 3178 3270 3362 3454 3546 3638 3730 3822 3914 4006 4098 4190 4282 4374 4466 4558 4650 4742 4834 4926 5018 5110 5202 5294 5386 5478 5570 5662 5754 5846 5938 6030 6122 6214 6306 6398 6490 6582 6674 6766 6858 6950 7042 7134 7226 7318 7410 7502 7594 7686 7778 7870 7962 8054 8146 8238 8330 8422 ] -> [74] rcvbuf=[74 166 258 350 442 534 626 718 810 902 994 1086 1178 1270 1362 1454 1546 1638 1730 1822 1914 2006 2098 2190 2282 2374 2466 2558 2650 2742 2834 2926 3018 3110 3202 3294 3386 3478 3570 3662 3754 3846 3938 4030 4122 4214 4306 4398 4490 4582 4674 4766 4858 4950 5042 5134 5226 5318 5410 5502 5594 5686 5778 5870 5962 6054 6146 6238 6330 6422 6514 6606 6698 6790 6882 6974 7066 7158 7250 7342 7434 7526 7618 7710 7802 7894 7986 8078 8170 8262 8354 8446 ] -> [76] rcvbuf=[76 168 260 352 444 536 628 720 812 904 996 1088 1180 1272 1364 1456 1548 1640 1732 1824 1916 2008 2100 2192 2284 2376 2468 2560 2652 2744 2836 2928 3020 3112 3204 3296 3388 3480 3572 3664 3756 3848 3940 4032 4124 4216 4308 4400 4492 4584 4676 4768 4860 4952 5044 5136 5228 5320 5412 5504 5596 5688 5780 5872 5964 6056 6148 6240 6332 6424 6516 6608 6700 6792 6884 6976 7068 7160 7252 7344 7436 7528 7620 7712 7804 7896 7988 8080 8172 8264 8356 8448 ] -> [78] rcvbuf=[78 170 262 354 446 538 630 722 814 906 998 1090 1182 1274 1366 1458 1550 1642 1734 1826 1918 2010 2102 2194 2286 2378 2470 2562 2654 2746 2838 2930 3022 3114 3206 3298 3390 3482 3574 3666 3758 3850 3942 4034 4126 4218 4310 4402 4494 4586 4678 4770 4862 4954 5046 5138 5230 5322 5414 5506 5598 5690 5782 5874 5966 6058 6150 6242 6334 6426 6518 6610 6702 6794 6886 6978 7070 7162 7254 7346 7438 7530 7622 7714 7806 7898 7990 8082 8174 8266 8358 8450 ] -> [41] rcvbuf=[41 133 225 317 409 501 593 685 777 869 961 1053 1145 1237 1329 1421 1513 1605 1697 1789 1881 1973 2065 2157 2249 2341 2433 2525 2617 2709 2801 2893 2985 3077 3169 3261 3353 3445 3537 3629 3721 3813 3905 3997 4089 4181 4273 4365 4457 4549 4641 4733 4825 4917 5009 5101 5193 5285 5377 5469 5561 5653 5745 5837 5929 6021 6113 6205 6297 6389 6481 6573 6665 6757 6849 6941 7033 7125 7217 7309 7401 7493 7585 7677 7769 7861 7953 8045 8137 8229 8321 8413 ] -> [43] rcvbuf=[43 135 227 319 411 503 595 687 779 871 963 1055 1147 1239 1331 1423 1515 1607 1699 1791 1883 1975 2067 2159 2251 2343 2435 2527 2619 2711 2803 2895 2987 3079 3171 3263 3355 3447 3539 3631 3723 3815 3907 3999 4091 4183 4275 4367 4459 4551 4643 4735 4827 4919 5011 5103 5195 5287 5379 5471 5563 5655 5747 5839 5931 6023 6115 6207 6299 6391 6483 6575 6667 6759 6851 6943 7035 7127 7219 7311 7403 7495 7587 7679 7771 7863 7955 8047 8139 8231 8323 8415 ] -> [36] rcvbuf=[36 128 220 312 404 496 588 680 772 864 956 1048 1140 1232 1324 1416 1508 1600 1692 1784 1876 1968 2060 2152 2244 2336 2428 2520 2612 2704 2796 2888 2980 3072 3164 3256 3348 3440 3532 3624 3716 3808 3900 3992 4084 4176 4268 4360 4452 4544 4636 4728 4820 4912 5004 5096 5188 5280 5372 5464 5556 5648 5740 5832 5924 6016 6108 6200 6292 6384 6476 6568 6660 6752 6844 6936 7028 7120 7212 7304 7396 7488 7580 7672 7764 7856 7948 8040 8132 8224 8316 8408 ] -> [38] rcvbuf=[38 130 222 314 406 498 590 682 774 866 958 1050 1142 1234 1326 1418 1510 1602 1694 1786 1878 1970 2062 2154 2246 2338 2430 2522 2614 2706 2798 2890 2982 3074 3166 3258 3350 3442 3534 3626 3718 3810 3902 3994 4086 4178 4270 4362 4454 4546 4638 4730 4822 4914 5006 5098 5190 5282 5374 5466 5558 5650 5742 5834 5926 6018 6110 6202 6294 6386 6478 6570 6662 6754 6846 6938 7030 7122 7214 7306 7398 7490 7582 7674 7766 7858 7950 8042 8134 8226 8318 8410 ] -> [52] rcvbuf=[52 144 236 328 420 512 604 696 788 880 972 1064 1156 1248 1340 1432 1524 1616 1708 1800 1892 1984 2076 2168 2260 2352 2444 2536 2628 2720 2812 2904 2996 3088 3180 3272 3364 3456 3548 3640 3732 3824 3916 4008 4100 4192 4284 4376 4468 4560 4652 4744 4836 4928 5020 5112 5204 5296 5388 5480 5572 5664 5756 5848 5940 6032 6124 6216 6308 6400 6492 6584 6676 6768 6860 6952 7044 7136 7228 7320 7412 7504 7596 7688 7780 7872 7964 8056 8148 8240 8332 8424 ] -> [54] rcvbuf=[54 146 238 330 422 514 606 698 790 882 974 1066 1158 1250 1342 1434 1526 1618 1710 1802 1894 1986 2078 2170 2262 2354 2446 2538 2630 2722 2814 2906 2998 3090 3182 3274 3366 3458 3550 3642 3734 3826 3918 4010 4102 4194 4286 4378 4470 4562 4654 4746 4838 4930 5022 5114 5206 5298 5390 5482 5574 5666 5758 5850 5942 6034 6126 6218 6310 6402 6494 6586 6678 6770 6862 6954 7046 7138 7230 7322 7414 7506 7598 7690 7782 7874 7966 8058 8150 8242 8334 8426 ] -> [29] rcvbuf=[29 121 213 305 397 489 581 673 765 857 949 1041 1133 1225 1317 1409 1501 1593 1685 1777 1869 1961 2053 2145 2237 2329 2421 2513 2605 2697 2789 2881 2973 3065 3157 3249 3341 3433 3525 3617 3709 3801 3893 3985 4077 4169 4261 4353 4445 4537 4629 4721 4813 4905 4997 5089 5181 5273 5365 5457 5549 5641 5733 5825 5917 6009 6101 6193 6285 6377 6469 6561 6653 6745 6837 6929 7021 7113 7205 7297 7389 7481 7573 7665 7757 7849 7941 8033 8125 8217 8309 8401 ] -> [31] rcvbuf=[31 123 215 307 399 491 583 675 767 859 951 1043 1135 1227 1319 1411 1503 1595 1687 1779 1871 1963 2055 2147 2239 2331 2423 2515 2607 2699 2791 2883 2975 3067 3159 3251 3343 3435 3527 3619 3711 3803 3895 3987 4079 4171 4263 4355 4447 4539 4631 4723 4815 4907 4999 5091 5183 5275 5367 5459 5551 5643 5735 5827 5919 6011 6103 6195 6287 6379 6471 6563 6655 6747 6839 6931 7023 7115 7207 7299 7391 7483 7575 7667 7759 7851 7943 8035 8127 8219 8311 8403 ] -> [45] rcvbuf=[45 137 229 321 413 505 597 689 781 873 965 1057 1149 1241 1333 1425 1517 1609 1701 1793 1885 1977 2069 2161 2253 2345 2437 2529 2621 2713 2805 2897 2989 3081 3173 3265 3357 3449 3541 3633 3725 3817 3909 4001 4093 4185 4277 4369 4461 4553 4645 4737 4829 4921 5013 5105 5197 5289 5381 5473 5565 5657 5749 5841 5933 6025 6117 6209 6301 6393 6485 6577 6669 6761 6853 6945 7037 7129 7221 7313 7405 7497 7589 7681 7773 7865 7957 8049 8141 8233 8325 8417 ] -> [47] rcvbuf=[47 139 231 323 415 507 599 691 783 875 967 1059 1151 1243 1335 1427 1519 1611 1703 1795 1887 1979 2071 2163 2255 2347 2439 2531 2623 2715 2807 2899 2991 3083 3175 3267 3359 3451 3543 3635 3727 3819 3911 4003 4095 4187 4279 4371 4463 4555 4647 4739 4831 4923 5015 5107 5199 5291 5383 5475 5567 5659 5751 5843 5935 6027 6119 6211 6303 6395 6487 6579 6671 6763 6855 6947 7039 7131 7223 7315 7407 7499 7591 7683 7775 7867 7959 8051 8143 8235 8327 8419 ] -> [42] rcvbuf=[42 134 226 318 410 502 594 686 778 870 962 1054 1146 1238 1330 1422 1514 1606 1698 1790 1882 1974 2066 2158 2250 2342 2434 2526 2618 2710 2802 2894 2986 3078 3170 3262 3354 3446 3538 3630 3722 3814 3906 3998 4090 4182 4274 4366 4458 4550 4642 4734 4826 4918 5010 5102 5194 5286 5378 5470 5562 5654 5746 5838 5930 6022 6114 6206 6298 6390 6482 6574 6666 6758 6850 6942 7034 7126 7218 7310 7402 7494 7586 7678 7770 7862 7954 8046 8138 8230 8322 8414 ] -> [44] rcvbuf=[44 136 228 320 412 504 596 688 780 872 964 1056 1148 1240 1332 1424 1516 1608 1700 1792 1884 1976 2068 2160 2252 2344 2436 2528 2620 2712 2804 2896 2988 3080 3172 3264 3356 3448 3540 3632 3724 3816 3908 4000 4092 4184 4276 4368 4460 4552 4644 4736 4828 4920 5012 5104 5196 5288 5380 5472 5564 5656 5748 5840 5932 6024 6116 6208 6300 6392 6484 6576 6668 6760 6852 6944 7036 7128 7220 7312 7404 7496 7588 7680 7772 7864 7956 8048 8140 8232 8324 8416 ] -> [30] rcvbuf=[30 122 214 306 398 490 582 674 766 858 950 1042 1134 1226 1318 1410 1502 1594 1686 1778 1870 1962 2054 2146 2238 2330 2422 2514 2606 2698 2790 2882 2974 3066 3158 3250 3342 3434 3526 3618 3710 3802 3894 3986 4078 4170 4262 4354 4446 4538 4630 4722 4814 4906 4998 5090 5182 5274 5366 5458 5550 5642 5734 5826 5918 6010 6102 6194 6286 6378 6470 6562 6654 6746 6838 6930 7022 7114 7206 7298 7390 7482 7574 7666 7758 7850 7942 8034 8126 8218 8310 8402 ] -> [46] rcvbuf=[46 138 230 322 414 506 598 690 782 874 966 1058 1150 1242 1334 1426 1518 1610 1702 1794 1886 1978 2070 2162 2254 2346 2438 2530 2622 2714 2806 2898 2990 3082 3174 3266 3358 3450 3542 3634 3726 3818 3910 4002 4094 4186 4278 4370 4462 4554 4646 4738 4830 4922 5014 5106 5198 5290 5382 5474 5566 5658 5750 5842 5934 6026 6118 6210 6302 6394 6486 6578 6670 6762 6854 6946 7038 7130 7222 7314 7406 7498 7590 7682 7774 7866 7958 8050 8142 8234 8326 8418 ] -> [63] rcvbuf=[63 155 247 339 431 523 615 707 799 891 983 1075 1167 1259 1351 1443 1535 1627 1719 1811 1903 1995 2087 2179 2271 2363 2455 2547 2639 2731 2823 2915 3007 3099 3191 3283 3375 3467 3559 3651 3743 3835 3927 4019 4111 4203 4295 4387 4479 4571 4663 4755 4847 4939 5031 5123 5215 5307 5399 5491 5583 5675 5767 5859 5951 6043 6135 6227 6319 6411 6503 6595 6687 6779 6871 6963 7055 7147 7239 7331 7423 7515 7607 7699 7791 7883 7975 8067 8159 8251 8343 8435 ] -> [61] rcvbuf=[61 153 245 337 429 521 613 705 797 889 981 1073 1165 1257 1349 1441 1533 1625 1717 1809 1901 1993 2085 2177 2269 2361 2453 2545 2637 2729 2821 2913 3005 3097 3189 3281 3373 3465 3557 3649 3741 3833 3925 4017 4109 4201 4293 4385 4477 4569 4661 4753 4845 4937 5029 5121 5213 5305 5397 5489 5581 5673 5765 5857 5949 6041 6133 6225 6317 6409 6501 6593 6685 6777 6869 6961 7053 7145 7237 7329 7421 7513 7605 7697 7789 7881 7973 8065 8157 8249 8341 8433 ] -> [60] rcvbuf=[60 152 244 336 428 520 612 704 796 888 980 1072 1164 1256 1348 1440 1532 1624 1716 1808 1900 1992 2084 2176 2268 2360 2452 2544 2636 2728 2820 2912 3004 3096 3188 3280 3372 3464 3556 3648 3740 3832 3924 4016 4108 4200 4292 4384 4476 4568 4660 4752 4844 4936 5028 5120 5212 5304 5396 5488 5580 5672 5764 5856 5948 6040 6132 6224 6316 6408 6500 6592 6684 6776 6868 6960 7052 7144 7236 7328 7420 7512 7604 7696 7788 7880 7972 8064 8156 8248 8340 8432 ] -> [62] rcvbuf=[62 154 246 338 430 522 614 706 798 890 982 1074 1166 1258 1350 1442 1534 1626 1718 1810 1902 1994 2086 2178 2270 2362 2454 2546 2638 2730 2822 2914 3006 3098 3190 3282 3374 3466 3558 3650 3742 3834 3926 4018 4110 4202 4294 4386 4478 4570 4662 4754 4846 4938 5030 5122 5214 5306 5398 5490 5582 5674 5766 5858 5950 6042 6134 6226 6318 6410 6502 6594 6686 6778 6870 6962 7054 7146 7238 7330 7422 7514 7606 7698 7790 7882 7974 8066 8158 8250 8342 8434 ] diff --git a/teshsuite/smpi/coll-alltoallv/coll-alltoallv.c b/teshsuite/smpi/coll-alltoallv/coll-alltoallv.c index 9e74d4b7aa..db5fe0b385 100644 --- a/teshsuite/smpi/coll-alltoallv/coll-alltoallv.c +++ b/teshsuite/smpi/coll-alltoallv/coll-alltoallv.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -134,7 +134,9 @@ int main(int argc, char **argv) print_buffer_int(sdispls, size, "sdisp:", rank); print_buffer_int(rdispls, size, "rdisp:", rank); - MPI_Alltoallv(sbuf, sendcounts, sdispls, MPI_INT, rbuf, recvcounts, rdispls, MPI_INT, comm); + status = MPI_Alltoallv(sbuf, sendcounts, sdispls, MPI_INT, rbuf, recvcounts, rdispls, MPI_INT, comm); + if (status != MPI_SUCCESS) + printf("MPI_Alltoallv did not return MPI_SUCCESS\n"); print_buffer_int(rbuf, size2, "rbuf:", rank); diff --git a/teshsuite/smpi/coll-barrier/coll-barrier.c b/teshsuite/smpi/coll-barrier/coll-barrier.c index 75f34c633f..55a2bfe24f 100644 --- a/teshsuite/smpi/coll-barrier/coll-barrier.c +++ b/teshsuite/smpi/coll-barrier/coll-barrier.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-bcast/coll-bcast.c b/teshsuite/smpi/coll-bcast/coll-bcast.c index 1cfa9f7631..7843c8ea00 100644 --- a/teshsuite/smpi/coll-bcast/coll-bcast.c +++ b/teshsuite/smpi/coll-bcast/coll-bcast.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-gather/coll-gather.c b/teshsuite/smpi/coll-gather/coll-gather.c index bc15cc0e4f..615ff264f2 100644 --- a/teshsuite/smpi/coll-gather/coll-gather.c +++ b/teshsuite/smpi/coll-gather/coll-gather.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-reduce-scatter/coll-reduce-scatter.c b/teshsuite/smpi/coll-reduce-scatter/coll-reduce-scatter.c index f6968a8f3f..21a9111c40 100644 --- a/teshsuite/smpi/coll-reduce-scatter/coll-reduce-scatter.c +++ b/teshsuite/smpi/coll-reduce-scatter/coll-reduce-scatter.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2022. The SimGrid Team. +/* Copyright (c) 2013-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-reduce/coll-reduce.c b/teshsuite/smpi/coll-reduce/coll-reduce.c index db40cd7861..1f3560df44 100644 --- a/teshsuite/smpi/coll-reduce/coll-reduce.c +++ b/teshsuite/smpi/coll-reduce/coll-reduce.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/coll-scatter/coll-scatter.c b/teshsuite/smpi/coll-scatter/coll-scatter.c index be469e5b37..c3b9ff0333 100644 --- a/teshsuite/smpi/coll-scatter/coll-scatter.c +++ b/teshsuite/smpi/coll-scatter/coll-scatter.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/fort_args/fort_args.f90 b/teshsuite/smpi/fort_args/fort_args.f90 index a76a87cdc4..11c94dc993 100644 --- a/teshsuite/smpi/fort_args/fort_args.f90 +++ b/teshsuite/smpi/fort_args/fort_args.f90 @@ -1,4 +1,4 @@ -! Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. +! Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. ! This program is free software; you can redistribute it and/or modify it ! under the terms of the license (GNU LGPL) which comes with this package. diff --git a/teshsuite/smpi/gh-139/gh-139.c b/teshsuite/smpi/gh-139/gh-139.c index 43f59eccfc..68e9b5c8ee 100644 --- a/teshsuite/smpi/gh-139/gh-139.c +++ b/teshsuite/smpi/gh-139/gh-139.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. +/* Copyright (c) 2019-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/io-all-at/io-all-at.c b/teshsuite/smpi/io-all-at/io-all-at.c index bd0ba00ffe..00481d085c 100644 --- a/teshsuite/smpi/io-all-at/io-all-at.c +++ b/teshsuite/smpi/io-all-at/io-all-at.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/io-all-at/io-all-at.tesh b/teshsuite/smpi/io-all-at/io-all-at.tesh index a16c8b2435..d29e4e06ef 100644 --- a/teshsuite/smpi/io-all-at/io-all-at.tesh +++ b/teshsuite/smpi/io-all-at/io-all-at.tesh @@ -7,40 +7,60 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p > (maestro@) [rank 3] -> carl > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 -> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 -> (3@carl) Position after write in MPI_File /scratch/testfile : 16 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 -> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 -> (1@carl) Position after write in MPI_File /scratch/testfile : 8 -> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 +> (0@bob) Position after write in MPI_File /scratch/testfile : 4 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (2@bob) Position after write in MPI_File /scratch/testfile : 12 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 12 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 -> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 -> (0@bob) Position after write in MPI_File /scratch/testfile : 4 +> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 +> (1@carl) Position after write in MPI_File /scratch/testfile : 8 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 8 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 +> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 +> (3@carl) Position after write in MPI_File /scratch/testfile : 16 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 16 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 -> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 39 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 26 -> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 39 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 13 -> (3@carl) Write in MPI_File /scratch/testfile, 12 bytes written, readsize 12 bytes, movesize 12 -> (3@carl) Position after write in MPI_File /scratch/testfile : 51 -> (1@carl) Write in MPI_File /scratch/testfile, 12 bytes written, readsize 12 bytes, movesize 12 -> (1@carl) Position after write in MPI_File /scratch/testfile : 25 -> (0@bob) Write in MPI_File /scratch/testfile, 12 bytes written, readsize 12 bytes, movesize 12 +> (0@bob) Write in MPI_File /scratch/testfile, 12 bytes written, count 3, writesize 12 bytes, movesize 12 > (0@bob) Position after write in MPI_File /scratch/testfile : 12 -> (2@bob) Write in MPI_File /scratch/testfile, 12 bytes written, readsize 12 bytes, movesize 12 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 40 +> (2@bob) Write in MPI_File /scratch/testfile, 12 bytes written, count 3, writesize 12 bytes, movesize 12 > (2@bob) Position after write in MPI_File /scratch/testfile : 38 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 48 +> (1@carl) Write in MPI_File /scratch/testfile, 12 bytes written, count 3, writesize 12 bytes, movesize 12 +> (1@carl) Position after write in MPI_File /scratch/testfile : 25 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 44 +> (3@carl) Write in MPI_File /scratch/testfile, 12 bytes written, count 3, writesize 12 bytes, movesize 12 +> (3@carl) Position after write in MPI_File /scratch/testfile : 51 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 52 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 16 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 -> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 12 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 8 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 16 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 12 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 8 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 16 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 12 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 8 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 @@ -49,11 +69,19 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 26 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 39 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 13 -> (3@carl) Read in MPI_File /scratch/testfile, 12 bytes read, readsize 12 bytes, movesize 12 -> (3@carl) Position after read in MPI_File /scratch/testfile : 51 -> (1@carl) Read in MPI_File /scratch/testfile, 12 bytes read, readsize 12 bytes, movesize 12 -> (1@carl) Position after read in MPI_File /scratch/testfile : 25 -> (2@bob) Read in MPI_File /scratch/testfile, 12 bytes read, readsize 12 bytes, movesize 12 -> (2@bob) Position after read in MPI_File /scratch/testfile : 38 -> (0@bob) Read in MPI_File /scratch/testfile, 12 bytes read, readsize 12 bytes, movesize 12 +> (0@bob) Read in MPI_File /scratch/testfile, 12 bytes read, count 3, readsize 12 bytes, movesize 12 > (0@bob) Position after read in MPI_File /scratch/testfile : 12 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 40 +> (2@bob) Read in MPI_File /scratch/testfile, 12 bytes read, count 3, readsize 12 bytes, movesize 12 +> (2@bob) Position after read in MPI_File /scratch/testfile : 38 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 48 +> (1@carl) Read in MPI_File /scratch/testfile, 12 bytes read, count 3, readsize 12 bytes, movesize 12 +> (1@carl) Position after read in MPI_File /scratch/testfile : 25 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 44 +> (3@carl) Read in MPI_File /scratch/testfile, 12 bytes read, count 3, readsize 12 bytes, movesize 12 +> (3@carl) Position after read in MPI_File /scratch/testfile : 51 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 52 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 16 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 12 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 8 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 diff --git a/teshsuite/smpi/io-all/io-all.c b/teshsuite/smpi/io-all/io-all.c index 2154cb9d1b..a07df7d8be 100644 --- a/teshsuite/smpi/io-all/io-all.c +++ b/teshsuite/smpi/io-all/io-all.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/io-all/io-all.tesh b/teshsuite/smpi/io-all/io-all.tesh index fe91aa9f97..36445e043a 100644 --- a/teshsuite/smpi/io-all/io-all.tesh +++ b/teshsuite/smpi/io-all/io-all.tesh @@ -7,32 +7,40 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p > (maestro@) [rank 3] -> carl > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 -> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 -> (3@carl) Position after write in MPI_File /scratch/testfile : 16 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 -> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 -> (1@carl) Position after write in MPI_File /scratch/testfile : 8 -> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 +> (0@bob) Position after write in MPI_File /scratch/testfile : 4 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (2@bob) Position after write in MPI_File /scratch/testfile : 12 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 12 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 -> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 -> (0@bob) Position after write in MPI_File /scratch/testfile : 4 +> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 +> (1@carl) Position after write in MPI_File /scratch/testfile : 8 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 8 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 +> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 +> (3@carl) Position after write in MPI_File /scratch/testfile : 16 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 16 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 -> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 39 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 26 -> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 39 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 13 -> (3@carl) Write in MPI_File /scratch/testfile, 12 bytes written, readsize 12 bytes, movesize 12 -> (3@carl) Position after write in MPI_File /scratch/testfile : 51 -> (1@carl) Write in MPI_File /scratch/testfile, 12 bytes written, readsize 12 bytes, movesize 12 -> (1@carl) Position after write in MPI_File /scratch/testfile : 25 -> (0@bob) Write in MPI_File /scratch/testfile, 12 bytes written, readsize 12 bytes, movesize 12 +> (0@bob) Write in MPI_File /scratch/testfile, 12 bytes written, count 3, writesize 12 bytes, movesize 12 > (0@bob) Position after write in MPI_File /scratch/testfile : 12 -> (2@bob) Write in MPI_File /scratch/testfile, 12 bytes written, readsize 12 bytes, movesize 12 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 40 +> (2@bob) Write in MPI_File /scratch/testfile, 12 bytes written, count 3, writesize 12 bytes, movesize 12 > (2@bob) Position after write in MPI_File /scratch/testfile : 38 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 48 +> (1@carl) Write in MPI_File /scratch/testfile, 12 bytes written, count 3, writesize 12 bytes, movesize 12 +> (1@carl) Position after write in MPI_File /scratch/testfile : 25 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 44 +> (3@carl) Write in MPI_File /scratch/testfile, 12 bytes written, count 3, writesize 12 bytes, movesize 12 +> (3@carl) Position after write in MPI_File /scratch/testfile : 51 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 52 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 @@ -41,11 +49,15 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 26 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 39 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 13 -> (3@carl) Read in MPI_File /scratch/testfile, 12 bytes read, readsize 12 bytes, movesize 12 -> (3@carl) Position after read in MPI_File /scratch/testfile : 51 -> (1@carl) Read in MPI_File /scratch/testfile, 12 bytes read, readsize 12 bytes, movesize 12 -> (1@carl) Position after read in MPI_File /scratch/testfile : 25 -> (2@bob) Read in MPI_File /scratch/testfile, 12 bytes read, readsize 12 bytes, movesize 12 -> (2@bob) Position after read in MPI_File /scratch/testfile : 38 -> (0@bob) Read in MPI_File /scratch/testfile, 12 bytes read, readsize 12 bytes, movesize 12 +> (0@bob) Read in MPI_File /scratch/testfile, 12 bytes read, count 3, readsize 12 bytes, movesize 12 > (0@bob) Position after read in MPI_File /scratch/testfile : 12 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 40 +> (2@bob) Read in MPI_File /scratch/testfile, 12 bytes read, count 3, readsize 12 bytes, movesize 12 +> (2@bob) Position after read in MPI_File /scratch/testfile : 38 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 48 +> (1@carl) Read in MPI_File /scratch/testfile, 12 bytes read, count 3, readsize 12 bytes, movesize 12 +> (1@carl) Position after read in MPI_File /scratch/testfile : 25 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 44 +> (3@carl) Read in MPI_File /scratch/testfile, 12 bytes read, count 3, readsize 12 bytes, movesize 12 +> (3@carl) Position after read in MPI_File /scratch/testfile : 51 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 52 diff --git a/teshsuite/smpi/io-ordered/io-ordered.c b/teshsuite/smpi/io-ordered/io-ordered.c index 4803e213c6..7c039e39ce 100644 --- a/teshsuite/smpi/io-ordered/io-ordered.c +++ b/teshsuite/smpi/io-ordered/io-ordered.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/io-ordered/io-ordered.tesh b/teshsuite/smpi/io-ordered/io-ordered.tesh index de8aa49996..d1f446b1b2 100644 --- a/teshsuite/smpi/io-ordered/io-ordered.tesh +++ b/teshsuite/smpi/io-ordered/io-ordered.tesh @@ -9,14 +9,22 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 80 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 40 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 120 -> (3@carl) Write in MPI_File /scratch/testfile, 40 bytes written, readsize 40 bytes, movesize 40 -> (3@carl) Position after write in MPI_File /scratch/testfile : 160 -> (1@carl) Write in MPI_File /scratch/testfile, 40 bytes written, readsize 40 bytes, movesize 40 -> (1@carl) Position after write in MPI_File /scratch/testfile : 80 -> (2@bob) Write in MPI_File /scratch/testfile, 40 bytes written, readsize 40 bytes, movesize 40 -> (2@bob) Position after write in MPI_File /scratch/testfile : 120 -> (0@bob) Write in MPI_File /scratch/testfile, 40 bytes written, readsize 40 bytes, movesize 40 +> (0@bob) Write in MPI_File /scratch/testfile, 40 bytes written, count 10, writesize 40 bytes, movesize 40 > (0@bob) Position after write in MPI_File /scratch/testfile : 40 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 40 +> (2@bob) Write in MPI_File /scratch/testfile, 40 bytes written, count 10, writesize 40 bytes, movesize 40 +> (2@bob) Position after write in MPI_File /scratch/testfile : 120 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 120 +> (1@carl) Write in MPI_File /scratch/testfile, 40 bytes written, count 10, writesize 40 bytes, movesize 40 +> (1@carl) Position after write in MPI_File /scratch/testfile : 80 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 80 +> (3@carl) Write in MPI_File /scratch/testfile, 40 bytes written, count 10, writesize 40 bytes, movesize 40 +> (3@carl) Position after write in MPI_File /scratch/testfile : 160 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 160 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 @@ -25,14 +33,22 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 80 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 40 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 120 -> (3@carl) Read in MPI_File /scratch/testfile, 40 bytes read, readsize 40 bytes, movesize 40 -> (3@carl) Position after read in MPI_File /scratch/testfile : 160 -> (1@carl) Read in MPI_File /scratch/testfile, 40 bytes read, readsize 40 bytes, movesize 40 -> (1@carl) Position after read in MPI_File /scratch/testfile : 80 -> (2@bob) Read in MPI_File /scratch/testfile, 40 bytes read, readsize 40 bytes, movesize 40 -> (2@bob) Position after read in MPI_File /scratch/testfile : 120 -> (0@bob) Read in MPI_File /scratch/testfile, 40 bytes read, readsize 40 bytes, movesize 40 +> (0@bob) Read in MPI_File /scratch/testfile, 40 bytes read, count 10, readsize 40 bytes, movesize 40 > (0@bob) Position after read in MPI_File /scratch/testfile : 40 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 40 +> (2@bob) Read in MPI_File /scratch/testfile, 40 bytes read, count 10, readsize 40 bytes, movesize 40 +> (2@bob) Position after read in MPI_File /scratch/testfile : 120 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 120 +> (1@carl) Read in MPI_File /scratch/testfile, 40 bytes read, count 10, readsize 40 bytes, movesize 40 +> (1@carl) Position after read in MPI_File /scratch/testfile : 80 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 80 +> (3@carl) Read in MPI_File /scratch/testfile, 40 bytes read, count 10, readsize 40 bytes, movesize 40 +> (3@carl) Position after read in MPI_File /scratch/testfile : 160 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 160 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 diff --git a/teshsuite/smpi/io-shared/io-shared.c b/teshsuite/smpi/io-shared/io-shared.c index 1f7dba92b4..6aa07ce963 100644 --- a/teshsuite/smpi/io-shared/io-shared.c +++ b/teshsuite/smpi/io-shared/io-shared.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/io-shared/io-shared.tesh b/teshsuite/smpi/io-shared/io-shared.tesh index 15e85018d5..c8927d4d24 100644 --- a/teshsuite/smpi/io-shared/io-shared.tesh +++ b/teshsuite/smpi/io-shared/io-shared.tesh @@ -7,34 +7,41 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p > (maestro@) [rank 3] -> carl > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 -> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 -> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (0@bob) Position after write in MPI_File /scratch/testfile : 4 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (2@bob) Position after write in MPI_File /scratch/testfile : 8 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 8 -> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (3@carl) Position after write in MPI_File /scratch/testfile : 12 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 -> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (1@carl) Position after write in MPI_File /scratch/testfile : 16 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 16 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 -> (0@bob) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 +> (0@bob) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 > (0@bob) Position after read in MPI_File /scratch/testfile : 4 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (2@bob) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 4 +> (2@bob) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 > (2@bob) Position after read in MPI_File /scratch/testfile : 8 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 8 -> (3@carl) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 +> (3@carl) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 > (3@carl) Position after read in MPI_File /scratch/testfile : 12 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 -> (1@carl) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 +> (1@carl) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 > (1@carl) Position after read in MPI_File /scratch/testfile : 16 - +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 16 diff --git a/teshsuite/smpi/io-simple-at/io-simple-at.c b/teshsuite/smpi/io-simple-at/io-simple-at.c index cff189c796..bb0ffdcc6c 100644 --- a/teshsuite/smpi/io-simple-at/io-simple-at.c +++ b/teshsuite/smpi/io-simple-at/io-simple-at.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/io-simple-at/io-simple-at.tesh b/teshsuite/smpi/io-simple-at/io-simple-at.tesh index 748e012d17..68ec494e21 100644 --- a/teshsuite/smpi/io-simple-at/io-simple-at.tesh +++ b/teshsuite/smpi/io-simple-at/io-simple-at.tesh @@ -7,25 +7,33 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p > (maestro@) [rank 3] -> carl > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 -> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (0@bob) Position after write in MPI_File /scratch/testfile : 4 -> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (2@bob) Position after write in MPI_File /scratch/testfile : 12 -> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 -> (3@carl) Position after write in MPI_File /scratch/testfile : 16 -> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 +> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (1@carl) Position after write in MPI_File /scratch/testfile : 8 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 +> (3@carl) Position after write in MPI_File /scratch/testfile : 16 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 +> (0@bob) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 +> (0@bob) Position after read in MPI_File /scratch/testfile : 4 +> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (2@bob) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 +> (2@bob) Position after read in MPI_File /scratch/testfile : 12 +> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (3@carl) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 -> (3@carl) Position after read in MPI_File /scratch/testfile : 16 -> (1@carl) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 +> (1@carl) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 > (1@carl) Position after read in MPI_File /scratch/testfile : 8 -> (0@bob) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 -> (0@bob) Position after read in MPI_File /scratch/testfile : 4 -> (2@bob) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 -> (2@bob) Position after read in MPI_File /scratch/testfile : 12 +> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 +> (3@carl) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 +> (3@carl) Position after read in MPI_File /scratch/testfile : 16 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0 diff --git a/teshsuite/smpi/io-simple/io-simple.c b/teshsuite/smpi/io-simple/io-simple.c index fc12c9ac89..c7338c712e 100644 --- a/teshsuite/smpi/io-simple/io-simple.c +++ b/teshsuite/smpi/io-simple/io-simple.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2019-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/io-simple/io-simple.tesh b/teshsuite/smpi/io-simple/io-simple.tesh index 762083141c..e6de2e095e 100644 --- a/teshsuite/smpi/io-simple/io-simple.tesh +++ b/teshsuite/smpi/io-simple/io-simple.tesh @@ -7,25 +7,25 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p > (maestro@) [rank 3] -> carl > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 -> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (0@bob) Position after write in MPI_File /scratch/testfile : 4 -> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (2@bob) Position after write in MPI_File /scratch/testfile : 12 -> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 -> (3@carl) Position after write in MPI_File /scratch/testfile : 16 -> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4 +> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 +> (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 > (1@carl) Position after write in MPI_File /scratch/testfile : 8 +> (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, count 1, writesize 4 bytes, movesize 4 +> (3@carl) Position after write in MPI_File /scratch/testfile : 16 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 8 +> (0@bob) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 +> (0@bob) Position after read in MPI_File /scratch/testfile : 4 +> (2@bob) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 +> (2@bob) Position after read in MPI_File /scratch/testfile : 12 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 12 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4 -> (3@carl) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 -> (3@carl) Position after read in MPI_File /scratch/testfile : 16 -> (1@carl) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 +> (1@carl) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 > (1@carl) Position after read in MPI_File /scratch/testfile : 8 -> (0@bob) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 -> (0@bob) Position after read in MPI_File /scratch/testfile : 4 -> (2@bob) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4 -> (2@bob) Position after read in MPI_File /scratch/testfile : 12 +> (3@carl) Read in MPI_File /scratch/testfile, 4 bytes read, count 1, readsize 4 bytes, movesize 4 +> (3@carl) Position after read in MPI_File /scratch/testfile : 16 diff --git a/teshsuite/smpi/macro-partial-shared-communication/macro-partial-shared-communication.c b/teshsuite/smpi/macro-partial-shared-communication/macro-partial-shared-communication.c index aab5e5f819..786b5e78cf 100644 --- a/teshsuite/smpi/macro-partial-shared-communication/macro-partial-shared-communication.c +++ b/teshsuite/smpi/macro-partial-shared-communication/macro-partial-shared-communication.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/macro-partial-shared/macro-partial-shared.c b/teshsuite/smpi/macro-partial-shared/macro-partial-shared.c index 3de3103366..e85b2aa2d3 100644 --- a/teshsuite/smpi/macro-partial-shared/macro-partial-shared.c +++ b/teshsuite/smpi/macro-partial-shared/macro-partial-shared.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -37,7 +37,7 @@ static int check_all(const uint8_t* buf, size_t start, size_t stop, uint8_t valu // Return true iff "enough" elements are equal to (i+value)%256 between buf[start] and buf[stop-1]. static int check_enough(const uint8_t* buf, size_t start, size_t stop, uint8_t value) { - int page_size = 0x1000; + const unsigned int page_size = 0x1000; size_t size = stop-start; if(size <= 2*page_size) // we are not sure to have a whole page that is shared return 1; diff --git a/teshsuite/smpi/macro-sample/macro-sample.c b/teshsuite/smpi/macro-sample/macro-sample.c index 9becaaa382..c777e7b11a 100644 --- a/teshsuite/smpi/macro-sample/macro-sample.c +++ b/teshsuite/smpi/macro-sample/macro-sample.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/macro-shared/macro-shared.c b/teshsuite/smpi/macro-shared/macro-shared.c index 43241d2234..fb90cb6c80 100644 --- a/teshsuite/smpi/macro-shared/macro-shared.c +++ b/teshsuite/smpi/macro-shared/macro-shared.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/mpich3-test/CMakeLists.txt b/teshsuite/smpi/mpich3-test/CMakeLists.txt index f5cc5c5533..8d021ea1a8 100644 --- a/teshsuite/smpi/mpich3-test/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/CMakeLists.txt @@ -28,22 +28,17 @@ set(txt_files ${txt_files} ${CMAKE_CURRENT_SOURCE_DIR}/README ${CMAKE_CURRENT_SOURCE_DIR}/include/mpitestconf.h ${CMAKE_CURRENT_SOURCE_DIR}/include/mpitestcxx.h ${CMAKE_CURRENT_SOURCE_DIR}/include/mpitest.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/mpithreadtest.h ${CMAKE_CURRENT_SOURCE_DIR}/include/mtest_datatype.h ${CMAKE_CURRENT_SOURCE_DIR}/include/mpitest.h PARENT_SCOPE) #build only once files used in each test (C version compiled here at root, F77 is in f77/util, and F90 in F90/util) -if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") -else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") -endif() +set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") include_directories("${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/") -if(enable_smpi AND enable_smpi_MPICH3_testsuite) +if(enable_smpi AND enable_testsuite_smpi_MPICH3) if(HAVE_PRIVATIZATION) add_library(mtest_c STATIC util/dtypes.c util/mtest.c util/mtestcheck.c util/mtest_datatype.c util/mtest_datatype_gen.c) else() @@ -51,7 +46,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endif() endif() -IF(enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) +IF(enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) ADD_TEST(test-smpi-mpich3-thread-f77 ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f77/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f77/ -tests=testlist -privatization=${HAVE_PRIVATIZATION} -execarg=--cfg=contexts/stack-size:8000 -execarg=--cfg=contexts/factory:thread -execarg=--cfg=smpi/privatization:${HAVE_PRIVATIZATION}) SET_TESTS_PROPERTIES(test-smpi-mpich3-thread-f77 PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") ADD_TEST(test-smpi-mpich3-thread-f90 ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f90/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f90/ -tests=testlist -privatization=${HAVE_PRIVATIZATION} -execarg=--cfg=smpi/privatization:${HAVE_PRIVATIZATION} -execarg=--cfg=contexts/factory:thread) diff --git a/teshsuite/smpi/mpich3-test/attr/CMakeLists.txt b/teshsuite/smpi/mpich3-test/attr/CMakeLists.txt index 19391f7c4c..c8b178dbe5 100644 --- a/teshsuite/smpi/mpich3-test/attr/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/attr/CMakeLists.txt @@ -1,15 +1,11 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") - foreach(file attr2type attrdeleteget attrend2 attrend attrerr attrerrcomm attrerrtype attrorder attrordercomm attrordertype attrt + foreach(file attr2type attrdelete attrdeleteget attrend2 attrend attrerr attrerrcomm attrerrtype attrorder attrordercomm attrordertype attrt baseattr2 baseattrcomm fkeyval fkeyvalcomm fkeyvaltype keyval_double_free) #attric add_executable(${file} EXCLUDE_FROM_ALL ${file}.c) add_dependencies(tests ${file}) @@ -17,12 +13,12 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endforeach() endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-attr-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/attr ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/attr -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-attr-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") endif() -foreach(file attr2type attrdeleteget attrend2 attrend attrerr attrerrcomm attrerrtype attrorder attrordercomm attrordertype attrt +foreach(file attr2type attrdelete attrdeleteget attrend2 attrend attrerr attrerrcomm attrerrtype attrorder attrordercomm attrordertype attrt baseattr2 baseattrcomm fkeyval attric fkeyvalcomm fkeyvaltype keyval_double_free keyval_double_free_comm keyval_double_free_type keyval_double_free_win) set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${file}.c) endforeach() diff --git a/teshsuite/smpi/mpich3-test/attr/attrdelete.c b/teshsuite/smpi/mpich3-test/attr/attrdelete.c new file mode 100644 index 0000000000..05f03e973b --- /dev/null +++ b/teshsuite/smpi/mpich3-test/attr/attrdelete.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +/* + Having attr delete function to delete another attribute. + */ +#include "mpi.h" +#include "mpitest.h" +#include + +int key1, key2, key3; + +int test_communicator(MPI_Comm comm); + +int main(int argc, char **argv) +{ + int errs; + MTest_Init(&argc, &argv); + errs = test_communicator(MPI_COMM_WORLD); + MTest_Finalize(errs); + return MTestReturnValue(errs); +} + +static int key2_delete_fn(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state) +{ + MPI_Comm_delete_attr(comm, key1); + MPI_Comm_delete_attr(comm, key3); + return MPI_SUCCESS; +} + +int test_communicator(MPI_Comm comm) +{ + int errs = 0; + int rank, size; + + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &size); + + MPI_Comm_create_keyval(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key1, NULL); + MPI_Comm_create_keyval(MPI_NULL_COPY_FN, key2_delete_fn, &key2, NULL); + MPI_Comm_create_keyval(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key3, NULL); + + MPI_Comm_set_attr(comm, key1, (void *) (MPI_Aint) rank); + MPI_Comm_set_attr(comm, key2, (void *) (MPI_Aint) (rank + 100)); + MPI_Comm_set_attr(comm, key3, (void *) (MPI_Aint) (rank + 200)); + + MPI_Comm_delete_attr(comm, key2); + + MPI_Comm_free_keyval(&key1); + MPI_Comm_free_keyval(&key2); + MPI_Comm_free_keyval(&key3); + + return errs; +} diff --git a/teshsuite/smpi/mpich3-test/attr/testlist b/teshsuite/smpi/mpich3-test/attr/testlist index 56fb8c5c9b..e8577c67b7 100644 --- a/teshsuite/smpi/mpich3-test/attr/testlist +++ b/teshsuite/smpi/mpich3-test/attr/testlist @@ -13,6 +13,7 @@ attrerr 1 #attrend2 5 attrerrcomm 1 attrerrtype 1 +attrdelete 1 attrdeleteget 1 attr2type 1 attrorder 1 diff --git a/teshsuite/smpi/mpich3-test/coll/CMakeLists.txt b/teshsuite/smpi/mpich3-test/coll/CMakeLists.txt index d75ca355fc..6b23c01b1a 100644 --- a/teshsuite/smpi/mpich3-test/coll/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/coll/CMakeLists.txt @@ -1,19 +1,17 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") + # There are too many warnings with these programs + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-compare") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") foreach(test allgather2 allgather3 allgather_struct allgatherv2 allgatherv3 - allred2 allred3 allred4 allred5 allred6 allredmany alltoall1 + allred2 allred3 allred4 allred5 allred6 allredmany allred_derived allred_float alltoall1 alltoallv0 alltoallv alltoallw1 alltoallw2 alltoallw_zeros bcasttest bcastzerotype coll2 coll3 coll4 coll5 coll6 coll7 coll8 - coll9 coll10 coll11 coll12 coll13 exscan exscan2 gather gather2 + coll9 coll10 coll11 coll12 coll13 exscan exscan2 gather gather2 gatherv gather_big ibarrier longuser nonblocking nonblocking2 nonblocking3 iallred # icallgather icallgatherv icallreduce # icalltoall icalltoallv icalltoallw icbarrier icbcast @@ -96,6 +94,8 @@ set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/allred6.c ${CMAKE_CURRENT_SOURCE_DIR}/allred.c ${CMAKE_CURRENT_SOURCE_DIR}/allredmany.c + ${CMAKE_CURRENT_SOURCE_DIR}/allred_derived.c + ${CMAKE_CURRENT_SOURCE_DIR}/allred_float.c ${CMAKE_CURRENT_SOURCE_DIR}/alltoall1.c ${CMAKE_CURRENT_SOURCE_DIR}/alltoallv0.c ${CMAKE_CURRENT_SOURCE_DIR}/alltoallv.c @@ -122,6 +122,7 @@ set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/gather2.c ${CMAKE_CURRENT_SOURCE_DIR}/gather_big.c ${CMAKE_CURRENT_SOURCE_DIR}/gather.c + ${CMAKE_CURRENT_SOURCE_DIR}/gatherv.c ${CMAKE_CURRENT_SOURCE_DIR}/iallred.c ${CMAKE_CURRENT_SOURCE_DIR}/ibarrier.c ${CMAKE_CURRENT_SOURCE_DIR}/icallgather.c diff --git a/teshsuite/smpi/mpich3-test/coll/allred_derived.c b/teshsuite/smpi/mpich3-test/coll/allred_derived.c new file mode 100644 index 0000000000..1b40edd6e2 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/coll/allred_derived.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpi.h" +#include +#include +#include "mpitest.h" +#include + +/* +static char MTEST_Descrip[] = "Test MPI_Allreduce with commutative user-defined operations"; +*/ + +#define MAX_BLOCKLEN 10000 +#define IS_COMMUTATIVE 1 + +/* We make the error count global so that we can easily control the output + of error information (in particular, limiting it after the first 10 + errors */ +int errs = 0; + +/* parameter for a vector type of MPI_INT */ +int g_blocklen = 1; +int g_stride = 1; + +void uop(void *, void *, int *, MPI_Datatype *); +void uop(void *cinPtr, void *coutPtr, int *count, MPI_Datatype * dtype) +{ + const int *cin = (const int *) cinPtr; + int *cout = (int *) coutPtr; + + int k = 0; + for (int i = 0; i < *count; i++) { + for (int j = 0; j < g_blocklen; j++) { + cout[k] += cin[k]; + k += g_stride; + } + } +} + +static void init_buf(void *buf, int count, int rank) +{ + int *p = buf; + + int k = 0; + for (int i = 0; i < count; i++) { + for (int j = 0; j < g_blocklen; j++) { + p[k] = rank + i + j; + k += g_stride; + } + } +} + +static int check_result(void *buf, int count, int size) +{ + int lerrs = 0; + int *p = buf; + + int k = 0; + for (int i = 0; i < count; i++) { + for (int j = 0; j < g_blocklen; j++) { + int exp = size * (size - 1) / 2 + (i + j) * size; + if (p[k] != exp) { + lerrs++; + if (errs + lerrs < 10) { + printf("[%d - %d] expected %d, got %d, %s\n", + i, j, exp, p[k], MTestGetIntracommName()); + } + } + k += g_stride; + } + } + return lerrs; +} + +int main(int argc, char *argv[]) +{ + MPI_Comm comm; + void *buf, *bufout; + MPI_Op op; + MPI_Datatype datatype; + + MTest_Init(&argc, &argv); + + MPI_Op_create(uop, IS_COMMUTATIVE, &op); + + while (MTestGetIntracommGeneral(&comm, 2, 1)) { + if (comm == MPI_COMM_NULL) { + continue; + } + + int rank, size; + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &size); + + int count = 10; + for (int n = 1; n < MAX_BLOCKLEN; n *= 2) { + g_blocklen = n; + int extent = g_blocklen * g_stride * sizeof(int); + MPI_Type_vector(g_blocklen, 1, g_stride, MPI_INT, &datatype); + MPI_Type_commit(&datatype); + + buf = (int *) malloc(extent * count); + if (!buf) { + MPI_Abort(MPI_COMM_WORLD, 1); + } + bufout = (int *) malloc(extent * count); + if (!bufout) { + MPI_Abort(MPI_COMM_WORLD, 1); + } + + init_buf(buf, count, rank); + MPI_Allreduce(buf, bufout, count, datatype, op, comm); + errs += check_result(bufout, count, size); + + /* do it again using MPI_IN_PLACE */ + init_buf(bufout, count, rank); + MPI_Allreduce(MPI_IN_PLACE, bufout, count, datatype, op, comm); + errs += check_result(bufout, count, size); + + free(buf); + free(bufout); + MPI_Type_free(&datatype); + } + + MTestFreeComm(&comm); + } + + MPI_Op_free(&op); + + MTest_Finalize(errs); + return MTestReturnValue(errs); +} diff --git a/teshsuite/smpi/mpich3-test/coll/allred_float.c b/teshsuite/smpi/mpich3-test/coll/allred_float.c new file mode 100644 index 0000000000..6b6ebc610f --- /dev/null +++ b/teshsuite/smpi/mpich3-test/coll/allred_float.c @@ -0,0 +1,98 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ +#include "mpi.h" +#include "mpitest.h" +#include +#include + +/* MPI_Allreduce need produce identical results on all ranks. This is + * particular challenging for floating point datatypes since computer + * floating point arithmetic do not follow associative law. This means + * certain algorithms that works for integers need to be excluded for + * floating point. + * + * This test checks when an inapproprate algorithms is used for floating + * point reduction. + */ + +/* single-precision float has roughly a precision of 7 decimal digits */ +#define BIG 1e6 +#define TINY 1e-2 + +#define N 8 + +float buf[N]; + +static void init_buf(int rank, int pos1, int pos2) +{ + /* Mix a pair of (BIG, -BIG) and TINY, the sum of array will be the sum of + * all TINYs if we add (BIG, -BIG) first, but different results following + * different associativity. A valid algorithm need to produce consistent + * results on all ranks. + */ + for (int i = 0; i < N; i++) { + if (rank == pos1) { + buf[i] = BIG; + } else if (rank == pos2) { + buf[i] = -BIG; + } else { + buf[i] = TINY; + } + } +} + +int main(int argc, char **argv) +{ + int errs = 0; + + MTest_Init(&argc, &argv); + + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (size < 3) { + printf("At least 3 processes required. More (e.g. 10) is recommended.\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + for (int pos1 = 0; pos1 < size; pos1++) { + for (int pos2 = pos1 + 1; pos2 < size; pos2++) { + init_buf(rank, pos1, pos2); + + MPI_Allreduce(MPI_IN_PLACE, buf, N, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD); + + float *check_buf=NULL; + if (rank == 0) { + check_buf = malloc(N * size * sizeof(float)); + } + MPI_Gather(buf, N, MPI_FLOAT, check_buf, N, MPI_FLOAT, 0, MPI_COMM_WORLD); + + if (rank == 0) { + MTestPrintfMsg(1, "BIG positions = (%d, %d), result = [", pos1, pos2); + for (int j = 0; j < N; j++) { + MTestPrintfMsg(1, "%f ", buf[j]); + } + MTestPrintfMsg(1, "]\n"); + + for (int i = 0; i < size; i++) { + for (int j = 0; j < N; j++) { + if (memcmp(&check_buf[i * N + j], &buf[j], sizeof(float)) != 0) { + if (errs < 10) { + printf("(%d - %d) Result [%d] from rank %d mismatch: %f != %f\n", + pos1, pos2, j, i, check_buf[i * N + j], buf[j]); + } + errs++; + } + } + } + free(check_buf); + } + } + } + + MTest_Finalize(errs); + return MTestReturnValue(errs); +} diff --git a/teshsuite/smpi/mpich3-test/coll/coll10.c b/teshsuite/smpi/mpich3-test/coll/coll10.c index d2a3981a80..95da8d9f0d 100644 --- a/teshsuite/smpi/mpich3-test/coll/coll10.c +++ b/teshsuite/smpi/mpich3-test/coll/coll10.c @@ -9,8 +9,6 @@ #define BAD_ANSWER 100000 -int assoc(int *, int *, int *, MPI_Datatype *); - /* The operation is inoutvec[i] = invec[i] op inoutvec[i] (see 4.9.4). The order is important. @@ -18,7 +16,7 @@ int assoc(int *, int *, int *, MPI_Datatype *); Note that the computation is in process rank (in the communicator) order, independent of the root. */ -int assoc(int *invec, int *inoutvec, int *len, MPI_Datatype * dtype) +static void assoc(int *invec, int *inoutvec, int *len, MPI_Datatype *dtype) { int i; for (i = 0; i < *len; i++) { @@ -31,7 +29,6 @@ int assoc(int *invec, int *inoutvec, int *len, MPI_Datatype * dtype) else inoutvec[i] = invec[i]; } - return (1); } int main(int argc, char **argv) diff --git a/teshsuite/smpi/mpich3-test/coll/gatherv.c b/teshsuite/smpi/mpich3-test/coll/gatherv.c new file mode 100644 index 0000000000..6423f355cb --- /dev/null +++ b/teshsuite/smpi/mpich3-test/coll/gatherv.c @@ -0,0 +1,90 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2001 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include +#include "mpitest.h" + +#define MAX_PROCESSES 10 + +int main(int argc, char **argv) +{ + int rank, size, i, j; + int table[MAX_PROCESSES][MAX_PROCESSES]; + int errors = 0; + int participants; + int displs[MAX_PROCESSES]; + int recv_counts[MAX_PROCESSES]; + + MTest_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + /* A maximum of MAX_PROCESSES processes can participate */ + if (size > MAX_PROCESSES) + participants = MAX_PROCESSES; + else + participants = size; + /* while (MAX_PROCESSES % participants) participants--; */ + if (MAX_PROCESSES % participants) { + fprintf(stderr, "Number of processors must divide %d\n", MAX_PROCESSES); + MPI_Abort(MPI_COMM_WORLD, 1); + } + if ((rank < participants)) { + + /* Determine what rows are my responsibility */ + int block_size = MAX_PROCESSES / participants; + int begin_row = rank * block_size; + int end_row = (rank + 1) * block_size; + int send_count = block_size * MAX_PROCESSES; + + /* Fill in the displacements and recv_counts */ + for (i = 0; i < participants; i++) { + displs[i] = i * block_size * MAX_PROCESSES; + recv_counts[i] = send_count; + } + + /* Paint my rows my color */ + for (i = begin_row; i < end_row; i++) + for (j = 0; j < MAX_PROCESSES; j++) + table[i][j] = rank + 10; + + /* Gather everybody's result together - sort of like an */ + /* inefficient allgather */ + for (i = 0; i < participants; i++) { + void *sendbuf = (i == rank ? MPI_IN_PLACE : &table[begin_row][0]); + MPI_Gatherv(sendbuf, send_count, MPI_INT, + &table[0][0], recv_counts, displs, MPI_INT, i, MPI_COMM_WORLD); + } + + + /* Everybody should have the same table now. + * + * The entries are: + * Table[i][j] = (i/block_size) + 10; + */ + for (i = 0; i < MAX_PROCESSES; i++) + if ((table[i][0] - table[i][MAX_PROCESSES - 1] != 0)) + errors++; + for (i = 0; i < MAX_PROCESSES; i++) { + for (j = 0; j < MAX_PROCESSES; j++) { + if (table[i][j] != (i / block_size) + 10) + errors++; + } + } + if (errors) { + /* Print out table if there are any errors */ + for (i = 0; i < MAX_PROCESSES; i++) { + printf("\n"); + for (j = 0; j < MAX_PROCESSES; j++) + printf(" %d", table[i][j]); + } + printf("\n"); + } + } + + MTest_Finalize(errors); + return MTestReturnValue(errors); +} diff --git a/teshsuite/smpi/mpich3-test/coll/longuser.c b/teshsuite/smpi/mpich3-test/coll/longuser.c index aa6b9c6b25..dbd22f65b3 100644 --- a/teshsuite/smpi/mpich3-test/coll/longuser.c +++ b/teshsuite/smpi/mpich3-test/coll/longuser.c @@ -7,19 +7,17 @@ #include #include -int add(double *, double *, int *, MPI_Datatype *); /* * User-defined operation on a long value (tests proper handling of * possible pipelining in the implementation of reductions with user-defined * operations). */ -int add(double *invec, double *inoutvec, int *len, MPI_Datatype * dtype) +static void add(double *invec, double *inoutvec, int *len, MPI_Datatype *dtype) { int i, n = *len; for (i = 0; i < n; i++) { inoutvec[i] = invec[i] + inoutvec[i]; } - return 0; } int main(int argc, char **argv) diff --git a/teshsuite/smpi/mpich3-test/coll/scatter2.c b/teshsuite/smpi/mpich3-test/coll/scatter2.c index 96a55b0ce1..677d03fb48 100644 --- a/teshsuite/smpi/mpich3-test/coll/scatter2.c +++ b/teshsuite/smpi/mpich3-test/coll/scatter2.c @@ -34,7 +34,7 @@ int main(int argc, char **argv) MPI_Type_vector(n, 1, stride, MPI_DOUBLE, &vec); MPI_Type_commit(&vec); MPI_Type_extent(vec, &vextent); - if (vextent != ((n - 1) * (MPI_Aint) stride + 1) * sizeof(double)) { + if (vextent != (MPI_Aint)(((n - 1) * stride + 1) * sizeof(double))) { err++; printf("Vector extent is %ld, should be %ld\n", (long) vextent, (long) (((n - 1) * stride + 1) * sizeof(double))); diff --git a/teshsuite/smpi/mpich3-test/coll/scatter3.c b/teshsuite/smpi/mpich3-test/coll/scatter3.c index 84e88bbcf4..12cbb472e0 100644 --- a/teshsuite/smpi/mpich3-test/coll/scatter3.c +++ b/teshsuite/smpi/mpich3-test/coll/scatter3.c @@ -39,7 +39,7 @@ int main(int argc, char **argv) MPI_Type_vector(n, 1, stride, MPI_DOUBLE, &vec); MPI_Type_commit(&vec); MPI_Type_extent(vec, &vextent); - if (vextent != ((n - 1) * (MPI_Aint) stride + 1) * sizeof(double)) { + if (vextent != (MPI_Aint)(((n - 1) * stride + 1) * sizeof(double))) { errs++; printf("Vector extent is %ld, should be %ld\n", (long) vextent, (long) (((n - 1) * stride + 1) * sizeof(double))); diff --git a/teshsuite/smpi/mpich3-test/coll/testlist b/teshsuite/smpi/mpich3-test/coll/testlist index 3b17eb2b43..31dae94ede 100644 --- a/teshsuite/smpi/mpich3-test/coll/testlist +++ b/teshsuite/smpi/mpich3-test/coll/testlist @@ -9,6 +9,8 @@ allred5 5 allred5 10 allred6 4 allred6 7 +allred_derived 4 +allred_float 10 reduce_mpich 5 reduce_mpich 10 reduce_local 2 mpiversion=2.2 @@ -80,6 +82,7 @@ exscan 10 exscan2 5 gather 4 gather2 4 +gatherv 5 scattern 4 scatter2 4 scatter3 4 diff --git a/teshsuite/smpi/mpich3-test/comm/CMakeLists.txt b/teshsuite/smpi/mpich3-test/comm/CMakeLists.txt index 4c2657ab9f..350a2075ab 100644 --- a/teshsuite/smpi/mpich3-test/comm/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/comm/CMakeLists.txt @@ -1,16 +1,12 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") - foreach(file cmfree cmsplit2 cmsplit cmsplit_type commcreate1 comm_create_group comm_group_half comm_group_rand - comm_info ctxalloc ctxsplit dup dup_with_info commname) + foreach(file cmfree cmfree2 cmsplit2 cmsplit cmsplit_type commcreate1 comm_create_group comm_group_half comm_group_rand + comm_info comm_info2 ctxalloc ctxsplit dup dup_with_info commname) # not compiled files # comm_idup comm_idup_mul comm_idup_overlap dupic ic1 ic2 iccreate icgroup icm icsplit probe-intercomm add_executable(${file} EXCLUDE_FROM_ALL ${file}.c) @@ -19,13 +15,13 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endforeach() endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-comm-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/comm ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/comm -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-comm-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") endif() -foreach(file cmfree cmsplit2 cmsplit cmsplit_type commcreate1 comm_create_group comm_group_half comm_group_rand - comm_info commname ctxalloc ctxsplit dup dupic dup_with_info ic1 ic2 +foreach(file cmfree cmfree2 cmsplit2 cmsplit cmsplit_type commcreate1 comm_create_group comm_group_half comm_group_rand + comm_info comm_info2 commname ctxalloc ctxsplit dup dupic dup_with_info ic1 ic2 iccreate icgroup icm icsplit probe-intercomm comm_create_group_idup comm_idup_comm comm_idup_mul comm_idup comm_idup_iallreduce comm_idup_nb comm_idup_comm2 comm_idup_isend comm_idup_overlap ) set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${file}.c) diff --git a/teshsuite/smpi/mpich3-test/comm/cmfree2.c b/teshsuite/smpi/mpich3-test/comm/cmfree2.c new file mode 100644 index 0000000000..fc94efb0bd --- /dev/null +++ b/teshsuite/smpi/mpich3-test/comm/cmfree2.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpi.h" +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test that communicators have reference count semantics"; +*/ + +int main(int argc, char *argv[]) +{ + int errs = 0; + int rank, size; + MPI_Comm comm; + + MTest_Init(&argc, &argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + if (size < 2) { + fprintf(stderr, "This test requires at least two processes."); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + MPI_Comm_dup(MPI_COMM_WORLD, &comm); + + if (rank == 0) { + MPI_Barrier(MPI_COMM_WORLD); + MPI_Ssend(NULL, 0, MPI_INT, 1, 0, comm); + MPI_Comm_free(&comm); + } else if (rank == 1) { + MPI_Request req; + /* recv an ssend after the user frees the comm */ + MPI_Irecv(NULL, 0, MPI_INT, 0, 0, comm, &req); + MPI_Comm_free(&comm); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Wait(&req, MPI_STATUS_IGNORE); + } else { + MPI_Comm_free(&comm); + MPI_Barrier(MPI_COMM_WORLD); + } + + MTest_Finalize(errs); + return MTestReturnValue(errs); +} diff --git a/teshsuite/smpi/mpich3-test/comm/comm_info2.c b/teshsuite/smpi/mpich3-test/comm/comm_info2.c new file mode 100644 index 0000000000..eb4de40981 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/comm/comm_info2.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include +#include +#include "mpitest.h" + + +/* + This program provides tests cases for the functional evaluation + of the MPI communicator info hints infrastructure. + */ + +int main(int argc, char **argv) +{ + int rank; + MPI_Info info_in, info_out; + int errs = 0; + MPI_Comm comm; + char query_key[MPI_MAX_INFO_KEY]; + char val[MPI_MAX_INFO_VAL]; + char new_key[MPI_MAX_INFO_KEY]; + MPI_Comm comm_dup2; + MPI_Comm comm_dup3; + MPI_Comm comm_dup4; + MPI_Comm comm_split1; + MPI_Info info_out2; + MPI_Info info_out3; + MPI_Info info_out5; + MPI_Info info_in3; + + + /* Read arguments: info key and value */ + snprintf(query_key, MPI_MAX_INFO_KEY, "arbitrary_key"); + snprintf(val, MPI_MAX_INFO_VAL, "arbitrary_val"); + + MTest_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + /* Goal of the test is only to make sure that MPI does not break */ + /* No expectation is made on if the hints are actually set */ + + /* Test 1: comm_dup */ + if (rank == 0) + MTestPrintfMsg(1, + "Testing MPI_Comm_dup with a source comm that has default comm infohints"); + MPI_Comm_dup(MPI_COMM_WORLD, &comm); + + /* Test 2: comm_set_info and comm_get_info */ + if (rank == 0) + MTestPrintfMsg(1, "Testing MPI_Comm_set_info and MPI_Comm_get_info"); + MPI_Info_create(&info_in); + MPI_Info_set(info_in, query_key, val); + MPI_Comm_set_info(comm, info_in); + MPI_Comm_get_info(comm, &info_out); + MPI_Info_free(&info_out); + + /* Test 3: com_dup after info is set in source comm */ + if (rank == 0) + MTestPrintfMsg(1, "Testing MPI_Comm_dup: source comm has user provided comm infohint"); + MPI_Comm_dup(comm, &comm_dup2); + MPI_Comm_get_info(comm_dup2, &info_out2); + MPI_Comm_free(&comm_dup2); + MPI_Info_free(&info_out2); + + /* Test 4: Comm_dup_with_info */ + if (rank == 0) + MTestPrintfMsg(1, "Testing MPI_Comm_dup_with_info"); + + /* Add 2 hints and create comm dup with info */ + MPI_Info_create(&info_in3); + MPI_Info_set(info_in3, query_key, val); + snprintf(new_key, MPI_MAX_INFO_KEY, "arbitrary_key_2"); + MPI_Info_set(info_in3, new_key, "arbitrary_value_2"); + MPI_Comm_dup_with_info(comm, info_in3, &comm_dup3); + MPI_Comm_get_info(comm_dup3, &info_out3); + MPI_Info_free(&info_in3); + MPI_Info_free(&info_out3); + MPI_Comm_free(&comm_dup3); + + /* Test 5: MPI_Comm_split_type */ + MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, info_in, &comm_split1); + MPI_Comm_get_info(comm_split1, &info_out5); + MPI_Info_free(&info_out5); + MPI_Comm_free(&comm_split1); + + /* Test 6: comm_dup_with_info with info=MPI_INFO_NULL */ + if (rank == 0) + MTestPrintfMsg(1, "Testing MPI_Comm_dup_with_info with MPI_INFO_NULL"); + MPI_Comm_dup_with_info(comm, MPI_INFO_NULL, &comm_dup4); + MPI_Comm_free(&comm_dup4); + + /* TODO - Test: MPI_Dist_graph_create_adjacent */ + + /* Release remaining resources */ + MPI_Info_free(&info_in); + MPI_Comm_free(&comm); + + MTest_Finalize(errs); + return MTestReturnValue(errs); +} diff --git a/teshsuite/smpi/mpich3-test/comm/testlist b/teshsuite/smpi/mpich3-test/comm/testlist index 4f2dc40600..74577b3d93 100644 --- a/teshsuite/smpi/mpich3-test/comm/testlist +++ b/teshsuite/smpi/mpich3-test/comm/testlist @@ -14,6 +14,7 @@ commname 4 ctxalloc 2 timeLimit=300 ctxsplit 4 timeLimit=300 cmfree 4 +cmfree2 2 cmsplit 4 cmsplit2 12 #probe-intercomm 2 @@ -35,3 +36,4 @@ dup_with_info 2 mpiversion=3.0 dup_with_info 4 mpiversion=3.0 dup_with_info 9 mpiversion=3.0 comm_info 6 mpiversion=3.0 +comm_info2 1 diff --git a/teshsuite/smpi/mpich3-test/datatype/CMakeLists.txt b/teshsuite/smpi/mpich3-test/datatype/CMakeLists.txt index 1f1bd33442..2e4d7bfd71 100644 --- a/teshsuite/smpi/mpich3-test/datatype/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/datatype/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") @@ -35,7 +31,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-datatype-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/datatype ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/datatype -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-datatype-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") endif() diff --git a/teshsuite/smpi/mpich3-test/errhan/CMakeLists.txt b/teshsuite/smpi/mpich3-test/errhan/CMakeLists.txt index 1a7cff1466..f16e19cf77 100644 --- a/teshsuite/smpi/mpich3-test/errhan/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/errhan/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") @@ -16,7 +12,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endforeach() endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-errhan-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/errhan ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/errhan -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-errhan-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") endif() diff --git a/teshsuite/smpi/mpich3-test/f77/attr/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/attr/CMakeLists.txt index c6464fe2d2..2b8909c338 100644 --- a/teshsuite/smpi/mpich3-test/f77/attr/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/attr/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f77/coll/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/coll/CMakeLists.txt index 632148848d..de624ed881 100644 --- a/teshsuite/smpi/mpich3-test/f77/coll/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/coll/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f77/comm/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/comm/CMakeLists.txt index 44b8e3ed16..f864421f26 100644 --- a/teshsuite/smpi/mpich3-test/f77/comm/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/comm/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f77/datatype/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/datatype/CMakeLists.txt index 2c55fa3175..615b08a68f 100644 --- a/teshsuite/smpi/mpich3-test/f77/datatype/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/datatype/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/teshsuite/smpi/mpich3-test/f77/ext/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/ext/CMakeLists.txt index 3eee5c8f38..9c4e6260e7 100644 --- a/teshsuite/smpi/mpich3-test/f77/ext/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/ext/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../include/") diff --git a/teshsuite/smpi/mpich3-test/f77/info/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/info/CMakeLists.txt index e1b635fd98..0bdc36cd5b 100644 --- a/teshsuite/smpi/mpich3-test/f77/info/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/info/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f77/init/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/init/CMakeLists.txt index 6e51d8d969..6e6b1274a4 100644 --- a/teshsuite/smpi/mpich3-test/f77/init/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/init/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f77/pt2pt/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/pt2pt/CMakeLists.txt index 0fa67d5f65..44e53d7a4b 100644 --- a/teshsuite/smpi/mpich3-test/f77/pt2pt/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/pt2pt/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f77/rma/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/rma/CMakeLists.txt index 6b659ce865..7b0ea935ed 100644 --- a/teshsuite/smpi/mpich3-test/f77/rma/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/rma/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f77/topo/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/topo/CMakeLists.txt index 19223a34a8..d713eb74b0 100644 --- a/teshsuite/smpi/mpich3-test/f77/topo/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/topo/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f77/util/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f77/util/CMakeLists.txt index 1387e60ec5..b8e9ebb39e 100644 --- a/teshsuite/smpi/mpich3-test/f77/util/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f77/util/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f90/coll/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f90/coll/CMakeLists.txt index b051d25598..22be2e5144 100644 --- a/teshsuite/smpi/mpich3-test/f90/coll/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f90/coll/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f90/datatype/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f90/datatype/CMakeLists.txt index bd31a74664..a8a45ce22c 100644 --- a/teshsuite/smpi/mpich3-test/f90/datatype/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f90/datatype/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f90/info/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f90/info/CMakeLists.txt index 00d809c13a..3ee04a0d6d 100644 --- a/teshsuite/smpi/mpich3-test/f90/info/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f90/info/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f90/init/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f90/init/CMakeLists.txt index cd3e8f32ed..18906d1071 100644 --- a/teshsuite/smpi/mpich3-test/f90/init/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f90/init/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f90/pt2pt/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f90/pt2pt/CMakeLists.txt index 89bcd81309..0004e520ed 100644 --- a/teshsuite/smpi/mpich3-test/f90/pt2pt/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f90/pt2pt/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f90/rma/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f90/rma/CMakeLists.txt index 8e004aff34..4bea7c0bf9 100644 --- a/teshsuite/smpi/mpich3-test/f90/rma/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f90/rma/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/f90/util/CMakeLists.txt b/teshsuite/smpi/mpich3-test/f90/util/CMakeLists.txt index 6f38ae4c5c..68fab4d1e1 100644 --- a/teshsuite/smpi/mpich3-test/f90/util/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/f90/util/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3 AND SMPI_FORTRAN) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpif90") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") diff --git a/teshsuite/smpi/mpich3-test/group/CMakeLists.txt b/teshsuite/smpi/mpich3-test/group/CMakeLists.txt index 69d64625a8..c1364f8917 100644 --- a/teshsuite/smpi/mpich3-test/group/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/group/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") @@ -16,7 +12,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endforeach() endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-group-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/group ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/group -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-group-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") endif() diff --git a/teshsuite/smpi/mpich3-test/include/mpitestconf.h b/teshsuite/smpi/mpich3-test/include/mpitestconf.h index 6ccd8014d0..c9f81f1387 100644 --- a/teshsuite/smpi/mpich3-test/include/mpitestconf.h +++ b/teshsuite/smpi/mpich3-test/include/mpitestconf.h @@ -57,9 +57,8 @@ //#define HAVE_FORTRAN_BINDING 0 /* Define to 1 if you have the `getrusage' function. */ -#ifndef WIN32 #define HAVE_GETRUSAGE 1 -#endif + /* Define if struct hostent contains h_addr_list */ #define HAVE_H_ADDR_LIST 1 @@ -142,9 +141,8 @@ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ -#ifndef WIN32 #define HAVE_SYS_RESOURCE_H 1 -#endif + /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 diff --git a/teshsuite/smpi/mpich3-test/include/mpithreadtest.h b/teshsuite/smpi/mpich3-test/include/mpithreadtest.h deleted file mode 100644 index 2bc6899b90..0000000000 --- a/teshsuite/smpi/mpich3-test/include/mpithreadtest.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ -/* - * - * (C) 2001 by Argonne National Laboratory. - * See COPYRIGHT in top-level directory. - */ -#ifndef MPITHREADTEST_H_INCLUDED -#define MPITHREADTEST_H_INCLUDED - -#include "mpitestconf.h" - -/* - Define routines to start a thread for different thread packages. - The routine that is started is expected to return data when it - exits; the type of this data is - - MTEST_THREAD_RETURN_TYPE -*/ - -#ifdef HAVE_WINDOWS_H -#include -#define MTEST_THREAD_RETURN_TYPE DWORD -#define MTEST_THREAD_HANDLE HANDLE -#define MTEST_THREAD_LOCK_TYPE HANDLE -#elif defined(HAVE_PTHREAD_H) -#include -#define MTEST_THREAD_RETURN_TYPE void * -#define MTEST_THREAD_HANDLE pthread_t -#define MTEST_THREAD_LOCK_TYPE pthread_mutex_t -#else -#error Unknown Thread Package -#endif - -/* A dummy retval that is ignored */ -#define MTEST_THREAD_RETVAL_IGN 0 - -int MTest_Start_thread(MTEST_THREAD_RETURN_TYPE(*fn) (void *p), void *arg); -int MTest_Join_threads(void); -int MTest_thread_lock_create(MTEST_THREAD_LOCK_TYPE *); -int MTest_thread_lock(MTEST_THREAD_LOCK_TYPE *); -int MTest_thread_unlock(MTEST_THREAD_LOCK_TYPE *); -int MTest_thread_lock_free(MTEST_THREAD_LOCK_TYPE *); -int MTest_thread_barrier_init(void); -int MTest_thread_barrier(int); -int MTest_thread_barrier_free(void); -#endif diff --git a/teshsuite/smpi/mpich3-test/info/CMakeLists.txt b/teshsuite/smpi/mpich3-test/info/CMakeLists.txt index dcca724d2b..068e157100 100644 --- a/teshsuite/smpi/mpich3-test/info/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/info/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") @@ -16,7 +12,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endforeach() endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-info-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/info ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/info -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-info-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") endif() diff --git a/teshsuite/smpi/mpich3-test/info/infovallen.c b/teshsuite/smpi/mpich3-test/info/infovallen.c index 39cf7070e4..cc3101f9ed 100644 --- a/teshsuite/smpi/mpich3-test/info/infovallen.c +++ b/teshsuite/smpi/mpich3-test/info/infovallen.c @@ -46,7 +46,7 @@ int main(int argc, char *argv[]) errs++; printf("Incorrect value for key %s\n", keys[i]); } - if (strlen(value) != vallen) { + if ((int)strlen(value) != vallen) { errs++; printf("value_len returned %d but actual len is %d\n", vallen, (int) strlen(value)); } diff --git a/teshsuite/smpi/mpich3-test/init/CMakeLists.txt b/teshsuite/smpi/mpich3-test/init/CMakeLists.txt index 973df2ff3f..951fa6c39d 100644 --- a/teshsuite/smpi/mpich3-test/init/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/init/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") @@ -16,7 +12,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endforeach() endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-init-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/init ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/init -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-init-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") endif() diff --git a/teshsuite/smpi/mpich3-test/io/CMakeLists.txt b/teshsuite/smpi/mpich3-test/io/CMakeLists.txt index cfde8723c6..4856c2474e 100644 --- a/teshsuite/smpi/mpich3-test/io/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/io/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") @@ -17,7 +13,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endforeach() endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-io-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/io ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -platformfile=../../../../examples/platforms/hosts_with_disks.xml -hostfile=../../hostfile_io -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/io -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-io-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") endif() diff --git a/teshsuite/smpi/mpich3-test/io/hindexed_io.c b/teshsuite/smpi/mpich3-test/io/hindexed_io.c index 5f4e0446fc..98192f26a3 100644 --- a/teshsuite/smpi/mpich3-test/io/hindexed_io.c +++ b/teshsuite/smpi/mpich3-test/io/hindexed_io.c @@ -46,7 +46,7 @@ int main(int argc, char **argv) data = malloc(data_size); verify = malloc(data_size * BLK_COUNT + HEADER + PAD); - for (i = 0; i < data_size / sizeof(int); i++) + for (i = 0; i < (int)(data_size / sizeof(int)); i++) data[i] = i; MPI_Type_create_hindexed_block(BLK_COUNT, data_size, disp, MPI_BYTE, &file_type); diff --git a/teshsuite/smpi/mpich3-test/perf/CMakeLists.txt b/teshsuite/smpi/mpich3-test/perf/CMakeLists.txt index fffa73f3d3..f0ec2a0a6d 100644 --- a/teshsuite/smpi/mpich3-test/perf/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/perf/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") @@ -17,7 +13,7 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) endforeach() endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-perf-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/perf ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -tests=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/perf/testlist -execarg=-platform\ ${CMAKE_HOME_DIRECTORY}/examples/platforms/cluster_backbone.xml -execarg=--log=root.thr:critical -execarg=--cfg=smpi/async-small-thresh:65536 -execarg=--cfg=contexts/factory:raw -execarg=--cfg=smpi/simulate-computation:0) endif() diff --git a/teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt b/teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt index 955ab60af1..3844964fe3 100644 --- a/teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt @@ -1,16 +1,12 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") - foreach(file anyall bottom eagerdt huge_anysrc huge_underflow inactivereq isendself isendirecv isendselfprobe issendselfcancel cancelanysrc pingping probenull - dtype_send greq1 probe-unexp rqstatus sendall sendflood sendrecv1 sendrecv2 sendrecv3 waitany-null waittestnull many_isend manylmt recv_any sendself scancel scancel2 rcancel bsend1 bsend2 bsend3 bsend4 bsend5 bsendalign bsendfrag bsendpending rqfreeb) + foreach(file anyall bottom eagerdt huge_anysrc huge_dupcomm huge_ssend huge_underflow inactivereq isendself isendrecv isendrecv_replace isendirecv isendselfprobe issendselfcancel large_tag multi_psend_derived cancelanysrc pingping probenull + dtype_send greq1 probe-unexp rqstatus sendall sendflood sendrecv1 sendrecv2 sendrecv3 waitany-null waittestnull many_isend manylmt recv_any sendself scancel scancel2 rcancel bsend1 bsend2 bsend3 bsend4 bsend5 bsendalign bsendfrag bsendpending rqfreeb pssend) # not compiled files: big_count_status mprobe # cancelrecv icsend large_message pscancel scancel_unmatch add_executable(${file} EXCLUDE_FROM_ALL ${file}.c) @@ -31,10 +27,12 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) unset(name) endif() -foreach(file anyall bottom eagerdt huge_anysrc huge_underflow inactivereq isendself isendirecv isendselfprobe issendselfcancel pingping probenull +foreach(file anyall bottom eagerdt huge_anysrc huge_dupcomm huge_ssend huge_underflow inactivereq isendrecv isendrecv_replace + isendself isendirecv isendselfprobe issendselfcancel large_tag multi_psend_derived pingping probenull probe-unexp sendall sendflood sendrecv1 sendrecv2 sendrecv3 waitany-null waittestnull big_count_status bsend1 bsend2 bsend3 bsend4 bsend5 bsendalign bsendfrag bsendpending - cancelrecv cancelanysrc dtype_send greq1 icsend large_message pscancel rcancel rqfreeb rqstatus scancel2 scancel sendself many_isend manylmt mprobe recv_any scancel_unmatch + cancelrecv cancelanysrc dtype_send greq1 icsend large_message pscancel pssend + rcancel rqfreeb rqstatus scancel2 scancel sendself many_isend manylmt mprobe recv_any scancel_unmatch ) set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${file}.c) endforeach() diff --git a/teshsuite/smpi/mpich3-test/pt2pt/huge_dupcomm.c b/teshsuite/smpi/mpich3-test/pt2pt/huge_dupcomm.c new file mode 100644 index 0000000000..a22c429d6e --- /dev/null +++ b/teshsuite/smpi/mpich3-test/pt2pt/huge_dupcomm.c @@ -0,0 +1,65 @@ +/* + * (C) 2018 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + * Portions of this code were written by Intel Corporation. + * Copyright (C) 2011-2018 Intel Corporation. Intel provides this material + * to Argonne National Laboratory subject to Software Grant and Corporate + * Contributor License Agreement dated February 8, 2012. + * + * This program checks if MPICH can correctly handle huge message sends + * over multiple different communicators simultaneously + * + */ + +#include +#include +#include + +#include "mpitest.h" + +#define COUNT (4*1024*1024) +#define NCOMMS 4 + +int main(int argc, char *argv[]) +{ + int *buff; + int size, rank; + int i; + MPI_Comm comms[NCOMMS]; + MPI_Request reqs[NCOMMS]; + + MTest_Init(&argc, &argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (size != 2) { + fprintf(stderr, "Launch with two processes\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + buff = malloc(COUNT * NCOMMS * sizeof(int)); + + for (i = 0; i < NCOMMS; i++) + MPI_Comm_dup(MPI_COMM_WORLD, &comms[i]); + + for (i = 0; i < NCOMMS; i++) { + if (rank == 0) + MPI_Isend(buff + COUNT * i, COUNT, MPI_INT, 1 /* dest */ , 0 /* tag */ , comms[i], + &reqs[i]); + else + MPI_Irecv(buff + COUNT * i, COUNT, MPI_INT, 0 /* src */ , 0 /* tag */ , comms[i], + &reqs[i]); + } + MPI_Waitall(NCOMMS, reqs, MPI_STATUSES_IGNORE); + + for (i = 0; i < NCOMMS; i++) + MPI_Comm_free(&comms[i]); + + free(buff); + + MTest_Finalize(0); + + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/pt2pt/huge_ssend.c b/teshsuite/smpi/mpich3-test/pt2pt/huge_ssend.c new file mode 100644 index 0000000000..cdd7f2c73b --- /dev/null +++ b/teshsuite/smpi/mpich3-test/pt2pt/huge_ssend.c @@ -0,0 +1,49 @@ +/* + * (C) 2018 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + * Portions of this code were written by Intel Corporation. + * Copyright (C) 2011-2018 Intel Corporation. Intel provides this material + * to Argonne National Laboratory subject to Software Grant and Corporate + * Contributor License Agreement dated February 8, 2012. + * + * This program checks if MPICH can correctly handle huge synchronous sends + * + */ + +#include +#include +#include + +#include "mpitest.h" + +#define COUNT (4*1024*1024) + +int main(int argc, char *argv[]) +{ + int *buff; + int size, rank; + + MTest_Init(&argc, &argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (size != 2) { + fprintf(stderr, "Launch with two processes\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + buff = malloc(COUNT * sizeof(int)); + + if (rank == 0) + MPI_Ssend(buff, COUNT, MPI_INT, 1, 0, MPI_COMM_WORLD); + else + MPI_Recv(buff, COUNT, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + free(buff); + + MTest_Finalize(0); + + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/pt2pt/inactivereq.c b/teshsuite/smpi/mpich3-test/pt2pt/inactivereq.c index fd9e7d0e33..ea7099cc3e 100644 --- a/teshsuite/smpi/mpich3-test/pt2pt/inactivereq.c +++ b/teshsuite/smpi/mpich3-test/pt2pt/inactivereq.c @@ -40,13 +40,53 @@ int StatusEmpty(MPI_Status * s) return errs ? 0 : 1; } -int main(int argc, char *argv[]) +int test_recv_init(int src_rank, const char *test_name); +int test_recv_init(int src_rank, const char *test_name) { MPI_Request r; MPI_Status s; int errs = 0; int flag; int buf[10]; + int tag = 27; + + MPI_Recv_init(buf, 10, MPI_INT, src_rank, tag, MPI_COMM_WORLD, &r); + + flag = 0; + s.MPI_TAG = 10; + s.MPI_SOURCE = 10; + MPI_Test(&r, &flag, &s); + if (!flag) { + errs++; + printf("Flag not true after MPI_Test (%s)\n", test_name); + printf("Aborting further tests to avoid hanging in MPI_Wait\n"); + return errs; + } + if (!StatusEmpty(&s)) { + errs++; + printf("Status not empty after MPI_Test (%s)\n", test_name); + } + + s.MPI_TAG = 10; + s.MPI_SOURCE = 10; + MPI_Wait(&r, &s); + if (!StatusEmpty(&s)) { + errs++; + printf("Status not empty after MPI_Wait (%s)\n", test_name); + } + + MPI_Request_free(&r); + + return errs; +} + +int main(int argc, char *argv[]) +{ + MPI_Request r; + MPI_Status s; + int errs = 0, e; + int flag; + int buf[10]; int rbuf[10]; int tag = 27; int dest = 0; @@ -57,7 +97,9 @@ int main(int argc, char *argv[]) MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); - /* Create a persistent send request */ + if (rank == 0) + MTestPrintfMsg(1, "Create a persistent send request\n"); + MPI_Send_init(buf, 10, MPI_INT, dest, tag, MPI_COMM_WORLD, &r); flag = 0; @@ -69,8 +111,7 @@ int main(int argc, char *argv[]) printf("Flag not true after MPI_Test (send)\n"); printf("Aborting further tests to avoid hanging in MPI_Wait\n"); MTest_Finalize(errs); - MPI_Finalize(); - return 0; + return MTestReturnValue(errs); } if (!StatusEmpty(&s)) { errs++; @@ -96,8 +137,7 @@ int main(int argc, char *argv[]) MPI_Wait(&r, &s); MPI_Waitall(size, rr, MPI_STATUSES_IGNORE); free(rr); - } - else { + } else { MPI_Start(&r); MPI_Wait(&r, &s); } @@ -111,8 +151,7 @@ int main(int argc, char *argv[]) printf("Flag not true after MPI_Test (send)\n"); printf("Aborting further tests to avoid hanging in MPI_Wait\n"); MTest_Finalize(errs); - MPI_Finalize(); - return 0; + return MTestReturnValue(errs); } if (!StatusEmpty(&s)) { errs++; @@ -131,37 +170,20 @@ int main(int argc, char *argv[]) MPI_Request_free(&r); - /* Create a persistent receive request */ - MPI_Recv_init(buf, 10, MPI_INT, dest, tag, MPI_COMM_WORLD, &r); + if (rank == 0) + MTestPrintfMsg(1, "Create a persistent receive request\n"); - flag = 0; - s.MPI_TAG = 10; - s.MPI_SOURCE = 10; - MPI_Test(&r, &flag, &s); - if (!flag) { - errs++; - printf("Flag not true after MPI_Test (recv)\n"); - printf("Aborting further tests to avoid hanging in MPI_Wait\n"); - MTest_Finalize(errs); - MPI_Finalize(); - return 0; - } - if (!StatusEmpty(&s)) { - errs++; - printf("Status not empty after MPI_Test (recv)\n"); - } + e = test_recv_init(dest, "recv"); + errs += e; + if (e) + goto fn_exit; - s.MPI_TAG = 10; - s.MPI_SOURCE = 10; - MPI_Wait(&r, &s); - if (!StatusEmpty(&s)) { - errs++; - printf("Status not empty after MPI_Wait (recv)\n"); - } + if (rank == 0) + MTestPrintfMsg(1, "Create a persistent receive (ANY_SOURCE) request\n"); - MPI_Request_free(&r); + errs += test_recv_init(MPI_ANY_SOURCE, "recv-anysource"); + fn_exit: MTest_Finalize(errs); - MPI_Finalize(); - return 0; + return MTestReturnValue(errs); } diff --git a/teshsuite/smpi/mpich3-test/pt2pt/isendrecv.c b/teshsuite/smpi/mpich3-test/pt2pt/isendrecv.c new file mode 100644 index 0000000000..63512e662d --- /dev/null +++ b/teshsuite/smpi/mpich3-test/pt2pt/isendrecv.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpi.h" +#include +#include +#include "mpitest.h" + +/* Similar test as isendirecv.c, but use MPI_Isendrecv */ + +int errs = 0; +int elems = 20; +int rank, nproc, dest; +MPI_Comm comm; +float *in_buf, *out_buf; +MPI_Request *reqs; + +/* sendrecv may use the same or different source and destination, + * offset defines the offset between them */ +static void test_sendrecv(int offset) +{ + for (int i = 0; i < nproc; i++) { + for (int j = 0; j < elems; j++) { + in_buf[i * elems + j] = -1.0; + out_buf[i * elems + j] = rank * 10000.0 + i * 100.0 + j; + } + } + + for (int i = 0; i < nproc; i++) { + int j = (i + offset) % nproc; + MPI_Isendrecv(&out_buf[elems * i], elems, MPI_FLOAT, i, 0, + &in_buf[elems * j], elems, MPI_FLOAT, j, 0, comm, &reqs[i]); + } + + MPI_Waitall(nproc, reqs, MPI_STATUSES_IGNORE); + + for (int i = 0; i < nproc; i++) { + for (int j = 0; j < elems; j++) { + if (in_buf[i * elems + j] != i * 10000.0 + rank * 100.0 + j) { + errs++; + } + } + } +} + +int main(int argc, char *argv[]) +{ + MTest_Init(&argc, &argv); + + comm = MPI_COMM_WORLD; + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &nproc); + + reqs = malloc(nproc * sizeof(MPI_Request)); + in_buf = malloc(elems * nproc * sizeof(float)); + out_buf = malloc(elems * nproc * sizeof(float)); + + for (int offset = 0; offset < nproc - 1; offset++) { + test_sendrecv(offset); + } + + free(reqs); + free(in_buf); + free(out_buf); + MTest_Finalize(errs); + return MTestReturnValue(errs); +} diff --git a/teshsuite/smpi/mpich3-test/pt2pt/isendrecv_replace.c b/teshsuite/smpi/mpich3-test/pt2pt/isendrecv_replace.c new file mode 100644 index 0000000000..f0174c91cf --- /dev/null +++ b/teshsuite/smpi/mpich3-test/pt2pt/isendrecv_replace.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +#include "mpi.h" +#include +#include +#include "mpitest.h" + +/* Similar test as isendirecv.c, but use MPI_Isendrecv_replace */ + +int errs = 0; +int elems = 20; +int rank, nproc, dest; +float *buf; +MPI_Comm comm; +MPI_Request *reqs; + +static void test_sendrecv(int offset) +{ + for (int i = 0; i < nproc; i++) { + for (int j = 0; j < elems; j++) { + buf[i * elems + j] = rank * 100.0 + j; + } + } + + for (int i = 0; i < nproc; i++) { + int j = (i + offset) % nproc; + MPI_Isendrecv_replace(&buf[elems * j], elems, MPI_FLOAT, i, 0, j, 0, comm, &reqs[i]); + } + + MPI_Waitall(nproc, reqs, MPI_STATUSES_IGNORE); + + for (int i = 0; i < nproc; i++) { + for (int j = 0; j < elems; j++) { + if (buf[i * elems + j] != i * 100.0 + j) { + if (errs < 10) { + fprintf(stderr, "buf(%d, %d) mismatch, got %f, expect %f\n", i, j, + buf[i * elems + j], (float) (i * 100.0 + j)); + } + errs++; + } + } + } +} + +/* sendrecv may use the same or different source and destination, + * offset defines the offset between them */ + +int main(int argc, char *argv[]) +{ + MTest_Init(&argc, &argv); + + comm = MPI_COMM_WORLD; + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &nproc); + + reqs = malloc(nproc * sizeof(MPI_Request)); + buf = malloc(elems * nproc * sizeof(float)); + + for (int offset = 0; offset < nproc - 1; offset++) { + test_sendrecv(offset); + } + + free(reqs); + free(buf); + MTest_Finalize(errs); + return MTestReturnValue(errs); +} diff --git a/teshsuite/smpi/mpich3-test/pt2pt/large_tag.c b/teshsuite/smpi/mpich3-test/pt2pt/large_tag.c new file mode 100644 index 0000000000..10eeb1ac28 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/pt2pt/large_tag.c @@ -0,0 +1,75 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2010 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include +#include +#include +#include "mpitest.h" + +/* Tests send/receive with large tag values. It mimics the usage of tags in + * some MPI-based libraries (e.g., PETSc). */ + +#define ITER 5 +#define BUF_COUNT (16) + +int recvbuf[BUF_COUNT], sendbuf[BUF_COUNT]; + +int main(int argc, char *argv[]) +{ + int x, size, rank, errs = 0; + void *tag_ub_val = NULL; + int tag = 0, flag = 0; + + MTest_Init(&argc, &argv); + + MPI_Comm_size(MPI_COMM_WORLD, &size); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + /* perform test only with two or more processes */ + if (size < 2) + goto exit; + + /* query the upper bound of tag value */ + MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &tag_ub_val, &flag); + tag = *(int *) tag_ub_val; + if (!flag || tag < 32767) { + fprintf(stdout, "%d -- Incorrect MPI_TAG_UB, found flag=%d, tag=%d\n", rank, flag, tag); + fflush(stdout); + errs++; + goto exit; + } + + /* send/receive with large tags from the upper bound */ + for (x = 0; x < ITER; x++) { + int i; + + if (rank == 0) { + /* reset send buffer */ + for (i = 0; i < BUF_COUNT; i++) + sendbuf[i] = x * BUF_COUNT + i; + + MPI_Send(sendbuf, BUF_COUNT, MPI_INT, 1, tag, MPI_COMM_WORLD); + } else if (rank == 1) { + MPI_Recv(recvbuf, BUF_COUNT, MPI_INT, 0, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + /* check correctness of received data */ + for (i = 0; i < BUF_COUNT; i++) { + int expected_val = x * BUF_COUNT + i; + if (recvbuf[i] != expected_val) { + errs++; + fprintf(stdout, "%d -- Received %d at index %d with tag %d, expected %d\n", + rank, recvbuf[i], i, tag, expected_val); + fflush(stdout); + } + } + } + tag--; + } + + exit: + MTest_Finalize(errs); + + return MTestReturnValue(errs); +} diff --git a/teshsuite/smpi/mpich3-test/pt2pt/multi_psend_derived.c b/teshsuite/smpi/mpich3-test/pt2pt/multi_psend_derived.c new file mode 100644 index 0000000000..84f670e39e --- /dev/null +++ b/teshsuite/smpi/mpich3-test/pt2pt/multi_psend_derived.c @@ -0,0 +1,94 @@ +/* + * (C) 2018 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + * Portions of this code were written by Intel Corporation. + * Copyright (C) 2011-2018 Intel Corporation. Intel provides this material + * to Argonne National Laboratory subject to Software Grant and Corporate + * Contributor License Agreement dated February 8, 2012. + * + * This program checks if MPICH can correctly handle multiple persistent + * communication calls with a derived datatype + * + */ + +#include +#include +#include +#include "mpitest.h" + +#define ITER 16 + +int main(int argc, char *argv[]) +{ + int size, rank; + int i; + MPI_Request req; + MPI_Datatype int_dup; + int v = 1, errs = 0; + + MTest_Init(&argc, &argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (size != 2) { + fprintf(stderr, "Launch with two processes\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + if (rank == 0) + MTestPrintfMsg(1, "Test 1: Persistent send - Recv\n"); + + if (rank == 0) { + MPI_Type_dup(MPI_INT, &int_dup); + v = 42; + MPI_Send_init(&v, 1, int_dup, 1, 0, MPI_COMM_WORLD, &req); + MPI_Type_free(&int_dup); + for (i = 0; i < ITER; i++) { + MPI_Status s; + MPI_Start(&req); + MPI_Wait(&req, &s); + } + MPI_Request_free(&req); + } else { + for (i = 0; i < ITER; i++) { + v = -1; + MPI_Recv(&v, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + if (v != 42) { + errs++; + fprintf(stderr, "Psend-recv iteration %d: Expected 42 but got %d\n", i, v); + } + } + } + + if (rank == 0) + MTestPrintfMsg(1, "Test 2: Send - Persistent recv (with ANY_SOURCE)\n"); + + if (rank == 0) { + for (i = 0; i < ITER; i++) { + v = i; + MPI_Send(&v, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); + } + } else { + MPI_Type_dup(MPI_INT, &int_dup); + MPI_Recv_init(&v, 1, int_dup, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &req); + MPI_Type_free(&int_dup); + for (i = 0; i < ITER; i++) { + MPI_Status s; + v = -1; + MPI_Start(&req); + MPI_Wait(&req, &s); + if (v != i) { + errs++; + fprintf(stderr, "Send-precv(anysrc) iteration %d: Expected %d but got %d\n", + i, i, v); + } + } + MPI_Request_free(&req); + } + + MTest_Finalize(errs); + MPI_Finalize(); + return MTestReturnValue(errs); +} diff --git a/teshsuite/smpi/mpich3-test/pt2pt/pssend.c b/teshsuite/smpi/mpich3-test/pt2pt/pssend.c new file mode 100644 index 0000000000..c93622486b --- /dev/null +++ b/teshsuite/smpi/mpich3-test/pt2pt/pssend.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) by Argonne National Laboratory + * See COPYRIGHT in top-level directory + */ + +/* + * This program checks the semantics of persistent synchronous send + */ +#include "mpi.h" +#include "mpitest.h" + +int main(int argc, char *argv[]) +{ + int errs = 0; + int size, rank; + MPI_Request req; + int flag; + + MTest_Init(&argc, &argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (size < 2) { + fprintf(stderr, "Launch with two processes\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + if (rank == 0) { + MPI_Ssend_init(NULL, 0, MPI_INT, 1, 0, MPI_COMM_WORLD, &req); + MPI_Start(&req); + + /* ssend cannot be complete at this point */ + MPI_Test(&req, &flag, MPI_STATUS_IGNORE); + if (flag != 0) { + errs++; + fprintf(stderr, "ERROR: synchronous send completed before matching recv was posted\n"); + } + } + + MPI_Barrier(MPI_COMM_WORLD); + + if (rank == 0) { + MPI_Wait(&req, MPI_STATUS_IGNORE); + MPI_Request_free(&req); + } else if (rank == 1) { + MPI_Recv(NULL, 0, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + + MTest_Finalize(errs); + + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/pt2pt/testlist b/teshsuite/smpi/mpich3-test/pt2pt/testlist index 6af72a266b..b9f8d4f6bd 100644 --- a/teshsuite/smpi/mpich3-test/pt2pt/testlist +++ b/teshsuite/smpi/mpich3-test/pt2pt/testlist @@ -17,6 +17,8 @@ bsend4 1 bsendalign 2 bsendpending 2 isendself 1 +isendrecv 4 +isendrecv_replace 4 #issendselfcancel 1 isendirecv 10 bsendfrag 2 @@ -33,6 +35,7 @@ scancel 2 xfail=ticket287 scancel2 2 #Needs MPI_Buffer_attach #pscancel 2 xfail=ticket287 +pssend 2 rcancel 2 #cancelrecv 2 xfail=ticket287 isendselfprobe 1 @@ -43,11 +46,15 @@ waitany-null 1 # this should be run only on machines with large amount of memory (>=8GB) # perhaps disable in the release tarball #large_message 3 +large_tag 2 #mprobe 2 mpiversion=3.0 #big_count_status 1 mpiversion=3.0 many_isend 3 manylmt 2 +multi_psend_derived 2 huge_anysrc 2 +huge_dupcomm 2 +huge_ssend 2 huge_underflow 2 dtype_send 2 recv_any 2 diff --git a/teshsuite/smpi/mpich3-test/rma/CMakeLists.txt b/teshsuite/smpi/mpich3-test/rma/CMakeLists.txt index dea3a7aee2..be6d1db0fd 100644 --- a/teshsuite/smpi/mpich3-test/rma/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/rma/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") set(MPICH_FLAGS "-DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DUSE_STDARG=1 -DHAVE_LONG_DOUBLE=1 -DHAVE_PROTOTYPES=1 -DHAVE_SIGNAL_H=1 -DHAVE_SIGACTION=1 -DHAVE_SLEEP=1 -DHAVE_SYSCONF=1 -Wno-error=unused-variable") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") @@ -41,10 +37,10 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite) set_target_properties(transpose3_shm PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS} -DUSE_WIN_ALLOCATE") endif() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-rma-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/rma ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/rma -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-rma-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") - if (enable_thread_sanitizer) + if (enable_thread_sanitizer OR enable_coverage) SET_TESTS_PROPERTIES(test-smpi-mpich3-rma-raw PROPERTIES TIMEOUT 1500) endif() endif() diff --git a/teshsuite/smpi/mpich3-test/topo/CMakeLists.txt b/teshsuite/smpi/mpich3-test/topo/CMakeLists.txt index 8b2da74f7f..7c032fc2fb 100644 --- a/teshsuite/smpi/mpich3-test/topo/CMakeLists.txt +++ b/teshsuite/smpi/mpich3-test/topo/CMakeLists.txt @@ -1,10 +1,6 @@ -if(enable_smpi AND enable_smpi_MPICH3_testsuite) - if(WIN32) - set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h") - else() - set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") - set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") - endif() +if(enable_smpi AND enable_testsuite_smpi_MPICH3) + set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc") + set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff") include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") @@ -23,7 +19,7 @@ foreach(file cartcreates cartshift1 cartsuball cartzero cartmap1 dgraph_unwgt di set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${file}.c) endforeach() -if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) +if (enable_testsuite_smpi_MPICH3 AND HAVE_RAW_CONTEXTS) ADD_TEST(test-smpi-mpich3-topo-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/topo ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${VALGRIND_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/topo -tests=testlist -execarg=--cfg=contexts/factory:raw) SET_TESTS_PROPERTIES(test-smpi-mpich3-topo-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") endif() diff --git a/teshsuite/smpi/mpich3-test/util/dtypes.c b/teshsuite/smpi/mpich3-test/util/dtypes.c index 239d4011e4..a186a728ac 100644 --- a/teshsuite/smpi/mpich3-test/util/dtypes.c +++ b/teshsuite/smpi/mpich3-test/util/dtypes.c @@ -350,7 +350,7 @@ int MTestDatatype2Check(void *inbuf, void *outbuf, int size_bytes) /* * This is a version of CheckData that prints error messages */ -static int MtestDatatype2CheckAndPrint(void *inbuf, void *outbuf, int size_bytes, +int MTestDatatype2CheckAndPrint(void *inbuf, void *outbuf, int size_bytes, char *typename, int typenum) { int errloc, world_rank; diff --git a/teshsuite/smpi/privatization/privatization.c b/teshsuite/smpi/privatization/privatization.c index 57f56c7722..c4ddc7a21b 100644 --- a/teshsuite/smpi/privatization/privatization.c +++ b/teshsuite/smpi/privatization/privatization.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.c b/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.c index 22b1ea6fed..a586ccd498 100644 --- a/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.c +++ b/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2022. The SimGrid Team. +/* Copyright (c) 2011-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.tesh b/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.tesh index 11476da66f..303f73eb7f 100644 --- a/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.tesh +++ b/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.tesh @@ -1,6 +1,6 @@ p Test dsend ! output sort -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ${bindir:=.}/../hostfile -platform ${platfdir}/small_platform.xml -np 2 --log=no_loc ${bindir:=.}/pt2pt-dsend -s --long --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning --cfg=smpi/simulate-computation:no --cfg=smpi/finalization-barrier:on +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ${bindir:=.}/../hostfile -platform ${platfdir}/small_platform.xml -np 2 --log=no_loc ${bindir:=.}/pt2pt-dsend -s --long --log=smpi_config.thres:warning --log=xbt_cfg.thres:warning --cfg=smpi/simulate-computation:no --cfg=smpi/barrier-finalization:on > [Jupiter:1:(2) 0.000000] [dsend/INFO] rank 1: data exchanged > [Tremblay:0:(1) 0.005896] [dsend/INFO] rank 0: data exchanged > [0.000000] [smpi/INFO] [rank 0] -> Tremblay @@ -11,7 +11,7 @@ p message size is 4 bytes p process 1 will finish at 0.5+2*4 (send) + 1+0.1*4 (isend) = 9.9s p process 2 will finish at 0.5+2*4 (time before first send) + 2*(1+0.5*4) (recv+irecv) + 0.005890 (network time, same as before) = 14.505890s ! output sort -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ${bindir:=.}/../hostfile -platform ${platfdir}/small_platform.xml -np 2 --log=no_loc ${bindir:=.}/pt2pt-dsend -s --long --log=smpi_config.thres:warning --cfg=smpi/or:0:1:0.5 --cfg=smpi/os:0:0.5:2 --cfg=smpi/ois:0:1:0.1 --cfg=smpi/simulate-computation:no --cfg=smpi/finalization-barrier:on --log=xbt_cfg.thres:warning +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ${bindir:=.}/../hostfile -platform ${platfdir}/small_platform.xml -np 2 --log=no_loc ${bindir:=.}/pt2pt-dsend -s --long --log=smpi_config.thres:warning --cfg=smpi/or:0:1:0.5 --cfg=smpi/os:0:0.5:2 --cfg=smpi/ois:0:1:0.1 --cfg=smpi/simulate-computation:no --cfg=smpi/barrier-finalization:on --log=xbt_cfg.thres:warning > [Jupiter:1:(2) 9.900000] [dsend/INFO] rank 1: data exchanged > [Tremblay:0:(1) 14.505896] [dsend/INFO] rank 0: data exchanged > [0.000000] [smpi/INFO] [rank 0] -> Tremblay diff --git a/teshsuite/smpi/pt2pt-pingpong/pt2pt-pingpong.c b/teshsuite/smpi/pt2pt-pingpong/pt2pt-pingpong.c index b0b6c66abb..c55917b436 100644 --- a/teshsuite/smpi/pt2pt-pingpong/pt2pt-pingpong.c +++ b/teshsuite/smpi/pt2pt-pingpong/pt2pt-pingpong.c @@ -1,6 +1,6 @@ /* A simple example ping-pong program to test MPI_Send and MPI_Recv */ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/timers/timers.c b/teshsuite/smpi/timers/timers.c index 03f6dffccc..53100712ff 100644 --- a/teshsuite/smpi/timers/timers.c +++ b/teshsuite/smpi/timers/timers.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/smpi/topo-cart-sub/topo-cart-sub.c b/teshsuite/smpi/topo-cart-sub/topo-cart-sub.c index cbaef0cbcf..afb0917932 100644 --- a/teshsuite/smpi/topo-cart-sub/topo-cart-sub.c +++ b/teshsuite/smpi/topo-cart-sub/topo-cart-sub.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. +/* Copyright (c) 2009-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/type-hvector/type-hvector.c b/teshsuite/smpi/type-hvector/type-hvector.c index 77088a2253..b303b8dc7c 100644 --- a/teshsuite/smpi/type-hvector/type-hvector.c +++ b/teshsuite/smpi/type-hvector/type-hvector.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/type-indexed/type-indexed.c b/teshsuite/smpi/type-indexed/type-indexed.c index 45681d367c..b24503e798 100644 --- a/teshsuite/smpi/type-indexed/type-indexed.c +++ b/teshsuite/smpi/type-indexed/type-indexed.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/type-struct/type-struct.c b/teshsuite/smpi/type-struct/type-struct.c index 425f98d05c..9ae85efa36 100644 --- a/teshsuite/smpi/type-struct/type-struct.c +++ b/teshsuite/smpi/type-struct/type-struct.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/smpi/type-vector/type-vector.c b/teshsuite/smpi/type-vector/type-vector.c index 950479eb6d..b968682b06 100644 --- a/teshsuite/smpi/type-vector/type-vector.c +++ b/teshsuite/smpi/type-vector/type-vector.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. +/* Copyright (c) 2012-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/surf/CMakeLists.txt b/teshsuite/surf/CMakeLists.txt deleted file mode 100644 index a9346ba940..0000000000 --- a/teshsuite/surf/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -foreach(x lmm_usage surf_usage surf_usage2) - add_executable (${x} EXCLUDE_FROM_ALL ${x}/${x}.cpp) - target_link_libraries(${x} simgrid) - set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x}) - set_property(TARGET ${x} APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") - add_dependencies(tests ${x}) - - set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.tesh) - set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.cpp) - - ADD_TESH(tesh-surf-${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/surf/${x} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/surf/${x} ${x}.tesh) -endforeach() - -add_executable (maxmin_bench EXCLUDE_FROM_ALL maxmin_bench/maxmin_bench.cpp) -target_link_libraries(maxmin_bench simgrid) -set_target_properties(maxmin_bench PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/maxmin_bench) -set_property(TARGET maxmin_bench APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") -add_dependencies(tests maxmin_bench) - -foreach(x small medium large) - set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/maxmin_bench/maxmin_bench_${x}.tesh) -endforeach() - -set(tesh_files ${tesh_files} PARENT_SCOPE) -set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/maxmin_bench/maxmin_bench.cpp PARENT_SCOPE) - -ADD_TESH(tesh-surf-maxmin-large --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/surf/maxmin_bench --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/surf/maxmin_bench maxmin_bench_large.tesh) - -if(enable_debug) - foreach(x small medium) - ADD_TESH(tesh-surf-maxmin-${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/surf/maxmin_bench --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/surf/maxmin_bench maxmin_bench_${x}.tesh) - endforeach() -endif() \ No newline at end of file diff --git a/teshsuite/surf/lmm_usage/lmm_usage.tesh b/teshsuite/surf/lmm_usage/lmm_usage.tesh deleted file mode 100644 index 1ab150d6b2..0000000000 --- a/teshsuite/surf/lmm_usage/lmm_usage.tesh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env tesh - -$ ${bindir:=.}/lmm_usage -> [0.000000] [surf_test/INFO] ***** Test 1 -> [0.000000] [surf_test/INFO] ***** Test 2 -> [0.000000] [surf_test/INFO] ***** Test 3 diff --git a/teshsuite/surf/surf_usage/surf_usage.tesh b/teshsuite/surf/surf_usage/surf_usage.tesh deleted file mode 100644 index 083d5528b8..0000000000 --- a/teshsuite/surf/surf_usage/surf_usage.tesh +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env tesh - -$ ${bindir:=.}/surf_usage ${platfdir}/two_hosts_profiles.xml -> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cpu/model' to 'Cas01' -> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'CM02' -> [0.000000] [surf_test/INFO] actionA state: SURF_ACTION_RUNNING -> [0.000000] [surf_test/INFO] actionB state: SURF_ACTION_RUNNING -> [0.000000] [surf_test/INFO] actionC state: SURF_ACTION_RUNNING -> [0.200000] [surf_test/INFO] Next Event : 0.2 -> [0.200016] [surf_test/INFO] Next Event : 0.200016 -> [0.200016] [surf_test/INFO] Network Done action -> [1.000000] [surf_test/INFO] Next Event : 1 -> [1.000000] [surf_test/INFO] CPU Failed action -> [2.000000] [surf_test/INFO] Next Event : 2 -> [7.320000] [surf_test/INFO] Next Event : 7.32 -> [7.320000] [surf_test/INFO] CPU Done action -> [10.000000] [surf_test/INFO] Next Event : 10 -> [11.000000] [surf_test/INFO] Next Event : 11 -> [12.000000] [surf_test/INFO] Next Event : 12 -> [20.000000] [surf_test/INFO] Next Event : 20 -> [21.000000] [surf_test/INFO] Next Event : 21 -> [22.000000] [surf_test/INFO] Next Event : 22 -> [30.000000] [surf_test/INFO] Next Event : 30 -> [31.000000] [surf_test/INFO] Next Event : 31 -> [32.000000] [surf_test/INFO] Next Event : 32 -> [40.000000] [surf_test/INFO] Next Event : 40 -> [41.000000] [surf_test/INFO] Next Event : 41 -> [42.000000] [surf_test/INFO] Next Event : 42 -> [50.000000] [surf_test/INFO] Next Event : 50 -> [51.000000] [surf_test/INFO] Next Event : 51 -> [52.000000] [surf_test/INFO] Next Event : 52 -> [53.000000] [surf_test/INFO] Next Event : 53 -> [60.000000] [surf_test/INFO] Next Event : 60 -> [61.000000] [surf_test/INFO] Next Event : 61 -> [62.000000] [surf_test/INFO] Next Event : 62 -> [63.000000] [surf_test/INFO] Next Event : 63 -> [70.000000] [surf_test/INFO] Next Event : 70 -> [71.000000] [surf_test/INFO] Next Event : 71 -> [72.000000] [surf_test/INFO] Next Event : 72 -> [74.000000] [surf_test/INFO] Next Event : 74 -> [80.000000] [surf_test/INFO] Next Event : 80 -> [81.000000] [surf_test/INFO] Next Event : 81 -> [82.000000] [surf_test/INFO] Next Event : 82 -> [83.000000] [surf_test/INFO] Next Event : 83 -> [84.000000] [surf_test/INFO] Next Event : 84 -> [90.000000] [surf_test/INFO] Next Event : 90 -> [91.000000] [surf_test/INFO] Next Event : 91 -> [92.000000] [surf_test/INFO] Next Event : 92 -> [95.000000] [surf_test/INFO] Next Event : 95 -> [100.000000] [surf_test/INFO] Next Event : 100 -> [101.000000] [surf_test/INFO] Next Event : 101 -> [102.000000] [surf_test/INFO] Next Event : 102 -> [104.000000] [surf_test/INFO] Next Event : 104 -> [105.000000] [surf_test/INFO] Next Event : 105 -> [110.000000] [surf_test/INFO] Next Event : 110 -> [111.000000] [surf_test/INFO] Next Event : 111 -> [112.000000] [surf_test/INFO] Next Event : 112 -> [116.000000] [surf_test/INFO] Next Event : 116 -> [120.000000] [surf_test/INFO] Next Event : 120 -> [121.000000] [surf_test/INFO] Next Event : 121 -> [122.000000] [surf_test/INFO] Next Event : 122 -> [125.000000] [surf_test/INFO] Next Event : 125 -> [126.000000] [surf_test/INFO] Next Event : 126 -> [130.000000] [surf_test/INFO] Next Event : 130 -> [131.000000] [surf_test/INFO] Next Event : 131 -> [132.000000] [surf_test/INFO] Next Event : 132 -> [132.500000] [surf_test/INFO] Next Event : 132.5 -> [132.500000] [surf_test/INFO] CPU Done action diff --git a/teshsuite/surf/surf_usage2/surf_usage2.tesh b/teshsuite/surf/surf_usage2/surf_usage2.tesh deleted file mode 100644 index a89c4fe129..0000000000 --- a/teshsuite/surf/surf_usage2/surf_usage2.tesh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env tesh - -$ ${bindir:=.}/surf_usage2 ${platfdir}/two_hosts_profiles.xml -> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'CM02' -> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cpu/model' to 'Cas01' -> [0.200000] [surf_test/INFO] Next Event : 0.2 -> [0.200016] [surf_test/INFO] Next Event : 0.200016 -> [0.200016] [surf_test/INFO] * Done Action -> [1.000000] [surf_test/INFO] Next Event : 1 -> [1.000000] [surf_test/INFO] * Done Action -> [2.000000] [surf_test/INFO] Next Event : 2 -> [7.320000] [surf_test/INFO] Next Event : 7.32 -> [7.320000] [surf_test/INFO] * Done Action -> [10.000000] [surf_test/INFO] Next Event : 10 -> [11.000000] [surf_test/INFO] Next Event : 11 -> [12.000000] [surf_test/INFO] Next Event : 12 -> [20.000000] [surf_test/INFO] Next Event : 20 -> [21.000000] [surf_test/INFO] Next Event : 21 -> [22.000000] [surf_test/INFO] Next Event : 22 -> [30.000000] [surf_test/INFO] Next Event : 30 -> [31.000000] [surf_test/INFO] Next Event : 31 -> [32.000000] [surf_test/INFO] Next Event : 32 -> [40.000000] [surf_test/INFO] Next Event : 40 -> [41.000000] [surf_test/INFO] Next Event : 41 -> [42.000000] [surf_test/INFO] Next Event : 42 -> [50.000000] [surf_test/INFO] Next Event : 50 -> [51.000000] [surf_test/INFO] Next Event : 51 -> [52.000000] [surf_test/INFO] Next Event : 52 -> [53.000000] [surf_test/INFO] Next Event : 53 -> [60.000000] [surf_test/INFO] Next Event : 60 -> [61.000000] [surf_test/INFO] Next Event : 61 -> [62.000000] [surf_test/INFO] Next Event : 62 -> [63.000000] [surf_test/INFO] Next Event : 63 -> [70.000000] [surf_test/INFO] Next Event : 70 -> [71.000000] [surf_test/INFO] Next Event : 71 -> [72.000000] [surf_test/INFO] Next Event : 72 -> [74.000000] [surf_test/INFO] Next Event : 74 -> [80.000000] [surf_test/INFO] Next Event : 80 -> [81.000000] [surf_test/INFO] Next Event : 81 -> [82.000000] [surf_test/INFO] Next Event : 82 -> [83.000000] [surf_test/INFO] Next Event : 83 -> [84.000000] [surf_test/INFO] Next Event : 84 -> [90.000000] [surf_test/INFO] Next Event : 90 -> [91.000000] [surf_test/INFO] Next Event : 91 -> [92.000000] [surf_test/INFO] Next Event : 92 -> [95.000000] [surf_test/INFO] Next Event : 95 -> [100.000000] [surf_test/INFO] Next Event : 100 -> [101.000000] [surf_test/INFO] Next Event : 101 -> [102.000000] [surf_test/INFO] Next Event : 102 -> [104.000000] [surf_test/INFO] Next Event : 104 -> [105.000000] [surf_test/INFO] Next Event : 105 -> [110.000000] [surf_test/INFO] Next Event : 110 -> [111.000000] [surf_test/INFO] Next Event : 111 -> [112.000000] [surf_test/INFO] Next Event : 112 -> [116.000000] [surf_test/INFO] Next Event : 116 -> [120.000000] [surf_test/INFO] Next Event : 120 -> [121.000000] [surf_test/INFO] Next Event : 121 -> [122.000000] [surf_test/INFO] Next Event : 122 -> [125.000000] [surf_test/INFO] Next Event : 125 -> [126.000000] [surf_test/INFO] Next Event : 126 -> [130.000000] [surf_test/INFO] Next Event : 130 -> [131.000000] [surf_test/INFO] Next Event : 131 -> [132.000000] [surf_test/INFO] Next Event : 132 -> [132.500000] [surf_test/INFO] Next Event : 132.5 -> [132.500000] [surf_test/INFO] * Done Action -> [132.500000] [surf_test/INFO] Simulation Terminated diff --git a/teshsuite/xbt/CMakeLists.txt b/teshsuite/xbt/CMakeLists.txt index 1d9a841427..d3c59bbd7a 100644 --- a/teshsuite/xbt/CMakeLists.txt +++ b/teshsuite/xbt/CMakeLists.txt @@ -19,18 +19,8 @@ foreach(x parallel_log_crashtest parmap_bench parmap_test signals) set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.cpp) endforeach() -if(HAVE_MMALLOC) - add_executable (mmalloc_test EXCLUDE_FROM_ALL ${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_test.cpp) - target_link_libraries(mmalloc_test simgrid) - set_target_properties(mmalloc_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mmalloc) - set_property(TARGET mmalloc_test APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") - add_dependencies(tests mmalloc_test) -endif() - -set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/log_usage/log_usage_ndebug.tesh - ${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_64.tesh - ${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_32.tesh PARENT_SCOPE) -set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_test.cpp PARENT_SCOPE) +set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/log_usage/log_usage_ndebug.tesh PARENT_SCOPE) +set(teshsuite_src ${teshsuite_src} PARENT_SCOPE) foreach(x cmdline log_large parallel_log_crashtest parmap_test) ADD_TESH(tesh-xbt-${x} --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/xbt/${x} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/xbt/${x} ${x}.tesh) @@ -46,11 +36,3 @@ if(enable_debug) else() ADD_TESH(tesh-xbt-log --cd ${CMAKE_BINARY_DIR}/teshsuite/xbt/log_usage ${CMAKE_HOME_DIRECTORY}/teshsuite/xbt/log_usage/log_usage_ndebug.tesh) endif() - -if(HAVE_MMALLOC) - if(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 bits - ADD_TESH(tesh-xbt-mmalloc-32 --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/xbt/mmalloc --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/xbt/mmalloc mmalloc_32.tesh) - else() - ADD_TESH(tesh-xbt-mmalloc-64 --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/xbt/mmalloc --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/xbt/mmalloc mmalloc_64.tesh) - endif() -endif() diff --git a/teshsuite/xbt/cmdline/cmdline.c b/teshsuite/xbt/cmdline/cmdline.c index e20d0f5f4e..01e988087a 100644 --- a/teshsuite/xbt/cmdline/cmdline.c +++ b/teshsuite/xbt/cmdline/cmdline.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -6,9 +6,6 @@ #include "simgrid/engine.h" #include -#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v335) -#include "simgrid/simix.h" // we don't need it, but someone must check that this file is actually usable in plain C - XBT_LOG_NEW_DEFAULT_CATEGORY(test, "Logging specific to this test"); int main(int argc, char** argv) diff --git a/teshsuite/xbt/log_large/log_large.c b/teshsuite/xbt/log_large/log_large.c index 1d3c873053..0da4ff68da 100644 --- a/teshsuite/xbt/log_large/log_large.c +++ b/teshsuite/xbt/log_large/log_large.c @@ -1,6 +1,6 @@ /* log_large_test -- log a very large string to test the dynamic variants */ -/* Copyright (c) 2007-2022. The SimGrid Team. +/* Copyright (c) 2007-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/xbt/log_usage/log_usage.c b/teshsuite/xbt/log_usage/log_usage.c index 60c34b6f89..ae5ae84070 100644 --- a/teshsuite/xbt/log_usage/log_usage.c +++ b/teshsuite/xbt/log_usage/log_usage.c @@ -1,6 +1,6 @@ /* log_usage - A test of normal usage of the log facilities */ -/* Copyright (c) 2004-2022. The SimGrid Team. +/* Copyright (c) 2004-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/teshsuite/xbt/mmalloc/mmalloc_32.tesh b/teshsuite/xbt/mmalloc/mmalloc_32.tesh deleted file mode 100644 index 06bc5435dd..0000000000 --- a/teshsuite/xbt/mmalloc/mmalloc_32.tesh +++ /dev/null @@ -1,110 +0,0 @@ -$ ${bindir:=.}/mmalloc_test --log=root.fmt:%m%n -> Allocating a new heap -> HeapA allocated -> 100 bytes allocated with offset 45000 -> 200 bytes allocated with offset 46000 -> 300 bytes allocated with offset 47000 -> 400 bytes allocated with offset 47200 -> 500 bytes allocated with offset 47400 -> 600 bytes allocated with offset 48000 -> 700 bytes allocated with offset 48400 -> 800 bytes allocated with offset 48800 -> 900 bytes allocated with offset 48c00 -> 1000 bytes allocated with offset 49000 -> 1100 bytes allocated with offset 4a000 -> 1200 bytes allocated with offset 4a800 -> 1300 bytes allocated with offset 4b000 -> 1400 bytes allocated with offset 4b800 -> 1500 bytes allocated with offset 4c000 -> 1600 bytes allocated with offset 4c800 -> 1700 bytes allocated with offset 4d000 -> 1800 bytes allocated with offset 4d800 -> 1900 bytes allocated with offset 4e000 -> 2000 bytes allocated with offset 4e800 -> 2100 bytes allocated with offset 4f000 -> 2200 bytes allocated with offset 50000 -> 2300 bytes allocated with offset 51000 -> 2400 bytes allocated with offset 52000 -> 2500 bytes allocated with offset 53000 -> 2600 bytes allocated with offset 54000 -> 2700 bytes allocated with offset 55000 -> 2800 bytes allocated with offset 56000 -> 2900 bytes allocated with offset 57000 -> 3000 bytes allocated with offset 58000 -> 3100 bytes allocated with offset 59000 -> 3200 bytes allocated with offset 5a000 -> 3300 bytes allocated with offset 5b000 -> 3400 bytes allocated with offset 5c000 -> 3500 bytes allocated with offset 5d000 -> 3600 bytes allocated with offset 5e000 -> 3700 bytes allocated with offset 5f000 -> 3800 bytes allocated with offset 60000 -> 3900 bytes allocated with offset 61000 -> 4000 bytes allocated with offset 62000 -> 4100 bytes allocated with offset 63000 -> 4200 bytes allocated with offset 65000 -> 4300 bytes allocated with offset 67000 -> 4400 bytes allocated with offset 69000 -> 4500 bytes allocated with offset 6b000 -> 4600 bytes allocated with offset 6d000 -> 4700 bytes allocated with offset 6f000 -> 4800 bytes allocated with offset 71000 -> 4900 bytes allocated with offset 73000 -> 5000 bytes allocated with offset 75000 -> 100 bytes allocated with offset 45080 -> 200 bytes allocated with offset 46100 -> 300 bytes allocated with offset 47600 -> 400 bytes allocated with offset 47800 -> 500 bytes allocated with offset 47a00 -> 600 bytes allocated with offset 49400 -> 700 bytes allocated with offset 49800 -> 800 bytes allocated with offset 49c00 -> 900 bytes allocated with offset 77000 -> 1000 bytes allocated with offset 77400 -> 1100 bytes allocated with offset 78000 -> 1200 bytes allocated with offset 78800 -> 1300 bytes allocated with offset 79000 -> 1400 bytes allocated with offset 79800 -> 1500 bytes allocated with offset 7a000 -> 1600 bytes allocated with offset 7a800 -> 1700 bytes allocated with offset 7b000 -> 1800 bytes allocated with offset 7b800 -> 1900 bytes allocated with offset 7c000 -> 2000 bytes allocated with offset 7c800 -> 2100 bytes allocated with offset 7d000 -> 2200 bytes allocated with offset 7e000 -> 2300 bytes allocated with offset 7f000 -> 2400 bytes allocated with offset 80000 -> 2500 bytes allocated with offset 81000 -> 2600 bytes allocated with offset 82000 -> 2700 bytes allocated with offset 83000 -> 2800 bytes allocated with offset 84000 -> 2900 bytes allocated with offset 85000 -> 3000 bytes allocated with offset 86000 -> 3100 bytes allocated with offset 87000 -> 3200 bytes allocated with offset 88000 -> 3300 bytes allocated with offset 89000 -> 3400 bytes allocated with offset 8a000 -> 3500 bytes allocated with offset 8b000 -> 3600 bytes allocated with offset 8c000 -> 3700 bytes allocated with offset 8d000 -> 3800 bytes allocated with offset 8e000 -> 3900 bytes allocated with offset 8f000 -> 4000 bytes allocated with offset 90000 -> 4100 bytes allocated with offset 91000 -> 4200 bytes allocated with offset 93000 -> 4300 bytes allocated with offset 95000 -> 4400 bytes allocated with offset 97000 -> 4500 bytes allocated with offset 99000 -> 4600 bytes allocated with offset 9b000 -> 4700 bytes allocated with offset 9d000 -> 4800 bytes allocated with offset 9f000 -> 4900 bytes allocated with offset a1000 -> 5000 bytes allocated with offset a3000 -> All blocks were correctly allocated. Free every second block -> Memset every second block to zero (yeah, they are not currently allocated :) -> Re-allocate every second block -> free all blocks (each one twice, to check that double free are correctly caught) -> free again all blocks (to really check that double free are correctly caught) -> Let's try different codepaths for mrealloc -> Damnit, I cannot break mmalloc this time. That's SO disappointing. diff --git a/teshsuite/xbt/mmalloc/mmalloc_64.tesh b/teshsuite/xbt/mmalloc/mmalloc_64.tesh deleted file mode 100644 index 17356ee80a..0000000000 --- a/teshsuite/xbt/mmalloc/mmalloc_64.tesh +++ /dev/null @@ -1,110 +0,0 @@ -$ ${bindir:=.}/mmalloc_test --log=root.fmt:%m%n -> Allocating a new heap -> HeapA allocated -> 100 bytes allocated with offset 39000 -> 200 bytes allocated with offset 39100 -> 300 bytes allocated with offset 3a000 -> 400 bytes allocated with offset 3a200 -> 500 bytes allocated with offset 3a400 -> 600 bytes allocated with offset 3b000 -> 700 bytes allocated with offset 3b400 -> 800 bytes allocated with offset 3b800 -> 900 bytes allocated with offset 3bc00 -> 1000 bytes allocated with offset 3c000 -> 1100 bytes allocated with offset 3d000 -> 1200 bytes allocated with offset 3d800 -> 1300 bytes allocated with offset 3e000 -> 1400 bytes allocated with offset 3e800 -> 1500 bytes allocated with offset 3f000 -> 1600 bytes allocated with offset 3f800 -> 1700 bytes allocated with offset 40000 -> 1800 bytes allocated with offset 40800 -> 1900 bytes allocated with offset 41000 -> 2000 bytes allocated with offset 41800 -> 2100 bytes allocated with offset 42000 -> 2200 bytes allocated with offset 43000 -> 2300 bytes allocated with offset 44000 -> 2400 bytes allocated with offset 45000 -> 2500 bytes allocated with offset 46000 -> 2600 bytes allocated with offset 47000 -> 2700 bytes allocated with offset 48000 -> 2800 bytes allocated with offset 49000 -> 2900 bytes allocated with offset 4a000 -> 3000 bytes allocated with offset 4b000 -> 3100 bytes allocated with offset 4c000 -> 3200 bytes allocated with offset 4d000 -> 3300 bytes allocated with offset 4e000 -> 3400 bytes allocated with offset 4f000 -> 3500 bytes allocated with offset 50000 -> 3600 bytes allocated with offset 51000 -> 3700 bytes allocated with offset 52000 -> 3800 bytes allocated with offset 53000 -> 3900 bytes allocated with offset 54000 -> 4000 bytes allocated with offset 55000 -> 4100 bytes allocated with offset 56000 -> 4200 bytes allocated with offset 58000 -> 4300 bytes allocated with offset 5a000 -> 4400 bytes allocated with offset 5c000 -> 4500 bytes allocated with offset 5e000 -> 4600 bytes allocated with offset 60000 -> 4700 bytes allocated with offset 62000 -> 4800 bytes allocated with offset 64000 -> 4900 bytes allocated with offset 66000 -> 5000 bytes allocated with offset 68000 -> 100 bytes allocated with offset 39200 -> 200 bytes allocated with offset 39300 -> 300 bytes allocated with offset 3a600 -> 400 bytes allocated with offset 3a800 -> 500 bytes allocated with offset 3aa00 -> 600 bytes allocated with offset 3c400 -> 700 bytes allocated with offset 3c800 -> 800 bytes allocated with offset 3cc00 -> 900 bytes allocated with offset 6a000 -> 1000 bytes allocated with offset 6a400 -> 1100 bytes allocated with offset 6b000 -> 1200 bytes allocated with offset 6b800 -> 1300 bytes allocated with offset 6c000 -> 1400 bytes allocated with offset 6c800 -> 1500 bytes allocated with offset 6d000 -> 1600 bytes allocated with offset 6d800 -> 1700 bytes allocated with offset 6e000 -> 1800 bytes allocated with offset 6e800 -> 1900 bytes allocated with offset 6f000 -> 2000 bytes allocated with offset 6f800 -> 2100 bytes allocated with offset 70000 -> 2200 bytes allocated with offset 71000 -> 2300 bytes allocated with offset 72000 -> 2400 bytes allocated with offset 73000 -> 2500 bytes allocated with offset 74000 -> 2600 bytes allocated with offset 75000 -> 2700 bytes allocated with offset 76000 -> 2800 bytes allocated with offset 77000 -> 2900 bytes allocated with offset 78000 -> 3000 bytes allocated with offset 79000 -> 3100 bytes allocated with offset 7a000 -> 3200 bytes allocated with offset 7b000 -> 3300 bytes allocated with offset 7c000 -> 3400 bytes allocated with offset 7d000 -> 3500 bytes allocated with offset 7e000 -> 3600 bytes allocated with offset 7f000 -> 3700 bytes allocated with offset 80000 -> 3800 bytes allocated with offset 81000 -> 3900 bytes allocated with offset 82000 -> 4000 bytes allocated with offset 83000 -> 4100 bytes allocated with offset 84000 -> 4200 bytes allocated with offset 86000 -> 4300 bytes allocated with offset 88000 -> 4400 bytes allocated with offset 8a000 -> 4500 bytes allocated with offset 8c000 -> 4600 bytes allocated with offset 8e000 -> 4700 bytes allocated with offset 90000 -> 4800 bytes allocated with offset 92000 -> 4900 bytes allocated with offset 94000 -> 5000 bytes allocated with offset 96000 -> All blocks were correctly allocated. Free every second block -> Memset every second block to zero (yeah, they are not currently allocated :) -> Re-allocate every second block -> free all blocks (each one twice, to check that double free are correctly caught) -> free again all blocks (to really check that double free are correctly caught) -> Let's try different codepaths for mrealloc -> Damnit, I cannot break mmalloc this time. That's SO disappointing. diff --git a/teshsuite/xbt/mmalloc/mmalloc_test.cpp b/teshsuite/xbt/mmalloc/mmalloc_test.cpp deleted file mode 100644 index 22ec93369d..0000000000 --- a/teshsuite/xbt/mmalloc/mmalloc_test.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/Exception.hpp" -#include "xbt.h" -#include "xbt/mmalloc.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -XBT_LOG_NEW_DEFAULT_CATEGORY(test,"this test"); - -constexpr int BUFFSIZE = 204800; -constexpr int TESTSIZE = 100; - -#define size_of_block(i) ((((i) % 50) + 1) * 100) - -static void check_block(const unsigned char* p, unsigned char b, int n) -{ - for (int i = 0; i < n; i++) - xbt_assert(p[i] == b, "value mismatch: %p[%d] = %#hhx, expected %#hhx", p, i, p[i], b); -} - -int main(int argc, char**argv) -{ - xbt_mheap_t heapA = nullptr; - std::array pointers; - xbt_init(&argc,argv); - - XBT_INFO("Allocating a new heap"); - unsigned long mask = ~((unsigned long)xbt_pagesize - 1); - auto* addr = reinterpret_cast(((unsigned long)sbrk(0) + BUFFSIZE) & mask); - heapA = xbt_mheap_new(addr, 0); - if (heapA == nullptr) { - perror("attach 1 failed"); - fprintf(stderr, "bye\n"); - exit(1); - } - - XBT_INFO("HeapA allocated"); - - int i; - int size; - for (i = 0; i < TESTSIZE; i++) { - size = size_of_block(i); - pointers[i] = mmalloc(heapA, size); - XBT_INFO("%d bytes allocated with offset %zx", size, (size_t)((char*)pointers[i] - (char*)heapA)); - } - XBT_INFO("All blocks were correctly allocated. Free every second block"); - for (i = 0; i < TESTSIZE; i+=2) { - mfree(heapA, pointers[i]); - } - XBT_INFO("Memset every second block to zero (yeah, they are not currently allocated :)"); - for (i = 0; i < TESTSIZE; i+=2) { - size = size_of_block(i); - memset(pointers[i],0, size); - } - XBT_INFO("Re-allocate every second block"); - for (i = 0; i < TESTSIZE; i+=2) { - size = size_of_block(i); - pointers[i] = mmalloc(heapA, size); - } - - XBT_INFO("free all blocks (each one twice, to check that double free are correctly caught)"); - for (i = 0; i < TESTSIZE; i++) { - bool gotit = false; - mfree(heapA, pointers[i]); - try { - mfree(heapA, pointers[i]); - } catch (const simgrid::Exception&) { - gotit = true; - } - xbt_assert(gotit, "FAIL: A double-free went undetected (for size:%d)", size_of_block(i)); - } - - XBT_INFO("free again all blocks (to really check that double free are correctly caught)"); - for (i = 0; i < TESTSIZE; i++) { - bool gotit = false; - try { - mfree(heapA, pointers[i]); - } catch (const simgrid::Exception&) { - gotit = true; - } - xbt_assert(gotit, "FAIL: A double-free went undetected (for size:%d)", size_of_block(i)); - } - - XBT_INFO("Let's try different codepaths for mrealloc"); - for (i = 0; i < TESTSIZE; i++) { - const std::vector> requests = { - {size_of_block(i) / 2, 0x77}, {size_of_block(i) * 2, 0xaa}, {1, 0xc0}, {0, 0}}; - pointers[i] = nullptr; - for (unsigned k = 0; k < requests.size(); ++k) { - size = requests[k].first; - pointers[i] = mrealloc(heapA, pointers[i], size); - if (k > 0) - check_block(static_cast(pointers[i]), requests[k - 1].second, - std::min(size, requests[k - 1].first)); - if (size > 0) - memset(pointers[i], requests[k].second, size); - } - } - - XBT_INFO("Damnit, I cannot break mmalloc this time. That's SO disappointing."); - return 0; -} diff --git a/teshsuite/xbt/parallel_log_crashtest/parallel_log_crashtest.cpp b/teshsuite/xbt/parallel_log_crashtest/parallel_log_crashtest.cpp index 2f4a558072..da10d2b81d 100644 --- a/teshsuite/xbt/parallel_log_crashtest/parallel_log_crashtest.cpp +++ b/teshsuite/xbt/parallel_log_crashtest/parallel_log_crashtest.cpp @@ -1,6 +1,6 @@ /* synchro_crashtest -- tries to crash the logging mechanism by doing parallel logs*/ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/teshsuite/xbt/parmap_bench/parmap_bench.cpp b/teshsuite/xbt/parmap_bench/parmap_bench.cpp index 7c6b63de5f..42d0692717 100644 --- a/teshsuite/xbt/parmap_bench/parmap_bench.cpp +++ b/teshsuite/xbt/parmap_bench/parmap_bench.cpp @@ -1,10 +1,10 @@ -/* Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/internal_config.h" // HAVE_FUTEX_H -#include "xbt/parmap.hpp" +#include "src/xbt/parmap.hpp" #include #include @@ -133,7 +133,7 @@ int main(int argc, char* argv[]) XBT_INFO("Parmap benchmark with %d workers (modes = %#x)...", nthreads, modes); XBT_INFO("%s", ""); - simgrid::kernel::context::set_nthreads(nthreads); + simgrid::kernel::context::Context::set_nthreads(nthreads); XBT_INFO("Benchmark for parmap create+apply+destroy (small comp):"); bench_all_modes(nthreads, timeout, modes, true, &fun_small_comp); diff --git a/teshsuite/xbt/parmap_test/parmap_test.cpp b/teshsuite/xbt/parmap_test/parmap_test.cpp index 514a6763a5..0e63aaa9f0 100644 --- a/teshsuite/xbt/parmap_test/parmap_test.cpp +++ b/teshsuite/xbt/parmap_test/parmap_test.cpp @@ -1,14 +1,14 @@ /* parmap_test -- test parmap */ -/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/internal_config.h" // HAVE_FUTEX_H +#include "src/xbt/parmap.hpp" #include #include -#include #include #include @@ -88,7 +88,7 @@ int main(int argc, char** argv) int status = 0; xbt_log_control_set("parmap_test.fmt:[%c/%p]%e%m%n"); simgrid::s4u::Engine e(&argc, argv); - simgrid::kernel::context::set_nthreads(16); // dummy value > 1 + simgrid::kernel::context::Context::set_nthreads(16); // dummy value > 1 XBT_INFO("Basic testing posix"); status += test_parmap_basic(XBT_PARMAP_POSIX); diff --git a/teshsuite/xbt/signals/signals.cpp b/teshsuite/xbt/signals/signals.cpp index fc4fcadc15..a0c1676d8e 100644 --- a/teshsuite/xbt/signals/signals.cpp +++ b/teshsuite/xbt/signals/signals.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -11,29 +11,29 @@ static void worker() { simgrid::s4u::Host* other_host = simgrid::s4u::Host::by_name("Fafard"); unsigned int first = - simgrid::s4u::Host::on_state_change.connect([](simgrid::s4u::Host const&) { XBT_INFO("First callback"); }); + simgrid::s4u::Host::on_onoff.connect([](simgrid::s4u::Host const&) { XBT_INFO("First callback"); }); unsigned int second = - simgrid::s4u::Host::on_state_change.connect([](simgrid::s4u::Host const&) { XBT_INFO("Second callback"); }); + simgrid::s4u::Host::on_onoff.connect([](simgrid::s4u::Host const&) { XBT_INFO("Second callback"); }); unsigned int third = - simgrid::s4u::Host::on_state_change.connect([](simgrid::s4u::Host const&) { XBT_INFO("Third callback"); }); + simgrid::s4u::Host::on_onoff.connect([](simgrid::s4u::Host const&) { XBT_INFO("Third callback"); }); XBT_INFO("Turning off: Three callbacks should be triggered"); other_host->turn_off(); XBT_INFO("Disconnect the second callback"); - simgrid::s4u::Host::on_state_change.disconnect(second); + simgrid::s4u::Host::on_onoff.disconnect(second); XBT_INFO("Turning on: Two callbacks should be triggered"); other_host->turn_on(); XBT_INFO("Disconnect the first callback"); - simgrid::s4u::Host::on_state_change.disconnect(first); + simgrid::s4u::Host::on_onoff.disconnect(first); XBT_INFO("Turning off: One callback should be triggered"); other_host->turn_off(); XBT_INFO("Disconnect the third callback"); - simgrid::s4u::Host::on_state_change.disconnect(third); + simgrid::s4u::Host::on_onoff.disconnect(third); XBT_INFO("Turning on: No more callbacks"); other_host->turn_on(); } diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index b05f9f9767..591f664308 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,11 +1,8 @@ set(bin_files ${bin_files} ${CMAKE_CURRENT_SOURCE_DIR}/fix-paje-trace.sh - ${CMAKE_CURRENT_SOURCE_DIR}/generate-dwarf-functions ${CMAKE_CURRENT_SOURCE_DIR}/normalize-pointers.py ${CMAKE_CURRENT_SOURCE_DIR}/sg_xml_unit_converter.py ${CMAKE_CURRENT_SOURCE_DIR}/simgrid_update_xml.pl - ${CMAKE_CURRENT_SOURCE_DIR}/simgrid_convert_TI_traces.py - ${CMAKE_CURRENT_SOURCE_DIR}/MSG_visualization/colorize.pl - ${CMAKE_CURRENT_SOURCE_DIR}/MSG_visualization/trace2fig.pl PARENT_SCOPE) + ${CMAKE_CURRENT_SOURCE_DIR}/simgrid_convert_TI_traces.py PARENT_SCOPE) set(txt_files ${txt_files} ${CMAKE_CURRENT_SOURCE_DIR}/pkg-config/simgrid.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/address_sanitizer.supp diff --git a/tools/MSG_visualization/colorize.pl b/tools/MSG_visualization/colorize.pl deleted file mode 100755 index c98cf326a6..0000000000 --- a/tools/MSG_visualization/colorize.pl +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env perl - -# Copyright (c) 2005-2022. The SimGrid Team. -# All rights reserved. - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the license (GNU LGPL) which comes with this package. - -$col_white = "\033[00m"; -$col_black = "\033[30m"; -$col_red = "\033[31m"; -$col_green = "\033[32m"; -$col_yellow = "\033[33m"; -$col_blue = "\033[34m"; -$col_purple = "\033[35m"; -$col_cyan = "\033[36m"; -$col_ltgray = "\033[37m"; -$col_darkgray = "\033[30m"; - -$col_norm = $col_white; -$col_background = "\033[07m"; -$col_brighten = "\033[01m"; -$col_underline = "\033[04m"; -$col_blink = "\033[05m"; - -# Customize colors here... -$col_default = $col_ltgray; -my (@coltab) = ( - $col_green, $col_yellow, - $col_purple, $col_cyan, - $col_red, $col_blue, - $col_background . $col_green, - $col_background . $col_yellow, $col_background . $col_purple, - $col_background . $col_cyan, $col_background . $col_red, - $col_background . $col_blue, $col_background . $col_magenta, -); - -my %pid; - -# Get options -while (($_ = $ARGV[0]) =~ /^-/) { - shift; - if (/-location/i) { - $opt_print_location = 1; shift; - } elsif (/-h(elp)?$|-u(sage)?$/i) { - print< - - where is a text file of values or '-' for STDIN - -Options: () denote short version - - -location Print the location in the code of the message. -EOH -; - exit; - } -} - -sub pidcolor { - my $pid = shift; - - unless (defined($pid{$pid})) { - # first time we see this pid. Affect it a color - $pid{$pid}=(scalar keys %pid) % (scalar @coltab); - } - return $coltab[$pid{$pid}]; -} - -sub print_line { - my($host,$procname,$pid,$date,$location,$xbt_channel,$message)=@_; - - print $col_norm; - printf "[% 10.6f]",$date; - - print pidcolor($pid); - - if(defined($location)) { - printf "[%10s:%-10s] %s ",$host,$procname,$location; - } else { - printf "[%10s:%-10s]",$host,$procname; - } - print " $message"; - print $col_norm."\n"; -} - -# Read the messages and do the job -while (<>) { - $orgline = $thisline = $_; - - # Typical line [Gatien:slave:(9) 11.243148] msg/gos.c:137: [msg_gos/DEBUG] Action terminated - if ($thisline =~ /^\[(.+):([^:]+):\((\d+)\) ([\d\.]*)\] ([^\[]*) \[([^\[]*)\] (.*)$/) { - $host=$1; - $procname=$2; - $pid=$3; - $date=$4; - if($opt_print_location) { - $location=$5; - $location =~ s/:$//; - } else { - $location = undef; - } - $xbt_channel=$6; - $message=$7; - - print_line($host,$procname,$pid,$date,$location,$xbt_channel,$message); - # Typical line [Boivin:slave:(2) 9.269357] [pmm/INFO] ROW: step(2)<>myrow(0). Receive data from TeX - } elsif ($thisline =~ /^\[([^:]+):([^:]+):\((\d+)\) ([\d\.]*)\] \[([^\[]*)\] (.*)$/) { - $host=$1; - $procname=$2; - $pid=$3; - $date=$4; - $xbt_channel=$5; - $message=$6; - print_line($host,$procname,$pid,$date,undef,$xbt_channel,$message); - } elsif ( $thisline =~ /^==(\d+)== (.*)$/) { - # take care of valgrind outputs - print pidcolor($1)."$2\n"; - - } else { - print $col_default. $orgline; - } -} - -print $col_norm; diff --git a/tools/MSG_visualization/trace2fig.pl b/tools/MSG_visualization/trace2fig.pl deleted file mode 100755 index cbc09d0d06..0000000000 --- a/tools/MSG_visualization/trace2fig.pl +++ /dev/null @@ -1,434 +0,0 @@ -#!/usr/bin/env perl - -# Copyright (c) 2006-2022. The SimGrid Team. -# All rights reserved. - -# This program is free software; you can redistribute it and/or modify it -# under the terms of the license (GNU LGPL) which comes with this package. - -use strict; -use warnings; - -#use Data::Dumper; -use XFig; -use POSIX; - -my($grid_Y_size)=225; -my($grid_X_size)=100550; # Can be changed to improve readability in function of the total execution time - -my($color_suspended)=1; -my($color_compute)=2; -my($color_wait_for_recpt)=3; -my($color_communicate)=4; - -# Determine the order of the colors in the legend -my(@color_list)=($color_compute,$color_communicate,$color_wait_for_recpt,$color_suspended); - -sub read_cat { - my(%Cat); - my($filename)=@_; - my($line); - - open INPUT, $filename; - - while (defined($line=)) { - chomp $line; - if($line =~ /^7\s/) { - my($event,$date,$id,$type,$father,@name) = split(/\s+/,$line); - - $Cat{$id}{name}="@name "; - $Cat{$id}{name}=~s/\"//g; - $Cat{$id}{father}=$father; - $Cat{$id}{type}=$type; - $Cat{$id}{date}=$date; - } - } - close INPUT; - return \%Cat; -} - -sub read_event { - my($filename,$Cat)=@_; - my($line); - - open INPUT, $filename; - - while (defined($line=)) { - chomp $line; - if($line =~ /^11\s/) { - my($event,$date,$type,$id,$state) = split(/\s+/,$line); - push @{$$Cat{$id}{state}}, [$date,$state]; - } - if($line =~ /^12\s/) { - my($event,$date,$type,$id) = split(/\s+/,$line); - push @{$$Cat{$id}{state}}, [$date]; - } - } - close INPUT; -} - -sub read_link { - my($filename)=@_; - my($line); - my(%link); - - open INPUT, $filename; - - while (defined($line=)) { - chomp $line; - if($line =~ /^16\s/) { - my($event,$date,$type,$father,$channel,$src,$key,$trash) = split(/\t+/,$line); - my($numkey)=hex "$key"; - while (defined($link{$numkey})) {$numkey++;} - $link{$numkey}{src}=$src; - $link{$numkey}{src_date}=$date; - - } - if($line =~ /^17\s/) { - my($event,$date,$type,$father,$channel,$dst,$key,$trash) = split(/\t+/,$line); - my($numkey)=hex "$key"; - while (defined($link{$numkey}{dst})) {$numkey++;} - $link{$numkey}{dst}=$dst; - $link{$numkey}{dst_date}=$date; - } - } - close INPUT; - return \%link; -} - -sub build_cat_tree { - my($root,$Cat)=@_; - my(@children)=(); - my($cat); - - foreach $cat (keys %$Cat) { - if($$Cat{$cat}{father} eq $root) { - push @children, build_cat_tree($cat,$Cat); - } -# print "$$Cat{$cat}{name}\t\t $Cat{$cat}{father}\n"; - } - return [$root,@children]; -} - -sub build_cat_list { - my($tree,$cat_list)=@_; - my($root) = shift @$tree; - my($u); - - push @$cat_list,$root; - - foreach $u (@$tree) { - build_cat_list($u,$cat_list); - } - unshift @$tree, $root; -} - -sub cat_sorting_function { - my($cat1,$cat2,$Cat)=@_; - if (!defined($$Cat{$cat1}{state})) { - if (!defined($$Cat{$cat2}{state})) { - return 0; - } else { - return 1; - } - } - - if (!defined($$Cat{$cat2}{state})) { - return -1; - } - - my($comp) = $$Cat{$$Cat{$cat1}{'father'}}{'name'} cmp $$Cat{$$Cat{$cat2}{'father'}}{'name'}; - if ($comp == 0) { - return $$Cat{$cat1}{'name'} cmp $$Cat{$cat2}{'name'}; - } else { - return $comp; - } -} - -sub update_host_Y { - my($host,$i) = @_; - if (!defined($$host{'Y_min_host'})) { - $$host{'Y_min_host'} = $i; - } else { - if ($$host{'Y_min_host'} > $i) { - $$host{'Y_min_host'} = $i; - } - } - if (!defined($$host{'Y_max_host'})) { - $$host{'Y_max_host'} = $i+1; - } else { - if ($$host{'Y_max_host'} < $i+1) { - $$host{'Y_max_host'} = $i+1; - } - } -} - -sub set_cat_position { - my($Cat,$cat_list)=@_; - my($i)=0; - my($cat); - foreach $cat (sort {cat_sorting_function($a,$b,$Cat)} @$cat_list) { - if(defined($$Cat{$cat}{state})) { - update_host_Y($$Cat{$$Cat{$cat}{'father'}},$i); - $$Cat{$cat}{Y_min} = $i; - $$Cat{$cat}{Y_max} = $i+1; - $i++; - } - } -} - -sub create_fig { - my($filename)=shift; - my($fig)=new XFig; - $fig->{object} = 'compound'; # Compound - $fig->{elements} = []; - $fig->{version} = 3.2; - $fig->{orientation} = 'Landscape'; - $fig->{justification} = 'Center'; - $fig->{units} = 'Metric'; - $fig->{papersize} = 'A4'; - $fig->{magnification} = '100.00'; - $fig->{multiplepage} = 'Single'; - $fig->{transparent} = '-2'; - $fig->{resolution} = '1200'; - $fig->{coordsystem} = '2'; - $fig->{filename} = $filename; - return $fig; -} - -sub draw_cat { - my($fig,$Cat,$Link)=@_; - my($cat,$e,$link); - my($max_string_length)=0; - foreach $cat (keys %$Cat) { - next unless (defined($$Cat{$cat}{Y_min}) && - defined($$Cat{$cat}{Y_max})); - my($text) = new XFig ('text'); -# $text->{'text'} = "$$Cat{$$Cat{$cat}{father}}{name}"."$$Cat{$cat}{name}"; - my($printed_name)= $$Cat{$cat}{name}; - $printed_name =~ s/\d+ \(0\)\s*$//; - if (length($printed_name) > $max_string_length) { - $max_string_length = length($printed_name); - } - $text->{'text'} = "$printed_name"; - $text->{'y'} = ($$Cat{$cat}{Y_min}+$$Cat{$cat}{Y_max})/2*$grid_Y_size+68; - $text->{'x'} = -100; - $text->{'subtype'} = 2; - $fig->add ($text); - } - - my($max_date)=0; - foreach $cat (keys %$Cat) { - next unless (defined($$Cat{$cat}{Y_min}) && defined($$Cat{$cat}{Y_max})); - my(@states)=(); - my($e); - foreach $e (@{$$Cat{$cat}{state}}) { - my($new_date,$state) = ($$e[0],$$e[1]); - if ($new_date > $max_date) { - $max_date = $new_date; - } - if(defined($state)) { - push @states, $e; - } else { - my($old_event) = pop @states; - my($old_date) = $$old_event[0]; - $state = $$old_event[1]; - -# LM: I added the next line because of "undefined values"... -# normally, I think that this should not happen, but this part of code is a bit too cryptic to me - next unless (defined($state)); - - my($line) = new XFig ('polyline'); - - $line->{'depth'} = 50; # line - $line->{'subtype'} = 1; # line - $line->{'points'} = [ [$old_date*$grid_X_size, $$Cat{$cat}{Y_min}*$grid_Y_size], - [$new_date*$grid_X_size, $$Cat{$cat}{Y_min}*$grid_Y_size], - [$new_date*$grid_X_size, $$Cat{$cat}{Y_max}*$grid_Y_size], - [$old_date*$grid_X_size, $$Cat{$cat}{Y_max}*$grid_Y_size], - [$old_date*$grid_X_size, $$Cat{$cat}{Y_min}*$grid_Y_size] ]; - $line->{'areafill'} = 20; - if($state eq "S") { - $line->{'fillcolor'} = $color_suspended; - } elsif ($state eq "E") { - $line->{'fillcolor'} = $color_compute; - } elsif ($state eq "B") { - $line->{'fillcolor'} = $color_wait_for_recpt; - } elsif ($state eq "C") { - $line->{'fillcolor'} = $color_communicate; - } - $fig->add ($line); - } - } - } - - foreach $link (keys %$Link) { - my($line) = new XFig ('polyline'); - my($src_date)=$$Link{$link}{src_date}; - my($src)=$$Link{$link}{src}; - my($dst_date)=$$Link{$link}{dst_date}; - my($dst)=$$Link{$link}{dst}; - $line->{'subtype'} = 1; # line - - print STDERR "$link: $src ($src_date) -> $dst ($dst_date)\n"; - - print STDERR "$$Cat{$src}{name} -> $$Cat{$dst}{name}\n"; - $line->{'points'} = [ [$src_date*$grid_X_size, - ($$Cat{$src}{Y_min}+$$Cat{$src}{Y_max})/2*$grid_Y_size], - [$dst_date*$grid_X_size, - ($$Cat{$dst}{Y_min}+$$Cat{$dst}{Y_max})/2*$grid_Y_size] ]; - $line->{'forwardarrow'} = ['1', '1', '1.00', '60.00', '120.00']; - $fig->add ($line); - } - -# Host visualization - my($max_Y)= 0; - - my($index_fill)=0; - my($width_of_one_letter)=80; - my($min_x_for_host)=-400 - $max_string_length*$width_of_one_letter; - my($host_text_x)= $min_x_for_host + 200; - - foreach $cat (keys %$Cat) { - next unless (defined($$Cat{$cat}{Y_min_host}) && defined($$Cat{$cat}{Y_max_host})); - my($line) = new XFig ('polyline'); - - $line->{'depth'} = 150; - $line->{'subtype'} = 1; # line - $line->{'points'} = [ [$min_x_for_host, $$Cat{$cat}{Y_min_host}*$grid_Y_size], - [$max_date*$grid_X_size+150, $$Cat{$cat}{Y_min_host}*$grid_Y_size], - [$max_date*$grid_X_size+150, $$Cat{$cat}{Y_max_host}*$grid_Y_size], - [$min_x_for_host, $$Cat{$cat}{Y_max_host}*$grid_Y_size] ]; - $line->{'areafill'} = 4+3*($index_fill % 2); - $line->{'fillcolor'} = 0; - $line->{'thickness'} = 0; - $index_fill++; - $fig->add ($line); - - my($text) = new XFig ('text'); - $text->{'text'} = "$$Cat{$cat}{name}"; - $text->{'angle'} = 3.14159265/2; - $text->{'x'} = $host_text_x; - $text->{'y'} = ($$Cat{$cat}{Y_min_host}+$$Cat{$cat}{Y_max_host})/2*$grid_Y_size; - $text->{'subtype'} = 1; - $text->{'font_size'} = 30; - $fig->add ($text); - - if ($max_Y<$$Cat{$cat}{Y_max_host}) { - $max_Y = $$Cat{$cat}{Y_max_host}; - } - } - -# Legend: - my($i)=1; - my($color); - foreach $color (@color_list) { - my($min_x)=0; - my($min_Y)=($max_Y+1)*$grid_Y_size; - my($width)=1700; - my($height)=$grid_Y_size; - - my($line) = new XFig ('polyline'); - - $line->{'depth'} = 50; - $line->{'subtype'} = 1; # line - $line->{'points'} = [ [$min_x,$min_Y + ($i-1)*$height ], - [$min_x + $width,$min_Y + ($i-1)*$height], - [$min_x + $width,$min_Y+$height + ($i-1)*$height], - [$min_x,$min_Y+$height + ($i-1)*$height], - [$min_x,$min_Y+ ($i-1)*$height]]; - $line->{'areafill'} = 20; - $line->{'fillcolor'} = $color; - $fig->add ($line); - - my($text) = new XFig ('text'); - - if ($color==$color_suspended) { - $text->{'text'} = "Suspended"; - } - if ($color==$color_compute) { - $text->{'text'} = "Computing"; - } - if ($color==$color_wait_for_recpt) { - $text->{'text'} = "Waiting for reception"; - } - if ($color==$color_communicate) { - $text->{'text'} = "Communicating"; - } - - $text->{'y'} = $min_Y + ($i-0.5)*$height +68; - $text->{'x'} = 50; - $text->{'subtype'} = 0; - $fig->add ($text); - $i++; - } - -# Time axis - my($line) = new XFig ('polyline'); - $line->{'depth'} = 0; - $line->{'subtype'} = 1; # line - $line->{'points'} = [ [0,0],[$max_date * $grid_X_size+150,0] ]; - $line->{'forwardarrow'} = ['1', '1', '1.00', '60.00', '120.00']; - $fig->add ($line); - - my($digits)=POSIX::floor(log($max_date)/log(10)); - my($exponent) = 10**$digits; - my($mantissa)= $max_date / $exponent; - my($incr); - if ($mantissa<2) { - $incr = $exponent/10; - } elsif ($mantissa<5) { - $incr = $exponent/4; - } else { - $incr = $exponent/2; - } - - print "$max_date $digits $exponent $mantissa $incr\n"; - my($x); - for($x=0; $x < $max_date; $x += $incr) { - print "$x\n"; - $line = new XFig ('polyline'); - $line->{'depth'} = 0; - $line->{'subtype'} = 1; # line - $line->{'points'} = [ [$x * $grid_X_size,0],[$x * $grid_X_size, -100] ]; - $line->{'forwardarrow'} = 0; - $fig->add ($line); - - my($text) = new XFig ('text'); - $text->{'text'} = "$x"; - $text->{'y'} = -200; - $text->{'x'} = $x * $grid_X_size; - $text->{'subtype'} = 1; - $fig->add ($text); - } - -# Empty line so that the text of the time axis can be seen on the pdf - $line = new XFig ('polyline'); - $line->{'depth'} = 999; - $line->{'subtype'} = 1; # line - $line->{'thickness'} = 0; - $line->{'points'} = [ [0,0],[0, -400] ]; - $fig->add ($line); -} - -sub main { - my($Cat) = read_cat($ARGV[0]); - my($cat_tree)=build_cat_tree("0",$Cat); - read_event($ARGV[0],$Cat); - my($Link)=read_link($ARGV[0]); -# print Dumper($cat_tree); -# print Dumper($Cat); - my($cat_list)=[]; - build_cat_list($cat_tree,$cat_list); - shift @$cat_list; - shift @$cat_list; -# print "@$cat_list \n"; - set_cat_position($Cat,$cat_list); - - my($fig)=create_fig("toto.fig"); - draw_cat($fig,$Cat,$Link); - $fig->writefile (); - system "fig2dev -L pdf toto.fig toto.pdf"; -} - -main; diff --git a/tools/address_sanitizer.supp b/tools/address_sanitizer.supp index 995908ef5c..f478e89651 100644 --- a/tools/address_sanitizer.supp +++ b/tools/address_sanitizer.supp @@ -20,3 +20,21 @@ odr_violation:^__tag$ # size=16 'stored_vtable' /usr/include/boost/function/function_template.hpp:933:32 odr_violation:^stored_vtable$ + +# size=40 'cfg_bmf_max_iteration' ../src/kernel/lmm/bmf.hpp:77:44 +odr_violation:^cfg_bmf_max_iteration$ +# size=40 'cfg_bmf_precision' ../src/kernel/lmm/bmf.hpp:80:47 +odr_violation:^cfg_bmf_precision$ + +# size=56 'on_completion' ../include/simgrid/s4u/Activity.hpp:235:55 +odr_violation:^on_completion$ +# size=56 'on_veto' ../include/simgrid/s4u/Activity.hpp:236:49 +odr_violation:^on_veto$ +# size=56 'on_suspend' ../include/simgrid/s4u/Activity.hpp:237:55 +odr_violation:^on_suspend$ +# size=56 'on_resume' ../include/simgrid/s4u/Activity.hpp:238:55 +odr_violation:^on_resume$ + +# size=56 'on_start' ../include/simgrid/s4u/Comm.hpp:45:48 +# size=56 'on_start' ../include/simgrid/s4u/Exec.hpp:45:48 +odr_violation:^on_start$ diff --git a/tools/appveyor-irc-notify.py b/tools/appveyor-irc-notify.py deleted file mode 100644 index 3a84ebb54c..0000000000 --- a/tools/appveyor-irc-notify.py +++ /dev/null @@ -1,180 +0,0 @@ -""" -From: https://raw.githubusercontent.com/wesnoth/wesnoth/b28d8d469af047cbbb20b18757c07b1bfc6afa31/utils/appveyor/irc-notify.py -which is from: https://raw.githubusercontent.com/nexB/scancode-toolkit/48aeaf76ce9f53d02223c41c1b2ad1d1ad73b851/etc/scripts/irc-notify.py - -Copyright (C) 2015-2016 Christopher R. Wood - -This program is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software Foundation; -either version 2 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this -program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, -Fifth Floor, Boston, MA 02110-1301 USA. - -Simple AppVeyor IRC notification script. - -Modified by nexB on October 2016: - - rework the handling of environment variables. - - made the script use functions - - support only Appveyor loading its environment variable to craft IRC notices. - -Modified by Jyrki Vesterinen on November 2016: - - - join the channel instead of sending an external message. - -The first argument is a Freenode channel. Other arguments passed to the script will be -sent as notice messages content and any {var}-formatted environment variables will be -expanded automatically, replaced with a corresponding Appveyor environment variable -value. se commas to delineate multiple messages. - -Modified by Martin Quinson on June 2018: - - - Use OFTC instead of Freenode - -Example: -export APPVEYOR_URL=https://ci.appveyor.com -export APPVEYOR_PROJECT_NAME=attributecode -export APPVEYOR_REPO_COMMIT_AUTHOR=pombredanne -export APPVEYOR_REPO_COMMIT_TIMESTAMP=2016-10-31 -export APPVEYOR_REPO_PROVIDER=gihub -export APPVEYOR_REPO_BRANCH=repo_branch -export APPVEYOR_PULL_REQUEST_TITLE=pull_request_title -export APPVEYOR_BUILD_VERSION=1 -export APPVEYOR_REPO_COMMIT=22c95b72e29248dc4de9b85e590ee18f6f587de8 -export APPVEYOR_REPO_COMMIT_MESSAGE="some IRC test" -export APPVEYOR_ACCOUNT_NAME=nexB -export APPVEYOR_PULL_REQUEST_NUMBER=pull_request_number -export APPVEYOR_REPO_NAME=nexB/attributecode -python etc/scripts/irc-notify.py aboutcode '[{project_name}:{branch}] {short_commit}: "{message}" ({author}) {color_red}Succeeded','Details: {build_url} | Commit: {commit_url}' - -See also https://github.com/gridsync/gridsync/blob/master/appveyor.yml for examples -in Appveyor's YAML: - - on_success: - - "python etc/scripts/irc-notify.py channel [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_green}Succeeded,Details: {build_url},Commit: {commit_url}" - on_failure: - - "python etc/scripts/irc-notify.py channel [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_red}Failed,Details: {build_url},Commit: {commit_url}" - -""" - -import random -import socket -import ssl -import sys -import time - - -def appveyor_vars(): - """ - Return a dict of key value crafted from appveyor environment variables. - """ - from os import environ - - appveyor_url = environ.get('APPVEYOR_URL') - message_extended = environ.get('APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED') - configuration_name = environ.get('CONFIGURATION') - branch = environ.get('APPVEYOR_REPO_BRANCH') - author = environ.get('APPVEYOR_REPO_COMMIT_AUTHOR') - author_email = environ.get('APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL') - timestamp = environ.get('APPVEYOR_REPO_COMMIT_TIMESTAMP') - repo_provider = environ.get('APPVEYOR_REPO_PROVIDER') - project_name = environ.get('APPVEYOR_PROJECT_NAME') - project_slug = environ.get('APPVEYOR_PROJECT_SLUG') - pull_request_title = environ.get('APPVEYOR_PULL_REQUEST_TITLE') - build_version = environ.get('APPVEYOR_BUILD_VERSION') - commit = environ.get('APPVEYOR_REPO_COMMIT') - message = environ.get('APPVEYOR_REPO_COMMIT_MESSAGE') - account_name = environ.get('APPVEYOR_ACCOUNT_NAME') - pull_request_number = environ.get('APPVEYOR_PULL_REQUEST_NUMBER') - repo_name = environ.get('APPVEYOR_REPO_NAME') - - short_commit = commit[:7] - build_url = '{appveyor_url}/project/{account_name}/{project_slug}/build/{build_version}'.format(**locals()) - commit_url = 'https://{repo_provider}.com/{repo_name}/commit/{commit}'.format(**locals()) - - apvy_vars = dict( - appveyor_url=appveyor_url, - account_name=account_name, - project_name=project_name, - project_slug=project_slug, - build_version=build_version, - - build_url=build_url, - - repo_provider=repo_provider, - repo_name=repo_name, - branch=branch, - configuration_name=configuration_name, - author=author, - author_email=author_email, - timestamp=timestamp, - commit=commit, - short_commit=short_commit, - message=message, - message_extended=message_extended, - - pull_request_title=pull_request_title, - pull_request_number=pull_request_number, - - commit_url=commit_url, - - color_green='\x033', - color_red='\x034', - bold='\x02', - underline='\x1f', - plain='\x0f', - ) - return apvy_vars - - -if __name__ == '__main__': - apvy_vars = appveyor_vars() - - channel = sys.argv[1] - messages = sys.argv[2:] - messages = ' '.join(messages) - messages = messages.split(',') - messages = [msg.format(**apvy_vars).strip() for msg in messages] - - irc_username = 'Appveyor' - irc_nick = irc_username + str(random.randint(1, 9999)) - - try: - # establish connection - irc_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), ssl_version=ssl.PROTOCOL_TLS) - irc_sock.connect((socket.gethostbyname('irc.oftc.net'), 6697)) - irc_sock.send('NICK {0}\r\nUSER {0} * 0 :{0}\r\n'.format(irc_username).encode('utf_8')) - irc_file = irc_sock.makefile() - - while irc_file: - line = irc_file.readline() - print(line.rstrip()) - response = line.split() - - if response[0] == 'PING': - irc_file.send('PONG {}\r\n'.format(reponse[1]).encode('utf_8')) - - elif response[1] == '433': - irc_sock.send('NICK {}\r\n'.format(irc_nick).encode('utf_8')) - - elif response[1] == '001': - time.sleep(5) - # join the channel - irc_sock.send('JOIN #{}\r\n'.format(channel).encode('utf_8')) - # send messages - for msg in messages: - print('PRIVMSG #{} :{}'.format(channel, msg)) - irc_sock.send('PRIVMSG #{} :{}\r\n'.format(channel, msg).encode('utf_8')) - time.sleep(5) - # leave the channel - irc_sock.send('PART #{}\r\n'.format(channel).encode('utf_8')) - sys.exit() - except Exception: - e = sys.exc_info()[0] - print(e) - sys.exit() diff --git a/tools/cmake/CTestConfig.cmake b/tools/cmake/CTestConfig.cmake index 0debf7c1ed..f1723c8942 100644 --- a/tools/cmake/CTestConfig.cmake +++ b/tools/cmake/CTestConfig.cmake @@ -5,9 +5,6 @@ if(APPLE) SET(BUILDNAME "APPLE" CACHE INTERNAL "Buildname" FORCE) else() SET(BUILDNAME "UNIX" CACHE INTERNAL "Buildname" FORCE) - if(WIN32) - SET(BUILDNAME "WINDOWS" CACHE INTERNAL "Buildname" FORCE) - endif() endif() if(NOT enable_memcheck) @@ -20,10 +17,6 @@ if(enable_compile_warnings AND enable_compile_optimizations) SET(BUILDNAME "FULL_FLAGS" CACHE INTERNAL "Buildname" FORCE) endif() -if(SIMGRID_HAVE_MC) - SET(BUILDNAME "MODEL-CHECKING" CACHE INTERNAL "Buildname" FORCE) -endif() - if(enable_memcheck) SET(BUILDNAME "MEMCHECK" CACHE INTERNAL "Buildname" FORCE) endif() diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 2fbe5397fb..06c190e41a 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -1,29 +1,38 @@ ### define source packages set(EXTRA_DIST - src/bindings/java/MANIFEST.in + src/3rd-party/catch.hpp src/bindings/python/simgrid_python.cpp src/dag/dax.dtd src/dag/dax_dtd.c src/dag/dax_dtd.h - src/include/catch.hpp - src/include/mc/datatypes.h - src/include/mc/mc.h - src/include/simgrid/sg_config.hpp - src/include/xbt/coverage.h - src/include/xbt/mmalloc.h - src/include/xbt/parmap.hpp - src/include/xbt/xbt_modinter.h - src/include/xxhash.hpp src/kernel/actor/Simcall.hpp + src/kernel/resource/HostImpl.hpp src/kernel/resource/LinkImpl.hpp src/kernel/resource/NetworkModel.hpp + src/kernel/resource/NetworkModelFactors.hpp src/kernel/resource/SplitDuplexLinkImpl.hpp src/kernel/resource/StandardLinkImpl.hpp src/kernel/resource/WifiLinkImpl.hpp + src/kernel/resource/models/cpu_cas01.hpp + src/kernel/resource/models/cpu_ti.hpp + src/kernel/resource/models/disk_s19.hpp + src/kernel/resource/models/host_clm03.hpp + src/kernel/resource/models/network_cm02.hpp + src/kernel/resource/models/network_constant.hpp + src/kernel/resource/models/network_ib.hpp + src/kernel/resource/models/network_ns3.hpp + src/kernel/resource/models/ns3/ns3_simulator.hpp + src/kernel/resource/models/ptask_L07.hpp + + src/mc/datatypes.h + src/mc/mc.h src/mc/mc_mmu.hpp src/mc/mc_record.hpp - src/msg/msg_private.hpp + + src/simgrid/sg_config.hpp + src/simgrid/math_utils.h + src/smpi/colls/coll_tuned_topo.hpp src/smpi/colls/colls_private.hpp src/smpi/colls/smpi_mvapich2_selector_stampede.hpp @@ -31,44 +40,16 @@ set(EXTRA_DIST src/smpi/include/smpi_utils.hpp src/smpi/smpi_main.c src/smpi/smpi_replay_main.cpp - src/surf/HostImpl.hpp - src/surf/cpu_cas01.hpp - src/surf/cpu_ti.hpp - src/surf/disk_s19.hpp - src/surf/host_clm03.hpp - src/surf/network_cm02.hpp - src/surf/network_constant.hpp - src/surf/network_ib.hpp - src/surf/network_ns3.hpp - src/surf/network_smpi.hpp - src/surf/ns3/ns3_simulator.hpp - src/surf/ptask_L07.hpp - src/surf/surf_interface.hpp - src/surf/xml/simgrid.dtd - src/surf/xml/simgrid_dtd.c - src/surf/xml/simgrid_dtd.h - src/surf/xml/surfxml_sax_cb.cpp - - src/xbt/automaton/automaton_lexer.yy.c - src/xbt/automaton/parserPromela.lex - src/xbt/automaton/parserPromela.tab.cacc - src/xbt/automaton/parserPromela.tab.hacc - src/xbt/automaton/parserPromela.yacc + src/kernel/xml/simgrid.dtd + src/kernel/xml/simgrid_dtd.c + src/kernel/xml/simgrid_dtd.h + src/kernel/xml/platf_sax_cb.cpp + + src/xbt/coverage.h src/xbt/dict_private.h src/xbt/log_private.hpp src/xbt/mallocator_private.h - - src/xbt/mmalloc/mfree.c - src/xbt/mmalloc/mm_legacy.c - src/xbt/mmalloc/mm_module.c - src/xbt/mmalloc/mmalloc.c - src/xbt/mmalloc/mmalloc.info - src/xbt/mmalloc/mmalloc.texi - src/xbt/mmalloc/mmorecore.c - src/xbt/mmalloc/mmprivate.h - src/xbt/mmalloc/mrealloc.c - src/xbt/mmalloc/swag.c - src/xbt/mmalloc/swag.h + src/xbt/parmap.hpp ) set(SMPI_SRC @@ -245,20 +226,18 @@ set(SMPI_SRC src/smpi/plugins/ampi/ampi.hpp src/smpi/plugins/ampi/instr_ampi.cpp src/smpi/plugins/ampi/instr_ampi.hpp - src/surf/network_ib.cpp - src/surf/network_smpi.cpp + src/kernel/resource/models/network_ib.cpp ) set(STHREAD_SRC src/sthread/sthread_impl.cpp src/sthread/sthread.c src/sthread/sthread.h + src/sthread/ObjectAccess.cpp ) set(XBT_SRC src/xbt/OsSemaphore.hpp src/xbt/PropertyHolder.cpp - src/xbt/automaton/automaton.c - src/xbt/automaton/automatonparse_promela.c src/xbt/backtrace.cpp src/xbt/config.cpp src/xbt/dict.cpp @@ -278,30 +257,75 @@ set(XBT_SRC src/xbt/xbt_log_appender_file.cpp src/xbt/xbt_log_layout_format.cpp src/xbt/xbt_log_layout_simple.cpp - src/xbt/xbt_main.cpp + src/xbt/xbt_misc.cpp src/xbt/xbt_os_file.cpp src/xbt/xbt_os_time.c src/xbt/xbt_parse_units.cpp src/xbt/xbt_replay.cpp src/xbt/xbt_str.cpp - src/xbt/xbt_virtu.cpp + src/xbt/utils/iter/iterator_wrapping.hpp + src/xbt/utils/iter/subsets.hpp + src/xbt/utils/iter/powerset.hpp + src/xbt/utils/iter/variable_for_loop.hpp + src/xbt/utils/iter/LazyKSubsets.hpp + src/xbt/utils/iter/LazyPowerset.hpp ) -if(HAVE_MMALLOC) - set(XBT_SRC ${XBT_SRC} src/xbt/mmalloc/mm.c ) -else() - set(EXTRA_DIST ${EXTRA_DIST} src/xbt/mmalloc/mm.c) -endif() - set(NS3_SRC - src/surf/network_ns3.cpp - src/surf/ns3/ns3_simulator.cpp + src/kernel/resource/models/network_ns3.cpp + src/kernel/resource/models/ns3/ns3_simulator.cpp ) -set(SURF_SRC +set(KERNEL_SRC src/kernel/EngineImpl.cpp src/kernel/EngineImpl.hpp + src/kernel/activity/ActivityImpl.cpp + src/kernel/activity/ActivityImpl.hpp + src/kernel/activity/BarrierImpl.cpp + src/kernel/activity/BarrierImpl.hpp + src/kernel/activity/CommImpl.cpp + src/kernel/activity/CommImpl.hpp + src/kernel/activity/ConditionVariableImpl.cpp + src/kernel/activity/ConditionVariableImpl.hpp + src/kernel/activity/ExecImpl.cpp + src/kernel/activity/ExecImpl.hpp + src/kernel/activity/IoImpl.cpp + src/kernel/activity/IoImpl.hpp + src/kernel/activity/MailboxImpl.cpp + src/kernel/activity/MailboxImpl.hpp + src/kernel/activity/MessImpl.cpp + src/kernel/activity/MessImpl.hpp + src/kernel/activity/MessageQueueImpl.cpp + src/kernel/activity/MessageQueueImpl.hpp + src/kernel/activity/MutexImpl.cpp + src/kernel/activity/MutexImpl.hpp + src/kernel/activity/SemaphoreImpl.cpp + src/kernel/activity/SemaphoreImpl.hpp + src/kernel/activity/SleepImpl.cpp + src/kernel/activity/SleepImpl.hpp + src/kernel/activity/Synchro.cpp + src/kernel/activity/Synchro.hpp + + src/kernel/actor/ActorImpl.cpp + src/kernel/actor/ActorImpl.hpp + src/kernel/actor/CommObserver.cpp + src/kernel/actor/CommObserver.hpp + src/kernel/actor/Simcall.cpp + src/kernel/actor/SimcallObserver.cpp + src/kernel/actor/SimcallObserver.hpp + src/kernel/actor/SynchroObserver.cpp + src/kernel/actor/SynchroObserver.hpp + + src/kernel/context/Context.cpp + src/kernel/context/Context.hpp + src/kernel/context/ContextRaw.cpp + src/kernel/context/ContextRaw.hpp + src/kernel/context/ContextSwapped.cpp + src/kernel/context/ContextSwapped.hpp + src/kernel/context/ContextThread.cpp + src/kernel/context/ContextThread.hpp + src/kernel/lmm/System.cpp src/kernel/lmm/System.hpp src/kernel/lmm/fair_bottleneck.cpp @@ -314,8 +338,12 @@ set(SURF_SRC src/kernel/resource/CpuImpl.hpp src/kernel/resource/DiskImpl.cpp src/kernel/resource/DiskImpl.hpp + src/kernel/resource/FactorSet.cpp + src/kernel/resource/FactorSet.hpp + src/kernel/resource/HostImpl.cpp src/kernel/resource/Model.cpp src/kernel/resource/NetworkModel.cpp + src/kernel/resource/NetworkModelFactors.cpp src/kernel/resource/Resource.hpp src/kernel/resource/SplitDuplexLinkImpl.cpp src/kernel/resource/StandardLinkImpl.cpp @@ -323,6 +351,14 @@ set(SURF_SRC src/kernel/resource/VirtualMachineImpl.hpp src/kernel/resource/WifiLinkImpl.cpp + src/kernel/resource/models/cpu_cas01.cpp + src/kernel/resource/models/cpu_ti.cpp + src/kernel/resource/models/disk_s19.cpp + src/kernel/resource/models/host_clm03.cpp + src/kernel/resource/models/network_cm02.cpp + src/kernel/resource/models/network_constant.cpp + src/kernel/resource/models/ptask_L07.cpp + src/kernel/resource/profile/Event.hpp src/kernel/resource/profile/FutureEvtSet.cpp src/kernel/resource/profile/FutureEvtSet.hpp @@ -349,24 +385,14 @@ set(SURF_SRC src/kernel/timer/Timer.cpp - src/surf/HostImpl.cpp - src/surf/cpu_cas01.cpp - src/surf/cpu_ti.cpp - src/surf/disk_s19.cpp - src/surf/host_clm03.cpp - src/surf/network_cm02.cpp - src/surf/network_constant.cpp - src/surf/ptask_L07.cpp - src/surf/sg_platf.cpp - src/surf/surf_interface.cpp - src/surf/xml/platf.hpp - src/surf/xml/platf_private.hpp - src/surf/xml/surfxml_parseplatf.cpp - src/surf/xml/surfxml_sax_cb.cpp + src/kernel/xml/platf.hpp + src/kernel/xml/platf_private.hpp + src/kernel/xml/sg_platf.cpp + src/kernel/xml/platf_sax_cb.cpp ) if (Eigen3_FOUND) - set(SURF_SRC - ${SURF_SRC} + set(KERNEL_SRC + ${KERNEL_SRC} src/kernel/lmm/bmf.cpp src/kernel/lmm/bmf.hpp) else() @@ -375,6 +401,18 @@ else() src/kernel/lmm/bmf.cpp src/kernel/lmm/bmf.hpp) endif() +# Boost context may not be available +if (HAVE_BOOST_CONTEXTS) + set(KERNEL_SRC + ${KERNEL_SRC} + src/kernel/context/ContextBoost.cpp + src/kernel/context/ContextBoost.hpp) +else() + set(EXTRA_DIST + ${EXTRA_DIST} + src/kernel/context/ContextBoost.cpp + src/kernel/context/ContextBoost.hpp) +endif() set(PLUGINS_SRC src/plugins/ProducerConsumer.cpp @@ -383,73 +421,22 @@ set(PLUGINS_SRC src/plugins/host_dvfs.cpp src/plugins/host_energy.cpp src/plugins/host_load.cpp + src/plugins/jbod.cpp src/plugins/link_energy.cpp src/plugins/link_energy_wifi.cpp src/plugins/link_load.cpp src/plugins/vm/VmLiveMigration.cpp src/plugins/vm/VmLiveMigration.hpp src/plugins/vm/dirty_page_tracking.cpp + src/plugins/battery.cpp + src/plugins/chiller.cpp + src/plugins/solar_panel.cpp ) -set(SIMIX_SRC - src/kernel/activity/ActivityImpl.cpp - src/kernel/activity/ActivityImpl.hpp - src/kernel/activity/BarrierImpl.cpp - src/kernel/activity/BarrierImpl.hpp - src/kernel/activity/CommImpl.cpp - src/kernel/activity/CommImpl.hpp - src/kernel/activity/ConditionVariableImpl.cpp - src/kernel/activity/ConditionVariableImpl.hpp - src/kernel/activity/ExecImpl.cpp - src/kernel/activity/ExecImpl.hpp - src/kernel/activity/IoImpl.cpp - src/kernel/activity/IoImpl.hpp - src/kernel/activity/MailboxImpl.cpp - src/kernel/activity/MailboxImpl.hpp - src/kernel/activity/MutexImpl.cpp - src/kernel/activity/MutexImpl.hpp - src/kernel/activity/SemaphoreImpl.cpp - src/kernel/activity/SemaphoreImpl.hpp - src/kernel/activity/SleepImpl.cpp - src/kernel/activity/SleepImpl.hpp - src/kernel/activity/Synchro.cpp - src/kernel/activity/Synchro.hpp - src/kernel/actor/ActorImpl.cpp - src/kernel/actor/ActorImpl.hpp - src/kernel/actor/CommObserver.cpp - src/kernel/actor/CommObserver.hpp - src/kernel/actor/Simcall.cpp - src/kernel/actor/SimcallObserver.cpp - src/kernel/actor/SimcallObserver.hpp - src/kernel/actor/SynchroObserver.cpp - src/kernel/actor/SynchroObserver.hpp - src/kernel/context/Context.cpp - src/kernel/context/Context.hpp - src/kernel/context/ContextRaw.cpp - src/kernel/context/ContextRaw.hpp - src/kernel/context/ContextSwapped.cpp - src/kernel/context/ContextSwapped.hpp - src/kernel/context/ContextThread.cpp - src/kernel/context/ContextThread.hpp - src/simix/libsmx.cpp - src/simix/smx_context.cpp - ) - -# Boost context may not be available -if (HAVE_BOOST_CONTEXTS) - set(SIMIX_SRC - ${SIMIX_SRC} - src/kernel/context/ContextBoost.cpp - src/kernel/context/ContextBoost.hpp) -else() - set(EXTRA_DIST - ${EXTRA_DIST} - src/kernel/context/ContextBoost.cpp - src/kernel/context/ContextBoost.hpp) -endif() set(S4U_SRC src/s4u/s4u_Activity.cpp + src/s4u/s4u_ActivitySet.cpp src/s4u/s4u_Actor.cpp src/s4u/s4u_Barrier.cpp src/s4u/s4u_Comm.cpp @@ -461,86 +448,28 @@ set(S4U_SRC src/s4u/s4u_Io.cpp src/s4u/s4u_Link.cpp src/s4u/s4u_Mailbox.cpp + src/s4u/s4u_Mess.cpp + src/s4u/s4u_MessageQueue.cpp src/s4u/s4u_Mutex.cpp src/s4u/s4u_Netzone.cpp src/s4u/s4u_Semaphore.cpp + src/s4u/s4u_Task.cpp src/s4u/s4u_VirtualMachine.cpp ) set(SIMGRID_SRC src/simgrid/Exception.cpp + src/simgrid/module.cpp + src/simgrid/module.hpp src/simgrid/sg_config.cpp src/simgrid/sg_version.cpp src/simgrid/util.hpp ) -set(MSG_SRC - src/msg/msg_comm.cpp - src/msg/msg_global.cpp - src/msg/msg_legacy.cpp - src/msg/msg_process.cpp - src/msg/msg_task.cpp - ) - set(DAG_SRC src/dag/loaders.cpp ) -set(JMSG_C_SRC - src/bindings/java/JavaContext.cpp - src/bindings/java/JavaContext.hpp - src/bindings/java/jmsg.cpp - src/bindings/java/jmsg.hpp - src/bindings/java/jmsg_as.cpp - src/bindings/java/jmsg_as.hpp - src/bindings/java/jmsg_comm.cpp - src/bindings/java/jmsg_comm.h - src/bindings/java/jmsg_host.cpp - src/bindings/java/jmsg_host.h - src/bindings/java/jmsg_process.cpp - src/bindings/java/jmsg_process.h - src/bindings/java/jmsg_synchro.cpp - src/bindings/java/jmsg_synchro.h - src/bindings/java/jmsg_task.cpp - src/bindings/java/jmsg_task.h - src/bindings/java/jmsg_vm.cpp - src/bindings/java/jmsg_vm.h - src/bindings/java/jxbt_utilities.cpp - src/bindings/java/jxbt_utilities.hpp - ) - -set(JMSG_JAVA_SRC - src/bindings/java/org/simgrid/NativeLib.java - src/bindings/java/org/simgrid/msg/As.java - src/bindings/java/org/simgrid/msg/Comm.java - src/bindings/java/org/simgrid/msg/Host.java - src/bindings/java/org/simgrid/msg/HostFailureException.java - src/bindings/java/org/simgrid/msg/HostNotFoundException.java - src/bindings/java/org/simgrid/msg/JniException.java - src/bindings/java/org/simgrid/msg/Msg.java - src/bindings/java/org/simgrid/msg/MsgException.java - src/bindings/java/org/simgrid/msg/Mutex.java - src/bindings/java/org/simgrid/msg/Process.java - src/bindings/java/org/simgrid/msg/ProcessKilledError.java - src/bindings/java/org/simgrid/msg/ProcessNotFoundException.java - src/bindings/java/org/simgrid/msg/Semaphore.java - src/bindings/java/org/simgrid/msg/Task.java - src/bindings/java/org/simgrid/msg/TaskCancelledException.java - src/bindings/java/org/simgrid/msg/TimeoutException.java - src/bindings/java/org/simgrid/msg/TransferFailureException.java - src/bindings/java/org/simgrid/msg/VM.java - ) - -set(JTRACE_C_SRC - src/bindings/java/jtrace.cpp - src/bindings/java/jtrace.h - ) - -set(JTRACE_JAVA_SRC src/bindings/java/org/simgrid/trace/Trace.java) - -list(APPEND JMSG_C_SRC ${JTRACE_C_SRC}) -list(APPEND JMSG_JAVA_SRC ${JTRACE_JAVA_SRC}) - set(TRACING_SRC src/instr/instr_config.cpp src/instr/instr_interface.cpp @@ -562,6 +491,7 @@ set(TRACING_SRC set(MC_SRC_BASE src/mc/mc_base.cpp src/mc/mc_base.hpp + src/mc/mc_client_api.cpp src/mc/mc_config.cpp src/mc/mc_config.hpp src/mc/mc_global.cpp @@ -571,34 +501,50 @@ set(MC_SRC_BASE src/mc/transition/Transition.cpp ) -set(MC_SRC - src/mc/explo/CommunicationDeterminismChecker.cpp +set(MC_SRC_STATELESS + src/mc/api/ActorState.hpp + src/mc/api/ClockVector.cpp + src/mc/api/ClockVector.hpp + src/mc/api/State.cpp + src/mc/api/State.hpp + src/mc/api/RemoteApp.cpp + src/mc/api/RemoteApp.hpp + src/mc/explo/DFSExplorer.cpp src/mc/explo/DFSExplorer.hpp + src/mc/explo/Exploration.cpp src/mc/explo/Exploration.hpp - src/mc/explo/LivenessChecker.cpp - src/mc/explo/LivenessChecker.hpp + src/mc/explo/CommunicationDeterminismChecker.cpp + src/mc/explo/UdporChecker.cpp src/mc/explo/UdporChecker.hpp - src/mc/inspect/DwarfExpression.cpp - src/mc/inspect/DwarfExpression.hpp - src/mc/inspect/Frame.cpp - src/mc/inspect/Frame.hpp - src/mc/inspect/LocationList.cpp - src/mc/inspect/LocationList.hpp - src/mc/inspect/ObjectInformation.cpp - src/mc/inspect/ObjectInformation.hpp - src/mc/inspect/Type.hpp - src/mc/inspect/Variable.hpp - src/mc/inspect/mc_dwarf.cpp - src/mc/inspect/mc_dwarf.hpp - src/mc/inspect/mc_dwarf_attrnames.cpp - src/mc/inspect/mc_dwarf_tagnames.cpp - src/mc/inspect/mc_member.cpp - src/mc/inspect/mc_unw.cpp - src/mc/inspect/mc_unw.hpp - src/mc/inspect/mc_unw_vmread.cpp + src/mc/explo/udpor/Comb.hpp + src/mc/explo/udpor/Configuration.hpp + src/mc/explo/udpor/Configuration.cpp + src/mc/explo/udpor/EventSet.cpp + src/mc/explo/udpor/EventSet.hpp + src/mc/explo/udpor/ExtensionSetCalculator.cpp + src/mc/explo/udpor/ExtensionSetCalculator.hpp + src/mc/explo/udpor/History.cpp + src/mc/explo/udpor/History.hpp + src/mc/explo/udpor/maximal_subsets_iterator.cpp + src/mc/explo/udpor/maximal_subsets_iterator.hpp + src/mc/explo/udpor/UnfoldingEvent.cpp + src/mc/explo/udpor/UnfoldingEvent.hpp + src/mc/explo/udpor/Unfolding.cpp + src/mc/explo/udpor/Unfolding.hpp + src/mc/explo/udpor/udpor_forward.hpp + src/mc/explo/udpor/udpor_tests_private.hpp + + src/mc/explo/odpor/Execution.cpp + src/mc/explo/odpor/Execution.hpp + src/mc/explo/odpor/WakeupTree.cpp + src/mc/explo/odpor/WakeupTree.hpp + src/mc/explo/odpor/WakeupTreeIterator.cpp + src/mc/explo/odpor/WakeupTreeIterator.hpp + src/mc/explo/odpor/odpor_forward.hpp + src/mc/explo/odpor/odpor_tests_private.hpp src/mc/remote/AppSide.cpp src/mc/remote/AppSide.hpp @@ -606,78 +552,61 @@ set(MC_SRC src/mc/remote/Channel.hpp src/mc/remote/CheckerSide.cpp src/mc/remote/CheckerSide.hpp - src/mc/remote/RemoteProcess.cpp - src/mc/remote/RemoteProcess.hpp src/mc/remote/RemotePtr.hpp src/mc/remote/mc_protocol.h - src/mc/sosp/ChunkedData.cpp - src/mc/sosp/ChunkedData.hpp - src/mc/sosp/PageStore.cpp - src/mc/sosp/PageStore.hpp - src/mc/sosp/Region.cpp - src/mc/sosp/Region.hpp - src/mc/sosp/Snapshot.cpp - src/mc/sosp/Snapshot.hpp - src/mc/transition/Transition.hpp + src/mc/transition/TransitionActor.cpp + src/mc/transition/TransitionActor.hpp src/mc/transition/TransitionAny.cpp src/mc/transition/TransitionAny.hpp src/mc/transition/TransitionComm.cpp src/mc/transition/TransitionComm.hpp + src/mc/transition/TransitionObjectAccess.cpp + src/mc/transition/TransitionObjectAccess.hpp src/mc/transition/TransitionRandom.cpp src/mc/transition/TransitionRandom.hpp src/mc/transition/TransitionSynchro.cpp src/mc/transition/TransitionSynchro.hpp - src/mc/AddressSpace.hpp - src/mc/ModelChecker.cpp - src/mc/ModelChecker.hpp - src/mc/Session.cpp - src/mc/Session.hpp - src/mc/VisitedState.cpp - src/mc/VisitedState.hpp - src/mc/api.cpp - src/mc/api.hpp - src/mc/api/State.cpp - src/mc/api/State.hpp - src/mc/compare.cpp - src/mc/mc_client_api.cpp + src/mc/mc_environ.h src/mc/mc_exit.hpp src/mc/mc_forward.hpp - src/mc/mc_hash.cpp - src/mc/mc_hash.hpp - src/mc/mc_ignore.hpp - src/mc/mc_pattern.hpp src/mc/mc_private.hpp src/mc/mc_record.cpp - src/mc/mc_safety.hpp - src/mc/mc_smx.cpp - src/mc/udpor_global.cpp - src/mc/udpor_global.hpp + + src/mc/api/strategy/BasicStrategy.hpp + src/mc/api/strategy/MaxMatchComm.hpp + src/mc/api/strategy/MinMatchComm.hpp + src/mc/api/strategy/Strategy.hpp + src/mc/api/strategy/UniformStrategy.hpp ) set(MC_SIMGRID_MC_SRC src/mc/explo/simgrid_mc.cpp) set(headers_to_install include/simgrid/actor.h + include/simgrid/activity_set.h include/simgrid/barrier.h include/simgrid/comm.h include/simgrid/engine.h include/simgrid/exec.h include/simgrid/Exception.hpp include/simgrid/chrono.hpp + include/simgrid/plugins/battery.hpp + include/simgrid/plugins/chiller.hpp include/simgrid/plugins/dvfs.h include/simgrid/plugins/energy.h include/simgrid/plugins/file_system.h + include/simgrid/plugins/jbod.hpp include/simgrid/plugins/live_migration.h include/simgrid/plugins/load.h + include/simgrid/plugins/solar_panel.hpp include/simgrid/plugins/ProducerConsumer.hpp include/simgrid/instr.h include/simgrid/mailbox.h include/simgrid/modelchecker.h include/simgrid/forward.h - include/simgrid/simix.h include/simgrid/simix.hpp include/simgrid/kernel/ProfileBuilder.hpp include/simgrid/kernel/Timer.hpp @@ -690,6 +619,7 @@ set(headers_to_install include/simgrid/vm.h include/simgrid/zone.h include/simgrid/s4u/Activity.hpp + include/simgrid/s4u/ActivitySet.hpp include/simgrid/s4u/Actor.hpp include/simgrid/s4u/Barrier.hpp include/simgrid/s4u/Comm.hpp @@ -701,14 +631,16 @@ set(headers_to_install include/simgrid/s4u/Io.hpp include/simgrid/s4u/Link.hpp include/simgrid/s4u/Mailbox.hpp + include/simgrid/s4u/MessageQueue.hpp + include/simgrid/s4u/Mess.hpp include/simgrid/s4u/Mutex.hpp include/simgrid/s4u/NetZone.hpp include/simgrid/s4u/Semaphore.hpp + include/simgrid/s4u/Task.hpp include/simgrid/s4u/VirtualMachine.hpp include/simgrid/s4u.hpp include/simgrid/kernel/resource/Action.hpp - include/simgrid/kernel/resource/NetworkModelIntf.hpp include/simgrid/kernel/resource/Model.hpp include/simgrid/kernel/routing/ClusterZone.hpp @@ -729,7 +661,6 @@ set(headers_to_install include/smpi/mpi.h include/smpi/sampi.h include/smpi/smpi.h - include/smpi/smpi_main.h include/smpi/smpi_helpers.h include/smpi/smpi_helpers_internal.h include/smpi/smpi_extended_traces.h @@ -738,8 +669,6 @@ set(headers_to_install include/xbt.h include/xbt/asserts.h include/xbt/asserts.hpp - include/xbt/automaton.h - include/xbt/automaton.hpp include/xbt/backtrace.hpp include/xbt/base.h include/xbt/config.h @@ -781,41 +710,33 @@ set(source_of_generated_headers ### depend of some variables set upper if(${HAVE_UCONTEXT_CONTEXTS}) #ucontext - set(SIMIX_SRC ${SIMIX_SRC} src/kernel/context/ContextUnix.hpp + set(KERNEL_SRC ${KERNEL_SRC} src/kernel/context/ContextUnix.hpp src/kernel/context/ContextUnix.cpp) else() # NOT ucontext set(EXTRA_DIST ${EXTRA_DIST} src/kernel/context/ContextUnix.hpp src/kernel/context/ContextUnix.cpp) endif() -### Simgrid Lib sources +### SimGrid Lib sources set(simgrid_sources ${S4U_SRC} ${SIMGRID_SRC} ${MC_SRC_BASE} - ${SIMIX_SRC} - ${SURF_SRC} + ${KERNEL_SRC} ${TRACING_SRC} ${XBT_SRC} ${PLUGINS_SRC} ${DAG_SRC} ) -if(${enable_msg}) - set(headers_to_install ${headers_to_install} include/simgrid/msg.h) - set(simgrid_sources ${simgrid_sources} ${MSG_SRC}) -else() - set(EXTRA_DIST ${EXTRA_DIST} include/simgrid/msg.h - ${MSG_SRC}) -endif() - if(enable_smpi) set(simgrid_sources ${simgrid_sources} ${SMPI_SRC}) endif() if(SIMGRID_HAVE_MC) - set(simgrid_sources ${simgrid_sources} ${MC_SRC}) + set(simgrid_sources ${simgrid_sources} ${MC_SRC_STATELESS}) endif() +set(EXTRA_DIST ${EXTRA_DIST} ${MC_SRC_STATELESS}) if(SIMGRID_HAVE_NS3) set(headers_to_install ${headers_to_install} include/simgrid/plugins/ns3.hpp) @@ -827,15 +748,9 @@ endif() set(DOC_SOURCES doc/doxygen/FAQ.doc - doc/doxygen/inside.doc - doc/doxygen/inside_tests.doc - doc/doxygen/inside_cmake.doc doc/doxygen/inside_extending.doc doc/doxygen/inside_release.doc - doc/doxygen/module-surf.doc - doc/doxygen/module-index.doc doc/doxygen/outcomes_vizu.doc - doc/doxygen/platform.doc doc/doxygen/uhood.doc doc/doxygen/uhood_switch.doc @@ -859,27 +774,18 @@ set(DOC_SOURCES docs/source/_ext/showfile.css docs/source/_ext/showfile.js docs/source/_ext/showfile.py - docs/source/_ext/javasphinx/LICENSE - docs/source/_ext/javasphinx/MANIFEST.in - docs/source/_ext/javasphinx/README.md - docs/source/_ext/javasphinx/doc/conf.py - docs/source/_ext/javasphinx/doc/index.rst - docs/source/_ext/javasphinx/javasphinx/__init__.py - docs/source/_ext/javasphinx/javasphinx/apidoc.py - docs/source/_ext/javasphinx/javasphinx/compiler.py - docs/source/_ext/javasphinx/javasphinx/domain.py - docs/source/_ext/javasphinx/javasphinx/extdoc.py - docs/source/_ext/javasphinx/javasphinx/formatter.py - docs/source/_ext/javasphinx/javasphinx/htmlrst.py - docs/source/_ext/javasphinx/javasphinx/util.py - docs/source/_ext/javasphinx/setup.py docs/source/_static/css/custom.css docs/source/_templates/breadcrumbs.html + docs/source/img/design-scheduling-parallel.svg + docs/source/img/design-scheduling-simulatedtime.svg + docs/source/img/design-scheduling-wallclock.svg docs/source/img/eclipseScreenShot.png docs/source/img/extlink.png docs/source/img/extlink.svg docs/source/img/graphical-toc.svg + docs/source/img/lmm-overview.svg + docs/source/img/plugin-energy.svg docs/source/img/smpi_simgrid_alltoall_pair_16.png docs/source/img/smpi_simgrid_alltoall_ring_16.png docs/source/img/starzone.drawio @@ -892,7 +798,6 @@ set(DOC_SOURCES docs/source/img/zoom_comm.svg docs/source/application.rst - docs/source/app_msg.rst docs/source/app_s4u.rst docs/source/app_smpi.rst docs/source/The_XBT_toolbox.rst @@ -900,6 +805,8 @@ set(DOC_SOURCES docs/source/community.rst docs/source/Configuring_SimGrid.rst docs/source/Deploying_your_application.rst + docs/source/Contributors_Documentation.rst + docs/source/Examples.rst docs/source/Experimental_setup.rst docs/source/index.rst docs/source/intl.rst @@ -936,6 +843,12 @@ set(DOC_SOURCES docs/source/tuto_s4u/master-workers-lab3.cpp docs/source/tuto_s4u/master-workers-lab4.cpp + docs/source/Tutorial_DAG.rst + docs/source/img/battery_degradation.svg + docs/source/img/dag1.svg + docs/source/img/dag2.svg + docs/source/img/dag.svg + docs/source/Tutorial_MPI_Applications.rst docs/source/tuto_smpi/3hosts.png docs/source/tuto_smpi/3hosts.xml @@ -944,6 +857,9 @@ set(DOC_SOURCES docs/source/tuto_smpi/gemm_mpi.cpp docs/source/tuto_smpi/roundtrip.c + docs/source/tuto_mc/ndet-receive-mpi.c + docs/source/tuto_mc/ndet-receive-s4u.cpp + docs/source/tuto_disk/analysis.org docs/source/tuto_disk/analysis.irst docs/source/tuto_disk/CMakeLists.txt @@ -956,8 +872,6 @@ set(DOC_SOURCES docs/source/tuto_disk/fig/simgrid_results.png docs/source/tuto_disk/init.el docs/source/tuto_disk/tuto_disk.cpp - docs/source/tuto_network_calibration/clustering_ckmeans.ipynb - docs/source/tuto_network_calibration/clustering_dhist.ipynb docs/source/tuto_network_calibration/CMakeLists.txt docs/source/tuto_network_calibration/dahu_platform_ckmeans.cpp docs/source/tuto_network_calibration/dahu_platform_dhist.cpp @@ -995,12 +909,6 @@ set(DOC_TOOLS ) # these files get copied automatically to the html documentation -set(DOC_IMG - ${CMAKE_HOME_DIRECTORY}/doc/webcruft/Paje_MSG_screenshot.jpg - ${CMAKE_HOME_DIRECTORY}/doc/webcruft/Paje_MSG_screenshot_thn.jpg - ${CMAKE_HOME_DIRECTORY}/doc/webcruft/eclipseScreenShot.png - ${CMAKE_HOME_DIRECTORY}/doc/webcruft/output.goal.pdf - ) set(bin_files ${bin_files} @@ -1027,7 +935,6 @@ set(txt_files set(CMAKEFILES_TXT examples/c/CMakeLists.txt examples/cpp/CMakeLists.txt - examples/deprecated/java/CMakeLists.txt examples/platforms/CMakeLists.txt examples/python/CMakeLists.txt examples/smpi/CMakeLists.txt @@ -1038,11 +945,9 @@ set(CMAKEFILES_TXT examples/smpi/smpi_s4u_masterworker/CMakeLists.txt examples/sthread/CMakeLists.txt - teshsuite/java/CMakeLists.txt teshsuite/kernel/CMakeLists.txt teshsuite/mc/CMakeLists.txt teshsuite/models/CMakeLists.txt - teshsuite/msg/CMakeLists.txt teshsuite/platforms/CMakeLists.txt teshsuite/python/CMakeLists.txt teshsuite/s4u/CMakeLists.txt @@ -1082,7 +987,6 @@ set(CMAKEFILES_TXT teshsuite/smpi/mpich3-test/rma/CMakeLists.txt teshsuite/smpi/mpich3-test/topo/CMakeLists.txt - teshsuite/surf/CMakeLists.txt teshsuite/xbt/CMakeLists.txt tools/CMakeLists.txt tools/graphicator/CMakeLists.txt @@ -1101,27 +1005,23 @@ set(CMAKE_SOURCE_FILES tools/cmake/Distrib.cmake tools/cmake/Documentation.cmake tools/cmake/Flags.cmake - tools/cmake/Java.cmake tools/cmake/MaintainerMode.cmake tools/cmake/MakeLib.cmake - tools/cmake/MakeLibWin.cmake tools/cmake/Modules/FindGraphviz.cmake - tools/cmake/Modules/FindLibdw.cmake - tools/cmake/Modules/FindLibelf.cmake tools/cmake/Modules/FindLibevent.cmake - tools/cmake/Modules/FindLibunwind.cmake tools/cmake/Modules/FindNS3.cmake tools/cmake/Modules/FindPAPI.cmake tools/cmake/Modules/FindValgrind.cmake + tools/cmake/Modules/nlohmann_jsonConfig.cmake tools/cmake/Modules/pybind11Config.cmake tools/cmake/Option.cmake tools/cmake/Tests.cmake - tools/cmake/cross-mingw.cmake tools/cmake/scripts/fixup_simgrid_dtd_l.pl tools/cmake/scripts/my_valgrind.pl tools/cmake/scripts/update_tesh.pl tools/cmake/test_prog/prog_asan.cpp tools/cmake/test_prog/prog_makecontext.c + tools/cmake/test_prog/prog_ns3.cpp tools/cmake/test_prog/prog_stackgrowth.c tools/cmake/test_prog/prog_stacksetup.c tools/cmake/test_prog/prog_tsan.cpp @@ -1215,15 +1115,6 @@ set(PLATFORMS_EXAMPLES examples/platforms/vivaldi.xml examples/platforms/wifi.xml examples/platforms/wifi_energy.xml + examples/platforms/wifi_large_cell.xml examples/platforms/wifi_ns3.xml ) - -set(generated_src_files - src/xbt/automaton/automaton_lexer.yy.c - src/xbt/automaton/parserPromela.tab.cacc - src/xbt/automaton/parserPromela.tab.hacc - ) - -foreach(file ${generated_src_files}) - set_source_files_properties(${file} PROPERTIES GENERATED true) -endforeach(file ${generated_src_files}) diff --git a/tools/cmake/Distrib.cmake b/tools/cmake/Distrib.cmake index 8d871e31c9..50952960ff 100644 --- a/tools/cmake/Distrib.cmake +++ b/tools/cmake/Distrib.cmake @@ -25,14 +25,6 @@ endif() install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/tesh DESTINATION ${CMAKE_INSTALL_BINDIR}/) -install(PROGRAMS ${CMAKE_HOME_DIRECTORY}/tools/MSG_visualization/colorize.pl - DESTINATION ${CMAKE_INSTALL_BINDIR}/ - RENAME simgrid-colorizer) - -add_custom_target(simgrid-colorizer ALL - COMMENT "Install ${CMAKE_BINARY_DIR}/bin/colorize" - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_HOME_DIRECTORY}/tools/MSG_visualization/colorize.pl ${CMAKE_BINARY_DIR}/bin/colorize) - install(PROGRAMS ${CMAKE_HOME_DIRECTORY}/tools/simgrid_update_xml.pl DESTINATION ${CMAKE_INSTALL_BINDIR}/ RENAME simgrid_update_xml) @@ -51,13 +43,8 @@ add_custom_target(simgrid_convert_TI_traces ALL # libraries install(TARGETS simgrid DESTINATION ${CMAKE_INSTALL_LIBDIR}/) - -if(enable_java) - set(SIMGRID_JAR_TO_INSTALL "${SIMGRID_JAR}") - install(TARGETS simgrid-java DESTINATION ${CMAKE_INSTALL_LIBDIR}/) - install(FILES ${SIMGRID_JAR_TO_INSTALL} - DESTINATION java/ - RENAME simgrid.jar) +if("${CMAKE_SYSTEM}" MATCHES "Linux") + install(TARGETS sthread DESTINATION ${CMAKE_INSTALL_LIBDIR}/) endif() # pkg-config files @@ -94,20 +81,16 @@ endforeach(file ${examples_to_install}) set(source_to_pack ${headers_to_install} ${source_of_generated_headers} - ${JMSG_C_SRC} - ${JMSG_JAVA_SRC} ${MC_SRC_BASE} ${MC_SRC} ${MC_SIMGRID_MC_SRC} - ${MSG_SRC} ${S4U_SRC} ${NS3_SRC} ${PLUGINS_SRC} ${DAG_SRC} ${SIMGRID_SRC} - ${SIMIX_SRC} ${SMPI_SRC} - ${SURF_SRC} + ${KERNEL_SRC} ${TRACING_SRC} ${XBT_RL_SRC} ${XBT_SRC} @@ -115,7 +98,6 @@ set(source_to_pack ${EXTRA_DIST} ${CMAKE_SOURCE_FILES} ${CMAKEFILES_TXT} - ${DOC_IMG} ${DOC_SOURCES} ${DOC_TOOLS} ${PLATFORMS_EXAMPLES} @@ -225,14 +207,6 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E remove_directory ${PROJECT_NAME}-${release_version}/) add_dependencies(dist dist-dir) -if(NOT enable_maintainer_mode) - add_custom_target(echo-dist - COMMAND ${CMAKE_COMMAND} -E echo "WARNING: ----------------------------------------------------" - COMMAND ${CMAKE_COMMAND} -E echo "WARNING: Distrib is generated without option maintainer mode " - COMMAND ${CMAKE_COMMAND} -E echo "WARNING: ----------------------------------------------------") - add_dependencies(dist echo-dist) -endif() - ########################################### ### Fill in the "make distcheck" target ### ########################################### @@ -240,10 +214,13 @@ endif() set(CMAKE_BINARY_TEST_DIR ${CMAKE_BINARY_DIR}) # Allow to test the "make dist" -add_custom_target(distcheck +add_custom_target(distcheck-archive COMMAND ${CMAKE_COMMAND} -E echo "XXX Compare archive with git repository" COMMAND ${CMAKE_HOME_DIRECTORY}/tools/internal/check_dist_archive -batch ${CMAKE_BINARY_TEST_DIR}/${PROJECT_NAME}-${release_version}.tar.gz + ) +add_dependencies(distcheck-archive dist) +add_custom_target(distcheck-configure COMMAND ${CMAKE_COMMAND} -E echo "XXX Remove old copy" COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_TEST_DIR}/${PROJECT_NAME}-${release_version} @@ -260,7 +237,10 @@ add_custom_target(distcheck COMMAND ${CMAKE_COMMAND} -E echo "XXX Check generated files -- please copy new version if they are different" COMMAND ${CMAKE_COMMAND} -E compare_files ${CMAKE_HOME_DIRECTORY}/MANIFEST.in ${CMAKE_BINARY_TEST_DIR}/${PROJECT_NAME}-${release_version}/_build/MANIFEST.in + ) +add_dependencies(distcheck-configure distcheck-archive) +add_custom_target(distcheck COMMAND ${CMAKE_COMMAND} -E echo "XXX Build" COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_TEST_DIR}/${PROJECT_NAME}-${release_version}/_build ${CMAKE_MAKE_PROGRAM} -j 4 @@ -276,7 +256,7 @@ add_custom_target(distcheck COMMAND ${CMAKE_COMMAND} -E echo "XXX Remove temp directories" COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_TEST_DIR}/${PROJECT_NAME}-${release_version} ) -add_dependencies(distcheck dist) +add_dependencies(distcheck distcheck-configure) ####################################### ### Fill in the "make check" target ### diff --git a/tools/cmake/Documentation.cmake b/tools/cmake/Documentation.cmake index 51813a3556..dd025f8bf4 100644 --- a/tools/cmake/Documentation.cmake +++ b/tools/cmake/Documentation.cmake @@ -1,78 +1,11 @@ ### -### Generate all parts of the documentation on non-Windows systems +### Generate the manpages documentation. The sphinx content is not handled in cmake but with the Build.sh script ### -### - HTML with doxygen (reference and manual) -### - Javadoc (reference) -### - manpages (reference of tools) -### -### This file is not loaded on windows #### Generate the html documentation -if (enable_documentation) - find_package(Doxygen REQUIRED) -else() - find_package(Doxygen) -endif() - find_path(FIG2DEV_PATH NAMES fig2dev PATHS NO_DEFAULT_PATHS) if(enable_documentation) - ADD_CUSTOM_TARGET(documentation - COMMENT "Generating the SimGrid documentation..." - DEPENDS ${DOC_SOURCES} ${source_doxygen} - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/doc/doxygen - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/doc/example_lists - COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/doc/html - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/doc/html - COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/doc/xml - COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/docs/source/api - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/doc - ) - - message(STATUS "Doxygen version: ${DOXYGEN_VERSION}") - - if(DOXYGEN_VERSION VERSION_LESS "1.8") - ADD_CUSTOM_TARGET(error_doxygen - COMMAND ${CMAKE_COMMAND} -E echo "Doxygen must be at least version 1.8 to generate documentation. Version found: ${DOXYGEN_VERSION}" - COMMAND false - ) - add_dependencies(documentation error_doxygen) - endif() - - foreach(file ${DOC_IMG}) - ADD_CUSTOM_COMMAND(TARGET documentation COMMAND ${CMAKE_COMMAND} -E copy ${file} ${CMAKE_BINARY_DIR}/doc/html/) - endforeach() - - ADD_CUSTOM_COMMAND(TARGET documentation - COMMAND pwd - COMMAND ${CMAKE_COMMAND} -E echo "XX Generate list of files in examples/ for routing models" - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/doc/example_lists/ - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/doxygen/list_routing_models_examples.sh Floyd > ${CMAKE_BINARY_DIR}/doc/example_lists/example_filelist_routing_floyd - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/doxygen/list_routing_models_examples.sh Dijkstra > ${CMAKE_BINARY_DIR}/doc/example_lists/example_filelist_routing_dijkstra - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/doxygen/list_routing_models_examples.sh DijkstraCache > ${CMAKE_BINARY_DIR}/doc/example_lists/example_filelist_routing_dijkstra_cache - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/doxygen/list_routing_models_examples.sh 'routing="None"' > ${CMAKE_BINARY_DIR}/doc/example_lists/example_filelist_routing_none - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/doxygen/list_routing_models_examples.sh 'routing="Cluster"' > ${CMAKE_BINARY_DIR}/doc/example_lists/example_filelist_routing_cluster - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/doxygen/list_routing_models_examples.sh 'routing="Vivaldi"' > ${CMAKE_BINARY_DIR}/doc/example_lists/example_filelist_routing_vivaldi - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/doxygen/list_routing_models_examples.sh 'routing="Full"' > ${CMAKE_BINARY_DIR}/doc/example_lists/example_filelist_routing_full - COMMAND ${CMAKE_COMMAND} -E echo "XX Generate list of files in examples/ for XML tags" - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/doxygen/list_routing_models_examples.sh ' ${CMAKE_BINARY_DIR}/doc/example_lists/example_filelist_xmltag_mount - COMMAND ${CMAKE_HOME_DIRECTORY}/tools/doxygen/list_routing_models_examples.sh ' ${CMAKE_BINARY_DIR}/doc/example_lists/example_filelist_xmltag_linkctn - COMMAND ${CMAKE_COMMAND} -E echo "XX Run doxygen" - COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/doc - ) - - if (Java_FOUND) - find_path(JAVADOC_PATH NAMES javadoc PATHS NO_DEFAULT_PATHS) - mark_as_advanced(JAVADOC_PATH) - - ADD_CUSTOM_COMMAND(TARGET documentation - COMMAND ${CMAKE_COMMAND} -E echo "XX Javadoc pass" - COMMAND ${JAVADOC_PATH}/javadoc -quiet -d ${CMAKE_BINARY_DIR}/doc/html/javadoc/ ${CMAKE_HOME_DIRECTORY}/src/bindings/java/org/simgrid/*.java ${CMAKE_HOME_DIRECTORY}/src/bindings/java/org/simgrid/*/*.java - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/doc - ) - endif() - #### Generate the manpages if( NOT MANPAGE_DIR) set( MANPAGE_DIR ${CMAKE_BINARY_DIR}/manpages ) diff --git a/tools/cmake/Flags.cmake b/tools/cmake/Flags.cmake index 6fdaa31346..21213be8a3 100644 --- a/tools/cmake/Flags.cmake +++ b/tools/cmake/Flags.cmake @@ -1,7 +1,7 @@ ## ## This file is in charge of setting our paranoid flags with regard to warnings and optimization. ## -## It is only used for gcc and clang. MSVC builds don't load this file. +## It is only used for gcc, clang and Intel compilers. ## ## These flags do break some classical CMake tests, so you don't ## want to do so before the very end of the configuration. @@ -14,10 +14,8 @@ set(optCFLAGS "") set(warnCXXFLAGS "") if(enable_compile_warnings) - set(warnCFLAGS "-fno-common -Wall -Wunused -Wmissing-declarations -Wpointer-arith -Wwrite-strings -Wno-unused-function -Wno-unused-parameter -Wno-strict-aliasing") - if(CMAKE_COMPILER_IS_GNUCC) - set(warnCFLAGS "${warnCFLAGS} -Wclobbered -Wformat-signedness -Wno-error=clobbered -Wno-unused-local-typedefs -Wno-error=attributes -Wno-error=maybe-uninitialized") - endif() + set(warnCFLAGS "-fno-common -Wall -Wextra -Wunused -Wmissing-declarations -Wpointer-arith -Wwrite-strings -Wno-unused-function -Wno-unused-local-typedefs -Wno-unused-parameter -Wno-strict-aliasing") + if (CMAKE_CXX_COMPILER_ID MATCHES "Intel") # ignore remarks: # 191: type qualifier is meaningless on cast type @@ -31,19 +29,32 @@ if(enable_compile_warnings) # 11003: no IR in object file xxxx; was the source file compiled with xxxx set(warnCFLAGS "${warnCFLAGS} -diag-disable=191,1418,2196,2651,3179 -diag-warning=597,2330,11003") endif() + set(warnCXXFLAGS "${warnCFLAGS}") + + if(CMAKE_COMPILER_IS_GNUCC) + set(warnCFLAGS "${warnCFLAGS} -Wclobbered -Wformat-signedness -Wno-error=clobbered -Wno-error=attributes -Wno-error=maybe-uninitialized") + endif() - set(warnCXXFLAGS "${warnCFLAGS} -Wall -Wextra -Wunused -Wmissing-declarations -Wpointer-arith -Wwrite-strings -Wno-unused-function -Wno-unused-parameter -Wno-strict-aliasing") if(CMAKE_COMPILER_IS_GNUCXX) set(warnCXXFLAGS "${warnCXXFLAGS} -Wclobbered -Wformat-signedness -Wno-error=clobbered -Wno-free-nonheap-object -Wno-unused-local-typedefs -Wno-error=attributes -Wno-error=maybe-uninitialized") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0") + # workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81767 + set(warnCXXFLAGS "${warnCXXFLAGS} -Wno-error=unused-variable") + endif() + if (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "13.2.0") + # workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101361 + set(warnCXXFLAGS "${warnCXXFLAGS} -Wno-error=stringop-overread -Wno-error=stringop-overflow") + endif() endif() - if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0") - # workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81767 - set(warnCXXFLAGS "${warnCXXFLAGS} -Wno-error=unused-variable") - endif() + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") # don't care about class that become struct, avoid issue of empty C structs # size (coming from libunwind.h) set(warnCXXFLAGS "${warnCXXFLAGS} -Wno-mismatched-tags -Wno-extern-c-compat") + # also ignore deprecated builtins (seen with clang 15 + boost 1.79) + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "15.0") + set(warnCXXFLAGS "${warnCXXFLAGS} -Wno-deprecated-builtins") + endif() endif() # the one specific to C but refused by C++ @@ -58,7 +69,6 @@ if(enable_compile_warnings) elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -warn all") endif() - set(CMAKE_JAVA_COMPILE_FLAGS "-Xlint") endif() # NDEBUG gives a lot of "initialized but unused variables" errors. Don't die anyway. @@ -71,13 +81,12 @@ if(enable_compile_warnings AND enable_debug) endif() # Activate the warnings on #if FOOBAR when FOOBAR has no value -# It breaks on FreeBSD within Boost headers, so activate this only in Pure Hardcore debug mode. -if(enable_maintainer_mode) +if("${CMAKE_SYSTEM}" MATCHES "Linux") # Breaks on FreeBSD within Boost headers :( set(warnCFLAGS "${warnCFLAGS} -Wundef") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wundef") endif() -# Se the optimisation flags +# Set the optimisation flags # NOTE, we should CMAKE_BUILD_TYPE for this if(enable_compile_optimizations) set(optCFLAGS "-O3 -funroll-loops -fno-strict-aliasing ") @@ -85,27 +94,24 @@ else() set(optCFLAGS "-O0 ") endif() -#ARM platforms have signed char by default, switch to unsigned for consistancy +# ARM platforms have signed char by default, switch to unsigned for consistancy if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") set(optCFLAGS "${optCFLAGS} -fsigned-char") endif() -if(enable_compile_optimizations AND CMAKE_COMPILER_IS_GNUCC - AND (NOT enable_model-checking)) +if(enable_compile_optimizations AND CMAKE_COMPILER_IS_GNUCC) # This is redundant (already in -03): set(optCFLAGS "${optCFLAGS} -finline-functions ") endif() # Do not leak the current directory into the binaries -if(CMAKE_COMPILER_IS_GNUCC) - execute_process(COMMAND realpath --relative-to=${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR} - RESULT_VARIABLE RESULT OUTPUT_VARIABLE RELATIVE_SOURCE_DIR ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(RESULT EQUAL 0) - message(STATUS "Relative source directory is \"${RELATIVE_SOURCE_DIR}\".") - else() - message(WARNING "Failed to find relative source directory. Using \".\".") - set(RELATIVE_SOURCE_DIR ".") +if(CMAKE_COMPILER_IS_GNUCC AND NOT enable_coverage) + if (CMAKE_VERSION VERSION_LESS "3.20") + file(RELATIVE_PATH RELATIVE_SOURCE_DIR ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + else() # cmake >= 3.20 + cmake_path(RELATIVE_PATH CMAKE_SOURCE_DIR BASE_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE RELATIVE_SOURCE_DIR) endif() + message(STATUS "Relative source directory is \"${RELATIVE_SOURCE_DIR}\".") if (CMAKE_C_COMPILER_VERSION VERSION_LESS "8.0") set(optCFLAGS "${optCFLAGS} -fdebug-prefix-map=\"${CMAKE_SOURCE_DIR}=${RELATIVE_SOURCE_DIR}\"") else() @@ -116,20 +122,11 @@ endif() # Configure LTO if(enable_lto) # User wants LTO. Try if we can do that set(enable_lto OFF) - if(enable_compile_optimizations - AND (NOT enable_model-checking)) - if(CMAKE_VERSION VERSION_LESS "3.9") - if ( CMAKE_COMPILER_IS_GNUCC - AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.5") - AND (LINKER_VERSION VERSION_GREATER "2.22")) - set(enable_lto ON) - endif() - else() - include(CheckIPOSupported) - check_ipo_supported(RESULT ipo LANGUAGES C CXX) - if(ipo) - set(enable_lto ON) - endif() + if(enable_compile_optimizations) + include(CheckIPOSupported) + check_ipo_supported(RESULT ipo LANGUAGES C CXX) + if(ipo) + set(enable_lto ON) endif() endif() @@ -139,11 +136,7 @@ if(enable_lto) # User wants LTO. Try if we can do that if(NOT enable_compile_optimizations) message(STATUS "LTO disabled: Compile-time optimizations turned off.") else() - if(enable_model-checking) - message(STATUS "LTO disabled when compiling with model-checking.") - else() - message(STATUS "LTO does not seem usable -- try updating your build chain.") - endif() + message(STATUS "LTO does not seem usable -- try updating your build chain.") endif() endif() else() @@ -176,25 +169,6 @@ if(enable_lto) # User wants LTO, and it seems usable. Go for it endif() endif() -if(enable_model-checking AND enable_compile_optimizations) - # Forget it, do not optimize the code (because it confuses the MC): - set(optCFLAGS "-O0") - # But you can still optimize this: - set(src_list ${simgrid_sources}) - # except... - list(REMOVE_ITEM src_list ${SIMIX_SRC} ${S4U_SRC}) - # but... - list(APPEND src_list - src/kernel/actor/Simcall.cpp) - foreach(src ${src_list}) - set (mcCFLAGS "-O3 -funroll-loops -fno-strict-aliasing") - if(CMAKE_COMPILER_IS_GNUCC) - set (mcCFLAGS "${mcCFLAGS} -finline-functions") - endif() - set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS ${mcCFLAGS}) - endforeach() -endif() - if (CMAKE_C_COMPILER_ID MATCHES "Intel") # honor parentheses when determining the order of expression evaluation. # disallow optimizations for floating-point arithmetic with Nans or +-Infs (breaks Eigen3) @@ -214,11 +188,6 @@ if(CMAKE_SYSTEM_NAME MATCHES "Darwin") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE=700 -D_DARWIN_C_SOURCE") endif() -# Avoid a failure seen with gcc 7.2.0 and ns3 3.27 -if(enable_ns3) - set_source_files_properties(src/surf/network_ns3.cpp PROPERTIES COMPILE_FLAGS " -Wno-unused-local-typedef") -endif() - set(TESH_OPTION "") if(enable_coverage) find_program(GCOV_PATH NAMES ENV{GCOV} gcov) @@ -281,27 +250,3 @@ if(NOT $ENV{LDFLAGS} STREQUAL "") message(STATUS "Add LDFLAGS: \"$ENV{LDFLAGS}\" to CMAKE_C_LINK_FLAGS") set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} $ENV{LDFLAGS}") endif() - -if(MINGW) - # http://stackoverflow.com/questions/10452262/create-64-bit-jni-under-windows - # We don't want to ship libgcc_s_seh-1.dll nor libstdc++-6.dll - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") - set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -static-libgcc") - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS} -static-libgcc -static-libstdc++") - - # JNI searches for stdcalls - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--add-stdcall-alias") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--add-stdcall-alias") - set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -Wl,--add-stdcall-alias") - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS} -Wl,--add-stdcall-alias") - - # Specify the data model that we are using (yeah it may help Java) - if(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 bits - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64") - endif() -endif() diff --git a/tools/cmake/Java.cmake b/tools/cmake/Java.cmake deleted file mode 100644 index 72813dcca3..0000000000 --- a/tools/cmake/Java.cmake +++ /dev/null @@ -1,173 +0,0 @@ -## -## The Cmake definitions for the use of Java (and Scala) -## This file is loaded only if the Java option is activated -## - -find_package(Java 1.8 COMPONENTS Runtime Development) -if (NOT ${Java_FOUND}) - message(FATAL_ERROR "Java not found (need at least Java8). Please install the JDK or disable that option") -endif() -set(Java_FOUND 1) -include(UseJava) - -find_package(JNI REQUIRED) -message(STATUS "[Java] JNI found: ${JNI_FOUND}") -message(STATUS "[Java] JNI include dirs: ${JNI_INCLUDE_DIRS}") - -if(WIN32) - execute_process(COMMAND java -d64 -version - OUTPUT_VARIABLE JVM_IS_64_BITS) - if("${JVM_IS_64_BITS}" MATCHES "Error") - message(fatal_error "SimGrid can only use Java 64 bits") - endif() -endif() - -# Rules to build libsimgrid-java -################################ - -add_library(simgrid-java SHARED ${JMSG_C_SRC}) -set_target_properties(simgrid-java PROPERTIES VERSION ${libsimgrid-java_version}) -set_target_properties(simgrid-java PROPERTIES SKIP_BUILD_RPATH ON) -set_property(TARGET simgrid-java - APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") - -target_link_libraries(simgrid-java simgrid) -add_dependencies(tests simgrid-java) - -get_target_property(COMMON_INCLUDES simgrid-java INCLUDE_DIRECTORIES) -if (COMMON_INCLUDES) - set_target_properties(simgrid-java PROPERTIES INCLUDE_DIRECTORIES "${COMMON_INCLUDES};${JNI_INCLUDE_DIRS}") -else() - set_target_properties(simgrid-java PROPERTIES INCLUDE_DIRECTORIES "${JNI_INCLUDE_DIRS}") -endif() - -get_target_property(CHECK_INCLUDES simgrid-java INCLUDE_DIRECTORIES) -message(STATUS "[Java] simgrid-java includes: ${CHECK_INCLUDES}") - -# Rules to build simgrid.jar -############################ - -## Files to include in simgrid.jar -## -set(SIMGRID_JAR "${CMAKE_BINARY_DIR}/simgrid.jar") -set(MANIFEST_IN_FILE "${CMAKE_HOME_DIRECTORY}/src/bindings/java/MANIFEST.in") -set(MANIFEST_FILE "${CMAKE_BINARY_DIR}/src/bindings/java/MANIFEST.MF") - -set(LIBSIMGRID_SO libsimgrid${CMAKE_SHARED_LIBRARY_SUFFIX}) -set(LIBSIMGRID_JAVA_SO ${CMAKE_SHARED_LIBRARY_PREFIX}simgrid-java${CMAKE_SHARED_LIBRARY_SUFFIX}) - -## Here is how to build simgrid.jar -## -add_jar(simgrid-java_jar ${JMSG_JAVA_SRC} OUTPUT_NAME simgrid) - -if(enable_lib_in_jar) - add_dependencies(simgrid-java_jar simgrid-java) - add_dependencies(simgrid-java_jar simgrid) -endif() - -if (enable_documentation) - add_custom_command( - TARGET simgrid-java_jar POST_BUILD - COMMENT "Add the documentation into simgrid.jar..." - DEPENDS ${MANIFEST_IN_FILE} - ${CMAKE_HOME_DIRECTORY}/COPYING - ${CMAKE_HOME_DIRECTORY}/ChangeLog - ${CMAKE_HOME_DIRECTORY}/NEWS - ${CMAKE_HOME_DIRECTORY}/LICENSE-LGPL-2.1 - - COMMAND ${CMAKE_COMMAND} -E copy ${MANIFEST_IN_FILE} ${MANIFEST_FILE} - COMMAND ${CMAKE_COMMAND} -E echo "Specification-Version: \\\"${SIMGRID_VERSION_MAJOR}.${SIMGRID_VERSION_MINOR}.${SIMGRID_VERSION_PATCH}\\\"" >> ${MANIFEST_FILE} - COMMAND ${CMAKE_COMMAND} -E echo "Implementation-Version: \\\"${GIT_VERSION}\\\"" >> ${MANIFEST_FILE} - - COMMAND ${Java_JAVADOC_EXECUTABLE} -quiet -d doc/javadoc -sourcepath ${CMAKE_HOME_DIRECTORY}/src/bindings/java/ org.simgrid.msg org.simgrid.trace - - COMMAND ${JAVA_ARCHIVE} -uvmf ${MANIFEST_FILE} ${SIMGRID_JAR} doc/javadoc - COMMAND ${JAVA_ARCHIVE} -uvf ${SIMGRID_JAR} -C ${CMAKE_HOME_DIRECTORY} COPYING -C ${CMAKE_HOME_DIRECTORY} ChangeLog -C ${CMAKE_HOME_DIRECTORY} LICENSE-LGPL-2.1 -C ${CMAKE_HOME_DIRECTORY} NEWS - ) -endif() - -### -### Pack the java libraries into the jarfile if asked to do so -### - -if(enable_lib_in_jar) - set(SG_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}) - - if(${SG_SYSTEM_NAME} MATCHES "kFreeBSD") - set(SG_SYSTEM_NAME GNU/kFreeBSD) - endif() - - set(JAVA_NATIVE_PATH NATIVE/${SG_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}) - if( (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^i[3-6]86$") OR - (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64") OR - (${CMAKE_SYSTEM_PROCESSOR} MATCHES "AMD64") ) - if(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 bits - set(JAVA_NATIVE_PATH NATIVE/${SG_SYSTEM_NAME}/x86) - else() - set(JAVA_NATIVE_PATH NATIVE/${SG_SYSTEM_NAME}/amd64) - endif() - endif() - if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "armv7l") - set(JAVA_NATIVE_PATH NATIVE/${SG_SYSTEM_NAME}/arm) # Default arm (soft-float ABI) - endif() - - add_custom_command( - TARGET simgrid-java_jar POST_BUILD - COMMENT "Add the native libs into simgrid.jar..." - DEPENDS simgrid simgrid-java ${JAVALIBS} - - COMMAND ${CMAKE_COMMAND} -E make_directory ${JAVA_NATIVE_PATH} - - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/lib/${LIBSIMGRID_SO} ${JAVA_NATIVE_PATH}/${LIBSIMGRID_SO} - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/lib/${LIBSIMGRID_JAVA_SO} ${JAVA_NATIVE_PATH}/${LIBSIMGRID_JAVA_SO} - ) - -if(WIN32) - add_custom_command( - TARGET simgrid-java_jar POST_BUILD - COMMENT "Add the windows-specific native libs into simgrid.jar..." - DEPENDS simgrid simgrid-java ${JAVALIBS} - - # There is no way to disable the dependency of mingw-64 on that lib, unfortunately nor to script cmake -E properly - # So let's be brutal and copy it in any case (even on non-windows builds) from the location where appveyor provides it. - # The copy is only expected to work on the appveyor builder, but that's all we need right now - # since our users are directed to download that file as nightly build. - COMMAND ${CMAKE_COMMAND} -E copy_if_different C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/libwinpthread-1.dll ${JAVA_NATIVE_PATH}/libwinpthread-1.dll || true - COMMAND ${CMAKE_COMMAND} -E copy_if_different C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/libwinpthread-1.dll ${JAVA_NATIVE_PATH}/libwinpthread-1.dll || true - ) -endif() - -if(APPLE) - add_custom_command( - TARGET simgrid-java_jar POST_BUILD - COMMENT "Add the apple-specific native libs into simgrid.jar..." - DEPENDS simgrid simgrid-java ${JAVALIBS} - - # We need to fix the rpath of the simgrid-java library so that it - # searches the simgrid library in the right location - # - # Since we don't officially install the lib before copying it in - # the jarfile, the lib is searched for where it was built. Given - # how we unpack it, we need to instruct simgrid-java to forget - # about the build path, and search in its current directory - # instead. - # - # This has to be done with the classical Apple tools, as follows: - - COMMAND install_name_tool -change ${CMAKE_BINARY_DIR}/lib/libsimgrid.${SIMGRID_VERSION_MAJOR}.${SIMGRID_VERSION_MINOR}${CMAKE_SHARED_LIBRARY_SUFFIX} @loader_path/libsimgrid.dylib ${JAVA_NATIVE_PATH}/${LIBSIMGRID_JAVA_SO} - ) -endif(APPLE) - - add_custom_command( - TARGET simgrid-java_jar POST_BUILD - COMMENT "Packing back the simgrid.jar with the native libs (turn lib_in_jar off when coding in java)..." - DEPENDS simgrid simgrid-java ${JAVALIBS} - - COMMAND ${JAVA_ARCHIVE} -uvf ${SIMGRID_JAR} ${JAVA_NATIVE_PATH} - - COMMAND ${CMAKE_COMMAND} -E echo "-- Cmake put the native code in ${JAVA_NATIVE_PATH}" - COMMAND "${Java_JAVA_EXECUTABLE}" -classpath "${SIMGRID_JAR}" org.simgrid.NativeLib - ) -endif(enable_lib_in_jar) - -include_directories(${JNI_INCLUDE_DIRS} ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2}) diff --git a/tools/cmake/MaintainerMode.cmake b/tools/cmake/MaintainerMode.cmake index a2ab5449e7..42b4789db8 100644 --- a/tools/cmake/MaintainerMode.cmake +++ b/tools/cmake/MaintainerMode.cmake @@ -10,7 +10,14 @@ set(FLEX_MIN_PATCH 39) # Let's generate header files required by SMPI when the call location tracing # has been activated. -if(enable_maintainer_mode AND NOT WIN32) +if(enable_maintainer_mode) + if (enable_ns3) + message(STATUS "Maintainer mode activated with ns-3, not enabling GLIBCXX_DEBUG (diable ns-3 to get it).") + else() + message(STATUS "Maintainer mode activated, enabling GLIBCXX_DEBUG.") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_DEBUG") + endif() + add_custom_command(OUTPUT ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_extended_traces.h ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_extended_traces_fortran.h DEPENDS @@ -35,45 +42,14 @@ if(enable_maintainer_mode AND NOT WIN32) ) endif() -if(enable_maintainer_mode AND NOT WIN32) +if(enable_maintainer_mode) find_program(FLEX_EXE NAMES flex) find_program(FLEXML_EXE NAMES flexml) find_program(SED_EXE NAMES sed) - find_program(BISON_EXE NAMES bison) find_program(LEX_EXE NAMES lex) - mark_as_advanced(BISON_EXE) mark_as_advanced(LEX_EXE) - if(BISON_EXE AND LEX_EXE) - add_custom_command( - OUTPUT - ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/automaton_lexer.yy.c - ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.cacc - ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.hacc - - DEPENDS - ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.lex - ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.yacc - - COMMENT "Generating automaton source files" - COMMAND ${BISON_EXE} --name-prefix=xbt_automaton_parser_ -d -t parserPromela.yacc - COMMAND ${LEX_EXE} --prefix=xbt_automaton_parser_ --outfile=automaton_lexer.yy.c parserPromela.lex - WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/ - ) - - add_custom_target(automaton_generated_src - DEPENDS - ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/automaton_lexer.yy.c - ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.cacc - ${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.hacc - ) - - SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES - "${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.cacc;${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/parserPromela.tab.hacc;${CMAKE_HOME_DIRECTORY}/src/xbt/automaton/automaton_parse.yy.c" - ) - endif() - message(STATUS "Found flex: ${FLEX_EXE}") IF(FLEX_EXE) set(HAVE_FLEX 1) @@ -129,27 +105,26 @@ if(enable_maintainer_mode AND NOT WIN32) set(string1 "'s/extern /XBT_PUBLIC_DATA /'") set(string2 "'s/XBT_PUBLIC_DATA \\([^(]*\\)(/XBT_PUBLIC \\1(/'") - set(string3 "'s/XBT_PUBLIC void STag_surfxml_include/XBT_ATTRIB_NORETURN &/'") # remove with v5 of the dtd - set(string4 "'s/XBT_PUBLIC void STag_surfxml_\\(mount\\|storage\\)/XBT_ATTRIB_NORETURN &/'") # remove with v5 of the dtd + set(string3 "'s/XBT_PUBLIC void STag_simgrid_parse_include/XBT_ATTRIB_NORETURN &/'") # remove with v5 of the dtd + set(string4 "'s/XBT_PUBLIC void STag_simgrid_parse_\\(mount\\|storage\\)/XBT_ATTRIB_NORETURN &/'") # remove with v5 of the dtd set(string5 "'s/SET(DOCTYPE)/SET(ROOT_dax__adag)/'") - set(string9 "'s/#include /#if defined(_WIN32)\\n# ifndef __STRICT_ANSI__\\n# include \\n# include \\n# endif\\n#else\\n# include \\n#endif/g'") set(string14 "'\\!^ \\* Generated [0-9/]\\{10\\} [0-9:]\\{8\\}\\.$$!d'") ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid_dtd.h + OUTPUT ${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid_dtd.h ${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.h - ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid_dtd.c + ${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid_dtd.c ${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.c - DEPENDS ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid.dtd + DEPENDS ${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid.dtd ${CMAKE_HOME_DIRECTORY}/src/dag/dax.dtd - #${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid_dtd.l: ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid.dtd - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_HOME_DIRECTORY}/src/surf/xml - COMMAND ${FLEXML_EXE} --root-tags platform -b 1000000 -P surfxml --sysid=https://simgrid.org/simgrid.dtd -S src/surf/xml/simgrid_dtd.l -L src/surf/xml/simgrid.dtd - COMMAND ${PERL_EXE} ${CMAKE_HOME_DIRECTORY}/tools/cmake/scripts/fixup_simgrid_dtd_l.pl < src/surf/xml/simgrid_dtd.l > src/surf/xml/simgrid_dtd.l.tmp - COMMAND mv src/surf/xml/simgrid_dtd.l.tmp src/surf/xml/simgrid_dtd.l - COMMAND ${CMAKE_COMMAND} -E echo " Generated src/surf/xml/simgrid_dtd.l" + #${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid_dtd.l: ${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid.dtd + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_HOME_DIRECTORY}/src/kernel/xml + COMMAND ${FLEXML_EXE} --root-tags platform -b 1000000 -P simgrid_parse --sysid=https://simgrid.org/simgrid.dtd -S src/kernel/xml/simgrid_dtd.l -L src/kernel/xml/simgrid.dtd + COMMAND ${PERL_EXE} ${CMAKE_HOME_DIRECTORY}/tools/cmake/scripts/fixup_simgrid_dtd_l.pl < src/kernel/xml/simgrid_dtd.l > src/kernel/xml/simgrid_dtd.l.tmp + COMMAND mv src/kernel/xml/simgrid_dtd.l.tmp src/kernel/xml/simgrid_dtd.l + COMMAND ${CMAKE_COMMAND} -E echo " Generated src/kernel/xml/simgrid_dtd.l" #${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.l: ${CMAKE_HOME_DIRECTORY}/src/dag/dax.dtd COMMAND ${FLEXML_EXE} -b 1000000 --root-tags adag -P dax_ --sysid=dax.dtd -S src/dag/dax_dtd.l -L src/dag/dax.dtd @@ -157,15 +132,14 @@ if(enable_maintainer_mode AND NOT WIN32) COMMAND ${SED_EXE} -i ${string14} src/dag/dax_dtd.l COMMAND ${CMAKE_COMMAND} -E echo " Generated src/dag/dax_dtd.l" - #${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid_dtd.h: ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid.dtd - COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_HOME_DIRECTORY}/include/surf/simgrid.h - COMMAND ${FLEXML_EXE} --root-tags platform -P surfxml --sysid=https://simgrid.org/simgrid.dtd -H src/surf/xml/simgrid_dtd.h -L src/surf/xml/simgrid.dtd - COMMAND ${SED_EXE} -i ${string1} src/surf/xml/simgrid_dtd.h - COMMAND ${SED_EXE} -i ${string2} src/surf/xml/simgrid_dtd.h - COMMAND ${SED_EXE} -i ${string3} src/surf/xml/simgrid_dtd.h - COMMAND ${SED_EXE} -i ${string4} src/surf/xml/simgrid_dtd.h - COMMAND ${SED_EXE} -i ${string14} src/surf/xml/simgrid_dtd.h - COMMAND ${CMAKE_COMMAND} -E echo " Generated src/surf/xml/simgrid_dtd.h" + #${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid_dtd.h: ${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid.dtd + COMMAND ${FLEXML_EXE} --root-tags platform -P simgrid_parse --sysid=https://simgrid.org/simgrid.dtd -H src/kernel/xml/simgrid_dtd.h -L src/kernel/xml/simgrid.dtd + COMMAND ${SED_EXE} -i ${string1} src/kernel/xml/simgrid_dtd.h + COMMAND ${SED_EXE} -i ${string2} src/kernel/xml/simgrid_dtd.h + COMMAND ${SED_EXE} -i ${string3} src/kernel/xml/simgrid_dtd.h + COMMAND ${SED_EXE} -i ${string4} src/kernel/xml/simgrid_dtd.h + COMMAND ${SED_EXE} -i ${string14} src/kernel/xml/simgrid_dtd.h + COMMAND ${CMAKE_COMMAND} -E echo " Generated src/kernel/xml/simgrid_dtd.h" #${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.h: ${CMAKE_HOME_DIRECTORY}/src/dag/dax.dtd COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.h @@ -175,17 +149,15 @@ if(enable_maintainer_mode AND NOT WIN32) COMMAND ${SED_EXE} -i ${string14} src/dag/dax_dtd.h COMMAND ${CMAKE_COMMAND} -E echo " Generated src/dag/dax_dtd.h" - #surf/xml/simgrid_dtd.c: surf/xml/simgrid_dtd.l - COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid_dtd.c - COMMAND ${FLEX_EXE} -o src/surf/xml/simgrid_dtd.c -Psurf_parse_ --noline src/surf/xml/simgrid_dtd.l - COMMAND ${SED_EXE} -i ${string9} src/surf/xml/simgrid_dtd.c - COMMAND ${CMAKE_COMMAND} -E echo " Generated surf/xml/simgrid_dtd.c" + #kernel/xml/simgrid_dtd.c: kernel/xml/simgrid_dtd.l + COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid_dtd.c + COMMAND ${FLEX_EXE} -o src/kernel/xml/simgrid_dtd.c -Psimgrid_parse_ --noline src/kernel/xml/simgrid_dtd.l + COMMAND ${CMAKE_COMMAND} -E echo " Generated kernel/xml/simgrid_dtd.c" #dag/dax_dtd.c: dag/dax_dtd.l COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.c COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_HOME_DIRECTORY}/src/dag COMMAND ${FLEX_EXE} -o src/dag/dax_dtd.c -Pdax_ --noline src/dag/dax_dtd.l - COMMAND ${SED_EXE} -i ${string9} src/dag/dax_dtd.c COMMAND ${CMAKE_COMMAND} -E echo " Generated src/dag/dax_dtd.c" WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY} @@ -208,9 +180,9 @@ if(enable_maintainer_mode AND NOT WIN32) endif() - add_custom_target(maintainer_files - DEPENDS ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid_dtd.h - ${CMAKE_HOME_DIRECTORY}/src/surf/xml/simgrid_dtd.c - ${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.h - ${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.c - ) +add_custom_target(maintainer_files + DEPENDS ${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid_dtd.h + ${CMAKE_HOME_DIRECTORY}/src/kernel/xml/simgrid_dtd.c + ${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.h + ${CMAKE_HOME_DIRECTORY}/src/dag/dax_dtd.c + ) diff --git a/tools/cmake/MakeLib.cmake b/tools/cmake/MakeLib.cmake index c50bd886ba..79f4e27205 100644 --- a/tools/cmake/MakeLib.cmake +++ b/tools/cmake/MakeLib.cmake @@ -2,6 +2,7 @@ # On macOS, specify that rpath is useful to look for the dependencies # See https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling and Java.cmake +# TODO: is it still useful now that Java is gone? For Python maybe? set(CMAKE_MACOSX_RPATH TRUE) if(APPLE) SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # When installed, use system path @@ -28,6 +29,7 @@ add_dependencies(simgrid maintainer_files) if("${CMAKE_SYSTEM}" MATCHES "Linux") add_library(sthread SHARED ${STHREAD_SRC}) + set_target_properties(sthread PROPERTIES VERSION ${libsimgrid_version}) set_property(TARGET sthread APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") target_link_libraries(sthread simgrid) @@ -35,13 +37,13 @@ else() set(EXTRA_DIST ${EXTRA_DIST} ${STHREAD_SRC}) endif() -if(enable_model-checking) +if(SIMGRID_HAVE_MC) add_executable(simgrid-mc ${MC_SIMGRID_MC_SRC}) target_link_libraries(simgrid-mc simgrid) set_target_properties(simgrid-mc PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") set_property(TARGET simgrid-mc - APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") + APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") install(TARGETS simgrid-mc # install that binary without breaking the rpath on Mac RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/) add_dependencies(tests-mc simgrid-mc) @@ -88,6 +90,10 @@ if(HAVE_GRAPHVIZ) endif() endif() +if(SIMGRID_HAVE_JSON) + target_link_libraries(simgrid nlohmann_json::nlohmann_json) +endif() + if(NOT ${DL_LIBRARY} STREQUAL "") SET(SIMGRID_DEP "${SIMGRID_DEP} ${DL_LIBRARY}") endif() @@ -167,10 +173,6 @@ if(CMAKE_COMPILER_IS_GNUCC AND GCCLIBATOMIC_LIBRARY) endif() mark_as_advanced(GCCLIBATOMIC_LIBRARY) -if(enable_model-checking AND (NOT LINKER_VERSION VERSION_LESS "2.30")) - set(SIMGRID_DEP "${SIMGRID_DEP} -Wl,-znorelro -Wl,-znoseparate-code") -endif() - target_link_libraries(simgrid ${SIMGRID_DEP}) # Dependencies from maintainer mode @@ -178,6 +180,3 @@ target_link_libraries(simgrid ${SIMGRID_DEP}) if(enable_maintainer_mode) add_dependencies(simgrid smpi_generated_headers_call_location_tracing) endif() -if(enable_maintainer_mode AND BISON_EXE AND LEX_EXE) - add_dependencies(simgrid automaton_generated_src) -endif() diff --git a/tools/cmake/MakeLibWin.cmake b/tools/cmake/MakeLibWin.cmake deleted file mode 100644 index d76e274957..0000000000 --- a/tools/cmake/MakeLibWin.cmake +++ /dev/null @@ -1,36 +0,0 @@ -### Make Libs - -add_library(simgrid SHARED ${simgrid_sources}) - -if(MSVC) - set_target_properties(simgrid PROPERTIES - COMPILE_FLAGS "/DDLL_EXPORT" - VERSION ${libsimgrid_version} ) -else() - set_target_properties(simgrid PROPERTIES - COMPILE_FLAGS "-DDLL_EXPORT" - LINK_FLAGS "-shared" - VERSION ${libsimgrid_version} - PREFIX "lib" SUFFIX ".dll" - IMPORT_PREFIX "lib" IMPORT_SUFFIX ".dll") - - set(SIMGRID_DEP "-lm") - - if (HAVE_BOOST_CONTEXTS) - target_link_libraries(simgrid ${Boost_CONTEXT_LIBRARY}) - endif() - - if (HAVE_BOOST_STACKTRACE_BACKTRACE) - target_link_libraries(simgrid ${Boost_STACKTRACE_BACKTRACE_LIBRARY}) - endif() - - if (HAVE_BOOST_ADDR2LINE_BACKTRACE) - target_link_libraries(simgrid ${Boost_STACKTRACE_ADDR2LINE_LIBRARY}) - endif() -endif() - -target_link_libraries(simgrid ${SIMGRID_DEP}) - -# The library can obviously use the internal headers -set_property(TARGET simgrid - APPEND PROPERTY INCLUDE_DIRECTORIES "${INTERNAL_INCLUDES}") diff --git a/tools/cmake/Modules/FindGraphviz.cmake b/tools/cmake/Modules/FindGraphviz.cmake index 57f6771ea8..860a65e290 100644 --- a/tools/cmake/Modules/FindGraphviz.cmake +++ b/tools/cmake/Modules/FindGraphviz.cmake @@ -25,9 +25,9 @@ if(HAVE_CDT_LIB AND HAVE_CGRAPH_LIB AND HAVE_CGRAPH_H) include_directories(${file_graphviz_h} ${file_graphviz_h}/graphviz) link_directories(${lib_graphviz}) - set(HAVE_GRAPHVIZ "1") + set(HAVE_GRAPHVIZ ON) else() - set(HAVE_GRAPHVIZ "0") + set(HAVE_GRAPHVIZ OFF) endif() mark_as_advanced(HAVE_GRAPHVIZ) diff --git a/tools/cmake/Modules/FindLibdw.cmake b/tools/cmake/Modules/FindLibdw.cmake deleted file mode 100644 index 9574bda8c0..0000000000 --- a/tools/cmake/Modules/FindLibdw.cmake +++ /dev/null @@ -1,34 +0,0 @@ -find_path(LIBDW_INCLUDE_DIR "elfutils/libdw.h" - HINTS - $ENV{SIMGRID_LIBDW_LIBRARY_PATH} - $ENV{LD_LIBRARY_PATH} - $ENV{LIBDW_LIBRARY_PATH} - PATH_SUFFIXES include/ GnuWin32/include - PATHS - /opt - /opt/local - /opt/csw - /sw - /usr) -find_library(LIBDW_LIBRARY - NAMES dw - HINTS - $ENV{SIMGRID_LIBDW_LIBRARY_PATH} - $ENV{LD_LIBRARY_PATH} - $ENV{LIBDW_LIBRARY_PATH} - PATH_SUFFIXES lib/ GnuWin32/lib - PATHS - /opt - /opt/local - /opt/csw - /sw - /usr) -set(LIBDW_LIBRARIES "${LIBDW_LIBRARY}") - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - Libdw - DEFAULT_MSG - LIBDW_LIBRARIES - LIBDW_INCLUDE_DIR) -mark_as_advanced(LIBDW_INCLUDE_DIR LIBDW_LIBRARIES) diff --git a/tools/cmake/Modules/FindLibelf.cmake b/tools/cmake/Modules/FindLibelf.cmake deleted file mode 100644 index 1e1af815ad..0000000000 --- a/tools/cmake/Modules/FindLibelf.cmake +++ /dev/null @@ -1,34 +0,0 @@ -find_path(LIBELF_INCLUDE_DIR "libelf.h" - HINTS - $ENV{SIMGRID_LIBELF_LIBRARY_PATH} - $ENV{LD_LIBRARY_PATH} - $ENV{LIBELF_LIBRARY_PATH} - PATH_SUFFIXES include/ GnuWin32/include - PATHS - /opt - /opt/local - /opt/csw - /sw - /usr) -find_library(LIBELF_LIBRARY - NAMES elf - HINTS - $ENV{SIMGRID_LIBELF_LIBRARY_PATH} - $ENV{LD_LIBRARY_PATH} - $ENV{LIBELF_LIBRARY_PATH} - PATH_SUFFIXES lib/ GnuWin32/lib - PATHS - /opt - /opt/local - /opt/csw - /sw - /usr) -set(LIBELF_LIBRARIES "${LIBELF_LIBRARY}") - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - Libelf - DEFAULT_MSG - LIBELF_LIBRARIES - LIBELF_INCLUDE_DIR) -mark_as_advanced(LIBELF_INCLUDE_DIR LIBELF_LIBRARIES) diff --git a/tools/cmake/Modules/FindLibunwind.cmake b/tools/cmake/Modules/FindLibunwind.cmake deleted file mode 100644 index f636430d25..0000000000 --- a/tools/cmake/Modules/FindLibunwind.cmake +++ /dev/null @@ -1,99 +0,0 @@ -# Search for libunwind and components, both includes and libraries -# -# Copyright (C) 2003-2022 The SimGrid Team. -# This is distributed under the LGPL licence but please contact us for -# relicensing if you need. This is merely free software, no matter the licence. -# -# -# Input environment variables: -# LIBUNWIND_HINT: path to libunwind installation (e.g., /usr) -# (only needed for non-standard installs) -# -# You can tune the needed components here. -# TODO: we should take this as a parameter if I knew how to do so. - -# SimGrid needs unwind-ptrace on Linux and FreeBSD -if("${CMAKE_SYSTEM}" MATCHES "Linux|FreeBSD") - set(LIBUNWIND_COMPONENTS ${LIBUNWIND_COMPONENTS} unwind-ptrace unwind-generic) -endif() - -# -# Output variables: -# HAVE_LIBUNWIND : if all components were found was found -# LIBUNWIND_LIBRARIES: List of all libraries to load (-lunwind -lunwind-x86_64 and such) -# -# Other effects: -# - Calls include_directories() on where libunwind.h lives -# - Calls link_directories() on where the libs live - -# Of course also need the core lib -set(LIBUNWIND_COMPONENTS ${LIBUNWIND_COMPONENTS} "unwind") - -message(STATUS "Looking for libunwind:") -# Let's assume we have it, and invalidate if parts are missing -SET(HAVE_LIBUNWIND 1) - -# -# Search for the header file -# - -find_path(PATH_LIBUNWIND_H "libunwind.h" - HINTS - $ENV{LIBUNWIND_HINT} - $ENV{LD_LIBRARY_PATH} - PATH_SUFFIXES include/ GnuWin32/include - PATHS /opt /opt/local /opt/csw /sw /usr) -if(PATH_LIBUNWIND_H) - string(REGEX REPLACE "/libunwind.h" "" PATH_LIBUNWIND_H "${PATH_LIBUNWIND_H}") - message(" Found libunwind.h in ${PATH_LIBUNWIND_H}") - include_directories(${PATH_LIBUNWIND_H}) -else() - message(" NOT FOUND libunwind.h") - SET(HAVE_LIBUNWIND 0) -endif() -mark_as_advanced(PATH_LIBUNWIND_H) - -# -# Search for the library components -# - -foreach(component ${LIBUNWIND_COMPONENTS}) - find_library(PATH_LIBUNWIND_LIB_${component} - NAMES ${component} - HINTS - $ENV{LIBUNWIND_HINT} - $ENV{LD_LIBRARY_PATH} - PATH_SUFFIXES lib/ GnuWin32/lib lib/system - PATHS /opt /opt/local /opt/csw /sw /usr /usr/lib/) - if(PATH_LIBUNWIND_LIB_${component}) - # message(" ${component} ${PATH_LIBUNWIND_LIB_${component}}") - string(REGEX REPLACE "/lib${component}.*[.]${LIB_EXE}$" "" PATH_LIBUNWIND_LIB_${component} "${PATH_LIBUNWIND_LIB_${component}}") - message(" Found lib${component}.${LIB_EXE} in ${PATH_LIBUNWIND_LIB_${component}}") - link_directories(${PATH_LIBUNWIND_LIB_${component}}) - - if(${component} STREQUAL "unwind" AND APPLE) - # Apple forbids to link directly against its libunwind implementation - # So let's comply to that stupid restriction and link against the System framework - SET(LIBUNWIND_LIBRARIES "${LIBUNWIND_LIBRARIES} -lSystem") - else() - SET(LIBUNWIND_LIBRARIES "${LIBUNWIND_LIBRARIES} -l${component}") - endif() - - else() - message(" Looking for lib${component}.${LIB_EXE} - not found") - SET(HAVE_LIBUNWIND 0) - endif() - mark_as_advanced(PATH_LIBUNWIND_LIB_${component}) -endforeach() -unset(component) -unset(LIBUNWIND_COMPONENTS) - -# -# Conclude and cleanup -# -if(HAVE_LIBUNWIND) - message(STATUS "Dependencies induced by libunwind: ${LIBUNWIND_LIBRARIES}") -else() - message(STATUS "Some libunwind components are missing") - set(LIBUNWIND_LIBRARIES "") -endif() diff --git a/tools/cmake/Modules/FindNS3.cmake b/tools/cmake/Modules/FindNS3.cmake index 1c477439ab..997587276c 100644 --- a/tools/cmake/Modules/FindNS3.cmake +++ b/tools/cmake/Modules/FindNS3.cmake @@ -42,7 +42,7 @@ if(NS3_FOUND) # Starting from 3.36, ns3 provides a working pkg-config file, maki else() set(NS3_HINT ${ns3_path} CACHE PATH "Path to search for NS3 lib and include") - set(NS3_KNOWN_VERSIONS "3-dev" "3.28" "3.29" "3.30" "3.31" "3.32" "3.33" "3.34" "3.35") + set(NS3_KNOWN_VERSIONS "3-dev" "3.28" "3.29" "3.30" "3.31" "3.32" "3.33" "3.34" "3.35") # subsequent versions use pkg-config foreach (_ns3_ver ${NS3_KNOWN_VERSIONS}) list(APPEND _ns3_LIB_SEARCH_DIRS "ns${_ns3_ver}-core" "ns${_ns3_ver}-core-optimized" "ns${_ns3_ver}-core-debug" "ns${_ns3_ver}-core-default") @@ -126,8 +126,19 @@ else() endforeach() endif() +set(SIMGRID_HAVE_NS3_GetNextEventTime FALSE) if(SIMGRID_HAVE_NS3) - message(STATUS "ns-3 found (v${NS3_VERSION}; minor:${NS3_MINOR_VERSION}; patch:${NS3_PATCH_VERSION}; libpath: ${NS3_LIBRARY_PATH}).") + try_compile(compile_ns3 ${CMAKE_BINARY_DIR} ${CMAKE_HOME_DIRECTORY}/tools/cmake/test_prog/prog_ns3.cpp + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${NS3_INCLUDE_DIR}" "-DLINK_DIRECTORIES=${NS3_LIBRARY_PATH}" + LINK_LIBRARIES "${NS3_LIBRARIES}" + OUTPUT_VARIABLE compile_ns3_output) + if(NOT compile_ns3) + message(STATUS "ns-3 does not have the ns3::Simulator::GetNextEventTime patch. The ns-3 model will not be idempotent. Compilation output:\n ${compile_ns3_output}") + else() + set(SIMGRID_HAVE_NS3_GetNextEventTime TRUE) + endif() + file(REMOVE ${CMAKE_BINARY_DIR}/prog_ns3) + message(STATUS "ns-3 found (v${NS3_VERSION}; minor ver:${NS3_MINOR_VERSION}; patch ver:${NS3_PATCH_VERSION}; GetNextEventTime patch: ${SIMGRID_HAVE_NS3_GetNextEventTime}; libpath: ${NS3_LIBRARY_PATH}).") link_directories(${NS3_LIBRARY_PATH}) include_directories(${NS3_INCLUDE_DIR}) else() diff --git a/tools/cmake/Modules/FindPAPI.cmake b/tools/cmake/Modules/FindPAPI.cmake index 8427cfed56..28b2b3519b 100644 --- a/tools/cmake/Modules/FindPAPI.cmake +++ b/tools/cmake/Modules/FindPAPI.cmake @@ -17,7 +17,7 @@ # PAPI_LIBRARY The PAPI library # PAPI_INCLUDE_DIRS The location of PAPI headers -set(HAVE_PAPI 0) +set(HAVE_PAPI OFF) set(PAPI_HINT ${papi_path} CACHE PATH "Path to search for PAPI headers and library") find_path(PAPI_PREFIX @@ -55,7 +55,7 @@ endif() if (PAPI_LIBRARY) if(PAPI_INCLUDE_DIRS) - set(HAVE_PAPI 1) + set(HAVE_PAPI ON) mark_as_advanced(HAVE_PAPI) endif() endif() diff --git a/tools/cmake/Modules/nlohmann_jsonConfig.cmake b/tools/cmake/Modules/nlohmann_jsonConfig.cmake new file mode 100644 index 0000000000..27b0a864a8 --- /dev/null +++ b/tools/cmake/Modules/nlohmann_jsonConfig.cmake @@ -0,0 +1,15 @@ +include(FindPackageHandleStandardArgs) +set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG ${CMAKE_CURRENT_LIST_FILE}) +find_package_handle_standard_args(nlohmann_json CONFIG_MODE) + +if(NOT TARGET nlohmann_json::nlohmann_json) + include("${CMAKE_CURRENT_LIST_DIR}/nlohmann_jsonTargets.cmake") + if((NOT TARGET nlohmann_json) AND + (NOT nlohmann_json_FIND_VERSION OR + nlohmann_json_FIND_VERSION VERSION_LESS 3.2.0)) + add_library(nlohmann_json INTERFACE IMPORTED) + set_target_properties(nlohmann_json PROPERTIES + INTERFACE_LINK_LIBRARIES nlohmann_json::nlohmann_json + ) + endif() +endif() diff --git a/tools/cmake/Option.cmake b/tools/cmake/Option.cmake index b165f3575a..e35aa12748 100644 --- a/tools/cmake/Option.cmake +++ b/tools/cmake/Option.cmake @@ -1,5 +1,5 @@ ### ARGs use -D[var]=[ON/OFF] or [1/0] or [true/false](see below) -### ex: cmake -Denable_java=ON -Denable_ns3=ON ./ +### ex: cmake -Denable_ns3=ON ./ set(BIBTEX2HTML ${BIBTEX2HTML} CACHE PATH "Path to bibtex2html") @@ -23,32 +23,46 @@ option(enable_debug "Turn this off to remove all debug messages option(enable_documentation "Whether to produce documentation" off) option(enable_ns3 "Whether ns-3 model is activated." off) -option(enable_java "Whether the Java bindings are activated." off) -option(enable_msg "Whether the MSG module is activated." off) -option(enable_lib_in_jar "Whether the native libraries are bundled in a Java jar file" on) -option(minimal-bindings "Whether to compile the bindings libraries (Java/Python) with the minimal dependency set" off) -mark_as_advanced(minimal-bindings) -if(minimal-bindings) - set(enable_lib_in_jar on) +option(enable_msg "Java was removed from SimGrid v3.33. Please do not enable it here." off) +mark_as_advanced(enable_msg) +if (enable_msg) + message(FATAL_ERROR "MSG was removed from SimGrid v3.33. Please stick to v3.32 or earlier if you need Java.") +endif() + +option(enable_java "Java was removed from SimGrid v3.33. Please do not enable it here." off) +mark_as_advanced(enable_java) +if (enable_java) + message(FATAL_ERROR "Java was removed from SimGrid v3.33. Please stick to v3.32 or earlier if you need Java.") endif() -option(enable_model-checking "Turn this on to experiment with our prototype of model-checker (hinders the simulation's performance even if turned off at runtime)" off) -option(enable-model-checking "Please set 'enable_model-checking' instead" off) +option(minimal-bindings "Whether to compile the Python bindings libraries with the minimal dependency set" off) +mark_as_advanced(minimal-bindings) + +option(enable_model-checking "Turn this on to experiment with our prototype of model-checker" on) +option(enable-model-checking "Please set 'enable_model-checking' instead" on) mark_as_advanced(enable-model-checking) if(enable-model-checking) SET(enable_model-checking ON CACHE BOOL "Whether to compile the model-checker" FORCE) endif() -if(WIN32) - option(enable_smpi "Whether SMPI is included in the library." off) -else() - option(enable_smpi "Whether SMPI is included in the library." on) - # PAPI does not support windows (they did in 3.7, but not anymore in 5.x) - # See http://icl.cs.utk.edu/papi/custom/index.html?lid=62&slid=96 - option(enable_smpi_papi "Whether SMPI supports PAPI bindings." off) +option(enable_smpi "Whether SMPI is included in the library." on) +option(enable_smpi_papi "Whether SMPI supports PAPI bindings." off) + +option(enable_testsuite_smpi_MPICH3 "Whether the test suite form MPICH 3 should be built." off) +option(enable_smpi_MPICH3_testsuite "Please use 'enable_testsuite_smpi_MPICH3' instead." off) +mark_as_advanced(enable_smpi_MPICH3_testsuite) +if(enable_smpi_MPICH3_testsuite) + SET(enable_testsuite_smpi_MPICH3 ON CACHE BOOL "Whether the test suite form MPICH 3 should be built." FORCE) endif() -option(enable_smpi_MPICH3_testsuite "Whether the test suite form MPICH 3 should be built" off) -option(enable_smpi_MBI_testsuite "Whether the test suite from MBI should be built." off) + +option(enable_testsuite_smpi_MBI "Whether the test suite from MBI should be built." off) +option(enable_smpi_MBI_testsuite "Please use 'enable_testsuite_smpi_MBI' instead." off) +mark_as_advanced(enable_smpi_MBI_testsuite) +if(enable_smpi_MBI_testsuite) + SET(enable_testsuite_smpi_MBI ON CACHE BOOL "Whether the test suite from MBI should be built." FORCE) +endif() + +option(enable_testsuite_McMini "Whether the test suite from McMini should be built." off) # Internal targets used by jenkins ### diff --git a/tools/cmake/Tests.cmake b/tools/cmake/Tests.cmake index c6d4aa0a54..c5567a06ab 100644 --- a/tools/cmake/Tests.cmake +++ b/tools/cmake/Tests.cmake @@ -19,6 +19,7 @@ IF(enable_memcheck) SET(VALGRIND_WRAPPER ${VALGRIND_WRAPPER}\ --xml=yes\ --xml-file=memcheck_test_%p.memcheck\ --child-silent-after-fork=yes\ ) endif() set(TESH_OPTION ${TESH_OPTION} --setenv VALGRIND_NO_LEAK_CHECK=--leak-check=no\ --show-leak-kinds=none) + set(TESH_OPTION ${TESH_OPTION} --setenv VALGRIND_NO_TRACE_CHILDREN=--trace-children=no) # message(STATUS "tesh wrapper: ${VALGRIND_WRAPPER}") @@ -40,9 +41,6 @@ ENDIF() MACRO(ADD_TESH NAME) SET(ARGT ${ARGV}) LIST(REMOVE_AT ARGT 0) - IF(WIN32) - STRING(REPLACE "§" "\;" ARGT "${ARGT}") - ENDIF() if(VALGRIND_WRAPPER) ADD_TEST(${NAME} ${TESH_COMMAND} --wrapper "${VALGRIND_WRAPPER}" ${TESH_OPTION} ${ARGT}) else() @@ -112,18 +110,9 @@ MACRO(SET_TESH_PROPERTIES NAME FACTORIES) ENDFOREACH() ENDMACRO() -IF(enable_java) - IF(WIN32) - SET(TESH_CLASSPATH_SEPARATOR "§") - ELSE() - SET(TESH_CLASSPATH_SEPARATOR ":") - ENDIF() - SET(TESH_CLASSPATH "${CMAKE_BINARY_DIR}/examples/deprecated/java/${TESH_CLASSPATH_SEPARATOR}${CMAKE_BINARY_DIR}/teshsuite/java/${TESH_CLASSPATH_SEPARATOR}${SIMGRID_JAR}") -ENDIF() - # New tests should use the Catch Framework set(UNIT_TESTS src/xbt/unit-tests_main.cpp - src/kernel/resource/NetworkModelIntf_test.cpp + src/kernel/resource/NetworkModelFactors_test.cpp src/kernel/resource/SplitDuplexLinkImpl_test.cpp src/kernel/resource/profile/Profile_test.cpp src/kernel/routing/DijkstraZone_test.cpp @@ -138,11 +127,23 @@ set(UNIT_TESTS src/xbt/unit-tests_main.cpp src/xbt/dynar_test.cpp src/xbt/random_test.cpp src/xbt/xbt_str_test.cpp + src/xbt/utils/iter/subsets_tests.cpp src/kernel/lmm/maxmin_test.cpp) + +set(MC_UNIT_TESTS src/mc/explo/odpor/ClockVector_test.cpp + src/mc/explo/odpor/Execution_test.cpp + src/mc/explo/odpor/WakeupTree_test.cpp + + src/mc/explo/udpor/Unfolding_test.cpp + src/mc/explo/udpor/UnfoldingEvent_test.cpp + src/mc/explo/udpor/EventSet_test.cpp + src/mc/explo/udpor/ExtensionSet_test.cpp + src/mc/explo/udpor/History_test.cpp + src/mc/explo/udpor/Configuration_test.cpp) if (SIMGRID_HAVE_MC) - set(UNIT_TESTS ${UNIT_TESTS} src/mc/sosp/Snapshot_test.cpp src/mc/sosp/PageStore_test.cpp) + set(UNIT_TESTS ${UNIT_TESTS} ${MC_UNIT_TESTS}) else() - set(EXTRA_DIST ${EXTRA_DIST} src/mc/sosp/Snapshot_test.cpp src/mc/sosp/PageStore_test.cpp) + set(EXTRA_DIST ${EXTRA_DIST} ${MC_UNIT_TESTS}) endif() if (SIMGRID_HAVE_EIGEN3) set(UNIT_TESTS ${UNIT_TESTS} src/kernel/lmm/bmf_test.cpp) diff --git a/tools/cmake/cross-mingw.cmake b/tools/cmake/cross-mingw.cmake deleted file mode 100644 index b82b5c52aa..0000000000 --- a/tools/cmake/cross-mingw.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# cmake -DCMAKE_TOOLCHAIN_FILE=tools/cmake/cross-mingw.cmake .. - -set (CMAKE_SYSTEM_NAME Windows) -set (CMAKE_SYSTEM_PROCESSOR x86_64) - -set (CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc-win32) -set (CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++-win32) -set (CMAKE_Fortran_COMPILER /usr/bin/x86_64-w64-mingw32-gfortran-win32) - -set (CMAKE_FIND_ROOT_PATH /usr/lib/gcc/x86_64-w64-mingw32/ /usr/i686-w64-mingw32/) - -set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/tools/cmake/scripts/fixup_simgrid_dtd_l.pl b/tools/cmake/scripts/fixup_simgrid_dtd_l.pl index 67f66de210..7a2d251526 100755 --- a/tools/cmake/scripts/fixup_simgrid_dtd_l.pl +++ b/tools/cmake/scripts/fixup_simgrid_dtd_l.pl @@ -10,12 +10,12 @@ while (<>) { # Accept the alternative DTD location if (/DOCTYPE.*simgrid.org.simgrid.dtd/) { - print ' "" SET(ROOT_surfxml_platform);'."\n"; + print ' "" SET(ROOT_simgrid_parse_platform);'."\n"; } # Completely rewrite the error handling mechanism to use exceptions instead of printing to stderr if (/fprintf.stderr, .*? flexml_err_msg.;/) { - print(' surf_parse_error(flexml_err_msg);'."\n"); + print(' simgrid_parse_error(flexml_err_msg);'."\n"); next; } diff --git a/tools/cmake/scripts/my_valgrind.pl b/tools/cmake/scripts/my_valgrind.pl index be6180b147..d2ec57b312 100755 --- a/tools/cmake/scripts/my_valgrind.pl +++ b/tools/cmake/scripts/my_valgrind.pl @@ -1,6 +1,6 @@ #!/usr/bin/env perl -# Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -8,6 +8,7 @@ use strict; use warnings; +# Many other parameters (such as trace-children) are set in Tests.cmake my @argv = ("valgrind", "--quiet"); my $count = 0; diff --git a/tools/cmake/scripts/update_tesh.pl b/tools/cmake/scripts/update_tesh.pl index 6d6b5191ee..26d9ab358b 100755 --- a/tools/cmake/scripts/update_tesh.pl +++ b/tools/cmake/scripts/update_tesh.pl @@ -1,6 +1,6 @@ #!/usr/bin/env perl -# Copyright (c) 2012-2022. The SimGrid Team. +# Copyright (c) 2012-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/tools/cmake/test_prog/prog_asan.cpp b/tools/cmake/test_prog/prog_asan.cpp index b2a165f76a..82f02d1d8f 100644 --- a/tools/cmake/test_prog/prog_asan.cpp +++ b/tools/cmake/test_prog/prog_asan.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2022. The SimGrid Team. +/* Copyright (c) 2017-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/tools/cmake/test_prog/prog_makecontext.c b/tools/cmake/test_prog/prog_makecontext.c index 40bdb59b8a..7637bab1fc 100644 --- a/tools/cmake/test_prog/prog_makecontext.c +++ b/tools/cmake/test_prog/prog_makecontext.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/tools/cmake/test_prog/prog_ns3.cpp b/tools/cmake/test_prog/prog_ns3.cpp new file mode 100644 index 0000000000..c763cbdcf4 --- /dev/null +++ b/tools/cmake/test_prog/prog_ns3.cpp @@ -0,0 +1,7 @@ +#include "ns3/simulator.h" + +int main() +{ + ns3::Simulator::GetNextEventTime(); + return 0; +} \ No newline at end of file diff --git a/tools/cmake/test_prog/prog_stackgrowth.c b/tools/cmake/test_prog/prog_stackgrowth.c index dd1bc02a81..62dcaa4377 100644 --- a/tools/cmake/test_prog/prog_stackgrowth.c +++ b/tools/cmake/test_prog/prog_stackgrowth.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. +/* Copyright (c) 2010-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/tools/cmake/test_prog/prog_stacksetup.c b/tools/cmake/test_prog/prog_stacksetup.c index 654c7b89d5..b5aeacc6cd 100644 --- a/tools/cmake/test_prog/prog_stacksetup.c +++ b/tools/cmake/test_prog/prog_stacksetup.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ diff --git a/tools/cmake/test_prog/prog_tsan.cpp b/tools/cmake/test_prog/prog_tsan.cpp index 66431db6e0..f076267cbd 100644 --- a/tools/cmake/test_prog/prog_tsan.cpp +++ b/tools/cmake/test_prog/prog_tsan.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2020-2022. The SimGrid Team. +/* Copyright (c) 2020-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/tools/docker/Dockerfile.build-deps b/tools/docker/Dockerfile.build-deps index 0979cc7f02..7eb4d254df 100644 --- a/tools/docker/Dockerfile.build-deps +++ b/tools/docker/Dockerfile.build-deps @@ -1,5 +1,5 @@ -# Base image -FROM debian:testing +# Base image: bookworm is Debian 12 +FROM debian:bookworm # Install the dependencies: # - of the website @@ -8,7 +8,7 @@ RUN apt-get --allow-releaseinfo-change update && \ apt install -y \ bibclean emacs-nox org-mode elpa-ess elpa-htmlize wget unzip r-cran-ggplot2 r-cran-tidyr r-cran-dplyr libtext-bibtex-perl && \ apt install -y \ - g++ gcc gfortran default-jdk pybind11-dev \ + g++ gcc gfortran pybind11-dev \ git \ valgrind \ libboost-dev libboost-all-dev \ @@ -17,7 +17,8 @@ RUN apt-get --allow-releaseinfo-change update && \ python3-pip \ doxygen fig2dev \ chrpath \ - libdw-dev libevent-dev libunwind8-dev \ - python3-sphinx python3-breathe python3-sphinx-rtd-theme + libevent-dev \ + python3-sphinx python3-breathe python3-sphinx-rtd-theme && \ + apt clean && apt autoclean # linkchecker \ diff --git a/tools/docker/Dockerfile.stable b/tools/docker/Dockerfile.stable index 1f2d1c4f53..011ae00c03 100644 --- a/tools/docker/Dockerfile.stable +++ b/tools/docker/Dockerfile.stable @@ -17,6 +17,6 @@ RUN echo "DOWNLOAD_URL: ${DLURL}" && \ make -j4 && \ mkdir debian/ && touch debian/control && dpkg-shlibdeps --ignore-missing-info lib/*.so -llib/ -O/tmp/deps && \ make install && make clean && \ - apt remove -y g++ gcc git valgrind default-jdk gfortran libboost-dev libboost-all-dev libeigen3-dev cmake dpkg-dev wget python3-dev pybind11-dev && \ + apt remove -y git valgrind libeigen3-dev cmake dpkg-dev wget python3-dev pybind11-dev && \ apt install `sed -e 's/shlibs:Depends=//' -e 's/([^)]*)//g' -e 's/,//g' /tmp/deps` && \ apt autoremove -y && apt autoclean && apt clean diff --git a/tools/docker/Dockerfile.tuto-mc b/tools/docker/Dockerfile.tuto-mc index b1f64bb7b4..f13861dbd7 100644 --- a/tools/docker/Dockerfile.tuto-mc +++ b/tools/docker/Dockerfile.tuto-mc @@ -13,15 +13,15 @@ RUN apt update && apt -y upgrade # - Get the tutorial files (with an empty makefile advising to run cmake before make, just in case) # - Remove everything that was installed, and re-install what's needed by the SimGrid libraries before the Gran Final Cleanup # - Keep g++ gcc gfortran as any MC user will use (some of) them -RUN apt install -y g++ gcc git valgrind gfortran libboost-dev libeigen3-dev libboost-stacktrace-dev cmake dpkg-dev libunwind-dev libdw-dev libelf-dev libevent-dev python3-dev && \ +RUN apt install -y g++ gcc git valgrind gfortran libboost-dev libeigen3-dev libboost-stacktrace-dev cmake dpkg-dev libdw-dev libelf-dev libevent-dev python3-dev && \ mkdir /source/ && cd /source && git clone --depth=1 https://framagit.org/simgrid/simgrid.git simgrid.git && \ cd simgrid.git && \ - cmake -DCMAKE_INSTALL_PREFIX=/usr/ -Denable_model-checking=ON -Denable_documentation=OFF -Denable_java=OFF -Denable_smpi=ON -Denable_compile_optimizations=ON . && \ + cmake -DCMAKE_INSTALL_PREFIX=/usr/ -Denable_model-checking=ON -Denable_documentation=OFF -Denable_smpi=ON -Denable_compile_optimizations=ON . && \ make -j6 install && \ git clone --depth=1 https://framagit.org/simgrid/tutorial-model-checking /source/tuto-mc.git && \ printf "ndet-receive-s4u:\n\t@echo \"Please run the following command before make:\";echo \" cmake .\"; exit 1" > /source/tuto-mc.git/Makefile &&\ mkdir debian/ && touch debian/control && dpkg-shlibdeps --ignore-missing-info lib/*.so -llib/ -O/tmp/deps && \ - apt remove -y dpkg-dev libunwind-dev libdw-dev libelf-dev libevent-dev && \ + apt remove -y dpkg-dev libdw-dev libelf-dev libevent-dev && \ apt install -y `sed -e 's/shlibs:Depends=//' -e 's/([^)]*)//g' -e 's/,//g' /tmp/deps` && rm /tmp/deps && \ apt autoremove -y && apt autoclean && apt clean diff --git a/tools/docker/Dockerfile.unstable b/tools/docker/Dockerfile.unstable index 2198d180d2..c3bf640660 100644 --- a/tools/docker/Dockerfile.unstable +++ b/tools/docker/Dockerfile.unstable @@ -12,6 +12,6 @@ RUN apt-get --allow-releaseinfo-change update && apt -y upgrade && \ make -j4 install && \ mkdir debian/ && touch debian/control && dpkg-shlibdeps --ignore-missing-info lib/*.so -llib/ -O/tmp/deps && \ git reset --hard master && git clean -dfx && \ - apt remove -y g++ gcc git valgrind default-jdk gfortran libboost-dev libboost-all-dev libeigen3-dev cmake dpkg-dev python3-dev pybind11-dev && \ + apt remove -y git valgrind libeigen3-dev cmake dpkg-dev wget python3-dev pybind11-dev && \ apt install `sed -e 's/shlibs:Depends=//' -e 's/([^)]*)//g' -e 's/,//g' /tmp/deps` && \ apt autoremove -y && apt autoclean && apt clean diff --git a/tools/fix-paje-trace.sh b/tools/fix-paje-trace.sh index cc3f5cca77..c6603dcf0e 100755 --- a/tools/fix-paje-trace.sh +++ b/tools/fix-paje-trace.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2010-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. diff --git a/tools/generate-dwarf-functions b/tools/generate-dwarf-functions deleted file mode 100755 index 838d833f62..0000000000 --- a/tools/generate-dwarf-functions +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env sh -# Generate files from a given dwarf.h -# Usage: tools/generate-dwarf-functions /usr/include/dwarf.h - -HEADER="\ -/* Copyright (c) 2014-$(date +%Y). The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -/* Warning: autogenerated, do not edit! */ - -#include \"src/mc/inspect/mc_dwarf.hpp\" - -#include -#include " - -cat - > src/mc/inspect/mc_dwarf_tagnames.cpp < tagname_map = { - {0x00, "DW_TAG_invalid"}, -$(sed -n 's/.*\(DW_TAG_[^ ]*\) = \(0x[0-9a-f]*\).*/ {\2, "\1"},/p' -- "$1") -}; -} - -namespace simgrid::dwarf { - -/** @brief Get the name of a dwarf tag (DW_TAG_*) from its code - * - * @param tag tag code (see the DWARF specification) - * @return name of the tag - */ -XBT_PRIVATE -const char* tagname(int tag) -{ - auto name = tagname_map.find(tag); - return name == tagname_map.end() ? "DW_TAG_unknown" : name->second; -} - -} // namespace simgrid::dwarf -EOF - -cat - > src/mc/inspect/mc_dwarf_attrnames.cpp << EOF -$HEADER - -namespace { -const std::unordered_map attrname_map = { -$(sed -n 's/.*\(DW_AT_[^ ]*\) = \(0x[0-9a-f]*\).*/ {\2, "\1"},/p' -- "$1") -}; -} - -namespace simgrid::dwarf { - -/** @brief Get the name of an attribute (DW_AT_*) from its code - * - * @param attr attribute code (see the DWARF specification) - * @return name of the attribute - */ -XBT_PRIVATE -const char* attrname(int attr) -{ - auto name = attrname_map.find(attr); - return name == attrname_map.end() ? "DW_AT_unknown" : name->second; -} - -} // namespace simgrid::dwarf -EOF diff --git a/tools/git-hooks/clang-format.pre-commit b/tools/git-hooks/clang-format.pre-commit index e3e077f36c..ebb259a833 100755 --- a/tools/git-hooks/clang-format.pre-commit +++ b/tools/git-hooks/clang-format.pre-commit @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) 2015, David Martin. All rights reserved. -# Copyright (c) 2017-2022. The SimGrid team. All rights reserved. +# Copyright (c) 2017-2023. The SimGrid team. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: diff --git a/tools/graphicator/graphicator.cpp b/tools/graphicator/graphicator.cpp index bc9a50a535..368892bd08 100644 --- a/tools/graphicator/graphicator.cpp +++ b/tools/graphicator/graphicator.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2022. The SimGrid Team. +/* Copyright (c) 2008-2023. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ int main(int argc, char** argv) simgrid::instr::platform_graph_export_graphviz(outputfile); } else { - xbt_assert(false, "Unknown output file format, please use '.dot' or .csv' extension\n"); + xbt_die("Unknown output file format, please use '.dot' or .csv' extension"); } return 0; } diff --git a/tools/internal/check_dist_archive b/tools/internal/check_dist_archive index 002b11bc3f..097032623d 100755 --- a/tools/internal/check_dist_archive +++ b/tools/internal/check_dist_archive @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2013-2022. The SimGrid Team. +# Copyright (c) 2013-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/tools/internal/check_dist_archive.exclude b/tools/internal/check_dist_archive.exclude index e2796f303e..0bf5d2782b 100644 --- a/tools/internal/check_dist_archive.exclude +++ b/tools/internal/check_dist_archive.exclude @@ -11,15 +11,10 @@ + BuildSimGrid\.sh + COPYRIGHT\.template -+ README\.coding -+ \.appveyor\.yml + \.circleci/.* + \.clang-format -+ \.classpath + \.editorconfig + \.gitlab-ci\.yml -+ \.lgtm\.yml -+ \.project + \.readthedocs.yml + sonar-project\.properties @@ -29,11 +24,12 @@ + docs/default.nix + docs/source/tuto_network_calibration/network_calibration_tutorial.ipynb ++ docs/source/tuto_network_calibration/clustering_ckmeans.ipynb ++ docs/source/tuto_network_calibration/clustering_dhist.ipynb -+ tools/appveyor-irc-notify\.py + tools/docker/.* + tools/git-hooks/.* + tools/internal/.* + tools/jenkins/.* -+ src/simix/simix_network\.tla ++ doc/simix_network\.tla diff --git a/tools/internal/indent b/tools/internal/indent index 8cbe42e713..929578be15 100755 --- a/tools/internal/indent +++ b/tools/internal/indent @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2011-2022. The SimGrid Team. +# Copyright (c) 2011-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/tools/internal/spell_comments.pl b/tools/internal/spell_comments.pl index f2704f4fbc..d53cf9a773 100755 --- a/tools/internal/spell_comments.pl +++ b/tools/internal/spell_comments.pl @@ -1,6 +1,6 @@ #!/usr/bin/env perl -# Copyright (c) 2013-2022. The SimGrid Team. +# Copyright (c) 2013-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/tools/internal/spell_dict.txt b/tools/internal/spell_dict.txt index abbf35a471..86b7ac16a1 100644 --- a/tools/internal/spell_dict.txt +++ b/tools/internal/spell_dict.txt @@ -38,9 +38,6 @@ https inlining ingroup int -java -Java -JNI kcachegrind KILLME lat @@ -65,7 +62,6 @@ ModelChecker modelchecker MPI MPICH -msg mutex NetZone nullptr diff --git a/tools/internal/update_copyright_header b/tools/internal/update_copyright_header index b8525fc9e8..7f0f378935 100755 --- a/tools/internal/update_copyright_header +++ b/tools/internal/update_copyright_header @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2014-2022. The SimGrid Team. +# Copyright (c) 2014-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/tools/jenkins/Coverage.sh b/tools/jenkins/Coverage.sh index 91c891575d..39fde22018 100755 --- a/tools/jenkins/Coverage.sh +++ b/tools/jenkins/Coverage.sh @@ -10,12 +10,9 @@ die() { echo "XXXX Cleanup previous attempts. Remaining content of /tmp:" rm -f /tmp/cc* +rm -f /tmp/simgrid-mc-* rm -f /tmp/*.so rm -f /tmp/*.so.* -rm -rf /tmp/simgrid-java* -rm -rf /var/tmp/simgrid-java* -rm -rf /tmp/jvm-* -find "$WORKSPACE" -name "hs_err_pid*.log" -exec rm -f {} + ls /tmp df -h echo "XXXX Let's go" @@ -59,8 +56,6 @@ NUMPROC="$(nproc)" || NUMPROC=1 cd "$BUILDFOLDER" -rm -rf java_cov* -rm -rf jacoco_cov* rm -rf python_cov* rm -rf xml_coverage.xml @@ -70,54 +65,38 @@ cmake -Denable_documentation=OFF \ -Denable_compile_optimizations=OFF -Denable_compile_warnings=ON \ -Denable_mallocators=ON \ -Denable_ns3=ON \ - -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=ON -Denable_model-checking=ON \ + -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=ON -Denable_model-checking=ON \ -Denable_smpi_papi=ON \ - -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_smpi_MBI_testsuite=ON \ + -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_testsuite_smpi_MBI=ON -Denable_testsuite_McMini=ON \ -Denable_coverage=ON -DLTO_EXTRA_FLAG="auto" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON "$WORKSPACE" #build with sonarqube scanner wrapper /home/ci/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-outputs make -j$NUMPROC tests -JACOCO_PATH="/usr/local/share/jacoco" -export JAVA_TOOL_OPTIONS="-javaagent:${JACOCO_PATH}/lib/jacocoagent.jar" export PYTHON_TOOL_OPTIONS="/usr/bin/python3-coverage run --parallel-mode --branch" ctest --no-compress-output -D ExperimentalTest -j$NUMPROC || true ctest -D ExperimentalCoverage || true -unset JAVA_TOOL_OPTIONS if [ -f Testing/TAG ] ; then - files=$( find . -size +1c -name "jacoco.exec" ) - i=0 - for file in $files - do - sourcepath=$( dirname "$file" ) - #convert jacoco reports in xml ones - ant -f "$WORKSPACE"/tools/jenkins/jacoco.xml -Dexamplesrcdir="$WORKSPACE" -Dbuilddir="$BUILDFOLDER"/"${sourcepath}" -Djarfile="$BUILDFOLDER"/simgrid.jar -Djacocodir=${JACOCO_PATH}/lib - #convert jacoco xml reports in cobertura xml reports - cover2cover.py "$BUILDFOLDER"/"${sourcepath}"/report.xml .. ../src/bindings/java src/bindings/java > "$BUILDFOLDER"/java_coverage_${i}.xml - #save jacoco xml report as sonar only allows it - mv "$BUILDFOLDER"/"${sourcepath}"/report.xml "$BUILDFOLDER"/jacoco_cov_${i}.xml - i=$((i + 1)) - done - #convert python coverage reports in xml ones cd "$BUILDFOLDER" find .. -size +1c -name ".coverage*" -exec mv {} . \; /usr/bin/python3-coverage combine /usr/bin/python3-coverage xml -i -o ./python_coverage.xml - cd "$WORKSPACE" #convert all gcov reports to xml cobertura reports - gcovr -r . --xml-pretty -e teshsuite -e build/MBI -e examples/smpi/NAS -e examples/smpi/mc -u -o "$BUILDFOLDER"/xml_coverage.xml + gcovr -r "$WORKSPACE" --xml-pretty -e "$WORKSPACE"/teshsuite -e MBI -e "$WORKSPACE"/examples/smpi/NAS -e "$WORKSPACE"/examples/smpi/mc -u -o xml_coverage.xml --gcov-ignore-parse-errors all --gcov-ignore-errors all + + cd "$WORKSPACE" xsltproc "$WORKSPACE"/tools/jenkins/ctest2junit.xsl build/Testing/"$( head -n 1 < build/Testing/TAG )"/Test.xml > CTestResults_memcheck.xml #generate sloccount report sloccount --duplicates --wide --details "$WORKSPACE" | grep -v -e '.git' -e 'mpich3-test' -e 'sloccount.sc' -e 'build/' -e 'xml_coverage.xml' -e 'CTestResults_memcheck.xml' -e 'DynamicAnalysis.xml' > "$WORKSPACE"/sloccount.sc #generate PVS-studio report - EXCLUDEDPATH="-e $WORKSPACE/src/include/catch.hpp -e $WORKSPACE/src/include/xxhash.hpp -e $WORKSPACE/teshsuite/smpi/mpich3-test/ -e *_dtd.c -e *_dtd.h -e *.yy.c -e *.tab.cacc -e *.tab.hacc -e $WORKSPACE/src/smpi/colls/ -e $WORKSPACE/examples/smpi/NAS/ -e $WORKSPACE/examples/smpi/gemm/gemm.c -e $WORKSPACE/src/msg/ -e $WORKSPACE/include/msg/ -e $WORKSPACE/examples/deprecated/ -e $WORKSPACE/teshsuite/msg/" + EXCLUDEDPATH="-e $WORKSPACE/src/3rd-party/catch.hpp -e $WORKSPACE/teshsuite/smpi/mpich3-test/ -e *_dtd.c -e *_dtd.h -e *.yy.c -e *.tab.cacc -e *.tab.hacc -e $WORKSPACE/src/smpi/colls/ -e $WORKSPACE/examples/smpi/NAS/ -e $WORKSPACE/examples/smpi/gemm/gemm.cq" pvs-studio-analyzer analyze -f "$BUILDFOLDER"/compile_commands.json -o "$WORKSPACE"/pvs.log $EXCLUDEDPATH -j$NUMPROC # Disable: # V521 Such expressions using the ',' operator are dangerous. (-> commas in catch.hpp), diff --git a/tools/jenkins/DynamicAnalysis.sh b/tools/jenkins/DynamicAnalysis.sh index 55d2ad02f8..2f7d99fe5e 100755 --- a/tools/jenkins/DynamicAnalysis.sh +++ b/tools/jenkins/DynamicAnalysis.sh @@ -10,12 +10,9 @@ die() { echo "XXXX Cleanup previous attempts. Remaining content of /tmp:" rm -f /tmp/cc* +rm -f /tmp/simgrid-mc-* rm -f /tmp/*.so rm -f /tmp/*.so.* -rm -rf /tmp/simgrid-java* -rm -rf /var/tmp/simgrid-java* -rm -rf /tmp/jvm-* -find "$WORKSPACE" -name "hs_err_pid*.log" -exec rm -f {} + ls /tmp df -h echo "XXXX Let's go" @@ -64,7 +61,7 @@ ctest -D ExperimentalStart || true cmake -Denable_documentation=OFF -Denable_python=OFF \ -Denable_compile_optimizations=OFF -Denable_compile_warnings=ON \ -Denable_mallocators=OFF \ - -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=OFF -Denable_model-checking=OFF \ + -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=OFF -Denable_testsuite_McMini=OFF -Denable_model-checking=OFF \ -Denable_ns3=ON \ -Denable_memcheck_xml=ON -DLTO_EXTRA_FLAG="auto" "$WORKSPACE" diff --git a/tools/jenkins/Flags.sh b/tools/jenkins/Flags.sh index 2c49b12377..1fe6b380c3 100755 --- a/tools/jenkins/Flags.sh +++ b/tools/jenkins/Flags.sh @@ -18,7 +18,7 @@ onoff() { fi } -[ $# -eq 5 ] || die "Needs 5 arguments : JAVA MC SMPI DEBUG MSG" +[ $# -eq 3 ] || die "Needs 3 arguments : MC SMPI DEBUG" ### Cleanup previous runs @@ -44,55 +44,62 @@ cd "$WORKSPACE"/build #we can't just receive ON or OFF as values as display is bad in the resulting jenkins matrix -if [ "$1" = "JAVA" ] -then - buildjava="ON" -else - buildjava="OFF" -fi - -if [ "$2" = "MC" ] +if [ "$1" = "MC" ] then buildmc="ON" else buildmc="OFF" fi -if [ "$3" = "SMPI" ] +if [ "$2" = "SMPI" ] then buildsmpi="ON" else buildsmpi="OFF" fi -if [ "$4" = "DEBUG" ] +if [ "$3" = "DEBUG" ] then builddebug="ON" else builddebug="OFF" fi -if [ "$5" = "MSG" ] -then - buildmsg="ON" +echo "Step ${STEP}/${NSTEPS} - Building with debug=${builddebug}, SMPI=${buildsmpi}, MC=${buildmc}" + +if [ "${builddebug}/${buildsmpi}/${buildmc}" = "ON/ON/ON" ]; then + # ${buildmc}=ON because "why not", and especially because it doesn't + # compile with -D_GLIBCXX_DEBUG and -Denable_ns3=ON together + export CXXFLAGS=-D_GLIBCXX_DEBUG + runtests="ON" else - buildmsg="OFF" + runtests="OFF" fi -if [ $buildmsg = "OFF" ] && [ $buildjava = "ON" ] -then - echo "Don't even try to build Java without MSG" - exit 0 +GENERATOR="Unix Makefiles" +BUILDER=make +VERBOSE_BUILD="VERBOSE=1" +if which ninja 2>/dev/null >/dev/null ; then + GENERATOR=Ninja + BUILDER=ninja + VERBOSE_BUILD="-v" fi -echo "Step ${STEP}/${NSTEPS} - Building with java=${buildjava}, debug=${builddebug}, SMPI=${buildsmpi}, MC=${buildmc}, MSG=${buildmsg}" -cmake -Denable_documentation=OFF -Denable_java=${buildjava} -Denable_msg=${buildmsg} \ - -Denable_compile_optimizations=OFF -Denable_compile_warnings=ON \ +cmake -G"$GENERATOR" -Denable_documentation=OFF \ + -Denable_compile_optimizations=${runtests} -Denable_compile_warnings=ON \ -Denable_mallocators=ON -Denable_debug=${builddebug} \ - -Denable_smpi=${buildsmpi} -Denable_smpi_MPICH3_testsuite=${buildsmpi} -Denable_model-checking=${buildmc} \ - -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_smpi_MBI_testsuite=OFF \ - -Denable_ns3=$(onoff test "$buildmc" != "ON") -DNS3_HINT=/builds/ns-3-dev/build/ -Denable_coverage=OFF -DLTO_EXTRA_FLAG="auto" "$WORKSPACE" + -Denable_smpi=${buildsmpi} -Denable_testsuite_smpi_MPICH3=${buildsmpi} -Denable_model-checking=${buildmc} \ + -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_testsuite_smpi_MBI=OFF -Denable_testsuite_McMini=OFF \ + -Denable_ns3=$(onoff test "$buildmc" != "ON") -DNS3_HINT=/builds/ns-3-dev/build/ \ + -Denable_coverage=OFF -DLTO_EXTRA_FLAG="auto" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + "$WORKSPACE" + +${BUILDER} -j$NUMPROC tests ${VERBOSE_BUILD} + +if [ "$runtests" = "ON" ]; then + # exclude tests known to fail with _GLIBCXX_DEBUG + ctest -j$NUMPROC -E '^[ps]thread-|mc-bugged1-liveness' --output-on-failure +fi -make -j$NUMPROC tests cd .. rm -rf build diff --git a/tools/jenkins/Sanitizers.sh b/tools/jenkins/Sanitizers.sh index bcbe8540d2..ef5ae0e4c0 100755 --- a/tools/jenkins/Sanitizers.sh +++ b/tools/jenkins/Sanitizers.sh @@ -74,13 +74,14 @@ cd "$WORKSPACE"/build ctest -D ExperimentalStart || true -cmake -Denable_documentation=OFF -Denable_java=OFF \ +cmake -Denable_documentation=OFF \ -Denable_compile_optimizations=ON -Denable_compile_warnings=ON \ -Denable_mallocators=OFF \ - -Denable_smpi=ON -Denable_smpi_MPICH3_testsuite=ON -Denable_model-checking=OFF \ + -Denable_smpi=ON -Denable_testsuite_smpi_MPICH3=ON -Denable_model-checking=OFF \ -Denable_ns3=ON \ - -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_smpi_MBI_testsuite=OFF -Denable_coverage=OFF\ - -Denable_fortran=OFF -Denable_python=OFF -DLTO_EXTRA_FLAG="auto" ${SANITIZER_OPTIONS} "$WORKSPACE" + -Denable_memcheck=OFF -Denable_memcheck_xml=OFF -Denable_testsuite_smpi_MBI=OFF -Denable_testsuite_McMini=OFF -Denable_coverage=OFF\ + -Denable_fortran=OFF -Denable_python=OFF -DLTO_EXTRA_FLAG="auto" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache\ + ${SANITIZER_OPTIONS} "$WORKSPACE" make -j$NUMPROC tests ctest --no-compress-output -D ExperimentalTest || true diff --git a/tools/jenkins/build.sh b/tools/jenkins/build.sh index 6ad94b0fa7..0438427009 100755 --- a/tools/jenkins/build.sh +++ b/tools/jenkins/build.sh @@ -2,6 +2,13 @@ # This script is used by various build projects on Jenkins +case "$JENKINS_HOME" in +*-qualif) + echo "Build skipped on $JENKINS_HOME." + exit 0 + ;; +esac + # See https://ci.inria.fr/simgrid/job/SimGrid/configure # See https://ci.inria.fr/simgrid/job/Simgrid-Windows/configure @@ -10,24 +17,15 @@ export LC_ALL=C echo "XXXX Cleanup previous attempts. Remaining content of /tmp:" rm -f /tmp/cc* +rm -f /tmp/simgrid-mc-* rm -f /tmp/*.so rm -f /tmp/*.so.* -rm -rf /tmp/simgrid-java* -rm -rf /var/tmp/simgrid-java* -rm -rf /tmp/jvm-* -find $WORKSPACE -name "hs_err_pid*.log" -exec rm -f {} + ls /tmp df -h echo "XXXX Let's go" set -e -# Help older cmakes -if [ -e /usr/lib/jvm/java-7-openjdk-amd64 ] ; -then - export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64 -fi - # usage: die status message... die () { status=${1:-1} @@ -131,6 +129,13 @@ echo "Branch built is $branch_name" NUMBER_OF_PROCESSORS="$(nproc)" || NUMBER_OF_PROCESSORS=1 GENERATOR="Unix Makefiles" +BUILDER=make +VERBOSE_BUILD="VERBOSE=1" +if which ninja 2>/dev/null >/dev/null ; then + GENERATOR=Ninja + BUILDER=ninja + VERBOSE_BUILD="-v" +fi ulimit -c 0 || true @@ -151,11 +156,6 @@ if [ "$os" = "Debian" ] ; then have_NS3="yes" fi fi -MAY_HINT_AT_NS3="" -if [ $NODE_NAME = "ubuntu-lts" ] ; then - MAY_HINT_AT_NS3="-DNS3_HINT=/builds/ns-3-dev/build/" - have_NS3="yes" -fi if [ "$os" = "nixos" ] ; then have_NS3="yes" fi @@ -176,7 +176,7 @@ echo "XX pwd: $(pwd)" echo "XX" cmake -G"$GENERATOR" -Denable_documentation=OFF "$WORKSPACE" -make dist -j $NUMBER_OF_PROCESSORS +${BUILDER} dist -j $NUMBER_OF_PROCESSORS SIMGRID_VERSION=$(cat VERSION) echo "XX" @@ -194,14 +194,6 @@ echo "XX pwd: $(pwd)" echo "XX" set -x -if cmake --version | grep -q 3\.11 ; then - # -DCMAKE_DISABLE_SOURCE_CHANGES=ON is broken with java on CMake 3.11 - # https://gitlab.kitware.com/cmake/cmake/issues/17933 - MAY_DISABLE_SOURCE_CHANGE="" -else - MAY_DISABLE_SOURCE_CHANGE="-DCMAKE_DISABLE_SOURCE_CHANGES=ON" -fi - if [ "$os" = "CentOS" ]; then if [ "$(ld -v | cut -d\ -f4 | cut -c1-4)" = "2.30" ]; then echo "Temporary disable LTO, believed to be broken on this system." @@ -219,22 +211,20 @@ fi cmake -G"$GENERATOR" ${INSTALL:+-DCMAKE_INSTALL_PREFIX=$INSTALL} \ -Denable_debug=ON -Denable_documentation=OFF -Denable_coverage=OFF \ -Denable_model-checking=$(onoff test "$build_mode" = "ModelChecker") \ - -Denable_smpi_MBI_testsuite=OFF \ + -Denable_testsuite_smpi_MBI=OFF -Denable_testsuite_McMini=ON \ -Denable_compile_optimizations=$(onoff test "$build_mode" != "DynamicAnalysis") \ - -Denable_smpi_MPICH3_testsuite=$(onoff test "$build_mode" = "Debug") \ + -Denable_testsuite_smpi_MPICH3=$(onoff test "$build_mode" = "Debug") \ -Denable_mallocators=$(onoff test "$build_mode" != "DynamicAnalysis") \ -Denable_memcheck=$(onoff test "$build_mode" = "DynamicAnalysis") \ -Denable_compile_warnings=$(onoff test "$GENERATOR" != "MSYS Makefiles") -Denable_smpi=ON \ -Denable_ns3=$(onoff test "$have_NS3" = "yes" -a "$build_mode" = "Debug") \ -DSIMGRID_PYTHON_LIBDIR=${SIMGRID_PYTHON_LIBDIR} \ - ${MAY_DISABLE_SOURCE_CHANGE} ${MAY_DISABLE_LTO} ${MAY_HINT_AT_NS3} \ - -Denable_java=$(onoff test "$build_mode" = "ModelChecker") \ - -Denable_msg=$(onoff test "$build_mode" = "ModelChecker") \ + -DCMAKE_DISABLE_SOURCE_CHANGES=ON ${MAY_DISABLE_LTO} \ -DLTO_EXTRA_FLAG="auto" \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ "$SRCFOLDER" -set +x -make -j $NUMBER_OF_PROCESSORS VERBOSE=1 tests +${BUILDER} -j $NUMBER_OF_PROCESSORS ${VERBOSE_BUILD} tests echo "XX" echo "XX Run the tests" @@ -250,7 +240,7 @@ if test -n "$INSTALL" && [ "${branch_name}" = "origin/master" ] ; then rm -rf "$INSTALL" - make install + ${BUILDER} install fi echo "XX" diff --git a/tools/jenkins/ci-bigdft.sh b/tools/jenkins/ci-bigdft.sh index 29673a7af0..9391fa0c22 100755 --- a/tools/jenkins/ci-bigdft.sh +++ b/tools/jenkins/ci-bigdft.sh @@ -22,11 +22,17 @@ export PATH=$PWD/simgrid-dev/smpi_script/bin/:$PATH export LD_LIBRARY_PATH=$PWD/simgrid-dev/lib/:$LD_LIBRARY_PATH export JHBUILD_RUN_AS_ROOT=1 +#workaround issue with ntpoly 3.0.0 +sed -i 's|repository type="tarball" name="ntpoly" href="https://github.com/william-dawson/NTPoly/archive/"|repository type="git" name="ntpoly" href="https://github.com/william-dawson/"|' ../modulesets/hpc-upstream.modules +sed -i 's|module="ntpoly-v3.0.0.tar.gz"|module="ntpoly"|' ../modulesets/hpc-upstream.modules + ../Installer.py autogen -y ../Installer.py -f ../../tools/jenkins/gfortran-simgrid.rc -y build export OMP_NUM_THREADS=1 +#workaround issue with profiling optimization (for fugaku) which prevent f_free_ptr to use the simgrid version. Fix pending. +export FUTILE_PROFILING_DEPTH=-1 #cubic version cd ../bigdft/tests/DFT/cubic/C diff --git a/tools/jenkins/ci-starpu.sh b/tools/jenkins/ci-starpu.sh index ece7a084da..73864b4426 100755 --- a/tools/jenkins/ci-starpu.sh +++ b/tools/jenkins/ci-starpu.sh @@ -12,17 +12,17 @@ echo "XXXXXXXXXXXXXXXX Install APT dependencies" $SUDO apt-get update $SUDO apt-get -y install build-essential libboost-all-dev wget git xsltproc -for i in master 1.3 ; do +for i in master starpu-1.3 ; do echo "XXXXXXXXXXXXXXXX Build and test StarPU $i" rm -rf starpu* - wget https://files.inria.fr/starpu/simgrid/starpu-simgrid-$i.tar.gz - md5sum starpu-simgrid-$i.tar.gz - tar xf starpu-simgrid-$i.tar.gz + wget https://files.inria.fr/starpu/testing/$i/starpu-nightly-latest.tar.gz + md5sum starpu-nightly-latest.tar.gz + tar xf starpu-nightly-latest.tar.gz cd starpu-1* # NOTE: Do *not* introduce parameters to "make it work" here. # Things should "just work" with default parameters! - # Users should not have to tinker to get starpu working on top of simgrid, that is precisely why we have this CI + # Users should not have to tinker to get starpu working on top of SimGrid, that is precisely why we have this CI if [ $i = master ]; then # On master, fail if we use deprecated functions, so that StarPU people know they have to stop using them, fix it, and thus make CI happy again diff --git a/tools/jenkins/gfortran-simgrid.rc b/tools/jenkins/gfortran-simgrid.rc index 975e87d20c..e8ec004ced 100644 --- a/tools/jenkins/gfortran-simgrid.rc +++ b/tools/jenkins/gfortran-simgrid.rc @@ -6,12 +6,12 @@ def getcwd(): prefix=getcwd()+"/install" #Add the condition testing to run tests and includes PyYaml conditions.add("testing") -conditions.add("simulation") #to include simgrid compilation +conditions.add("simulation") #to include SimGrid compilation #List the module the this rcfile will build modules = ['spred',] #example of the potentialities of the python syntax in this file def env_configuration(): - return """--host=x86_64-linux-gnu 'FCFLAGS=-O2 -std=legacy -fopenmp -g -fbounds-check -fbacktrace -ffpe-trap=invalid,zero,overflow,denormal -Wall -fPIC' 'CFLAGS=-O2 -fopenmp -fPIC' 'LDFLAGS=-fopenmp -fPIC' --with-mpi3=false""" + return """--host=x86_64-linux-gnu 'FCFLAGS=-O2 -std=legacy -fopenmp -g -fbounds-check -fbacktrace -ffpe-trap=invalid,zero,overflow,denormal -Wall -fPIC' 'CFLAGS=-O2 -fopenmp -fPIC' 'LDFLAGS=-fopenmp -fPIC' 'CXXFLAGS=-Wall -O2 -g -fPIC' LIBS='-lstdc++' --with-mpi3=false""" #the following command sets the environment variable to give these settings #to all the modules diff --git a/tools/jenkins/jacoco.xml b/tools/jenkins/jacoco.xml deleted file mode 100644 index dd4ac04527..0000000000 --- a/tools/jenkins/jacoco.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/jenkins/project_description.sh b/tools/jenkins/project_description.sh index b002915e57..8af5e8d804 100755 --- a/tools/jenkins/project_description.sh +++ b/tools/jenkins/project_description.sh @@ -13,10 +13,6 @@ get_compiler(){ grep -m 1 "The C compiler identification" ./consoleText | sed "s/.*-- The C compiler identification is \([a-zA-Z0-9\.]*\)/\1/g" } -get_java(){ - grep -m 1 "Found Java:" ./consoleText | sed "s/.*-- Found Java.*found suitable version \"\([a-zA-Z0-9\.]*\)\",.*/\1/g" -} - get_cmake(){ grep -m 1 "Cmake version" ./consoleText| sed "s/.*-- Cmake version \([a-zA-Z0-9\.]*\)/\1/g" } @@ -25,8 +21,12 @@ get_eigen3(){ sed -n 's/.* Eigen3 library \.\+: \([^ ]*\) in .*/\1/p;T;q' ./consoleText } +get_json(){ + sed -n 's/.* JSON library \.\+: \([^ ]*\) in .*/\1/p;T;q' ./consoleText +} + get_ns3(){ - sed -n 's/.*-- ns-3 found (v\(3[-.0-9a-z]\+\); minor:.*/\1/p;T;q' ./consoleText + sed -n 's/.*-- ns-3 found (v\(3[-.0-9a-z]\+\).*/\1/p;T;q' ./consoleText } get_python(){ @@ -135,9 +135,9 @@ function sortTable(n, type) { MC Compiler Boost - Java Cmake Eigen3 + JSON ns-3 Python @@ -162,9 +162,9 @@ do fi boost=$(get_boost) compiler=$(get_compiler) - java=$(get_java) cmake=$(get_cmake) eigen3=$(get_eigen3) + json=$(get_json) ns3=$(get_ns3) py=$(get_python) os=$(grep -m 1 "OS Version" ./consoleText| sed "s/OS Version : \(.*\)/\1/g") @@ -200,9 +200,9 @@ do ${statusmc} $compiler $boost - $java $cmake $eigen3 + $json $ns3 $py @@ -210,40 +210,4 @@ EOF rm consoleText done - -#Appveyor - get ID of the last job with the API -BUILD_ID=$(curl -s "https://ci.appveyor.com/api/projects/mquinson/simgrid" | grep -o '\[{"jobId":"[a-zA-Z0-9]*",' | sed "s/\[{\"jobId\":\"//" | sed "s/\",//") -wget --quiet https://ci.appveyor.com/api/buildjobs/"$BUILD_ID"/log -O ./consoleText >/dev/null 2>&1 -sed -i -e "s/\r//g" ./consoleText -node="appveyor" -os="Windows Server 2012 - VS2015 + mingw64 5.3.0" -boost=$(get_boost) -compiler=$(get_compiler) -java=$(get_java) -cmake=$(get_cmake) -eigen3=$(get_eigen3) -ns3=$(get_ns3) -py=$(get_python) -success=$(grep -m 1 "Build success" ./consoleText) -ball="${icons[failure]}" -if [ -n "$success" ]; then - ball="${icons[success]}" -fi -cat < - $node - $os - <${ball}> - <${icons[disabled]}> - $compiler - $boost - $java - $cmake - $eigen3 - $ns3 - $py - -EOF -rm consoleText - echo "" diff --git a/tools/normalize-pointers.py b/tools/normalize-pointers.py index c8bd7ff9f2..54335398bf 100755 --- a/tools/normalize-pointers.py +++ b/tools/normalize-pointers.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright (c) 2013-2022. The SimGrid Team. +# Copyright (c) 2013-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/tools/sg_xml_unit_converter.py b/tools/sg_xml_unit_converter.py index 0803d70244..f357521cb4 100644 --- a/tools/sg_xml_unit_converter.py +++ b/tools/sg_xml_unit_converter.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (c) 2013-2022. The SimGrid Team. +# Copyright (c) 2013-2023. The SimGrid Team. # All rights reserved. # This program is free software; you can redistribute it and/or modify it diff --git a/tools/simgrid-monkey b/tools/simgrid-monkey index 8a70894e7e..c5699eaa8f 100755 --- a/tools/simgrid-monkey +++ b/tools/simgrid-monkey @@ -1,6 +1,6 @@ #! /usr/bin/env python3 -# The goal is to introduce random failures in a simulation, to test simgrid under extreme conditions. +# The goal is to introduce random failures in a simulation, to test SimGrid under extreme conditions. # # It is made of several components. # @@ -13,7 +13,7 @@ # Kill the link #0 after 42 seconds (using a kernel::Timer) # # * a python script: tools/simgrid-monkey (this file) -# * It takes a regular simgrid simulation as a parameter, use the cmonkey plugin to get the information about it, +# * It takes a regular SimGrid simulation as a parameter, use the cmonkey plugin to get the information about it, # and then restart many runs, with one resource being turn_off() + turn_on() in each run. # * Each resource gets killed between each timestamps, and on each timestamp. # * So the amount of simulations is: 1 + (host_c+link_c) * timestamps * 2 @@ -65,7 +65,7 @@ def get_info(cmd): #print(f"hosts:{host_count} links:{link_count} timestamps:{' '.join(([str(i) for i in timestamps]))}") return (host_count, link_count, timestamps) -parser = argparse.ArgumentParser(description='Run a simgrid simulation, and turn off/on resources at random.') +parser = argparse.ArgumentParser(description='Run a SimGrid simulation, and turn off/on resources at random.') parser.add_argument('--valgrind', help="Run the simulations in valgrind") parser.add_argument('command', nargs='*') args = parser.parse_args() diff --git a/tools/simgrid.supp b/tools/simgrid.supp index 10397ae82f..e1c3f281de 100644 --- a/tools/simgrid.supp +++ b/tools/simgrid.supp @@ -143,73 +143,7 @@ fun:agconcat } -# libunwind seems to be using msync poorly, thus triggering these -# https://github.com/JuliaLang/julia/issues/4533 -{ - msync unwind - Memcheck:Param - msync(start) - ... - obj:*/libpthread*.so - ... -} - -{ - ignore unwind cruft - Memcheck:Param - rt_sigprocmask(set) - ... - obj:/usr/lib/x86_64-linux-gnu/libunwind.so.* - ... -} -{ - ignore unwind cruft - Memcheck:Param - msync(start) - ... - obj:/usr/lib/x86_64-linux-gnu/libunwind.so.* - ... -} -{ - ignore unwind cruft - Memcheck:Param - write(buf) - ... - fun:_ULx86_64_step - obj:/usr/lib/x86_64-linux-gnu/libunwind.so.* -} - -{ - ignore unwind invalid reads - Memcheck:Addr8 - fun:_Ux86_64_setcontext -} - -# Java cruft -{ - JavaCruft 1 - Memcheck:Addr4 - ... - fun:_ZN9JavaCalls11call_helperEP9JavaValueP12methodHandleP17JavaCallArgumentsP6Thread - fun:JVM_DoPrivileged - ... -} -{ - JavaCruft 2 - Memcheck:Cond - ... - fun:_ZN13CompileBroker25invoke_compiler_on_methodEP11CompileTask - ... -} - -{ - Somewhere within the Java conditions and monitors - Memcheck:Cond - fun:MarsagliaXORV - ... -} - -#ignore python cruft +# Ignore python cruft { ignore python cruft 1 Memcheck:Cond diff --git a/tools/simgrid_convert_TI_traces.py b/tools/simgrid_convert_TI_traces.py index dc9a1beca3..8c9cd3e47f 100755 --- a/tools/simgrid_convert_TI_traces.py +++ b/tools/simgrid_convert_TI_traces.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 -# Copyright (c) 2018-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2018-2023. The SimGrid Team. All rights reserved. # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. ''' This script is intended to convert SMPI time independent traces (TIT) from the -old format (simgrid version <= 3.19) to the new format. +old format (SimGrid version <= 3.19) to the new format. On the previous format each MPI_wait calls were associated to the last ISend of IRecv call arbitrarily. @@ -15,7 +15,7 @@ IRecv call arbitrarily. This new that includes tags field that links MPI_wait calls to the MPI_ISend or MPI_IRecv associated to this wait. -This script reproduce the old behavior of simgrid because information are +This script reproduce the old behavior of SimGrid because information are missing to add the tags properly. It also lower case all the mpi calls. It takes in input (as argument or in stdin) the trace list file that is only a diff --git a/tools/simgrid_update_xml.pl b/tools/simgrid_update_xml.pl index daea1f0eb0..e62d011134 100755 --- a/tools/simgrid_update_xml.pl +++ b/tools/simgrid_update_xml.pl @@ -2,10 +2,10 @@ eval 'exec perl -S $0 ${1+"$@"}' if $running_under_some_shell; -# This script updates the simgrid XML file passed as argument (modification in place) +# This script updates the SimGrid XML file passed as argument (modification in place) # It is built to do the conversion incrementally. -# Copyright (c) 2006-2022. The SimGrid Team. +# Copyright (c) 2006-2023. The SimGrid Team. # All rights reserved. # # This program is free software; you can redistribute it and/or modify it @@ -15,7 +15,7 @@ eval 'exec perl -S $0 ${1+"$@"}' =head1 NAME -simgrid_update_xml - updates simgrid XML files to latest version +simgrid_update_xml - updates SimGrid XML files to latest version =head1 SYNOPSIS @@ -23,7 +23,7 @@ B I =head1 DESCRIPTION -simgrid_update_xml updates the simgrid XML file passed as argument. The file +simgrid_update_xml updates the SimGrid XML file passed as argument. The file is modified in place, without any kind of backup. You may want to save a copy before running the script. @@ -160,7 +160,7 @@ In and , rename the 'availability_file' attribute into 'speed_file' =head1 COPYRIGHT AND LICENSE -Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. +Copyright (c) 2006-2023. The SimGrid Team. All rights reserved. This program is free software; you may redistribute it and/or modify it under the terms of GNU LGPL (v2.1) license. diff --git a/tools/smpi/generate_smpi_defines.pl b/tools/smpi/generate_smpi_defines.pl index 9ce19221ca..34c366afde 100755 --- a/tools/smpi/generate_smpi_defines.pl +++ b/tools/smpi/generate_smpi_defines.pl @@ -1,6 +1,6 @@ #!/usr/bin/env perl # -# Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. +# Copyright (c) 2016-2023. The SimGrid Team. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the license (GNU LGPL) which comes with this package. @@ -31,7 +31,7 @@ if (defined $options{f}) { $commentChar="!" } -print "$commentChar Copyright (c) 2016-2022. The SimGrid Team. All rights reserved.\n"; +print "$commentChar Copyright (c) 2016-2023. The SimGrid Team. All rights reserved.\n"; print "\n"; print "$commentChar This program is free software; you can redistribute it and/or modify it\n"; print "$commentChar under the terms of the license (GNU LGPL) which comes with this package.\n"; @@ -50,11 +50,11 @@ sub output_macro { # This is a GCC extension. The last statement is the value of the expression # in parentheses. if (defined $options{f}) { - print "#define ". lc($id) ." smpi_trace_set_call_location(__FILE__,__LINE__); call ". ucfirst $id ."\n"; - print "#define ". uc($id) ." smpi_trace_set_call_location(__FILE__,__LINE__); call ". ucfirst $id ."\n"; + print "#define ". lc($id) ." smpi_trace_set_call_location(__FILE__,__LINE__,\"". lc($id) ."\"); call ". ucfirst $id ."\n"; + print "#define ". uc($id) ." smpi_trace_set_call_location(__FILE__,__LINE__,\"". uc($id) ."\"); call ". ucfirst $id ."\n"; } else { - print "#define $id(...) (smpi_trace_set_call_location(__FILE__, __LINE__), $id(__VA_ARGS__))\n"; + print "#define $id(...) (smpi_trace_set_call_location(__FILE__, __LINE__, \"$id\"), $id(__VA_ARGS__))\n"; } } diff --git a/tools/tesh/CMakeLists.txt b/tools/tesh/CMakeLists.txt index 77e6bf9cb6..eb1caded82 100644 --- a/tools/tesh/CMakeLists.txt +++ b/tools/tesh/CMakeLists.txt @@ -6,7 +6,7 @@ foreach(x setenv set-output-ignore set-output-sort set-return set-timeout backgr catch-all-bg-output catch-return catch-signal catch-timeout catch-timeout-output catch-wrong-output cd color ignore-regexp IO-bigsize IO-broken-pipe IO-orders) set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${x}.tesh) - if(NOT enable_memcheck AND NOT WIN32) + if(NOT enable_memcheck) ADD_TESH(tesh-self-${x} --setenv bindir=${CMAKE_BINARY_DIR}/bin ${CMAKE_HOME_DIRECTORY}/tools/tesh/${x}.tesh) endif() endforeach() diff --git a/tools/tesh/IO-orders.tesh b/tools/tesh/IO-orders.tesh index e2c0a25d71..c7bbc672ee 100644 --- a/tools/tesh/IO-orders.tesh +++ b/tools/tesh/IO-orders.tesh @@ -7,6 +7,7 @@ p Order: in, out, cmd < $ cat > Test suite from stdin > [(stdin):3] cat +> > Test suite from stdin OK $ ${bindir:=.}/tesh @@ -16,6 +17,7 @@ p Order: out, in, cmd < $ cat > Test suite from stdin > [(stdin):3] cat +> > Test suite from stdin OK $ ${bindir:=.}/tesh @@ -25,6 +27,7 @@ p Order: out, cmd, in < < TOTO > Test suite from stdin > [(stdin):2] cat +> > Test suite from stdin OK $ ${bindir:=.}/tesh @@ -34,6 +37,7 @@ p Order: in, cmd, out < > TOTO > Test suite from stdin > [(stdin):2] cat +> > Test suite from stdin OK $ ${bindir:=.}/tesh @@ -43,6 +47,7 @@ p Order: cmd, out, in < < TOTO > Test suite from stdin > [(stdin):1] cat +> > Test suite from stdin OK $ ${bindir:=.}/tesh @@ -52,5 +57,6 @@ p Order: cmd, in, out < > TOTO > Test suite from stdin > [(stdin):1] cat +> > Test suite from stdin OK $ ${bindir:=.}/tesh diff --git a/tools/tesh/catch-signal.tesh b/tools/tesh/catch-signal.tesh index 2799b4f0d9..42fede22bc 100644 --- a/tools/tesh/catch-signal.tesh +++ b/tools/tesh/catch-signal.tesh @@ -19,7 +19,7 @@ $ perl segfault.pl p Check that we return the expected return value on SEGV ! expect return 11 < $ perl segfault.pl -$ ${bindir:=.}/tesh +$ ${bindir:=.}/tesh --no-auto-valgrind > Test suite from stdin > [(stdin):1] perl segfault.pl > Test suite `(stdin)': NOK (<(stdin):1> got signal SIGSEGV) diff --git a/tools/tesh/catch-timeout-output.tesh b/tools/tesh/catch-timeout-output.tesh index 227d93c77a..e308580806 100644 --- a/tools/tesh/catch-timeout-output.tesh +++ b/tools/tesh/catch-timeout-output.tesh @@ -14,6 +14,7 @@ > @@ -0,0 +1 @@ > +I crashed > Test suite `(stdin)': NOK (<(stdin):2> output mismatch) +> In addition, <(stdin):2> got signal SIGTERM. $ ${bindir:=.}/tesh diff --git a/tools/tesh/set-output-sort.tesh b/tools/tesh/set-output-sort.tesh index e560f56b0f..92b3400be2 100644 --- a/tools/tesh/set-output-sort.tesh +++ b/tools/tesh/set-output-sort.tesh @@ -75,19 +75,33 @@ $ ${bindir:=.}/tesh --ignore-jenkins > Test suite from stdin > [(stdin):1] Test sorting and filtering of output > [(stdin):3] true +> > [(stdin):6] true +> > [(stdin):8] printf 'profiling: foo\n' +> > [(stdin):10] printf 'profiling: foo' +> > [(stdin):13] printf 'profiling: foo\n' +> > [(stdin):16] printf 'profiling: foo' +> > [(stdin):18] printf 'a\nb\nc\nd\n' +> > [(stdin):24] printf 'a\nb\nc\nd' +> > [(stdin):31] printf 'c\nd\nb\na\n' +> > [(stdin):38] printf 'c\nd\nb\na' +> > [(stdin):44] printf 'a\nprofiling: foo\nprofiling: bar\nb\nc\nd\nprofiling: baz\n' +> > [(stdin):50] printf 'a\nprofiling: foo\nprofiling: bar\nb\nc\nd\nprofiling: baz' +> > [(stdin):57] printf 'c\nprofiling: foo\nprofiling: bar\nd\nb\na\nprofiling: baz\n' +> > [(stdin):64] printf 'c\nprofiling: foo\nprofiling: bar\nd\nb\na\nprofiling: baz' +> > Test suite from stdin OK p Check the Right Prefix Length (19) for "output sort" diff --git a/tools/tesh/tesh.py b/tools/tesh/tesh.py index 0d2825fff1..0db9022224 100755 --- a/tools/tesh/tesh.py +++ b/tools/tesh/tesh.py @@ -5,7 +5,7 @@ tesh -- testing shell ======================== -Copyright (c) 2012-2022. The SimGrid Team. All rights reserved. +Copyright (c) 2012-2023. The SimGrid Team. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the license (GNU LGPL) which comes with this package. @@ -46,10 +46,6 @@ else: # # -def is_windows(): - """ Check if running on Windows """ - return sys.platform.startswith('win') - # Singleton metaclass that works in Python 2 & 3 # http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python @@ -83,14 +79,24 @@ def fatal_error(msg): print("[Tesh/CRITICAL] " + str(msg)) tesh_exit(1) +# retrocompatibility: support ${aaa:=.} variable format +def replace_perl_variables(arg): + vname = arg.group(1) + vdefault = arg.group(2) + if vname in os.environ: + return "$" + vname + return vdefault def setenv(arg): """ Set an environment variable. arg must be a string with the format "variable=value" """ - print("[Tesh/INFO] setenv " + arg) + if '$' in arg: + arg = re.sub(r"\${(\w+):=([^}]*)}", replace_perl_variables, arg) + arg = expandvars2(arg) (var, val) = arg.split("=", 1) + print("[Tesh/INFO] setenv " + var + "=" + val) os.environ[var] = val # os.putenv(var, val) does not work # see http://stackoverflow.com/questions/17705419/python-os-environ-os-putenv-usr-bin-env @@ -120,7 +126,7 @@ def process_is_dead(pid): def kill_process_group(pid): """ This function send TERM signal + KILL signal after 0.2s to the group of the specified process """ if pid is None: - # Nobody to kill. We don't know who to kill on windows, or we don't have anyone to kill on signal handler + # Nobody to kill. We don't have anyone to kill on signal handler return try: @@ -200,6 +206,7 @@ class TeshState(Singleton): self.args_suffix = "" self.ignore_regexps_common = [] self.jenkins = False # not a Jenkins run by default + self.auto_valgrind = True self.timeout = 10 # default value: 10 sec self.wrapper = None self.keep = False @@ -241,6 +248,7 @@ class Cmd: self.output_display = False self.sort = -1 + self.rerun_with_valgrind = False self.ignore_regexps = TeshState().ignore_regexps_common @@ -306,20 +314,21 @@ class Cmd: _thread.start_new_thread(Cmd._run, (self, lock)) else: self._run() + if self.rerun_with_valgrind and TeshState().auto_valgrind: + print('\n\n\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX') + print( 'XXXXXXXXX Rerunning this test with valgrind to help debugging it XXXXXXXXX') + print( 'XXXXXXXX (this will fail if valgrind is not installed, of course) XXXXXXXX') + print( 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n\n\n') + + self.args = "valgrind " + self.args + self._run() return True + def _run(self, lock=None): # Python threads loose the cwd os.chdir(self.cwd) - # retrocompatibility: support ${aaa:=.} variable format - def replace_perl_variables(arg): - vname = arg.group(1) - vdefault = arg.group(2) - if vname in os.environ: - return "$" + vname - return vdefault - self.args = re.sub(r"\${(\w+):=([^}]*)}", replace_perl_variables, self.args) # replace bash environment variables ($THINGS) to their values @@ -348,17 +357,18 @@ class Cmd: self.args += TeshState().args_suffix logs = list() - logs.append("[{file}:{number}] {args}".format(file=FileReader().filename, - number=self.linenumber, args=self.args)) + msg = "[{file}:{number}] {args}".format(file=FileReader().filename, number=self.linenumber, args=self.args) + if self.background: + logs.append(msg) + else: + print(msg, flush=True) args = shlex.split(self.args) local_pid = None try: - preexec_function = None - if not is_windows(): - preexec_function = lambda: os.setpgid(0, 0) + preexec_function = lambda: os.setpgid(0, 0) proc = subprocess.Popen( # pylint: disable=subprocess-popen-preexec-fn args, bufsize=1, @@ -367,9 +377,8 @@ class Cmd: stderr=subprocess.STDOUT, universal_newlines=True, preexec_fn=preexec_function) - if not is_windows(): - local_pid = proc.pid - TeshState().running_pids.append(local_pid) + local_pid = proc.pid + TeshState().running_pids.append(local_pid) except PermissionError: logs.append("[{file}:{number}] Cannot start '{cmd}': The binary is not executable.".format( file=FileReader().filename, number=self.linenumber, cmd=args[0])) @@ -418,13 +427,17 @@ class Cmd: print('\n'.join(logs)) return - if self.output_display: - logs.append(str(stdout_data)) - # remove text colors ansi_escape = re.compile(r'\x1b[^m]*m') stdout_data = ansi_escape.sub('', stdout_data) + if self.output_display: + logs.append(str(stdout_data)) + + if self.rerun_with_valgrind: + print(str(stdout_data), file=sys.stderr) + return + if self.ignore_output: logs.append("(ignoring the output of <{cmd}> as requested)".format(cmd=cmd_name)) else: @@ -468,6 +481,18 @@ class Cmd: logs.append("Test suite `{file}': NOK (<{cmd}> output mismatch)".format( file=FileReader().filename, cmd=cmd_name)) + + # Also report any failed return code and/or signal we got in case of output mismatch + if not proc.returncode in self.expect_return: + if proc.returncode >= 0: + logs.append("In addition, <{cmd}> returned code {code}.".format( + cmd=cmd_name, code=proc.returncode)) + else: + logs.append("In addition, <{cmd}> got signal {sig}.".format(cmd=cmd_name, + sig=SIGNALS_TO_NAMES_DICT[-proc.returncode])) + if proc.returncode == -signal.SIGSEGV: + self.rerun_with_valgrind = True + if lock is not None: lock.release() if TeshState().keep: @@ -502,6 +527,10 @@ class Cmd: logs.append("Test suite `{file}': NOK (<{cmd}> got signal {sig})".format( file=FileReader().filename, cmd=cmd_name, sig=SIGNALS_TO_NAMES_DICT[-proc.returncode])) + + if proc.returncode == -signal.SIGSEGV: + self.rerun_with_valgrind = True + if lock is not None: lock.release() TeshState().set_return_code(max(-proc.returncode, 1)) @@ -542,6 +571,10 @@ def main(): '--ignore-jenkins', action='store_true', help='ignore all cruft generated on SimGrid continuous integration servers') + group1.add_argument( + '--no-auto-valgrind', + action='store_true', + help='do not automaticall launch segfaulting commands in valgrind') group1.add_argument('--wrapper', metavar='arg', help='Run each command in the provided wrapper (eg valgrind)') group1.add_argument( '--keep', @@ -561,14 +594,13 @@ def main(): re.compile(r"profiling:"), re.compile(r"Unable to clean temporary file C:"), re.compile(r".*Configuration change: Set 'contexts/"), - re.compile(r"Picked up JAVA_TOOL_OPTIONS: "), - re.compile(r"Picked up _JAVA_OPTIONS: "), re.compile(r"==[0-9]+== ?WARNING: ASan doesn't fully support"), re.compile(r"==[0-9]+== ?WARNING: ASan is ignoring requested __asan_handle_no_return: stack "), re.compile(r"False positive error reports may follow"), re.compile(r"For details see http://code\.google\.com/p/address-sanitizer/issues/detail\?id=189"), re.compile(r"For details see https://github\.com/google/sanitizers/issues/189"), re.compile(r"Python runtime initialized with LC_CTYPE=C .*"), + re.compile(r"sthread is intercepting the execution of \.*"), # Seen on CircleCI re.compile(r"cmake: /usr/local/lib/libcurl\.so\.4: no version information available \(required by cmake\)"), re.compile( @@ -577,6 +609,9 @@ def main(): ] TeshState().jenkins = True # This is a Jenkins build + if options.no_auto_valgrind: + TeshState().auto_valgrind = False + if options.teshfile is None: file = FileReader(None) print("Test suite from stdin") @@ -651,7 +686,10 @@ def main(): cmd.output_display = True cmd.ignore_output = True elif line[0:15] == "! expect return": - cmd.expect_return = [int(line[16:])] + try: + cmd.expect_return = [int(line[16:])] + except ValueError as err: + fatal_error("Invalid expect return value: \""+(line[16:])+"\"") #print("expect return "+str(int(line[16:]))) elif line[0:15] == "! expect signal": cmd.expect_return = [] @@ -666,11 +704,17 @@ def main(): if "no" in line[len("! timeout "):]: cmd.timeout = None else: - cmd.timeout = int(line[len("! timeout "):]) + try: + cmd.timeout = int(line[len("! timeout "):]) + except ValueError as err: + fatal_error("Invalid timeout value: \""+(line[len("! timeout "):])+"\"") elif line[0:len("! output sort")] == "! output sort": if len(line) >= len("! output sort "): - sort = int(line[len("! output sort "):]) + try: + sort = int(line[len("! output sort "):]) + except ValueError as err: + fatal_error("Invalid sort value: \""+(line[len("! output sort "):])+"\"") else: sort = 0 cmd.sort = sort @@ -681,7 +725,16 @@ def main(): cmd.add_ignore(line[len("! ignore "):]) else: - fatal_error("UNRECOGNIZED OPTION") + fatal_error(f"UNRECOGNIZED OPTION LINE: {line}\n" + "Valid requests:\n" + " ! output ignore\n" + " ! output sort\n" + " ! output display\n" + " ! setenv XX=YY\n" + " ! ignore XYZ\n" + " ! expect return NN\n" + " ! expect signal NN\n" + " ! timeout NN\n") line = file.readfullline()