@@ -90,105 +90,6 @@ prob = ODEProblem(foo, ones(5, 5), (0., 1.0), (ones(5,5), dualcache(zeros(5,5)))
90
90
solve (prob, TRBDF2 ())
91
91
```
92
92
93
- ### Handling Chunk Sizes
94
-
95
- It is important that the ` DiffCache ` matches the chunk sizes used in the actual differentiation. Let's
96
- understand this by looking at a real problem:
97
-
98
- ``` julia
99
- using ForwardDiff
100
- using PreallocationTools
101
-
102
- randmat = rand (10 , 2 )
103
- sto = similar (randmat)
104
- stod = dualcache (sto)
105
-
106
- function claytonsample! (sto, τ; randmat= randmat)
107
- sto = get_tmp (sto, τ)
108
- @show typeof (τ)
109
- @show size (sto), size (randmat)
110
- sto .= randmat
111
- τ == 0 && return sto
112
-
113
- n = size (sto, 1 )
114
- for i in 1 : n
115
- v = sto[i, 2 ]
116
- u = sto[i, 1 ]
117
- sto[i, 2 ] = (1 - u^ (- τ) + u^ (- τ)* v^ (- (τ/ (1 + τ))))^ (- 1 / τ)
118
- end
119
- return sto
120
- end
121
-
122
- ForwardDiff. derivative (τ -> claytonsample! (stod, τ), 0.3 )
123
- ```
124
-
125
- Notice that by default the ` dualcache ` builds a cache that is compatible with differentiation w.r.t the
126
- a variable sized as the cache variable, i.e. it's naturally made for Jacobians.
127
-
128
- ``` julia
129
- julia> typeof (dualcache (sto))
130
- PreallocationTools. DiffCache{Matrix{Float64}, Matrix{ForwardDiff. Dual{nothing , Float64, 10 }}}
131
- ```
132
-
133
- Notice that it choose a chunk size of 10, matching the chunk size that would be used if ` ForwardDiff.jacobian ` is used
134
- to calculate the derivative w.r.t. an input matching the size of ` sto ` (i.e., the Jacobian of ` claytonsample! ` w.r.t. ` randmat ` ).
135
- However, in our actual differentiation we have:
136
-
137
- ``` julia
138
- typeof (τ) = ForwardDiff. Dual{ForwardDiff. Tag{var"#49#50" , Float64}, Float64, 1 }
139
- ```
140
-
141
- a single chunk size because it's differentiating w.r.t. a single dimension. This messes with the sizes in the reinterpretation:
142
-
143
- ``` julia
144
- (size (sto), size (randmat)) = ((55 , 2 ), (10 , 2 ))
145
- ```
146
-
147
- The fix is to ensure that the cache is generated with the correct chunk size, i.e.:
148
-
149
- ``` julia
150
- stod = dualcache (sto,Val{1 })
151
- ```
152
-
153
- Thus the following code successfully computes the derivative in a non-allocating way:
154
-
155
- ``` julia
156
- using ForwardDiff
157
- using PreallocationTools
158
-
159
- randmat = rand (10 , 2 )
160
- sto = similar (randmat)
161
- stod = dualcache (sto,Val{1 })
162
-
163
- function claytonsample! (sto, τ; randmat= randmat)
164
- sto = get_tmp (sto, τ)
165
- sto .= randmat
166
- τ == 0 && return sto
167
-
168
- n = size (sto, 1 )
169
- for i in 1 : n
170
- v = sto[i, 2 ]
171
- u = sto[i, 1 ]
172
- sto[i, 2 ] = (1 - u^ (- τ) + u^ (- τ)* v^ (- (τ/ (1 + τ))))^ (- 1 / τ)
173
- end
174
- return sto
175
- end
176
-
177
- ForwardDiff. derivative (τ -> claytonsample! (stod, τ), 0.3 )
178
-
179
- 10 × 2 Matrix{Float64}:
180
- 0.0 0.171602
181
- 0.0 - 0.412736
182
- 0.0 0.149273
183
- 0.0 0.18172
184
- 0.0 0.144151
185
- 0.0 - 0.110773
186
- 0.0 0.221714
187
- 0.0 - 0.111034
188
- 0.0 - 0.0723283
189
- 0.0 0.251095
190
- ```
191
-
192
93
## LazyBufferCache
193
94
194
95
``` julia
0 commit comments