Ice Sheet System Model  4.18
Code documentation
Functions
adgradient_core.cpp File Reference
#include <set>
#include "./cores.h"
#include "../toolkits/toolkits.h"
#include "../classes/classes.h"
#include "../shared/shared.h"
#include "../modules/modules.h"
#include "../solutionsequences/solutionsequences.h"

Go to the source code of this file.

Functions

void adgradient_core (FemModel *femmodel)
 

Function Documentation

◆ adgradient_core()

void adgradient_core ( FemModel femmodel)

Definition at line 22 of file adgradient_core.cpp.

22  {
23 
24  /*diverse: */
25  int i;
26  int dummy;
27  int num_dependents=0;
28  int num_dependents_old=0;
29  int num_independents=0;
30  bool isautodiff = false;
31  int aDepIndex=0;
32  int my_rank=IssmComm::GetRank();
33 
34  /*state variables: */
35  IssmDouble *axp = NULL;
36  IssmPDouble *xp = NULL;
37 
38  /*intermediary: */
39  IssmPDouble *aWeightVector=NULL;
40  IssmPDouble *weightVectorTimesJac=NULL;
41 
42  /*output: */
43  IssmPDouble *totalgradient=NULL;
44 
45  /*AD mode on?: */
47 
48  if(isautodiff){
49 
50  #if defined(_HAVE_ADOLC_)
51  if(VerboseAutodiff())_printf0_(" start ad core\n");
52 
53  /*First, stop tracing: */
54  trace_off();
55 
56  if(VerboseAutodiff()){ /*{{{*/
57  size_t tape_stats[15];
58  tapestats(my_rank,tape_stats); //reading of tape statistics
59  int commSize=IssmComm::GetSize();
60  int *sstats=new int[7];
61  sstats[0]=tape_stats[NUM_OPERATIONS];
62  sstats[1]=tape_stats[OP_FILE_ACCESS];
63  sstats[2]=tape_stats[NUM_LOCATIONS];
64  sstats[3]=tape_stats[LOC_FILE_ACCESS];
65  sstats[4]=tape_stats[NUM_VALUES];
66  sstats[5]=tape_stats[VAL_FILE_ACCESS];
67  sstats[6]=tape_stats[TAY_STACK_SIZE];
68  int *rstats=NULL;
69  if (my_rank==0) rstats=new int[commSize*7];
71  if (my_rank==0) {
72  int offset=50;
73  int rOffset=(commSize/10)+1;
74  _printf_(" ADOLC statistics: \n");
75  _printf_(" "<<setw(offset)<<left<<"#independents: " <<setw(12)<<right<<tape_stats[NUM_INDEPENDENTS] << "\n");
76  _printf_(" "<<setw(offset)<<left<<"#dependents: " <<setw(12)<<right<<tape_stats[NUM_DEPENDENTS] << "\n");
77  _printf_(" "<<setw(offset)<<left<<"max #live active variables: " <<setw(12)<<right<<tape_stats[NUM_MAX_LIVES] << "\n");
78  _printf_(" operations: entry size "<< sizeof(unsigned char) << " Bytes \n");
79  _printf_(" "<<setw(offset)<<left<<" #entries in buffer (AutodiffObufsizeEnum) " <<setw(12)<<right<<tape_stats[OP_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+0] << (rstats[r*7+1]?" ->file":"") << "\n");
82  _printf_(" locations: entry size " << sizeof(locint) << " Bytes\n");
83  _printf_(" "<<setw(offset)<<left<<" #entries in buffer (AutodiffLbufsizeEnum) " <<setw(12)<<right<<tape_stats[LOC_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+2] << (rstats[r*7+3]?" ->file":"") << "\n");
86  _printf_(" constant values: entry size " << sizeof(double) << " Bytes\n");
87  _printf_(" "<<setw(offset)<<left<<" #entries in buffer (AutodiffCbufsizeEnum) " <<setw(12)<<right<<tape_stats[VAL_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+4] << (rstats[r*7+5]?" ->file":"") << "\n");
90  _printf_(" Taylor stack: entry size " << sizeof(revreal) << " Bytes\n");
91  _printf_(" "<<setw(offset)<<left<<" #entries in buffer (AutodiffTbufsizeEnum) " <<setw(12)<<right<<tape_stats[TAY_BUFFER_SIZE] << "\n");
92  for (int r=0;r<commSize;++r)
93  _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");
94  delete []rstats;
95  }
96  delete [] sstats;
97  } /*}}}*/
98 
99  /*retrieve parameters: */
102 
103  /*if no dependents, no point in running a driver: */
104  if(!(num_dependents*num_independents)) return;
105 
106  /*for adolc to run in parallel, we 0 out on rank~=0. But we still keep track of num_dependents:*/
107  num_dependents_old=num_dependents;
108  if (my_rank!=0){
109  num_dependents=0; num_independents=0;
110  }
111 
112  /*retrieve state variable: */
114 
115  /* driver argument */
116  xp=xNew<double>(num_independents);
117  for(i=0;i<num_independents;i++){
118  xp[i]=reCast<double,IssmDouble>(axp[i]);
119  }
120 
121  /*get the EDF pointer:*/
122  ext_diff_fct *anEDF_for_solverx_p=xDynamicCast<GenericParam<Adolc_edf> * >(femmodel->parameters->FindParamObject(AdolcParamEnum))->GetParameterValue().myEDF_for_solverx_p;
123 
124  /* these are always needed regardless of the interpreter */
125  anEDF_for_solverx_p->dp_x=xNew<double>(anEDF_for_solverx_p->max_n);
126  anEDF_for_solverx_p->dp_y=xNew<double>(anEDF_for_solverx_p->max_m);
127 
128  /* Ok, now we are going to call the fos_reverse in a loop on the index, from 0 to num_dependents, so
129  * as to generate num_dependents gradients: */
130 
131  /*Initialize outputs: */
132  totalgradient=xNewZeroInit<IssmPDouble>(num_independents);
133 
134  for(aDepIndex=0;aDepIndex<num_dependents_old;aDepIndex++){
135 
136  /*initialize direction index in the weights vector: */
137  aWeightVector=xNewZeroInit<IssmPDouble>(num_dependents);
138  if (my_rank==0) aWeightVector[aDepIndex]=1.0;
139 
140  /*initialize output gradient: */
141  weightVectorTimesJac=xNew<IssmPDouble>(num_independents);
142 
143  /*set the forward method function pointer: */
144  #ifdef _HAVE_GSL_
145  anEDF_for_solverx_p->fos_reverse=EDF_fos_reverse_for_solverx;
146  #endif
147  #ifdef _HAVE_MUMPS_
148  anEDF_for_solverx_p->fos_reverse_iArr=fos_reverse_mumpsSolveEDF;
149  #endif
150 
151  anEDF_for_solverx_p->dp_U=xNew<IssmPDouble>(anEDF_for_solverx_p->max_m);
152  anEDF_for_solverx_p->dp_Z=xNew<IssmPDouble>(anEDF_for_solverx_p->max_n);
153 
154  /*call driver: */
155  fos_reverse(my_rank,num_dependents,num_independents, aWeightVector, weightVectorTimesJac );
156 
157  /*Add to totalgradient: */
158  if(my_rank==0)for(i=0;i<num_independents;i++)totalgradient[i]+=weightVectorTimesJac[i];
159 
160  /*free resources :*/
161  xDelete(weightVectorTimesJac);
162  xDelete(aWeightVector);
163  }
164 
165  /*add totalgradient to results*/
166  femmodel->results->AddObject(new GenericExternalResult<IssmPDouble*>(femmodel->results->Size()+1,AutodiffJacobianEnum,totalgradient,num_independents,1,1,0.0));
167 
168  if(VerboseAutodiff())_printf0_(" end ad core\n");
169 
170  /* delete the allocated space for the parameters and free ressources:{{{*/
171  xDelete(anEDF_for_solverx_p->dp_x);
172  xDelete(anEDF_for_solverx_p->dp_X);
173  xDelete(anEDF_for_solverx_p->dpp_X);
174  xDelete(anEDF_for_solverx_p->dp_y);
175  xDelete(anEDF_for_solverx_p->dp_Y);
176  xDelete(anEDF_for_solverx_p->dpp_Y);
177  xDelete(anEDF_for_solverx_p->dp_U);
178  xDelete(anEDF_for_solverx_p->dpp_U);
179  xDelete(anEDF_for_solverx_p->dp_Z);
180  xDelete(anEDF_for_solverx_p->dpp_Z);
181  xDelete(xp);
182  xDelete(totalgradient);
183  xDelete(axp); /*}}}*/
184 
185  #elif defined(_HAVE_CODIPACK_)
186  fprintf(stderr, "*** Codipack adgradient_core()\n");
187  #else
188  _error_("Should not be requesting AD drivers when an AD library is not available!");
189  #endif
190  }
191 }
DataSet::Size
int Size()
Definition: DataSet.cpp:399
IssmDouble
double IssmDouble
Definition: types.h:37
_printf0_
#define _printf0_(StreamArgs)
Definition: Print.h:29
DataSet::AddObject
int AddObject(Object *object)
Definition: DataSet.cpp:252
_printf_
#define _printf_(StreamArgs)
Definition: Print.h:22
AutodiffXpEnum
@ AutodiffXpEnum
Definition: EnumDefinitions.h:57
FemModel::parameters
Parameters * parameters
Definition: FemModel.h:46
IssmComm::GetComm
static ISSM_MPI_Comm GetComm(void)
Definition: IssmComm.cpp:30
FemModel::results
Results * results
Definition: FemModel.h:48
AutodiffJacobianEnum
@ AutodiffJacobianEnum
Definition: EnumDefinitions.h:978
ISSM_MPI_INT
#define ISSM_MPI_INT
Definition: issmmpi.h:127
VerboseAutodiff
bool VerboseAutodiff(void)
Definition: Verbosity.cpp:29
xDelete
void xDelete(T **&aT_pp)
Definition: MemOps.h:97
IssmComm::GetSize
static int GetSize(void)
Definition: IssmComm.cpp:46
AutodiffIsautodiffEnum
@ AutodiffIsautodiffEnum
Definition: EnumDefinitions.h:50
GenericExternalResult
Definition: GenericExternalResult.h:21
IssmComm::GetRank
static int GetRank(void)
Definition: IssmComm.cpp:34
_error_
#define _error_(StreamArgs)
Definition: exceptions.h:49
AdolcParamEnum
@ AdolcParamEnum
Definition: EnumDefinitions.h:12
AutodiffNumDependentsEnum
@ AutodiffNumDependentsEnum
Definition: EnumDefinitions.h:52
Parameters::FindParam
void FindParam(bool *pinteger, int enum_type)
Definition: Parameters.cpp:262
IssmPDouble
IssmDouble IssmPDouble
Definition: types.h:38
Parameters::FindParamObject
Param * FindParamObject(int enum_type)
Definition: Parameters.cpp:588
AutodiffNumIndependentsEnum
@ AutodiffNumIndependentsEnum
Definition: EnumDefinitions.h:53
ISSM_MPI_Gather
int ISSM_MPI_Gather(void *sendbuf, int sendcnt, ISSM_MPI_Datatype sendtype, void *recvbuf, int recvcnt, ISSM_MPI_Datatype recvtype, int root, ISSM_MPI_Comm comm)
Definition: issmmpi.cpp:242
femmodel
FemModel * femmodel
Definition: esmfbinders.cpp:16