bellperson 0.21.0

zk-SNARK library
Documentation
version: 2.1

parameters:
  nightly-version:
    type: string
    default: "nightly-2021-04-24"

#orbs:
#  codecov: codecov/codecov@1.1.4

executors:
  default:
    machine:
      image: ubuntu-2004-cuda-11.2:202103-01
    working_directory: ~/gpuci
    resource_class: gpu.nvidia.medium

restore-workspace: &restore-workspace
  attach_workspace:
    at: ~/

restore-cache: &restore-cache
  restore_cache:
    keys:
      - cargo-v2-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
      - repo-source-{{ .Branch }}-{{ .Revision }}

commands:
  set-env-path:
    steps:
      - run:
          name: Set the PATH env variable
          command: |
            # Also put the Rust LLVM tools into the PATH.
            echo 'export PATH="$HOME:~/.cargo/bin:~/.rustup/toolchains/<< pipeline.parameters.nightly-version >>-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/usr/local/cuda-11.2/bin:$PATH"' | tee --append $BASH_ENV
            source $BASH_ENV

  install-gpu-deps:
    steps:
      - run:
          name: Install libraries for GPU tests
          command: |
            sudo apt update
            sudo apt install -y ocl-icd-opencl-dev

jobs:
  cargo_fetch:
    executor: default
    steps:
      - checkout
      - run: curl https://sh.rustup.rs -sSf | sh -s -- -y
      - set-env-path
      - run: echo $HOME
      - run: cargo --version
      - run: rustc --version
      - run:
          name: Update submodules
          command: git submodule update --init --recursive
      - run:
          name: Calculate dependencies
          command: cargo generate-lockfile
      - restore_cache:
          keys:
            - cargo-v2-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
      - run: cargo update
      - run: cargo fetch
      - run: rustup install $(cat rust-toolchain)
      - run: rustup default $(cat rust-toolchain)
      # A nightly build is needed for code coverage reporting
      - run: rustup toolchain install --profile minimal << pipeline.parameters.nightly-version >>
      - run: rustup component add --toolchain << pipeline.parameters.nightly-version >> llvm-tools-preview
      - run: rustc --version
      - run: rm -rf .git
      - persist_to_workspace:
          root: ~/
          paths:
            - gpuci
      - save_cache:
          key: cargo-v2-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
          paths:
            - "~/.cargo"
            - "~/.rustup"

  test:
    executor: default
    parameters:
      cargo-args:
        description: Addtional arguments for the cargo command
        type: string
        default: ""
      framework:
        description: Whether to use CUDA or OpenCL
        type: string
        default: ""
    environment:
      RUST_LOG: debug
      # Build the kernel only for the single architecture that is used on CI. This should reduce
      # the overall compile-time significantly.
      BELLMAN_CUDA_NVCC_ARGS: --fatbin --gpu-architecture=sm_75 --generate-code=arch=compute_75,code=sm_75
    steps:
      - set-env-path
      - install-gpu-deps
      - *restore-workspace
      - *restore-cache
      - run:
          name: Test << parameters.framework>> with << parameters.cargo-args >>
          command: BELLMAN_GPU_FRAMEWORK=<< parameters.framework >> cargo test << parameters.cargo-args >>

  test_ignored:
    executor: default
    environment:
      RUST_LOG: debug
    steps:
      - set-env-path
      - *restore-workspace
      - *restore-cache
      - run:
          name: Test ignored
          command: cargo test --release -- --ignored
          no_output_timeout: 30m
      - run:
          name: Show results
          command: cat aggregation.csv

  rustfmt:
    executor: default
    steps:
      - *restore-workspace
      - *restore-cache
      - set-env-path
      - run:
          name: Run cargo fmt
          command: cargo fmt --all -- --check

  clippy:
    executor: default
    environment:
      RUST_LOG: debug
      # Build the kernel only for the single architecture that is used on CI. This should reduce
      # the overall compile-time significantly.
      BELLMAN_CUDA_NVCC_ARGS: --fatbin --gpu-architecture=sm_75 --generate-code=arch=compute_75,code=sm_75
    steps:
      - *restore-workspace
      - *restore-cache
      - set-env-path
      - run:
          name: Run cargo clippy (default features)
          command: cargo clippy --all --all-targets -- -D warnings
      - run:
          name: Run cargo clippy (opencl)
          command: cargo clippy --all --all-targets --features opencl -- -D warnings
      - run:
          name: Run cargo clippy (cuda)
          command: cargo clippy --all --all-targets --features cuda -- -D warnings
      - run:
          name: Run cargo clippy (cuda,opencl)
          command: cargo clippy --all --all-targets --features cuda,opencl -- -D warnings

  coverage_run:
    executor: default
    parameters:
      cargo-args:
        description: Addtional arguments for the cargo command
        type: string
        default: ""
      test-args:
        description: Additional arguments for the test executable (after the `--`)
        type: string
        default: ""
    environment:
      # Incremental build is not supported when profiling
      CARGO_INCREMENTAL: 0
      # -Zinstrument-coverage: enable llvm coverage instrumentation
      # -Ccodegen-units=1: building in parallel is not supported when profiling
      # -Copt-level=0: disable optimizations for more accurate coverage
      # -Clink-dead-code: dead code should be considered as not covered code
      # -Coverflow-checks=off: checking for overflow is not needed for coverage reporting
      # -Cinline-threshold=0: do not inline
      RUSTFLAGS: -Zinstrument-coverage -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Cinline-threshold=0
      # Make sure that each run of an executable creates a new profile file, with the default
      # name they would override each other
      LLVM_PROFILE_FILE: "%m.profraw"
    steps:
      - *restore-workspace
      - *restore-cache
      - set-env-path
      - install-gpu-deps
      - run:
          name: Generate coverage report
          command: |
            RUST_LOG=info cargo +<< pipeline.parameters.nightly-version >> test --features _coverage << parameters.cargo-args >> -- --nocapture << parameters.test-args >>

            # Do *not* use sparse output. It leads to more lines that are not
            # taken into account at all
            llvm-profdata merge --output=default.profdata ./*.profraw

            # The compiled files contain the coverage information. From running the tests we don't
            # know what those files are called, hence use all files from the `./target/debug/deps`
            # directory which don't have an extension.
            OBJECT_FILES=$(find ./target/debug/deps/* -name '*' -not -name '*\.*' -printf '%p,'|head --bytes -1)
            # Only export the coverage of this project, we don't care about coverage of
            # dependencies
            llvm-cov export --ignore-filename-regex=".cargo|.rustup" --format=lcov -instr-profile=default.profdata --object=${OBJECT_FILES} > lcov.info
      ## Codecov automatically merges the reports in case there are several ones uploaded
      #- codecov/upload:
      #    file: lcov.info

workflows:
  version: 2.1

  test:
    jobs:
      - cargo_fetch
      - rustfmt:
          requires:
            - cargo_fetch
      - clippy:
          requires:
            - cargo_fetch
      - test:
          name: "Test CPU"
          cargo-args: "--workspace"
          requires:
            - cargo_fetch
      - test:
          name: "Test CPU (no default features)"
          cargo-args: "--workspace --no-default-features"
          requires:
            - cargo_fetch
      - test:
          name: "Test OpenCL only"
          cargo-args: "--workspace --release --features opencl"
          requires:
            - cargo_fetch
      - test:
          name: "Test CUDA only"
          cargo-args: "--release --features cuda"
          requires:
            - cargo_fetch
      - test:
          name: "Test CUDA/OpenCL (CUDA at run-time)"
          cargo-args: "--release --features cuda,opencl"
          framework: cuda
          requires:
            - cargo_fetch
      - test:
          name: "Test CUDA/OpenCL (OpenCL at run-time)"
          cargo-args: "--release --features cuda,opencl"
          framework: opencl
          requires:
            - cargo_fetch
      - test_ignored:
          requires:
            - cargo_fetch
      #- coverage_run:
      #    name: coverage_default_features
      #    requires:
      #      - cargo_fetch
      #- coverage_run:
      #    name: coverage_gpu_feature_lib
      #    cargo-args: "--features gpu --lib"
      #    # If run in parallel the GPU tests will block and hence fail
      #    test-args: "--test-threads=1"
      #    requires:
      #      - cargo_fetch
      #- coverage_run:
      #    name: coverage_gpu_feature_integration
      #    cargo-args: "--features gpu --test '*'"
      #    # If run in parallel the GPU tests will block and hence fail
      #    test-args: "--test-threads=1"
      #    requires:
      #      - cargo_fetch