30 int num_independents=0;
31 bool isautodiff,iscontrol;
33 size_t tape_stats[15];
44 if(isautodiff && !iscontrol){
46 #if defined(_HAVE_ADOLC_)
54 tapestats(my_rank,tape_stats);
56 int *sstats=
new int[7];
57 sstats[0]=tape_stats[NUM_OPERATIONS];
58 sstats[1]=tape_stats[OP_FILE_ACCESS];
59 sstats[2]=tape_stats[NUM_LOCATIONS];
60 sstats[3]=tape_stats[LOC_FILE_ACCESS];
61 sstats[4]=tape_stats[NUM_VALUES];
62 sstats[5]=tape_stats[VAL_FILE_ACCESS];
63 sstats[6]=tape_stats[TAY_STACK_SIZE];
65 if (my_rank==0) rstats=
new int[commSize*7];
69 int rOffset=(commSize/10)+1;
71 _printf_(
" "<<setw(offset)<<left<<
"#independents: " <<setw(12)<<right<<tape_stats[NUM_INDEPENDENTS] <<
"\n");
72 _printf_(
" "<<setw(offset)<<left<<
"#dependents: " <<setw(12)<<right<<tape_stats[NUM_DEPENDENTS] <<
"\n");
73 _printf_(
" "<<setw(offset)<<left<<
"max #live active variables: " <<setw(12)<<right<<tape_stats[NUM_MAX_LIVES] <<
"\n");
74 _printf_(
" operations: entry size "<<
sizeof(
unsigned char) <<
" Bytes \n");
75 _printf_(
" "<<setw(offset)<<left<<
" #entries in buffer (AutodiffObufsizeEnum) " <<setw(12)<<right<<tape_stats[OP_BUFFER_SIZE] <<
"\n");
76 for (
int r=0;r<commSize;++r)
77 _printf_(
" ["<<setw(rOffset)<<right<<r<<
"]"<<setw(offset-rOffset-4)<<left<<
" #entries total" <<setw(12)<<right<<rstats[r*7+0] << (rstats[r*7+1]?
" ->file":
"") <<
"\n");
78 _printf_(
" locations: entry size " <<
sizeof(locint) <<
" Bytes\n");
79 _printf_(
" "<<setw(offset)<<left<<
" #entries in buffer (AutodiffLbufsizeEnum) " <<setw(12)<<right<<tape_stats[LOC_BUFFER_SIZE] <<
"\n");
80 for (
int r=0;r<commSize;++r)
81 _printf_(
" ["<<setw(rOffset)<<right<<r<<
"]"<<setw(offset-rOffset-4)<<left<<
" #entries total" <<setw(12)<<right<<rstats[r*7+2] << (rstats[r*7+3]?
" ->file":
"") <<
"\n");
82 _printf_(
" constant values: entry size " <<
sizeof(
double) <<
" Bytes\n");
83 _printf_(
" "<<setw(offset)<<left<<
" #entries in buffer (AutodiffCbufsizeEnum) " <<setw(12)<<right<<tape_stats[VAL_BUFFER_SIZE] <<
"\n");
84 for (
int r=0;r<commSize;++r)
85 _printf_(
" ["<<setw(rOffset)<<right<<r<<
"]"<<setw(offset-rOffset-4)<<left<<
" #entries total" <<setw(12)<<right<<rstats[r*7+4] << (rstats[r*7+5]?
" ->file":
"") <<
"\n");
86 _printf_(
" Taylor stack: entry size " <<
sizeof(revreal) <<
" Bytes\n");
87 _printf_(
" "<<setw(offset)<<left<<
" #entries in buffer (AutodiffTbufsizeEnum) " <<setw(12)<<right<<tape_stats[TAY_BUFFER_SIZE] <<
"\n");
88 for (
int r=0;r<commSize;++r)
89 _printf_(
" ["<<setw(rOffset)<<right<<r<<
"]"<<setw(offset-rOffset-4)<<left<<
" #entries total" <<setw(12)<<right<<rstats[r*7+6] << (rstats[r*7+6]>tape_stats[TAY_BUFFER_SIZE]?
" ->file":
"") <<
"\n");
100 if(!(num_dependents*num_independents))
return;
104 num_dependents=0; num_independents=0;
111 xp=xNew<double>(num_independents);
112 for(i=0;i<num_independents;i++){
113 xp[i]=reCast<double,IssmDouble>(axp[i]);
122 if (strcmp(driver,
"fos_forward")==0){
125 double *tangentDir = NULL;
126 double *jacTimesTangentDir = NULL;
127 double *theOutput = NULL;
132 if (anIndepIndex<0 || anIndepIndex>=num_independents)
_error_(
"index value for AutodiffFosForwardIndexEnum should be in [0,num_independents-1]");
134 tangentDir=xNewZeroInit<double>(num_independents);
135 tangentDir[anIndepIndex]=1.0;
137 jacTimesTangentDir=xNew<double>(num_dependents);
138 theOutput=xNew<double>(num_dependents);
142 anEDF_for_solverx_p->fos_forward=EDF_fos_forward_for_solverx;
146 fos_forward(my_rank,num_dependents,num_independents, 0, xp, tangentDir, theOutput, jacTimesTangentDir );
156 else if ((strcmp(driver,
"fov_forward")==0) || (strcmp(driver,
"fov_forward_all")==0)){
160 int *indepIndices = NULL;
161 double **jacTimesSeed = NULL;
162 double **seed = NULL;
163 double *theOutput = NULL;
164 std::set<unsigned int> anIndexSet;
167 if (strcmp(driver,
"fov_forward_all")==0){
168 tangentDirNum=num_independents;
169 indepIndices=xNewZeroInit<int>(tangentDirNum);
170 for(i=0;i<num_independents;i++)indepIndices[i]=1;
177 if (tangentDirNum<1 || tangentDirNum>num_independents)
_error_(
"tangentDirNum should be in [1,num_independents]");
180 jacTimesSeed=xNew<double>(num_dependents,tangentDirNum);
184 anEDF_for_solverx_p->fov_forward=EDF_fov_forward_for_solverx;
189 seed=xNewZeroInit<double>(num_independents,tangentDirNum);
192 for (
int i=0; i<tangentDirNum; ++i) {
194 if (indepIndices[i]>num_independents) {
195 _error_(
"indepIndices values must be in [0,num_independents-1]");
197 if (anIndexSet.find(indepIndices[i])!=anIndexSet.end()) {
198 _error_(
"duplicate indepIndices values are not allowed until we implement Jacobian decompression");
200 anIndexSet.insert(indepIndices[i]);
203 seed[indepIndices[i]][i]=1.0;
207 theOutput=xNew<double>(num_dependents);
210 fov_forward(my_rank,num_dependents,num_independents, tangentDirNum, xp, seed, theOutput, jacTimesSeed );
223 else if (strcmp(driver,
"fos_reverse")==0) {
226 double *aWeightVector=NULL;
227 double *weightVectorTimesJac=NULL;
231 aWeightVector=xNewZeroInit<double>(num_dependents);
233 if (aDepIndex<0 || aDepIndex>=num_dependents)
_error_(
"index value for AutodiffFosReverseIndexEnum should be in [0,num_dependents-1]");
234 aWeightVector[aDepIndex]=1.0;
236 weightVectorTimesJac=xNew<double>(num_independents);
240 anEDF_for_solverx_p->fos_reverse=EDF_fos_reverse_for_solverx;
243 anEDF_for_solverx_p->fos_reverse_iArr=fos_reverse_mumpsSolveEDF;
247 fos_reverse(my_rank,num_dependents,num_independents, aWeightVector, weightVectorTimesJac );
256 else if ((strcmp(driver,
"fov_reverse")==0) || (strcmp(driver,
"fov_reverse_all")==0)){
258 int* depIndices=NULL;
261 double **weightsTimesJac=NULL;
262 double **weights=NULL;
263 std::set<unsigned int> anIndexSet;
266 if (strcmp(driver,
"fov_reverse_all")==0){
267 weightNum=num_dependents;
268 depIndices=xNewZeroInit<int>(weightNum);
269 for(i=0;i<num_dependents;i++)depIndices[i]=1;
276 if (weightNum<1 || weightNum>num_dependents)
_error_(
"tangentDirNum should be in [1,num_dependents]");
279 weightsTimesJac=xNew<double>(weightNum,num_independents);
283 anEDF_for_solverx_p->fov_reverse=EDF_fov_reverse_for_solverx;
287 weights=xNewZeroInit<double>(weightNum,num_dependents);
290 for (
int i=0; i<weightNum; ++i) {
292 if (depIndices[i]>num_dependents) {
293 _error_(
"depIndices values must be in [0,num_dependents-1]");
295 if (anIndexSet.find(depIndices[i])!=anIndexSet.end()) {
296 _error_(
"duplicate depIndices values are not allowed until we implement Jacobian decompression");
298 anIndexSet.insert(depIndices[i]);
301 weights[depIndices[i]][i]=1.0;
305 fov_reverse(my_rank,num_dependents,num_independents, weightNum, weights, weightsTimesJac );
315 else _error_(
"driver: " << driver <<
" not yet supported!");
324 #elif defined(_HAVE_CODIPACK_)
328 auto& tape_codi = IssmDouble::getGlobalTape();
329 tape_codi.setPassive();
334 tape_codi.printStatistics(std::cout);
335 codi_global.print(std::cout);
344 if(!(num_dependents*num_independents))
return;
350 if (strcmp(driver,
"fos_reverse")==0) {
353 double *weightVectorTimesJac=NULL;
358 if (aDepIndex<0 || aDepIndex>=num_dependents
359 || codi_global.output_indices.size() <= aDepIndex){
360 _error_(
"index value for AutodiffFosReverseIndexEnum should be in [0,num_dependents-1]");
362 tape_codi.setGradient(codi_global.output_indices[aDepIndex], 1.0);
365 tape_codi.evaluate();
367 weightVectorTimesJac=xNew<double>(num_independents);
369 auto in_size = codi_global.input_indices.size();
370 for(
size_t i = 0; i < in_size; ++i) {
371 weightVectorTimesJac[i] = tape_codi.getGradient(codi_global.input_indices[i]);
380 else _error_(
"driver: " << driver <<
" not yet supported!");
385 _error_(
"Should not be requesting AD drivers when an AD library is not available!");