source: stable/2.4/ADOL-C/src/externfcts.cpp

Last change on this file was 370, checked in by kulshres, 7 years ago

Merge branch '2.3.x_ISSM' into svn

This introduces the new externally differentiated functions API

From: Jean Utke <utke@…>

Please see comments in ADOL-C/include/adolc/externfcts.h for details

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

  • Property svn:keywords set to Author Date Id Revision
File size: 4.5 KB
Line 
1/*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File:     externfcts.cpp
4 Revision: $Id: externfcts.cpp 370 2012-11-22 13:18:52Z stefan $
5 Contents: functions and data types for extern (differentiated) functions.
6 
7 Copyright (c) Andreas Kowarz
8 
9 This file is part of ADOL-C. This software is provided as open source.
10 Any use, reproduction, or distribution of the software constitutes
11 recipient's acceptance of the terms of the accompanying license file.
12         
13----------------------------------------------------------------------------*/
14
15#include <adolc/externfcts.h>
16#include "externfcts_p.h"
17#include "taping_p.h"
18#include <adolc/adouble.h>
19#include "oplate.h"
20#include "buffer_temp.h"
21
22#include <cstring>
23
24/****************************************************************************/
25/*                                    extern differentiated functions stuff */
26
27#define ADOLC_BUFFER_TYPE \
28   Buffer< ext_diff_fct, ADOLC_ext_fct, EDFCTS_BLOCK_SIZE >
29static ADOLC_BUFFER_TYPE buffer(init_ext_diff_fct);
30static int oldTraceFlag;
31
32ext_diff_fct *reg_ext_fct(ADOLC_ext_fct ext_fct) {
33
34  // this call sets edf->function and edf->index:
35  ext_diff_fct * edf=buffer.append(ext_fct);
36
37  // for sanity make sure everything else is properly nullified
38  edf->zos_forward=0;
39
40  edf->fos_forward=0;
41  edf->hos_forward=0;
42  edf->fov_forward=0;
43  edf->hov_forward=0;
44
45  edf->fos_reverse=0;
46  edf->hos_reverse=0;
47  edf->fov_reverse=0;
48  edf->hov_reverse=0;
49 
50  edf->dp_x=0; 
51  edf->dp_X=0; 
52  edf->dpp_X=0;
53  edf->dppp_X=0;
54  edf->dp_y=0; 
55  edf->dp_Y=0; 
56  edf->dpp_Y=0; 
57  edf->dppp_Y=0;
58
59  edf->dp_U=0; 
60  edf->dpp_U=0; 
61  edf->dp_Z=0; 
62  edf->dpp_Z=0; 
63  edf->dppp_Z=0;
64
65  edf->spp_nz=0;
66
67  edf->max_n=0;
68  edf->max_m=0;
69
70  edf->nestedAdolc=true;
71  edf->dp_x_changes=true;
72  edf->dp_y_priorRequired=true;
73
74  return edf;
75}
76
77int call_ext_fct(ext_diff_fct *edfct,
78                 int n, double *xp, adouble *xa,
79                 int m, double *yp, adouble *ya)
80{
81    int i = 0, ret;
82    locint numVals;
83    double *vals;
84    ADOLC_OPENMP_THREAD_NUMBER;
85    ADOLC_OPENMP_GET_THREAD_NUMBER;
86
87    if (xa[n-1].loc()-xa[0].loc()!=n-1 || ya[m-1].loc()-ya[0].loc()!=m-1) fail(ADOLC_EXT_DIFF_LOCATIONGAP);
88    if (edfct==NULL) fail(ADOLC_EXT_DIFF_NULLPOINTER_STRUCT);
89
90    if (ADOLC_CURRENT_TAPE_INFOS.traceFlag) {
91        put_op(ext_diff);
92        ADOLC_PUT_LOCINT(edfct->index);
93        ADOLC_PUT_LOCINT(n);
94        ADOLC_PUT_LOCINT(m);
95        ADOLC_PUT_LOCINT(xa[i].loc());
96        ADOLC_PUT_LOCINT(ya[i].loc());
97        ADOLC_PUT_LOCINT(0);               /* keep space for checkpointing index */
98
99        oldTraceFlag=ADOLC_CURRENT_TAPE_INFOS.traceFlag;
100        ADOLC_CURRENT_TAPE_INFOS.traceFlag=0;
101    } else oldTraceFlag=0;
102
103    if (edfct->nestedAdolc) {
104      numVals = ADOLC_GLOBAL_TAPE_VARS.storeSize;
105      vals = new double[numVals];
106      memcpy(vals, ADOLC_GLOBAL_TAPE_VARS.store,
107             numVals * sizeof(double));
108    }
109
110    edfct->max_n=(edfct->max_n<n)?n:edfct->max_n;
111    edfct->max_m=(edfct->max_m<m)?m:edfct->max_m;
112
113    /* update taylor buffer if keep != 0 ; possible double counting as in
114     * adouble.cpp => correction in taping.c */
115
116    if (oldTraceFlag != 0) {
117      if (edfct->dp_x_changes) ADOLC_CURRENT_TAPE_INFOS.numTays_Tape += n;
118      if (edfct->dp_y_priorRequired) ADOLC_CURRENT_TAPE_INFOS.numTays_Tape += m;
119      if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors) {
120        if (edfct->dp_x_changes) for (i=0; i<n; ++i) ADOLC_WRITE_SCAYLOR(xa[i].getValue());
121        if (edfct->dp_y_priorRequired) for (i=0; i<m; ++i) ADOLC_WRITE_SCAYLOR(ya[i].getValue());
122      }
123    }
124
125    for (i=0; i<n; ++i) xp[i]=xa[i].getValue();
126    if (edfct->dp_y_priorRequired) for (i=0; i<m; ++i) yp[i]=ya[i].getValue();
127
128    ret=edfct->function(n, xp, m, yp);
129
130    if (edfct->nestedAdolc) {
131      memcpy(ADOLC_GLOBAL_TAPE_VARS.store, vals,
132          numVals * sizeof(double));
133      delete[] vals;
134    }
135
136    /* write back */
137    if (edfct->dp_x_changes) for (i=0; i<n; ++i) xa[i].setValue(xp[i]);
138    for (i=0; i<m; ++i) ya[i].setValue(yp[i]);
139
140    ADOLC_CURRENT_TAPE_INFOS.traceFlag=oldTraceFlag;
141
142    return ret;
143}
144
145ext_diff_fct *get_ext_diff_fct( int index ) {
146    return buffer.getElement(index);
147}
148
149void init_ext_diff_fct(ext_diff_fct *edfct) {
150    char *ptr;
151
152    ptr = (char *)edfct;
153    for (unsigned int i = 0; i < sizeof(ext_diff_fct); ++i) ptr[i]=0;
154}
155
156/****************************************************************************/
157/*                                                               THAT'S ALL */
158
Note: See TracBrowser for help on using the repository browser.