Skip to content

Batch mode formation minor fixes #15091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 12, 2018

Conversation

graydon
Copy link
Contributor

@graydon graydon commented Mar 9, 2018

This fixes a couple minor issues that arose while testing batch mode. Neither is critical to correct functioning, they just help testing.

The first eliminates a quadratic assert, which I incorrectly assumed was cheaper than a path I thought was already occurring at worse-than-quadratic complexity (relative to batch size). This is not true and to keep things moving quickly on large batches I believe it's not worth making this assertion; it doesn't check a condition that's very plausible anyways.

The second fixes a potential mismatch between the emitted order of primary-file arguments and additional output arguments passed to the frontend. This doesn't happen in normal runs, but when shuffling the batch constituents with -driver-batch-seed -- as happens when doing randomized testing -- it does. And in general it's a condition we ought to be ensuring regardless (at least until we do away with positionally pairing-up primaries and their additionals on the frontend command line).

@graydon graydon requested a review from jrose-apple March 9, 2018 01:36
@graydon
Copy link
Contributor Author

graydon commented Mar 9, 2018

@swift-ci please test

sortBatchInputJobs(ArrayRef<const Job *> jobs,
SmallVector<const Job *, 16> &sortedJobs,
Compilation &C) {
llvm::StringMap<const Job *> jobsByInput;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mapping by string seems expensive. Is it not possible to just use the order of jobs before shuffling?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, but I can perform a shuffle in a way that maintains the order if you prefer. I would like to leave this in as an assert that the orders match, in that case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it doesn't matter cause we do tons of other string lookups. This just wasn't the obvious way to get the original order back for me.

@swift-ci
Copy link
Contributor

swift-ci commented Mar 9, 2018

Build failed
Swift Test Linux Platform
Git Sha - 14f3904743d02cbcb469079e046870cf3a7ba17d

@swift-ci
Copy link
Contributor

swift-ci commented Mar 9, 2018

Build failed
Swift Test OS X Platform
Git Sha - 14f3904743d02cbcb469079e046870cf3a7ba17d

@graydon graydon force-pushed the batch-mode-formation-minor-fixes branch from 14f3904 to 4bdc0cf Compare March 9, 2018 04:49
@graydon graydon force-pushed the batch-mode-formation-minor-fixes branch from 4bdc0cf to 409c23c Compare March 9, 2018 04:56
@graydon
Copy link
Contributor Author

graydon commented Mar 9, 2018

@jrose-apple pushed update that does the shuffle on indices not jobs, thus maintaining invariant. Switched the comparison-to-the-input sequence to just be an assert.

@graydon
Copy link
Contributor Author

graydon commented Mar 9, 2018

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Mar 9, 2018

Build failed
Swift Test Linux Platform
Git Sha - 14f3904743d02cbcb469079e046870cf3a7ba17d

@swift-ci
Copy link
Contributor

swift-ci commented Mar 9, 2018

Build failed
Swift Test OS X Platform
Git Sha - 14f3904743d02cbcb469079e046870cf3a7ba17d

for (const Job *Cmd : Batchable) {
maybeAdvanceToNextPartition(i, Partition, Batchable.size());
std::vector<const Job*> &P = Partition[i];
for (size_t i = 0; i < Batchable.size(); ++i) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want, there's an llvm::for_each that can do parallel iteration over two containers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming you mean swift::for_each (in include/swift/Basic/STLExtras.h), nice!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, forgot it was us and not them.

// size of the first Remainder of them.
if (P < Remainder)
++TargetSize;
for (size_t N = 0; N < TargetSize; ++N) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use std::fill_n here but I guess it may or may not be clearer than just writing it out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

// RUN: %swiftc_driver -enable-batch-mode -driver-batch-seed 1 -driver-print-jobs -driver-skip-execution -j 3 -emit-module -module-name foo %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/file-04.swift %t/file-05.swift %t/file-06.swift %t/file-07.swift %t/file-08.swift %t/file-09.swift >%t/out.txt
// RUN: %FileCheck %s <%t/out.txt
//
// Each batch should get 3 primaries; check that each has 3 modules _in the same numeric order_.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are we going to do with this test when we switch to output file maps? Just delete it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I can add a note to that extent.

@graydon graydon force-pushed the batch-mode-formation-minor-fixes branch from 409c23c to fa830fe Compare March 9, 2018 18:13
@graydon
Copy link
Contributor Author

graydon commented Mar 9, 2018

@swift-ci please test and merge

1 similar comment
@graydon
Copy link
Contributor Author

graydon commented Mar 9, 2018

@swift-ci please test and merge

@graydon
Copy link
Contributor Author

graydon commented Mar 10, 2018

@swift-ci please test Linux platform

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - fa830fe

@graydon
Copy link
Contributor Author

graydon commented Mar 10, 2018

@swift-ci please test Linux platform

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - fa830fe

@graydon
Copy link
Contributor Author

graydon commented Mar 12, 2018

@swift-ci please smoke test and merge

@swift-ci swift-ci merged commit 7d16d13 into swiftlang:master Mar 12, 2018
@davezarzycki
Copy link
Contributor

davezarzycki commented Mar 12, 2018

The test suite fails after this pull request on Fedora Linux 27 (with ToT clang/llvm). Build log: http://znu.io/pr15091.log

The relevant error:

'BUILD_DIR=/home/dave/s/u/t/tools/swift' --sanitize 'SOURCE_DIR=/home/dave/s/u/tools/swift' --use-filecheck '/home/dave/s/u/t/bin/FileCheck' /home/dave/s/u/tools/swift/test/Driver/batch_mode.swift -check-prefix=SEED1
env SDKROOT= '/home/dave/s/u/t/bin/swiftc' -module-cache-path '/tmp/swift-testsuite-clang-module-cachephl7vb' -swift-version 3  -enable-batch-mode -driver-show-job-lifecycle -driver-skip-execution -j 4 -driver-batch-seed 2 /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-01.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-02.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-03.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-04.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-05.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-06.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-07.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-08.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-09.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-10.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-11.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-12.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-13.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-14.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-15.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-16.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-17.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-18.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-19.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-20.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-21.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-22.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-23.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-24.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-25.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-26.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-27.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-28.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-29.swift /home/dave/s/u/t/tools/swift/test-linux-x86_64/Driver/Output/batch_mode.swift.tmp/file-30.swift | /home/dave/s/u/tools/swift/utils/PathSanitizingFileCheck --sanitize 'BUILD_DIR=/home/dave/s/u/t/tools/swift' --sanitize 'SOURCE_DIR=/home/dave/s/u/tools/swift' --use-filecheck '/home/dave/s/u/t/bin/FileCheck' /home/dave/s/u/tools/swift/test/Driver/batch_mode.swift -check-prefix=SEED2
--
Exit Code: 1

Command Output (stderr):
--
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
Output placeholder
/home/dave/s/u/tools/swift/test/Driver/batch_mode.swift:56:11: error: expected string not found in input
// SEED2: Adding {compile: file-{{.*}} <= file-{{.*}}.swift} to batch 3
          ^
<stdin>:57:1: note: scanning from here
Adding {compile: file-23-9616ac.o <= file-23.swift} to batch 1
^

--

********************
Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 

2 warning(s) in tests.
Testing Time: 166.11s
********************
Failing Tests (1):
    Swift(linux-x86_64) :: Driver/batch_mode.swift

  Expected Passes    : 3029
  Expected Failures  : 80
  Unsupported Tests  : 1384
  Unexpected Failures: 1
FAILED: tools/swift/test/CMakeFiles/check-swift-linux-x86_64 
cd /home/dave/s/u/t/tools/swift/test && /usr/bin/cmake -E remove_directory /home/dave/s/u/t/./swift-test-results/x86_64-unknown-linux-gnu && /usr/bin/cmake -E make_directory /home/dave/s/u/t/./swift-test-results/x86_64-unknown-linux-gnu && /usr/bin/python2.7 /home/dave/s/u/utils/lit/lit.py --incremental -sv --timeout=3000 --xunit-xml-output=/home/dave/s/u/t/./swift-test-results/x86_64-unknown-linux-gnu/lit-tests.xml --param swift_test_subset=primary --param swift_test_mode=optimize_none /home/dave/s/u/t/tools/swift/test-linux-x86_64
ninja: build stopped: subcommand failed.

@jrose-apple
Copy link
Contributor

Uh, hm. The random number generation should be deterministic, since the definition minstd_rand is mandated by the standard.

@davezarzycki
Copy link
Contributor

Do the Swift Linux build bots use libstdc++ or libcxx?

@graydon
Copy link
Contributor Author

graydon commented Mar 12, 2018

Whatever stock ubuntu is, afaict. But .. well, I'm .. sympathetic to the idea that the prng ought to be stable, since it's spec'ed, but also that I meant the test that fails there to be not-sensitive to PRNG order, and I missed that the failing test here will now be sensitive.

@davezarzycki can you run this test and see if it passes?

https://github.com/google/libcxx/blob/master/test/numerics/rand/rand.predef/minstd_rand.pass.cpp

@davezarzycki
Copy link
Contributor

I built it with the same compiler I use to build Swift ToT. It passes.

I also just did a clean build and reinstall of ToT clang+llvm+lld in case it matters, and then did a clean build-and-test of llvm+clang+swift. Same error.

@graydon
Copy link
Contributor Author

graydon commented Mar 12, 2018

@davezarzycki Interesting; I wonder if this has something more to do with a container type behaving differently, like in the job queue or such. Can you grab the actual-output from the failing line of the test (eg. modify test/Driver/batch_mode.swift to redirect the 3rd %swiftc_driver execution -- the SEED2 one -- to a file and pastebin it?)

@davezarzycki
Copy link
Contributor

Here you go: http://znu.io/seed2.out

@graydon
Copy link
Contributor Author

graydon commented Mar 12, 2018

@davezarzycki Great, that clarified that it's definitely a different sequence, and that was enough to find the issue: the PRNG is spec'ed tightly enough not to vary this way, but std::shuffle isn't -- it uses the PRNG in a way that leaves some variation in implementation:

libstdc++: https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_algo.h#L3777-L3858
libcxx: https://github.com/llvm-mirror/libcxx/blob/master/include/algorithm#L3197-L3219

Different shuffle algorithms :(

So I need to make the test more order-insensitive. Thanks for catching this!

@davezarzycki
Copy link
Contributor

Hi @graydon – Thanks for being so responsive and helpful in debugging this :-)

@jrose-apple
Copy link
Contributor

Oh, oops. Once I ruled out the obvious thing I didn't keep thinking. Of course std::shuffle isn't spec'd in the same way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants