Skip to content
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

Cleanup for the framework PR #426

Merged

Conversation

makortel
Copy link

@makortel makortel commented Dec 2, 2019

PR description:

While preparing a PR for CMSSW master I noticed that the unit tests (within the "framework" part) were not fully working on a non-GPU machine. As a subsequent cleanup this PR proposes

  • remove an unnecessary import of the gpu Modifier in testCUDASwitch_cfg.py, and fix an input configuration parameter relevant when running without GPU
  • remove testCUDA_cfg.py as not really useful
  • rename exitSansCUDADevices.cc to requireCUDADevices.cc for consistency

Then I realized that at least with catch2 unit test framework just exiting the program in requireCUDADevices() is too harsh, especially when a subset of the tests (in a file) would be useful to run without GPUs. Therefore I added hasCUDADevices() that returns a bool, which allows me to return instead of exit() from catch2 tests.

PR validation:

Code compiles, unit tests run on both non-GPU and GPU machines.

@fwyzard
Copy link

fwyzard commented Dec 2, 2019

Then I realized that at least with catch2 unit test framework just exiting the program in requireCUDADevices() is too harsh, especially when a subset of the tests (in a file) would be useful to run without GPUs.

Do we have examples of this (running a subset of the tests without GPUs) ?

@makortel
Copy link
Author

makortel commented Dec 2, 2019

Then I realized that at least with catch2 unit test framework just exiting the program in requireCUDADevices() is too harsh, especially when a subset of the tests (in a file) would be useful to run without GPUs.

Do we have examples of this (running a subset of the tests without GPUs) ?

TEST_CASE("Use of CUDAProduct template", "[CUDACore]") {
SECTION("Default constructed") {
auto foo = CUDAProduct<int>();
REQUIRE(!foo.isValid());
auto bar = std::move(foo);
}
if (not hasCUDADevices()) {

and
TEST_CASE("Standard checks of TestCUDAProducerGPUFirst", s_tag) {
const std::string baseConfig{
R"_(from FWCore.TestProcessor.TestProcess import *
process = TestProcess()
process.load("HeterogeneousCore.CUDAServices.CUDAService_cfi")
process.toTest = cms.EDProducer("TestCUDAProducerGPUFirst")
process.moduleToTest(process.toTest)
)_"};
edm::test::TestProcessor::Config config{baseConfig};
SECTION("base configuration is OK") { REQUIRE_NOTHROW(edm::test::TestProcessor(config)); }
SECTION("No event data") {
// Calls produce(), so don't call without a GPU
if (not hasCUDADevices()) {
return;
}
edm::test::TestProcessor tester(config);
REQUIRE_NOTHROW(tester.test());
}
SECTION("beginJob and endJob only") {
edm::test::TestProcessor tester(config);
REQUIRE_NOTHROW(tester.testBeginAndEndJobOnly());
}
SECTION("Run with no LuminosityBlocks") {
edm::test::TestProcessor tester(config);
REQUIRE_NOTHROW(tester.testRunWithNoLuminosityBlocks());
}
SECTION("LuminosityBlock with no Events") {
edm::test::TestProcessor tester(config);
REQUIRE_NOTHROW(tester.testLuminosityBlockWithNoEvents());
}
}

@makortel
Copy link
Author

makortel commented Dec 2, 2019

Ok, neither of them is really testing essential functionality (on a non-GPU machine).

On the other hand, demonstrating that a test CUDA producer can be constructed and ran through lumi and run transitions without a GPU has some value (since that is what actually happens today with SwitchProducer).

Alternatively we could have separate unit test executables for GPU and non-GPU cases.

@fwyzard
Copy link

fwyzard commented Dec 3, 2019

@makortel I don't mind adding the extra possibility - however I'm confused about the tests themselves...

In test_CUDAProduct.cc there is only one test, so what is the difference from just return vs exit() ?

In test_TestCUDAProducerGPUFirst.cc there are multiple SECTIONs, so I guess there it makes sense.

But more importantly, what do you mean by

a test CUDA producer can be constructed and ran through lumi and run transitions without a GPU has some value (since that is what actually happens today with SwitchProducer).

?
I thought the SwitchProducer would only call one of the two modules (the CUDA one if we have a GPU, the non-CUDA otherwise).

@makortel
Copy link
Author

makortel commented Dec 3, 2019

In test_CUDAProduct.cc there is only one test, so what is the difference from just return vs exit() ?

With return the main() of catch2 can finish and report successful tests in stdout. With exit() the program just quits (with proper exit code though).

a test CUDA producer can be constructed and ran through lumi and run transitions without a GPU has some value (since that is what actually happens today with SwitchProducer).

?
I thought the SwitchProducer would only call one of the two modules (the CUDA one if we have a GPU, the non-CUDA otherwise).

Right, but that only applies to event transitions (i.e. produce() etc). Construction+destruction and run+lumi transitions take place for all modules that are in Tasks/Sequences via Paths and EndPaths that are specified in Schedule (or all paths if there is no Schedule). I fully agree this is confusing, see issue cms-sw#26438.

@fwyzard
Copy link

fwyzard commented Dec 3, 2019

I fully agree this is confusing, see issue cms-sw#26438.

Oh. Yes, yes, it is.

@fwyzard fwyzard merged commit 41b1c42 into cms-patatrack:CMSSW_11_0_X_Patatrack Dec 3, 2019
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.

2 participants