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

Implement persistence for ProcessBlock products #33969

Merged
merged 26 commits into from
Jul 18, 2021

Conversation

wddgit
Copy link
Contributor

@wddgit wddgit commented Jun 3, 2021

PR description:

Implements persistence for ProcessBlock products.

This continues the work started in #30117, which implemented the non-persistent part of the ProcessBlock feature of the Framework.

I am currently working on updating the TWIKI documentation related to ProcessBlock. At the moment this PR is being submitted, the documentation only covers the non-persistent parts of the ProcessBlock feature. My plan is that within a few days the content of this PR will be described in more detail there. Currently, the TWIKI page is located here:

https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideProcessBlockData

PR validation:

This PR adds many unit tests that cover all the features added by the PR.

This PR should have almost no effect at all on existing workflows. There is nothing outside of the new unit tests that creates persistent ProcessBlock products. A file written without any kept ProcessBlock products will be identical to a file written by a version of CMSSW that predates this PR. If no ProcessBlock products are read from input or kept in the output the added overheads in terms of CPU and memory should be negligible. And the behavior and output of a cmsRun job should not be affected at all.

Nothing should change in the output of existing workflows until future code changes are merged that cause ProcessBlock products to be saved to output files.

@cmsbuild
Copy link
Contributor

cmsbuild commented Jun 3, 2021

+code-checks

Logs: https://cmssdt.cern.ch/SDT/code-checks/cms-sw-PR-33969/23063

@cmsbuild
Copy link
Contributor

cmsbuild commented Jun 3, 2021

A new Pull Request was created by @wddgit (W. David Dagenhart) for master.

It involves the following packages:

DQMServices/FwkIO
DataFormats/Provenance
FWCore/Common
FWCore/Framework
FWCore/Integration
FWCore/ServiceRegistry
FWCore/Services
FWCore/Sources
FWCore/TFWLiteSelector
FWCore/TestProcessor
FWCore/Utilities
IOPool/Input
IOPool/Output
Mixing/Base

@smuzaffar, @civanch, @Dr15Jones, @kmaeshima, @andrius-k, @mdhildreth, @ErnestaP, @cmsbuild, @makortel, @jfernan2, @ahmad3213, @rvenditti can you please review it and eventually sign? Thanks.
@barvic, @makortel, @felicepantaleo, @rovere, @fwyzard, @fabiocos this is something you requested to watch as well.
@silviodonato, @dpiparo, @qliphy you are the release manager for this.

cms-bot commands are listed here

@wddgit
Copy link
Contributor Author

wddgit commented Jun 3, 2021

please test

@cmsbuild
Copy link
Contributor

cmsbuild commented Jun 4, 2021

+1

Summary: https://cmssdt.cern.ch/SDT/jenkins-artifacts/pull-request-integration/PR-6e4464/15627/summary.html
COMMIT: 13bddf4
CMSSW: CMSSW_12_0_X_2021-06-03-1100/slc7_amd64_gcc900
User test area: For local testing, you can use /cvmfs/cms-ci.cern.ch/week1/cms-sw/cmssw/33969/15627/install.sh to create a dev area with all the needed externals and cmssw changes.

Comparison Summary

Summary:

  • No significant changes to the logs found
  • Reco comparison results: 0 differences found in the comparisons
  • DQMHistoTests: Total files compared: 37
  • DQMHistoTests: Total histograms compared: 2650486
  • DQMHistoTests: Total failures: 1
  • DQMHistoTests: Total nulls: 0
  • DQMHistoTests: Total successes: 2650463
  • DQMHistoTests: Total skipped: 22
  • DQMHistoTests: Total Missing objects: 0
  • DQMHistoSizes: Histogram memory added: 0.0 KiB( 36 files compared)
  • Checked 155 log files, 37 edm output root files, 37 DQM output files
  • TriggerResults: no differences found

@jfernan2
Copy link
Contributor

jfernan2 commented Jun 4, 2021

+1

@civanch
Copy link
Contributor

civanch commented Jun 4, 2021

+1

Copy link
Contributor

@makortel makortel left a comment

Choose a reason for hiding this comment

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

Reviewed up to FWCore/Framework/interface/Frameworkfwd.h.


namespace edm {

StoredProcessBlockHelper::StoredProcessBlockHelper() {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
StoredProcessBlockHelper::StoredProcessBlockHelper() {}
StoredProcessBlockHelper::StoredProcessBlockHelper() = default;

would be tiny bit better ().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. That is better.

}

SECTION("Constructor") {
std::vector<std::string> testStrings{std::string("test1"), std::string("test2"), std::string("test3")};
Copy link
Contributor

Choose a reason for hiding this comment

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

How about

Suggested change
std::vector<std::string> testStrings{std::string("test1"), std::string("test2"), std::string("test3")};
std::vector<std::string> testStrings{"test1", "test2", "test3"};

?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. That is better.


edm::StoredProcessBlockHelper const* storedProcessBlockHelperConstPtr = &storedProcessBlockHelper;
REQUIRE(storedProcessBlockHelperConstPtr->processesWithProcessBlockProducts().empty());
REQUIRE(storedProcessBlockHelperConstPtr->processBlockCacheIndices().empty());
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the point of these two tests wrt. the ones on lines 14-15 that the functions can be called from a const object?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are two different function overloads for each of those functions, one const and one non-const. I was just trying to force all the functions to get called in the test. Maybe overkill for such trivial functions...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When I changed StoredProcessBlockAccessor to use set* functions instead of const accessors, I deleted this because it was not needed anymore.


bool productsFromInputKept() const { return productsFromInputKept_; }

static constexpr unsigned int invalidCacheIndex() { return 0xffffffff; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this invalidCacheIndex() the same as StoredProcessBlockHelper::invalidCacheIndex()? (I don't mean by value but by functionality, i.e. if one of them would be changed for some reason, would the other need to be changed)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for noticing this. After looking at this more closely, I realize that we only need the functions invalidCacheIndex and invalidProcessIndex defined in ProcessBlockHelperBase. The ones in StoredProcessBlockHelper and OutputProcessBlockHelper can be deleted. I am implementing this change now and it will be in the next set of commits I push.

StoredProcessBlockHelper does not need to know these special values at all. In an earlier version, I had some non-trivial functions in StoredProcessBlockHelper. But I moved those out of that class because it is a DataFormat. And it is not a problem for OutputProcessBlockHelper.cc to use the value from ProcessBlockHelperBase. It already includes the header. Much better to remove this duplication.


class ProcessBlockHelperBase {
public:
virtual ~ProcessBlockHelperBase() = default;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you move the definition to the .cc file (i.e. ProcessBlockHelperBase::~ProcessBlockHelperBase() = default;)?

In my recollection it is still beneficial for the vtable placement to have one of the virtual functions to defined in the .cc file (and in this case all others are pure virtual).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Thanks.

Comment on lines +47 to +54
static constexpr unsigned int invalidCacheIndex() { return 0xffffffff; }
static constexpr unsigned int invalidProcessIndex() { return 0xffffffff; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these functionally the same as in StoredProcessBlockHelper?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is fixed now. See response to related comment above in OutputProcessBlockHelper.h

Comment on lines 38 to 47
unsigned int position = 0;
bool found = false;
for (auto const& processFromHelper : processesWithProcessBlockProducts_) {
if (processFromHelper == desc.processName()) {
found = true;
break;
}
++position;
}
if (found && position >= bestPosition) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this could be replaced with std::find_if() along

Suggested change
unsigned int position = 0;
bool found = false;
for (auto const& processFromHelper : processesWithProcessBlockProducts_) {
if (processFromHelper == desc.processName()) {
found = true;
break;
}
++position;
}
if (found && position >= bestPosition) {
auto found = std::find_if(processesWithProcessBlockProducts_.begin(),
processesWithProcessBlockProducts_.end(),
[&desc](auto const& processFromHelper) {
return processFromHelper == desc.processName());
});
if (found != processesWithProcessBlockProducts_.end()) {
const unsigned int position = std::distance(processesWithProcessBlockProducts_.begin(), found);
if (position >= bestPosition) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. That is better. Thanks.

public:
virtual ~ProcessBlockHelperBase() = default;

std::vector<std::string>& processesWithProcessBlockProducts() { return processesWithProcessBlockProducts_; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the non-const accessor ("setter") used anywhere else than in the test code? There I'd find something along setProcessWithProcessBlockProducts() to be more clear (because of existing patterns elsewhere in the codebase).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I replaced the non-const accessor with the following two functions:

    void setProcessesWithProcessBlockProducts(std::vector<std::string> const& val)
    void emplaceBackProcessName(std::string const& processName)

Also fixed the related test

return processesWithProcessBlockProducts_;
}

std::vector<std::string>& addedProcesses() { return addedProcesses_; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Same question on non-const accessor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I replaced the non-const accessor with the following two functions:

void setAddedProcesses(std::vector<std::string> const& val)
void emplaceBackAddedProcessName(std::string const& processName)

Also fixed the related test

Comment on lines 81 to 82
std::vector<TTree*>&& processBlockTrees,
std::vector<std::string>&& processesWithProcessBlockTrees,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
std::vector<TTree*>&& processBlockTrees,
std::vector<std::string>&& processesWithProcessBlockTrees,
std::vector<TTree*> processBlockTrees,
std::vector<std::string> processesWithProcessBlockTrees,

would be a bit more general (allows call site to not move the arguments) with at most one move-constructor call more. Or is there a reason to require the caller to move the arguments (or construct temporaries)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. That is better. I made the same change to the FileBlock update function. At the moment these are both only called from one call site in RootFile.cc, but the extra flexibility might be useful someday.

Copy link
Contributor

@makortel makortel left a comment

Choose a reason for hiding this comment

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

More comments, up to FWCore/Framework/interface/WorkerManager.h.

}

struct TokenInfo {
public:
Copy link
Contributor

Choose a reason for hiding this comment

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

struct is public by default

Suggested change
public:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

}

// This gets used for stream type modules instead of registerProcessBlockCacheFiller
void copyProcessBlockCacheFiller(std::vector<edm::impl::TokenInfo>& tokenInfos,
Copy link
Contributor

Choose a reason for hiding this comment

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

Given that the arguments are moved from, would moveProcessBlockCacheFiller() be a better name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, I agree that name is better.

Comment on lines 216 to 218
std::get<ICacheType>(functors_).func_ =
std::function<std::shared_ptr<CacheType>(ProcessBlock const&, std::shared_ptr<CacheType> const&)>(
std::forward<Func>(func));
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the explicit type on the right hand side really needed, or would the following work?

Suggested change
std::get<ICacheType>(functors_).func_ =
std::function<std::shared_ptr<CacheType>(ProcessBlock const&, std::shared_ptr<CacheType> const&)>(
std::forward<Func>(func));
std::get<ICacheType>(functors_).func_ = std::forward<Func>(func);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. It compiles and it works. I agree it is easier to read using the implicit type conversion.

read from a EDM/ROOT file. This source should provide for delayed loading
of data, thus the quotation marks around contain.
3) DAQSource: creats EventPrincipals which contain raw data, as
delivered by the L1 trigger and event builder.
Copy link
Contributor

Choose a reason for hiding this comment

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

Have the removed comments become (or long been) obsolete?

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 think these comments have been obsolete for more than 10 years.

@@ -467,6 +485,16 @@ namespace edm {

InputSource::RunSourceSentry::~RunSourceSentry() { source_.actReg()->postSourceRunSignal_(index_); }

InputSource::ProcessBlockSourceSentry::ProcessBlockSourceSentry(InputSource const& source,
std::string const& processName)
: source_(source), processName_(processName) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I know we follow this pattern elsewhere too, but storing const references this way is potentially dangerous, because the const reference arguments bind to temporaries. Somehow the std::string const& looks more dangerous to my eye than the InputSource const& (can't really explain why). E.g. if we would ever change processBlockPrincipal.processName() to return a copy of the string, std::string_view, or char const*, the processName_ would be an invalid reference.

Changing the pattern elsewhere is clearly out of scope of this PR, but I wonder if we should at least consider taking the arguments e.g. by pointer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I understand your general concern with this pattern. It requires an awareness that the object held by reference stays alive longer than the object holding the reference. Maybe it is not so bad for sentries where the intent is for them to go out of scope relatively soon. (mostly here I just copied what we do for Runs...)

I checked and the string is a data member of the ProcessBlockPrincipal. The ProcessBlockPrincipal lives until EventProcessor gets destroyed at the very end of the process. It gets reused as necessary, not destroyed. At the moment, there isn't an actual problem where the variable goes out of scope. I think it is unlikely that we change the code such that the string becomes invalid before readProcessBlock completes.

How does a pointer help? If the object goes away, then the pointer is as invalid as the reference.

We could have the sentry hold the string as a data member (neither pointer nor reference). It could just copy it. I imagine the cost of creating one short string each time we read a ProcessBlock would be negligible. I could do that if you want.

The InputSource is more difficult. We could use a shared_ptr as an argument. Currently, it is held by a unique_ptr in EventProcessor and also lives until the EventProcessor is destroyed.

My first inclination is to leave this as is. If you want me to change it, let me know and I will.

Copy link
Contributor

Choose a reason for hiding this comment

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

My first inclination is to leave this as is

I would keep it as it is in this PR (for consistency, and to avoid "feature creep"), and possibly address the issue later with a separate PR.

How does a pointer help?

Function foo(string const&) binds to temporary strings (e.g. foo("bar")), whereas foo(string const*) does not (foo(&std:string("bar")) gives an error by default). Therefore, in general, taking objects whose address is stored (either as a pointer or a reference) for longer time than the function by pointer helps to catch cases where a temporary object is given.

I completely believe we don't have a real problem now. I'm more concerned of the general pattern (and towards heavier refactoring where object lifetimes could change).

Copy link
Contributor

@Dr15Jones Dr15Jones left a comment

Choose a reason for hiding this comment

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

Got up to FWCore/Framework changes

void setIndex(unsigned int value) { index_ = value; }

private:
unsigned int index_ = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is index 0 not allowed for actual uses?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

PoolSource always calls setIndex and explicitly sets the value of index_ for every event and this is saved in EventPrincipal via the function fillEventPrincipal. Zero is an allowed and legal value. For all other sources, there is still an EventToProcessBlockIndexes object in EventPrincipal. It holds the zero that comes from line 20, but it is never used for any purpose.

// This constructor exists for ROOT I/O
StoredProcessBlockHelper();

StoredProcessBlockHelper(std::vector<std::string> const& processesWithProcessBlockProducts);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
StoredProcessBlockHelper(std::vector<std::string> const& processesWithProcessBlockProducts);
explicit StoredProcessBlockHelper(std::vector<std::string> const& processesWithProcessBlockProducts);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Thanks.

return processesWithProcessBlockProducts_;
}

std::vector<std::string>& processesWithProcessBlockProducts() { return processesWithProcessBlockProducts_; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this instead of our regular set method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I changed it to use set methods which are preferred in the CMS style guide.

std::string const eventHistory = "EventHistory";
std::string const eventBranchMapper = "EventBranchMapper";

std::string const eventSelections = "EventSelections";
std::string const branchListIndexes = "BranchListIndexes";
std::string const eventToProcessBlockIndexes = "EventToProcessBlockIndexes";
Copy link
Contributor

Choose a reason for hiding this comment

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

Thought for the future. Given we now have std::string_view which can be constexpr we should probably change all of these and the accessor methods to use std::string_view just to avoid the runtime intialization.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see that for C++20 std::string constructor is also constexpr capable so maybe the idea is moot.

ProcessBlockHelperBase const* processBlockHelper() const { return processBlockHelper_; }

// These are intended to be used only for testing purposes
std::vector<unsigned int> const& translateFromStoredIndex() const { return translateFromStoredIndex_; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Using a friend could allow you to enforce this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I think I like it. A little strange to declare a class defined in FWCore/Integration as a friend in FWCore/Common, but I suppose there is not really any real dependence...

std::vector<unsigned int> const& storedCacheIndices,
std::vector<unsigned int>&& nEntries);

void fillEntriesFromPrimaryInput(std::vector<unsigned int>&& nEntries);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why use of &&? Value semantics is more in line with present C++ best practices.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I fixed three functions in this file with && arguments. One is now by value and the other two I changed to const&.


class SubProcessBlockHelper : public ProcessBlockHelperBase {
public:
ProcessBlockHelperBase const* topProcessBlockHelper() const override;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is final more appropriate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I changed override to final. This is the other class that inherits from ProcessBlockHelperBase.

std::vector<std::vector<unsigned int>> const& nEntries,
std::vector<unsigned int>& storedProcessOffset) const {
for (unsigned int iStored = 0; iStored < nInputProcesses + 1; ++iStored) {
storedProcessOffset[iStored] = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

What guarantees do you have that storedProcessOffset.size() >= nInputProcesses?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the loop to a ranged-for loop.

Maybe it is a little less error prone and more readable this way. Definitely the more modern style. To answer your question, the vector was initialized as follows and the size of it never changes:

std::vector<unsigned int> storedProcessOffset(nInputProcesses + 1, 0);

Originally, it seemed kind of intuitive to use an integer loop since this code is all about manipulating integer indexes and the index needs to be calculated even if it is not part of the loop. Usually, I am a big fan of ranged-for loops. I like them.

std::vector<std::vector<unsigned int>> const& nEntries,
std::vector<unsigned int>& processOffset) const {
for (unsigned int iStored = 0; iStored < nInputProcesses; ++iStored) {
processOffset[iStored] = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

same here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the loop to a ranged for loop. Same comments as above.

std::vector<std::vector<unsigned int>> const& nEntries,
std::vector<unsigned int>& storedFileInProcessOffset) const {
for (unsigned int iStored = 0; iStored < nInputProcesses; ++iStored) {
storedFileInProcessOffset[iStored] = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

same here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the loop to a ranged for loop. Same comments as above.

Copy link
Contributor

@makortel makortel left a comment

Choose a reason for hiding this comment

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

Reviewed up to FWCore/Framework/src/EventForOutput.cc.

@@ -131,9 +130,6 @@ namespace edm {
template <module::Abilities ABILITY, typename T, typename... VArgs>
struct CheckAbility<ABILITY, T, VArgs...> {
static constexpr bool kHasIt = (T::kAbilities == ABILITY) | CheckAbility<ABILITY, VArgs...>::kHasIt;
typedef std::
conditional_t<(T::kAbilities == ABILITY), typename T::Type, typename CheckAbility<ABILITY, VArgs...>::Type>
Type;
Copy link
Contributor

Choose a reason for hiding this comment

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

Did this type alias turn out to be unnecessary?

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. The typedef is not used anywhere in CMSSW so I deleted it. As I was double checking this, I noticed this TYPE typedef appears again 6 lines below, so I deleted that one also.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Move this deletion to a separate PR. #34406

@wddgit
Copy link
Contributor Author

wddgit commented Jul 9, 2021

I was hoping the dependent tests would not run. I can believe this might be necessary, but...

In the case of this test (see last commit), tests after a failure will likely all fail. It will be similar to the way compilation failures show up. We will need to look for the first failure and the rest of the failures will probably be a consequence of the first failure. I was hoping the cleanup step would not run when a failure occurred. As it is written now that cleanup would remove all the the log files until it hit a file that was never created. I could change the "rm" to "rm -rf", then it would be consistent. I am still thinking about this, if someone has a better idea...

@smuzaffar
Copy link
Contributor

smuzaffar commented Jul 9, 2021

@wddgit , I can update buildrules so that dependent test still fails but with error message that one of its dependency failed.

@wddgit
Copy link
Contributor Author

wddgit commented Jul 9, 2021

That would be better.

One thought, I am not sure if this is a good idea. Could an environment variable be set so the test could know something it depends on failed?

@smuzaffar
Copy link
Contributor

@wddgit , I was thinking of not even starting the dependent test and only write the error message with the failed dependencies name in the log of dependent test.

@wddgit
Copy link
Contributor Author

wddgit commented Jul 9, 2021

Even better. That sounds good.

@cmsbuild
Copy link
Contributor

cmsbuild commented Jul 9, 2021

+1

Summary: https://cmssdt.cern.ch/SDT/jenkins-artifacts/pull-request-integration/PR-6e4464/16663/summary.html
COMMIT: 6ecbb27
CMSSW: CMSSW_12_0_X_2021-07-09-0800/slc7_amd64_gcc900
User test area: For local testing, you can use /cvmfs/cms-ci.cern.ch/week0/cms-sw/cmssw/33969/16663/install.sh to create a dev area with all the needed externals and cmssw changes.

Comparison Summary

Summary:

  • No significant changes to the logs found
  • Reco comparison results: 0 differences found in the comparisons
  • DQMHistoTests: Total files compared: 38
  • DQMHistoTests: Total histograms compared: 2786260
  • DQMHistoTests: Total failures: 1
  • DQMHistoTests: Total nulls: 0
  • DQMHistoTests: Total successes: 2786237
  • DQMHistoTests: Total skipped: 22
  • DQMHistoTests: Total Missing objects: 0
  • DQMHistoSizes: Histogram memory added: 0.0 KiB( 37 files compared)
  • Checked 160 log files, 37 edm output root files, 38 DQM output files
  • TriggerResults: no differences found

1 similar comment
@cmsbuild
Copy link
Contributor

cmsbuild commented Jul 9, 2021

+1

Summary: https://cmssdt.cern.ch/SDT/jenkins-artifacts/pull-request-integration/PR-6e4464/16663/summary.html
COMMIT: 6ecbb27
CMSSW: CMSSW_12_0_X_2021-07-09-0800/slc7_amd64_gcc900
User test area: For local testing, you can use /cvmfs/cms-ci.cern.ch/week0/cms-sw/cmssw/33969/16663/install.sh to create a dev area with all the needed externals and cmssw changes.

Comparison Summary

Summary:

  • No significant changes to the logs found
  • Reco comparison results: 0 differences found in the comparisons
  • DQMHistoTests: Total files compared: 38
  • DQMHistoTests: Total histograms compared: 2786260
  • DQMHistoTests: Total failures: 1
  • DQMHistoTests: Total nulls: 0
  • DQMHistoTests: Total successes: 2786237
  • DQMHistoTests: Total skipped: 22
  • DQMHistoTests: Total Missing objects: 0
  • DQMHistoSizes: Histogram memory added: 0.0 KiB( 37 files compared)
  • Checked 160 log files, 37 edm output root files, 38 DQM output files
  • TriggerResults: no differences found

@wddgit
Copy link
Contributor Author

wddgit commented Jul 9, 2021

Tests passed and I've replied to all comments received so far and fixed everything I know that needed fixing. I am just waiting for more comments from Chris now and after that for approvals.

@makortel
Copy link
Contributor

On these specific points (from #33969 (comment))

  • FWCore/Framework/src/ProductResolvers.cc Do we need DelayedGetSignals for ProcessBlock products? (originally in a 6 June comment)

I'd say not for now.

  • FWCore/TFWLiteSelector/src/TFWLiteSelectorBasic.cc Should I add another overload for fillEventPrincipal?

I'd say not worth it.

  • FWCore/Integration/test/run_TestProcessBlock.sh Question about directing output to log files?

As you wrote, this is really a wider question and really beyond this PR. Not worth of preventing this PR being merged.

@makortel
Copy link
Contributor

+1

@jfernan2
Copy link
Contributor

+1

@wddgit
Copy link
Contributor Author

wddgit commented Jul 15, 2021

@civanch The simulation parts (in Mixing/Base) of this have not changed since you approved this about a month ago (thanks). Just letting you know that recently all the other review/changes were completed and all the other approvals are in, so if you could take a look again...

@makortel I actually changed the test to redirect the output to log files. If the test completes successfully, they all get deleted in a cleanup "test". If not, I think the cleanup step does not run and they will be available to look at in the tmp subdirectory (assuming my understanding of what scram will do is correct).

@civanch
Copy link
Contributor

civanch commented Jul 15, 2021

+1

@cmsbuild
Copy link
Contributor

This pull request is fully signed and it will be integrated in one of the next master IBs (tests are also fine). This pull request will now be reviewed by the release team before it's merged. @silviodonato, @dpiparo, @qliphy, @perrotta (and backports should be raised in the release meeting by the corresponding L2)

@perrotta
Copy link
Contributor

+1
(Extensively reviewed, and finally approved, by the core group)

@cmsbuild cmsbuild merged commit 7e1bd4e into cms-sw:master Jul 18, 2021
@wddgit wddgit deleted the ProcessBlockPersistence21 branch May 2, 2022 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants