-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
clad::gradient redefinition error #138
Comments
Hello there! void a_b_cubed_darg0_grad(double a, double c, double *_result) {
double _d__d_a = 0;
double _d__d_c = 0;
double _t0;
double _t1;
double _d__t0 = 0;
double _t2;
double _t3;
double _d__t1 = 0;
double _t4;
double _t5;
double _t6;
double _t7;
double _t8;
double _t9;
double _t10;
double _t11;
double _t12;
double _t13;
double _t14;
double _t15;
double _t16;
double _t17;
double _t18;
double _t19;
double _d_a = 1;
double _d_c = 0;
_t1 = a;
_t0 = a;
double _t00 = _t1 * _t0;
_t3 = c;
_t2 = c;
_t10 = _t3 * _t2;**//This is where the redifinition error occured earlier.**
_t6 = _d_a;
_t5 = a;
_t8 = a;
_t7 = _d_a;
_t9 = (_t6 * _t5 + _t8 * _t7);
_t4 = a;
_t11 = _t00;
_t10 = _d_a;**//This can lead to logical error.**
_t14 = _d_c;
_t13 = c;
_t16 = c;
_t15 = _d_c;
_t17 = (_t14 * _t13 + _t16 * _t15);
_t12 = c;
_t19 = _t10;
_t18 = _d_c;
double a_b_cubed_darg0_return = _t9 * _t4 + _t11 * _t10 + _t17 * _t12 + _t19 * _t18;**//This expression is unable to yield sum of cubes of a and b. Instead the expression: (_t00*_t4 + _t10*_t13); can be used.**
goto _label0;
_label0:
{
double _r4 = 1 * _t4;
double _r5 = _r4 * _t5;
_d__d_a += _r5;
double _r6 = _t6 * _r4;
_result[0UL] += _r6;
double _r7 = _r4 * _t7;
_result[0UL] += _r7;
double _r8 = _t8 * _r4;
_d__d_a += _r8;
double _r9 = _t9 * 1;
_result[0UL] += _r9;
double _r10 = 1 * _t10;
_d__t0 += _r10;
double _r11 = _t11 * 1;
_d__d_a += _r11;
double _r12 = 1 * _t12;
double _r13 = _r12 * _t13;
_d__d_c += _r13;
double _r14 = _t14 * _r12;
_result[1UL] += _r14;
double _r15 = _r12 * _t15;
_result[1UL] += _r15;
double _r16 = _t16 * _r12;
_d__d_c += _r16;
double _r17 = _t17 * 1;
_result[1UL] += _r17;
double _r18 = 1 * _t18;
_d__t1 += _r18;
double _r19 = _t19 * 1;
_d__d_c += _r19;
}
{
double _r2 = _d__t1 * _t2;
_result[1UL] += _r2;
double _r3 = _t3 * _d__t1;
_result[1UL] += _r3;
}
{
double _r0 = _d__t0 * _t0;
_result[0UL] += _r0;
double _r1 = _t1 * _d__t0;
_result[0UL] += _r1;
}
} I hope these changes solve the issue. |
I would recommend to reduce the input function to the minimal example which still shows the issue. I would start with: double a_b_cubed(double a, double c)
{
return a * a /** a*/ + /*c **/ c * c;
} And further reduce until we get a minimal reproducer. |
Basically double f(double a, double c) {
double _t1 = 1;
return 0;
}
//produces:
//void f_grad(double a, double c, double *_result) {
// ***
// double _t10 = 1;
// ***
//} is already a minimal reproducer in terms of potential colliding with other temporary variables for clad::gradient. |
Yes, however that would trigger another type of redefinition caused by the fact we chose to name our generated variables that way. In the example above, the generator gets confused and regenerates two variables with the same name twice. |
It seems to me the type of redefinition is the same in both cases. a_b_cubed_darg0_grad naming says that it's the result of chaining auto cubed_da = clad::differentiate(a_b_cubed, 0);
cubed_da.dump();
//The code is: double a_b_cubed_darg0(double a, double c) {
// double _d_a = 1;
// double _d_c = 0;
// double _t0 = a * a;
// double _t1 = c * c;
// return (_d_a * a + a * _d_a) * a + _t0 * _d_a + (_d_c * c + c * _d_c) * c + _t1 * _d_c;
//}
auto cubed_da_grad = clad::gradient(a_b_cubed_darg0);
cubed_da_grad.dump();
//The code is: void a_b_cubed_darg0_grad(double a, double c, double *_result) {
// double _d__d_a = 0;
// double _d__d_c = 0;
// double _t0;
// double _t1;
// double _d__t0 = 0;
// double _t2;
// double _t3;
// double _d__t1 = 0;
// double _t4;
// double _t5;
// double _t6;
// double _t7;
// double _t8;
// double _t9;
// double _t10; **kind of bank of temporary variables**
// ...
// double _d_a = 1;
// double _d_c = 0;
// _t1 = a;
// _t0 = a;
// double _t00 = _t1 * _t0;
// _t3 = c;
// _t2 = c;
// double _t10 = _t3 * _t2; **just cloning the expression from original function**
// ...
//} Or maybe I don't get the idea |
Ah, now I get your point. We should probably pinpoint the exact location in the code and figure out what's the best way to fix? |
Yeap I hope I will figure out how global variables store works and when it becomes not global |
Fixed in 80b8235 |
Applying forward mode (DiffMode::forward) and reverse mode to
yields a redefinition error (_t10) when derived code is manually used
i.e. a_b_cubed_darg0_grad(1, 2, result);
The text was updated successfully, but these errors were encountered: