Coverage and precompilation

Hi!

When I add precompilation statements from SnoopCompile, I start to see weird coverage results. Take a look here:

Everything seems fine when I remove those statements.

I saw that this can be improved if I run Julia with --inline=no when generating the coverage information. However, I am using the Github action julia-actions/julia-processcoverage@v1. Can anyone tell me what can I do to add this --inline=no option to that Github action?

That action actually just collects coverage files already generated by previous steps in your workflow, most likely from julia-actions/julia-runtest. To add --inline=no there, you change

      - uses: julia-actions/julia-runtest@v1

to

      - uses: julia-actions/julia-runtest@v1
        with:
          inline: no

Note: some code heavily depends on inlining for performance. I saw a test go from a few seconds to 300s+ with --inline=no! So you might want to be careful where you use it.

Thanks @ericphanson !

It does not have any time impact. However, the coverage did not improve :frowning: I am still seeing things like this if I use precompilation directives:

I am wondering if I can remove the precompilation if I am running for coverage computation.

It is ugly, but seems to work:

First, I add the precompilation directive as follows:

if Base.VERSION >= v"1.4.2" && !haskey(ENV, "STRING_MANIPULATION_NO_PRECOMPILATION")
    # This try/catch is necessary in case the precompilation statements do not
    # exists. In this case, StringManipulation.jl will work correctly but
    # without the optimizations.
    try
        include("../precompilation/precompile_StringManipulation.jl")
        _precompile_()
    catch
    end
end

Then, I removed the coverage processing from the main GitHub action.

After that, I create another action for the coverage using the following file:

name: Coverage
on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main
    tags: '*'
jobs:
  test:
    name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        version:
          - '1'  # This automatically expands to the latest stable 1.x release.
        os:
          - ubuntu-latest
        arch:
          - x64
    env:
      STRING_MANIPULATION_NO_PRECOMPILATION: ""
    steps:
      - uses: actions/checkout@v2
      - uses: julia-actions/setup-julia@v1
        with:
          version: ${{ matrix.version }}
          arch: ${{ matrix.arch }}
      - uses: actions/cache@v1
        env:
          cache-name: cache-artifacts
        with:
          path: ~/.julia/artifacts
          key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
          restore-keys: |
            ${{ runner.os }}-test-${{ env.cache-name }}-
            ${{ runner.os }}-test-
            ${{ runner.os }}-
      - uses: julia-actions/julia-buildpkg@v1
      - uses: julia-actions/julia-runtest@v1
      - uses: julia-actions/julia-processcoverage@v1
      - uses: codecov/codecov-action@v2
        with:
          file: lcov.info

And now everything works :slight_smile:

It would be interesting to know if this also happens on nightly, which has major changes to precompilation.

Off the top of my head, the most likely culprit may be constant-propagation, and if different code gets generated depending on whether you precompile.

Hi @tim.holy !

Thanks for the information, I will check :slight_smile: