Skip to content
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

Closed
jacklqiu opened this issue Jul 18, 2019 · 8 comments
Closed

clad::gradient redefinition error #138

jacklqiu opened this issue Jul 18, 2019 · 8 comments

Comments

@jacklqiu
Copy link
Contributor

Applying forward mode (DiffMode::forward) and reverse mode to

double a_b_cubed(double a, double c)
{
  return a * a * a + c * c * c;
}

yields a redefinition error (_t10) when derived code is manually used
i.e. a_b_cubed_darg0_grad(1, 2, result);

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;
    double _t10 = _t3 * _t2;
    _t6 = _d_a;
    _t5 = a;
    _t8 = a;
    _t7 = _d_a;
    _t9 = (_t6 * _t5 + _t8 * _t7);
    _t4 = a;
    _t11 = _t00;
    _t10 = _d_a;
    _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;
    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;
    }
}
@Medha-B
Copy link

Medha-B commented Mar 18, 2020

Hello there!
As the name suggests, redefinition error occurs due to defining a variable again
and again. I am making the necessary changes here.

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.

@vgvassilev
Copy link
Owner

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.

@blide
Copy link
Contributor

blide commented Mar 24, 2020

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.

@vgvassilev
Copy link
Owner

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.

@blide
Copy link
Contributor

blide commented Mar 24, 2020

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 clad::differentiate(a_b_cubed, 0) and clad::gradient(a_b_cubed_darg0), so the code snippet might be

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

@vgvassilev
Copy link
Owner

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?

@blide
Copy link
Contributor

blide commented Mar 24, 2020

Yeap I hope I will figure out how global variables store works and when it becomes not global

@vgvassilev
Copy link
Owner

Fixed in 80b8235

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants