GooFit  v2.1.3
ProdPdf.cu
Go to the documentation of this file.
1 #include <algorithm>
2 #include <goofit/PDFs/combine/ProdPdf.h>
3 
4 namespace GooFit {
5 
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
9 
10  int numParams = RO_CACHE(indices[0]);
11  fptype ret = 1;
12 
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]);
16 
17  // fptype curr = (*(reinterpret_cast<device_function_ptr>(device_function_table[fcnIdx])))(evt, p, paramIndices
18  // + parIdx);
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);
24  ret *= curr;
25 
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))
28  // if (0.0001 < ret)
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);
37  }
38 
39  return ret;
40 }
41 
42 __device__ device_function_ptr ptr_to_ProdPdfs = device_ProdPdfs;
43 
44 ProdPdf::ProdPdf(std::string n, std::vector<PdfBase *> comps)
45  : GooPdf(n)
46  , varOverlaps(false) {
47  std::vector<unsigned int> pindices;
48 
49  for(PdfBase *p : comps) {
50  components.push_back(p);
51  }
52 
53  observables = getObservables(); // Gathers from components
54 
55  std::vector<Observable> observableCheck; // Use to check for overlap in observables
56 
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());
61 
62  if(varOverlaps)
63  continue; // Only need to establish this once.
64 
65  std::vector<Observable> currObses = p->getObservables();
66 
67  for(Observable &o : currObses) {
68  if(find(observableCheck.begin(), observableCheck.end(), o) == observableCheck.end())
69  continue;
70 
71  varOverlaps = true;
72  break;
73  }
74 
75  observableCheck = p->getObservables();
76  }
77 
78  if(varOverlaps) { // Check for components forcing separate normalisation
79  for(PdfBase *p : comps) {
80  if(p->getSpecialMask() & PdfBase::ForceSeparateNorm)
81  varOverlaps = false;
82  }
83  }
84 
85  GET_FUNCTION_ADDR(ptr_to_ProdPdfs);
86  initialize(pindices);
87 }
88 
89 __host__ fptype ProdPdf::normalize() const {
90  if(varOverlaps) {
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));
94  MEMCPY_TO_SYMBOL(
95  normalisationFactors, host_normalisation, totalParams * sizeof(fptype), 0, cudaMemcpyHostToDevice);
96 
97  // Normalize numerically.
98  // std::cout << "Numerical normalisation of " << getName() << " due to varOverlaps.\n";
99  fptype ret = GooPdf::normalize();
100  // if (cpuDebug & 1)
101  // std::cout << "ProdPdf " << getName() << " has normalisation " << ret << " " << host_callnumber << std::endl;
102  return ret;
103  }
104 
105  // Normalize components individually
106  for(PdfBase *c : components) {
107  c->normalize();
108  }
109 
110  host_normalisation[parameters] = 1;
111  MEMCPY_TO_SYMBOL(normalisationFactors, host_normalisation, totalParams * sizeof(fptype), 0, cudaMemcpyHostToDevice);
112 
113  return 1.0;
114 }
115 } // namespace GooFit