25 #include <queso/Environment.h>
26 #include <queso/ScalarFunction.h>
27 #include <queso/ScalarFunctionSynchronizer.h>
28 #include <queso/BayesianJointPdf.h>
29 #include <queso/JointPdf.h>
30 #include <queso/GslVector.h>
31 #include <queso/GslMatrix.h>
36 template <
class V,
class M>
40 : m_env(inputFunction.domainSet().env()),
41 m_scalarFunction(inputFunction),
42 m_bayesianJointPdfPtr(dynamic_cast<const
BayesianJointPdf<V,M>* >(&m_scalarFunction)),
48 template <
class V,
class M>
54 template<
class V,
class M>
57 return m_scalarFunction.domainSet();
61 template <
class V,
class M>
63 const V* vecDirection,
68 double* extraOutput2)
const
72 if ((m_env.numSubEnvironments() < (
unsigned int) m_env.fullComm().NumProc()) &&
73 (m_auxVec.numOfProcsForStorage() == 1 )) {
74 bool stayInRoutine =
true;
76 const V* internalValues = NULL;
77 const V* internalDirection = NULL;
78 V* internalGrad = NULL;
79 M* internalHessian = NULL;
80 V* internalEffect = NULL;
90 std::vector<char> bufferChar(5,
'0');
92 if (m_env.subRank() == 0) {
93 internalValues = vecValues;
94 internalDirection = vecDirection;
95 internalGrad = gradVector;
96 internalHessian = hessianMatrix;
97 internalEffect = hessianEffect;
99 if (internalValues != NULL) bufferChar[0] =
'1';
100 if (internalDirection != NULL) bufferChar[1] =
'1';
101 if (internalGrad != NULL) bufferChar[2] =
'1';
102 if (internalHessian != NULL) bufferChar[3] =
'1';
103 if (internalEffect != NULL) bufferChar[4] =
'1';
106 m_env.subComm().syncPrintDebugMsg(
"In ScalarFunctionSynchronizer<V,M>::callFunction(), just before char Bcast()",3,3000000);
109 int count = (int) bufferChar.size();
110 m_env.subComm().Bcast((
void *) &bufferChar[0], count, RawValue_MPI_CHAR, 0,
111 "ScalarFunctionSynchronizer<V,M>::callFunction()",
112 "failed broadcast 1 of 3");
114 m_env.subComm().syncPrintDebugMsg(
"In ScalarFunctionSynchronizer<V,M>::callFunction(), just after char Bcast()",3,3000000);
118 if (bufferChar[0] ==
'1') {
124 std::vector<double> bufferDouble(m_auxVec.sizeLocal(),0.);
126 if (m_env.subRank() == 0) {
127 for (
unsigned int i = 0; i < internalValues->sizeLocal(); ++i) {
128 bufferDouble[i] = (*internalValues)[i];
156 count = (int) bufferDouble.size();
157 m_env.subComm().Bcast((
void *) &bufferDouble[0], count, RawValue_MPI_DOUBLE, 0,
158 "ScalarFunctionSynchronizer<V,M>::callFunction()",
159 "failed broadcast 2 of 3");
161 if (m_env.subRank() != 0) {
163 for (
unsigned int i = 0; i < tmpVec.sizeLocal(); ++i) {
164 tmpVec[i] = bufferDouble[i];
166 internalValues =
new V(tmpVec);
170 if (bufferChar[1] ==
'1') {
176 if (m_env.subRank() == 0) {
177 for (
unsigned int i = 0; i < internalDirection->sizeLocal(); ++i) {
178 bufferDouble[i] = (*internalDirection)[i];
182 count = (int) bufferDouble.size();
183 m_env.subComm().Bcast((
void *) &bufferDouble[0], count, RawValue_MPI_DOUBLE, 0,
184 "ScalarFunctionSynchronizer<V,M>::callFunction()",
185 "failed broadcast 3 of 3");
187 if (m_env.subRank() != 0) {
189 for (
unsigned int i = 0; i < tmpVec.sizeLocal(); ++i) {
190 tmpVec[i] = bufferDouble[i];
192 internalDirection =
new V(tmpVec);
199 if (m_env.subRank() != 0) {
200 if (bufferChar[2] ==
'1') internalGrad =
new V(m_auxVec);
201 if (bufferChar[3] ==
'1') internalHessian =
new M(m_auxVec);
202 if (bufferChar[4] ==
'1') internalEffect =
new V(m_auxVec);
205 m_env.subComm().syncPrintDebugMsg(
"In ScalarFunctionSynchronizer<V,M>::callFunction(), just before actual lnValue()",3,3000000);
206 m_env.subComm().Barrier();
207 result = m_scalarFunction.lnValue(*internalValues,
213 if (m_bayesianJointPdfPtr) {
214 *extraOutput1 = m_bayesianJointPdfPtr->lastComputedLogPrior();
218 if (m_bayesianJointPdfPtr) {
219 *extraOutput2 = m_bayesianJointPdfPtr->lastComputedLogLikelihood();
227 if (m_env.subRank() == 0) {
228 stayInRoutine =
false;
231 if (internalValues != NULL)
delete internalValues;
232 if (internalDirection != NULL)
delete internalDirection;
233 if (internalGrad != NULL)
delete internalGrad;
234 if (internalHessian != NULL)
delete internalHessian;
235 if (internalEffect != NULL)
delete internalEffect;
237 stayInRoutine = (vecValues == NULL) && (bufferChar[0] ==
'1');
240 }
while (stayInRoutine);
243 queso_require_msg(vecValues,
"vecValues should not be NULL");
245 m_env.subComm().Barrier();
246 result = m_scalarFunction.lnValue(*vecValues,
252 if (m_bayesianJointPdfPtr) {
253 *extraOutput1 = m_bayesianJointPdfPtr->lastComputedLogPrior();
257 if (m_bayesianJointPdfPtr) {
258 *extraOutput2 = m_bayesianJointPdfPtr->lastComputedLogLikelihood();
267 template <
class V,
class M>
269 double* extraOutput1,
270 double* extraOutput2)
const
274 if ((m_env.numSubEnvironments() < (
unsigned int) m_env.fullComm().NumProc()) &&
275 (m_auxVec.numOfProcsForStorage() == 1 )) {
276 bool stayInRoutine =
true;
278 const V* internalValues = NULL;
279 const V* internalDirection = NULL;
280 V* internalGrad = NULL;
281 M* internalHessian = NULL;
282 V* internalEffect = NULL;
292 std::vector<char> bufferChar(5,
'0');
294 if (m_env.subRank() == 0) {
295 internalValues = vecValues;
297 if (internalValues != NULL) bufferChar[0] =
'1';
298 if (internalDirection != NULL) bufferChar[1] =
'1';
299 if (internalGrad != NULL) bufferChar[2] =
'1';
300 if (internalHessian != NULL) bufferChar[3] =
'1';
301 if (internalEffect != NULL) bufferChar[4] =
'1';
304 m_env.subComm().syncPrintDebugMsg(
"In ScalarFunctionSynchronizer<V,M>::callFunction(), just before char Bcast()",3,3000000);
307 int count = (int) bufferChar.size();
308 m_env.subComm().Bcast((
void *) &bufferChar[0], count, RawValue_MPI_CHAR, 0,
309 "ScalarFunctionSynchronizer<V,M>::callFunction()",
310 "failed broadcast 1 of 3");
312 m_env.subComm().syncPrintDebugMsg(
"In ScalarFunctionSynchronizer<V,M>::callFunction(), just after char Bcast()",3,3000000);
316 if (bufferChar[0] ==
'1') {
322 std::vector<double> bufferDouble(m_auxVec.sizeLocal(),0.);
324 if (m_env.subRank() == 0) {
325 for (
unsigned int i = 0; i < internalValues->sizeLocal(); ++i) {
326 bufferDouble[i] = (*internalValues)[i];
354 count = (int) bufferDouble.size();
355 m_env.subComm().Bcast((
void *) &bufferDouble[0], count, RawValue_MPI_DOUBLE, 0,
356 "ScalarFunctionSynchronizer<V,M>::callFunction()",
357 "failed broadcast 2 of 3");
359 if (m_env.subRank() != 0) {
361 for (
unsigned int i = 0; i < tmpVec.sizeLocal(); ++i) {
362 tmpVec[i] = bufferDouble[i];
364 internalValues =
new V(tmpVec);
368 if (bufferChar[1] ==
'1') {
374 if (m_env.subRank() == 0) {
375 for (
unsigned int i = 0; i < internalDirection->sizeLocal(); ++i) {
376 bufferDouble[i] = (*internalDirection)[i];
380 count = (int) bufferDouble.size();
381 m_env.subComm().Bcast((
void *) &bufferDouble[0], count, RawValue_MPI_DOUBLE, 0,
382 "ScalarFunctionSynchronizer<V,M>::callFunction()",
383 "failed broadcast 3 of 3");
385 if (m_env.subRank() != 0) {
387 for (
unsigned int i = 0; i < tmpVec.sizeLocal(); ++i) {
388 tmpVec[i] = bufferDouble[i];
390 internalDirection =
new V(tmpVec);
397 if (m_env.subRank() != 0) {
398 if (bufferChar[2] ==
'1') internalGrad =
new V(m_auxVec);
399 if (bufferChar[3] ==
'1') internalHessian =
new M(m_auxVec);
400 if (bufferChar[4] ==
'1') internalEffect =
new V(m_auxVec);
403 m_env.subComm().syncPrintDebugMsg(
"In ScalarFunctionSynchronizer<V,M>::callFunction(), just before actual lnValue()",3,3000000);
404 m_env.subComm().Barrier();
405 result = m_scalarFunction.lnValue(*internalValues);
407 if (m_bayesianJointPdfPtr) {
408 *extraOutput1 = m_bayesianJointPdfPtr->lastComputedLogPrior();
412 if (m_bayesianJointPdfPtr) {
413 *extraOutput2 = m_bayesianJointPdfPtr->lastComputedLogLikelihood();
421 if (m_env.subRank() == 0) {
422 stayInRoutine =
false;
425 if (internalValues != NULL)
delete internalValues;
426 if (internalDirection != NULL)
delete internalDirection;
427 if (internalGrad != NULL)
delete internalGrad;
428 if (internalHessian != NULL)
delete internalHessian;
429 if (internalEffect != NULL)
delete internalEffect;
431 stayInRoutine = (vecValues == NULL) && (bufferChar[0] ==
'1');
434 }
while (stayInRoutine);
437 queso_require_msg(vecValues,
"vecValues should not be NULL");
439 m_env.subComm().Barrier();
440 result = m_scalarFunction.lnValue(*vecValues);
442 if (m_bayesianJointPdfPtr) {
443 *extraOutput1 = m_bayesianJointPdfPtr->lastComputedLogPrior();
447 if (m_bayesianJointPdfPtr) {
448 *extraOutput2 = m_bayesianJointPdfPtr->lastComputedLogLikelihood();
A templated (base) class for handling scalar functions.
double callFunction(const V *vecValues, const V *vecDirection, V *gradVector, M *hessianMatrix, V *hessianEffect, double *extraOutput1, double *extraOutput2) const
Calls the scalar function which will be synchronized.
A templated class for handling sets.
~ScalarFunctionSynchronizer()
Destructor.
ScalarFunctionSynchronizer(const BaseScalarFunction< V, M > &inputFunction, const V &auxVec)
Default constructor.
const VectorSet< V, M > & domainSet() const
Access to the domain set of the scalar function which will be synchronized.
A class for handling Bayesian joint PDFs.