Hydra 3.0.0
Hydra 3.0.0
It is the first release of the long-awaited 3 series. Overall, this release is expected to be faster
or at least to have similar performance to the previous releases.
There are many bug fixes and other changes across. The most significant ones are summarized below:
C++14 compiliant release
This release is the first C++14 compatible release. So, move the versions of NVCC, GCC, CLANG and so on, acordinaly.
Also, set the "--std" compiler flags to "--std=c++14" for both CUDA and host compilers.
The first the minimal CUDA version has now been moved to 9.2.
The support for extended C++ lambdas in CUDA is not complete. The restrictions are discussed in the page:
https://docs.nvidia.com/cuda/archive/10.2/cuda-c-programming-guide/index.html#extended-lambda
Hydra3 can not wrap generic lambdas in host code. If this feature is necessary, use host-only uwrapped lambdas.
Function call interface
This is probably the most impacting change in this release, making Hydra3 series backward incompatible with the previous series.
-
New interface for calling functors and lambdas.
a) Extensive statically-bound named parameter idiom support. This new idiom for specification of function call interfaces makes the definition callable objects in Hydra3 much more safe, straight forward, transparent and user friendly, without compromise performance. In many cases enhancing performance, indeed. From Hydra3, users will be able to define new types, with ad hoc names wrapping around primary types, using the macro
declarg(NewVar, Type)
.
These new types are searched in compile time to bind the function call, if the type
is not found a compile error is emitted, avoiding the generation of invalid or error prone code.
See how it works:... #include <hydra/functions/Gaussian.h> ... declarg(Angle, double) int main(int argv, char** argc) { ... auto gauss = hydra::Gaussian<Angle>(mean, signa); ... }
in the previous code snippet, wherever the object
gauss
is called, if the argument consists of one or tuples, which are the entry type of all multidimensional dataset classes in Hydra, theAngle
type identifier will be searched among the elements, if not found, code will not compile. If the argument is a non-tuple type, conversion will be tried. Multidimensional datasets can be defined using named parameters like in the snippet below:... #include <hydra/multivector.h> ... declarg(X, double) declarg(Y, double) declarg(Z, double) int main(int argv, char** argc) { //3D device buffer hydra::multivector< hydra::tuple<X,Y,Z>, hydra::device::sys_t> data(nentries); ... for(auto x: hydra::column<X>(data) std::cout << x << std::endl; }
b) Functors: as usual, it should derive from
hydra::BaseFunctor
, defined inhydra/Function.h
, but now the must inform their argument type, signature and number of parameters (hydra::Parameter
) at template instantiation time. It is also necessary to implement theResultType Evaluate(ArgType...)
method. Default constructors should be deleted, non-default and copy constructors, as well as assignments operators should be implemented as well. See how this works forhydra::Gaussian
://implementations omited, for complete details //see: hydra/functions/Gaussian.h template<typename ArgType, typename Signature=double(ArgType) > class Gaussian: public BaseFunctor<Gaussian<ArgType>, Signature, 2> { public: Gaussian()=delete; Gaussian(Parameter const& mean, Parameter const& sigma ); __hydra_host__ __hydra_device__ Gaussian(Gaussian<ArgType> const& other ); __hydra_host__ __hydra_device__ Gaussian<ArgType>& operator=(Gaussian<ArgType> const& other ); __hydra_host__ __hydra_device__ inline double Evaluate(ArgType x) const; };
c) Lambdas: Support for lambdas was updated to adhere the new interface. The new interface is implemented in `hydra/Lambda.h
... #include <hydra/multivector.h> #include <hydra/Lambda.h> ... declarg(X, double) declarg(Y, double) declarg(Z, double) int main(int argv, char** argc) { //3D device buffer hydra::multivector< hydra::tuple<X,Y,Z>, hydra::device::sys_t> data(nentries); //Lambda auto printer = hydra::wrap_lambda( []__hydra_dual__(X x, Y y){ print("x = %f y = %f", x(), y()); } ); for(auto entry: data) printer(entry); }
Random number generation
-
Support for analytical pseudo-random number generation (APRNG) added for many functors added via
hydra::Distribution<FunctorType>
specializations (see exampleexample/random/basic_distributions.inl
). -
Parallel filling of containers with random numbers (see example
example/random/fill_basic_distributions.inl
). In particular, there are some convenience functions in order to deploy in a generic and simple way the parallel filling of containers transparently, independently of the back-end. For a given instance of the functor of interest, the framework is informed of the presence of the APRNG method in compile time. If the APRNG
is not found a compile error is emitted, informing and suggesting the user to use thehydra::sample
interface, which implements a different filling strategy. The facility is decoupled from the underlying PRNG engine, in order to be compatible with the current pseudo-random engines already imlemented in Hydra, and future algorithms that will be made available over the time. If the user needs to use a specific PRNG engine, its type can be passed as template parameter to the convenience function, otherwise thehydra_thrust::default_random_engine
is used. As an example of filling of containers with random numbers see the snippet below:... #include <hydra/functions/Gaussian.h> ... declarg(Xvar, double) int main(int argv, char** argc) { ... auto gauss = hydra::Gaussian<Xvar>(mean, signa); auto data_d = hydra::device::vector<Xvar>(nentries); hydra::fill_random(data_d , gauss); ... }
The filling functions can be called also with a specific backend policy and with iterators instead of the whole container. The seed used by the PRNG engine can be also passed to the function as last parameter. The collection of all the convenience functions can be found in hydra/RandomFill.h
.
Phase-space generation
- Updated
hydra::Decays
container for supporting named variable idiom. - Changes in
hydra::PhaseSpace
andhydra::Decays
. - hydra::Chain not supported any more.
- New
Meld(...)
method inhydra::Decays
for building mixed datasets and decay chains. - Re-implemented logics for generation of events and associated weights.
Data fitting
-
Added support to multi-layered simultaneous fit of different models, over different datasets, deploying different parallelization strategies for each model. No categorization of the dataset is needed, but just to set up preliminarly the different component FCNs, that can be optimized in isolation or in the context of the simultaneous FCN. Simultaneous FCNs can be created via direct instantiation or using the convenience function
hydra::make_simultaneous_fcn(...)
, as shown in the following snippet.... #include <hydra/LogLikelihoodFCN.h> ... int main(int argv, char** argc) { ... //===================================================================================== // +----< fcn(model-x) // +----< simultaneous fcn 1 ----- | // | +----< fcn(model-y) // simultaneous fcn <----+ // | +----< fcn(model-w) // +----< simultaneous fcn 2 ------| // | +----< fcn(model-z) // +----< fcn(model-v) //===================================================================================== auto fcnX = hydra::make_loglikehood_fcn(modelX, dataX); auto fcnY = hydra::make_loglikehood_fcn(modelY, dataY); auto fcnW = hydra::make_loglikehood_fcn(modelY, dataY); auto fcnZ = hydra::make_loglikehood_fcn(modelZ, dataZ); auto fcnV = hydra::make_loglikehood_fcn(modelv, datav); auto sim_fcn1 = hydra::make_simultaneous_fcn(fcnx, fcny); auto sim_fcn2 = hydra::make_simultaneous_fcn(fcnw, fcnz); auto sim_fcn = hydra::make_simultaneous_fcn(sim_fcn1, sim_fcn2, fcnV); ... }
Moreover, the generic interface allows to build up a simultaneous FCN object by composing usual FCNs and simultaneous FCNs. An example of such new method can be found in
examples/fit/simultaneous_fit.inl
. -
Fitting of convoluted PDFs.
General
Many issues solved and bugs fixed across the tree:
1. https://github.com/MultithreadCorner/Hydra/issues/91#issue-631032116
2. https://github.com/MultithreadCorner/Hydra/issues/90
3. https://github.com/MultithreadCorner/Hydra/pull/89
4. https://github.com/MultithreadCorner/Hydra/issues/87
5. https://github.com/MultithreadCorner/Hydra/issues/86
6. https://github.com/MultithreadCorner/Hydra/issues/82
7. https://github.com/MultithreadCorner/Hydra/issues/77
and many others.
Acknowledgment note: Hydra's author is very thankful to all the people that in one way or another contributed to this release. In particular, Hydra's author would like to thanks Davide Brundu (@dbrundu) , for his generous contributions reporting bugs, sending some code and helping to expand the framework functionality.