2 #include <goofit/PDFs/combine/ProdPdf.h>
6 __device__ fptype device_ProdPdfs(fptype *evt, fptype *p, unsigned int *indices) {
7 // Index structure is nP | F1 P1 | F2 P2 | ...
8 // where nP is number of parameters, Fs are function indices, and Ps are parameter indices
10 int numParams = RO_CACHE(indices[0]);
13 for(int i = 1; i < numParams; i += 2) {
14 int fcnIdx = RO_CACHE(indices[i + 0]);
15 int parIdx = RO_CACHE(indices[i + 1]);
17 // fptype curr = (*(reinterpret_cast<device_function_ptr>(device_function_table[fcnIdx])))(evt, p, paramIndices
19 fptype curr = callFunction(evt, fcnIdx, parIdx);
20 curr *= normalisationFactors[parIdx];
21 // if ((isnan(ret)) || (isnan(curr)) || (isnan(normalisationFactors[parIdx])) || (isinf(ret)) || (isinf(curr)))
22 // printf("device_Prod 2: (%f %f %f %f %f) %f %f %f %i %i %i\n", evt[0], evt[1], evt[2], evt[3], evt[4], curr,
23 // ret, normalisationFactors[parIdx], i, parIdx, numParams);
26 // if ((0 == THREADIDX) && (0 == BLOCKIDX) && (gpuDebug & 1) && (paramIndices + debugParamIndex == indices))
27 // if ((1 > (int) floor(0.5 + evt[8])) && (gpuDebug & 1) && (paramIndices + debugParamIndex == indices))
29 // if ((gpuDebug & 1) && (isnan(curr)) && (paramIndices + debugParamIndex == indices))
30 // if ((isnan(ret)) || (isnan(curr)) || (isnan(normalisationFactors[parIdx])))
31 // printf("device_Prod: (%f %f %f %f %f) %f %f %f %i %i %i\n", evt[0], evt[1], evt[2], evt[3], evt[4], curr,
32 // ret, normalisationFactors[parIdx], i, parIdx, numParams);
33 // printf("(%i, %i) device_Prod: (%f %f %f %f) %f %f %f %i\n", BLOCKIDX, THREADIDX, evt[0], evt[8], evt[6],
34 // evt[7], curr, ret, normalisationFactors[parIdx], i);
35 // printf("(%i, %i) device_Prod: (%f %f) %f %f %f %i\n", BLOCKIDX, THREADIDX, evt[0], evt[1], curr, ret,
36 // normalisationFactors[parIdx], i);
42 __device__ device_function_ptr ptr_to_ProdPdfs = device_ProdPdfs;
44 ProdPdf::ProdPdf(std::string n, std::vector<PdfBase *> comps)
46 , varOverlaps(false) {
47 std::vector<unsigned int> pindices;
49 for(PdfBase *p : comps) {
50 components.push_back(p);
53 observables = getObservables(); // Gathers from components
55 std::vector<Observable> observableCheck; // Use to check for overlap in observables
57 // Indices stores (function index)(function parameter index)(variable index) for each component.
58 for(PdfBase *p : comps) {
59 pindices.push_back(p->getFunctionIndex());
60 pindices.push_back(p->getParameterIndex());
63 continue; // Only need to establish this once.
65 std::vector<Observable> currObses = p->getObservables();
67 for(Observable &o : currObses) {
68 if(find(observableCheck.begin(), observableCheck.end(), o) == observableCheck.end())
75 observableCheck = p->getObservables();
78 if(varOverlaps) { // Check for components forcing separate normalisation
79 for(PdfBase *p : comps) {
80 if(p->getSpecialMask() & PdfBase::ForceSeparateNorm)
85 GET_FUNCTION_ADDR(ptr_to_ProdPdfs);
89 __host__ fptype ProdPdf::normalize() const {
91 // Two or more components share an observable and cannot be separately
92 // normalized, since \int A*B dx does not equal int A dx * int B dx.
93 recursiveSetNormalisation(fptype(1.0));
95 normalisationFactors, host_normalisation, totalParams * sizeof(fptype), 0, cudaMemcpyHostToDevice);
97 // Normalize numerically.
98 // std::cout << "Numerical normalisation of " << getName() << " due to varOverlaps.\n";
99 fptype ret = GooPdf::normalize();
101 // std::cout << "ProdPdf " << getName() << " has normalisation " << ret << " " << host_callnumber << std::endl;
105 // Normalize components individually
106 for(PdfBase *c : components) {
110 host_normalisation[parameters] = 1;
111 MEMCPY_TO_SYMBOL(normalisationFactors, host_normalisation, totalParams * sizeof(fptype), 0, cudaMemcpyHostToDevice);
115 } // namespace GooFit