Skip to content

Commit

Permalink
Merge pull request #43988 from makortel/esproducerLambda
Browse files Browse the repository at this point in the history
Fix ESProducerExternalWork::setWhatAcquiredProducedWithLambda()
  • Loading branch information
cmsbuild authored Feb 19, 2024
2 parents 08a010d + bbf6db2 commit 1cfa1e5
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 43 deletions.
5 changes: 2 additions & 3 deletions FWCore/Framework/interface/ESProducerExternalWork.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,9 @@ namespace edm {
TProduceFunc&& produceFunc,
const es::Label& iLabel = {}) {
using AcquireTypes = eventsetup::impl::ReturnArgumentTypes<TAcquireFunc>;
using TRecord = typename AcquireTypes::argument_type;
using TAcquireReturn = typename AcquireTypes::return_type;
using ProduceTypes = eventsetup::impl::ReturnArgumentTypes<TProduceFunc>;
using TProduceReturn = typename ProduceTypes::return_type;
using TRecord = typename ProduceTypes::argument_type;
using TProduceReturn = std::invoke_result_t<TProduceFunc, TRecord const&, TAcquireReturn>;
using DecoratorType = eventsetup::CallbackSimpleDecorator<TRecord>;

return setWhatAcquiredProducedWithLambda<TAcquireReturn, TProduceReturn, TRecord>(
Expand Down
102 changes: 62 additions & 40 deletions FWCore/Framework/interface/es_impl/ReturnArgumentTypes.h
Original file line number Diff line number Diff line change
@@ -1,45 +1,67 @@
#ifndef FWCore_Framework_interface_es_impl_ReturnArgumentTypes_h
#define FWCore_Framework_interface_es_impl_ReturnArgumentTypes_h

namespace edm::eventsetup::impl {
template <typename F>
struct ReturnArgumentTypesImpl;

// function pointer
template <typename R, typename T>
struct ReturnArgumentTypesImpl<R (*)(T const&)> {
using argument_type = T;
using return_type = R;
};

// mutable functor/lambda
template <typename R, typename T, typename O>
struct ReturnArgumentTypesImpl<R (O::*)(T const&)> {
using argument_type = T;
using return_type = R;
};

// const functor/lambda
template <typename R, typename T, typename O>
struct ReturnArgumentTypesImpl<R (O::*)(T const&) const> {
using argument_type = T;
using return_type = R;
};

template <typename F, typename = void>
struct ReturnArgumentTypes;

template <typename F>
struct ReturnArgumentTypes<F, std::enable_if_t<std::is_class_v<F>>> {
using argument_type = typename ReturnArgumentTypesImpl<decltype(&F::operator())>::argument_type;
using return_type = typename ReturnArgumentTypesImpl<decltype(&F::operator())>::return_type;
};

template <typename F>
struct ReturnArgumentTypes<F, std::enable_if_t<std::is_pointer_v<F>>> {
using argument_type = typename ReturnArgumentTypesImpl<F>::argument_type;
using return_type = typename ReturnArgumentTypesImpl<F>::return_type;
};
} // namespace edm::eventsetup::impl
namespace edm {
class WaitingTaskWithArenaHolder;

namespace eventsetup::impl {
template <typename F>
struct ReturnArgumentTypesImpl;

// function pointer
template <typename R, typename T>
struct ReturnArgumentTypesImpl<R (*)(T const&)> {
using argument_type = T;
using return_type = R;
};
template <typename R, typename T>
struct ReturnArgumentTypesImpl<R (*)(T const&, WaitingTaskWithArenaHolder)> {
using argument_type = T;
using return_type = R;
};

// mutable functor/lambda
template <typename R, typename T, typename O>
struct ReturnArgumentTypesImpl<R (O::*)(T const&)> {
using argument_type = T;
using return_type = R;
};
template <typename R, typename T, typename O>
struct ReturnArgumentTypesImpl<R (O::*)(T const&, WaitingTaskWithArenaHolder)> {
using argument_type = T;
using return_type = R;
};

// const functor/lambda
template <typename R, typename T, typename O>
struct ReturnArgumentTypesImpl<R (O::*)(T const&) const> {
using argument_type = T;
using return_type = R;
};
template <typename R, typename T, typename O>
struct ReturnArgumentTypesImpl<R (O::*)(T const&, WaitingTaskWithArenaHolder) const> {
using argument_type = T;
using return_type = R;
};

//////////

template <typename F, typename = void>
struct ReturnArgumentTypes;

template <typename F>
struct ReturnArgumentTypes<F, std::enable_if_t<std::is_class_v<F>>> {
using argument_type = typename ReturnArgumentTypesImpl<decltype(&F::operator())>::argument_type;
using return_type = typename ReturnArgumentTypesImpl<decltype(&F::operator())>::return_type;
};

template <typename F>
struct ReturnArgumentTypes<F, std::enable_if_t<std::is_pointer_v<F>>> {
using argument_type = typename ReturnArgumentTypesImpl<F>::argument_type;
using return_type = typename ReturnArgumentTypesImpl<F>::return_type;
};

} // namespace eventsetup::impl
} // namespace edm

#endif
40 changes: 40 additions & 0 deletions FWCore/Integration/plugins/AcquireIntESProducer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ namespace edmtest {
const unsigned int secondsToWaitForWork_;
std::vector<TestValue*> uniqueTestPointers_;
std::vector<TestValue*> optionalTestPointers_;
std::vector<TestValue*> lambdaUniqueTestPointers_;
std::vector<TestValue*> lambdaOptionalTestPointers_;
};

AcquireIntESProducer::AcquireIntESProducer(edm::ParameterSet const& pset)
Expand All @@ -103,6 +105,42 @@ namespace edmtest {
&AcquireIntESProducer::acquireOptional,
&AcquireIntESProducer::produceOptional,
edm::es::Label("optional"));

setWhatAcquiredProducedWithLambda(
[this](ESTestRecordI const& record, edm::WaitingTaskWithArenaHolder holder) {
usleep(200000);
auto returnValue = std::make_unique<TestValue>(kAcquireTestValueUniquePtr1);
lambdaUniqueTestPointers_[record.iovIndex()] = returnValue.get();
return returnValue;
},
[this](ESTestRecordI const& record, auto testValue) {
usleep(200000);
if (testValue.get() != lambdaUniqueTestPointers_[record.iovIndex()]) {
throw cms::Exception("TestFailure") << "AcquireIntESProducer::<lambda produceUniquePtr>"
<< " unexpected value passed in as argument";
}
return std::make_unique<ESTestDataI>(kAcquireTestValueUniquePtr2);
},
edm::es::Label("uniquePtrLambda"));

setWhatAcquiredProducedWithLambda(
[this](ESTestRecordI const& record, edm::WaitingTaskWithArenaHolder holder) {
usleep(200000);
std::vector<TestValue> testVector;
testVector.push_back(kAcquireTestValueOptional1);
auto returnValue = std::make_optional<std::vector<TestValue>>(std::move(testVector));
lambdaOptionalTestPointers_[record.iovIndex()] = &returnValue.value()[0];
return returnValue;
},
[this](ESTestRecordI const& record, std::optional<std::vector<TestValue>> testValue) {
usleep(200000);
if (&testValue.value()[0] != lambdaOptionalTestPointers_[record.iovIndex()]) {
throw cms::Exception("TestFailure") << "AcquireIntESProducer::<lambda produceOptional>"
<< " unexpected value passed in as argument";
}
return std::make_unique<ESTestDataI>(kAcquireTestValueOptional2);
},
edm::es::Label("optionalLambda"));
}

AcquireIntESProducer::~AcquireIntESProducer() {
Expand All @@ -120,6 +158,8 @@ namespace edmtest {
server_->start();
uniqueTestPointers_.resize(nConcurrentIOVs);
optionalTestPointers_.resize(nConcurrentIOVs);
lambdaUniqueTestPointers_.resize(nConcurrentIOVs);
lambdaOptionalTestPointers_.resize(nConcurrentIOVs);
}
}

Expand Down
14 changes: 14 additions & 0 deletions FWCore/Integration/plugins/ConcurrentIOVAnalyzer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ namespace edmtest {
edm::ESGetToken<ESTestDataI, ESTestRecordI> esTokenFromAcquireIntESProducer_;
std::vector<int> expectedESAcquireTestResults_;
edm::ESGetToken<ESTestDataI, ESTestRecordI> esTokenUniquePtrTestValue_;
edm::ESGetToken<ESTestDataI, ESTestRecordI> esTokenLambdaUniquePtrTestValue_;
int expectedUniquePtrTestValue_;
edm::ESGetToken<ESTestDataI, ESTestRecordI> esTokenOptionalTestValue_;
edm::ESGetToken<ESTestDataI, ESTestRecordI> esTokenLambdaOptionalTestValue_;
int expectedOptionalTestValue_;
};

Expand All @@ -63,9 +65,11 @@ namespace edmtest {
}
if (expectedUniquePtrTestValue_ != 0) {
esTokenUniquePtrTestValue_ = esConsumes(edm::ESInputTag("", "uniquePtr"));
esTokenLambdaUniquePtrTestValue_ = esConsumes(edm::ESInputTag("", "uniquePtrLambda"));
}
if (expectedOptionalTestValue_ != 0) {
esTokenOptionalTestValue_ = esConsumes(edm::ESInputTag("", "optional"));
esTokenLambdaOptionalTestValue_ = esConsumes(edm::ESInputTag("", "optionalLambda"));
}
}

Expand Down Expand Up @@ -113,13 +117,23 @@ namespace edmtest {
<< "ConcurrentIOVAnalyzer::analyze,"
<< " value for unique_ptr test from EventSetup does not match expected value";
}
if (eventSetup.getData(esTokenLambdaUniquePtrTestValue_).value() != expectedUniquePtrTestValue_) {
throw cms::Exception("TestFailure")
<< "ConcurrentIOVAnalyzer::analyze,"
<< " value for lambda unique_ptr test from EventSetup does not match expected value";
}
}

if (expectedOptionalTestValue_ != 0) {
if (eventSetup.getData(esTokenOptionalTestValue_).value() != expectedOptionalTestValue_) {
throw cms::Exception("TestFailure") << "ConcurrentIOVAnalyzer::analyze,"
<< " value for optional test from EventSetup does not match expected value";
}
if (eventSetup.getData(esTokenLambdaOptionalTestValue_).value() != expectedOptionalTestValue_) {
throw cms::Exception("TestFailure")
<< "ConcurrentIOVAnalyzer::analyze,"
<< " value for lambda optional test from EventSetup does not match expected value";
}
}

if (!checkExpectedValues_) {
Expand Down

0 comments on commit 1cfa1e5

Please sign in to comment.