Skip to content

Improve efficiency of new_dynamic by catching IdenticalZero and IdenticalOne cases #232

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/cppad/core/ad.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,16 @@ private :
taddr_ = taddr;
ad_type_ = variable_enum;
}
// -----------------------------------------------------------------
// Make this parameter a new dynamic
void make_dynamic(tape_id_t id, addr_t taddr)
{ CPPAD_ASSERT_UNKNOWN( Parameter(*this) ); // currently a par
CPPAD_ASSERT_UNKNOWN( taddr > 0 ); // sure valid taddr

tape_id_ = id;
taddr_ = taddr;
ad_type_ = dynamic_enum;
}
// ---------------------------------------------------------------
// tape linking functions
//
Expand Down
33 changes: 22 additions & 11 deletions include/cppad/core/add.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,30 @@ AD<Base> operator + (const AD<Base> &left , const AD<Base> &right)
}
}
else if( dyn_left | dyn_right )
{ addr_t arg0 = left.taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
{ if( (! dyn_left) && IdenticalZero(left.value_) )
{
result.make_dynamic(right.tape_id_, right.taddr_);
}
else if( (! dyn_right) && IdenticalZero(right.value_) )
{
result.make_dynamic(left.tape_id_, left.taddr_);
}
else
{
addr_t arg0 = left.taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
arg0 = tape->Rec_.put_con_par(left.value_);
if( ! dyn_right )
if( ! dyn_right )
arg1 = tape->Rec_.put_con_par(right.value_);
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::add_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::add_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
}
}
return result;
}
Expand Down
30 changes: 20 additions & 10 deletions include/cppad/core/add_eq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,29 @@ AD<Base>& AD<Base>::operator += (const AD<Base> &right)
}
}
else if( dyn_left | dyn_right )
{ addr_t arg0 = taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
{ if( (! dyn_right) && IdenticalZero(right.value_) )
{ // this is left += 0, so do nothing
}
else if( (! dyn_left) && IdenticalZero(left))
{ // this is 0 += right
make_dynamic(right.tape_id_, right.taddr_);
}
else
{
addr_t arg0 = taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
arg0 = tape->Rec_.put_con_par(left);
if( ! dyn_right )
if( ! dyn_right )
arg1 = tape->Rec_.put_con_par(right.value_);
//
// parameters with a dynamic parameter results
taddr_ = tape->Rec_.put_dyn_par(
//
// parameters with a dynamic parameter results
taddr_ = tape->Rec_.put_dyn_par(
value_, local::add_dyn, arg0, arg1
);
tape_id_ = tape_id;
ad_type_ = dynamic_enum;
);
tape_id_ = tape_id;
ad_type_ = dynamic_enum;
}
}
return *this;
}
Expand Down
39 changes: 28 additions & 11 deletions include/cppad/core/azmul.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,19 +186,36 @@ azmul(const AD<Base>& x, const AD<Base>& y)
}
}
else if( dyn_x | dyn_y )
{ addr_t arg0 = x.taddr_;
addr_t arg1 = y.taddr_;
if( ! dyn_x )
{ if( (! dyn_x) && IdenticalZero(x.value_) )
{ // result = 0 * dynamic
}
else if ( ( ! dyn_y ) && IdenticalZero(y.value_) )
{ // result = dynamic * 0
}
else if( ( ! dyn_x ) && IdenticalOne(x.value_) )
{ // result = 1 * dynamic
result.make_dynamic(y.tape_id_, y.taddr_);
}
else if( ( ! dyn_y ) && IdenticalOne(y.value_) )
{ // result = dynamic * 1
result.make_dynamic(x.tape_id_, x.taddr_ );
}
else
{
addr_t arg0 = x.taddr_;
addr_t arg1 = y.taddr_;
if( ! dyn_x )
arg0 = tape->Rec_.put_con_par(x.value_);
if( ! dyn_y )
if( ! dyn_y )
arg1 = tape->Rec_.put_con_par(y.value_);
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::zmul_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::zmul_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
}
}
return result;
}
Expand Down
31 changes: 20 additions & 11 deletions include/cppad/core/div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,28 @@ AD<Base> operator / (const AD<Base> &left , const AD<Base> &right)
}
}
else if( dyn_left | dyn_right )
{ addr_t arg0 = left.taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
{ if ( (!dyn_left) && IdenticalZero(left.value_))
{ // 0 / dynamic
result.value_ = Base(0.0);
} else if( (!dyn_right) && IdenticalOne(right.value_))
{ // dynamic / 1
result.make_dynamic(left.tape_id_, left.taddr_);
} else
{
addr_t arg0 = left.taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
arg0 = tape->Rec_.put_con_par(left.value_);
if( ! dyn_right )
if( ! dyn_right )
arg1 = tape->Rec_.put_con_par(right.value_);
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::div_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::div_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
}
}
return result;
}
Expand Down
27 changes: 17 additions & 10 deletions include/cppad/core/div_eq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,26 @@ AD<Base>& AD<Base>::operator /= (const AD<Base> &right)
}
}
else if( dyn_left | dyn_right )
{ addr_t arg0 = taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
{ if( (!dyn_right) && IdenticalOne(right.value_))
{ // dynamic /= 1, so do nothing
} else if( (!dyn_left) && IdenticalZero(left))
{ // 0 /= dynamic, so do nothing
} else
{
addr_t arg0 = taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
arg0 = tape->Rec_.put_con_par(left);
if( ! dyn_right )
if( ! dyn_right )
arg1 = tape->Rec_.put_con_par(right.value_);
//
// parameters with a dynamic parameter results
taddr_ = tape->Rec_.put_dyn_par(
//
// parameters with a dynamic parameter results
taddr_ = tape->Rec_.put_dyn_par(
value_, local::div_dyn, arg0, arg1
);
tape_id_ = tape_id;
ad_type_ = dynamic_enum;
);
tape_id_ = tape_id;
ad_type_ = dynamic_enum;
}
}
return *this;
}
Expand Down
37 changes: 26 additions & 11 deletions include/cppad/core/mul.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,34 @@ AD<Base> operator * (const AD<Base> &left , const AD<Base> &right)
}
}
else if( dyn_left | dyn_right )
{ addr_t arg0 = left.taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
{ if ( (!dyn_left) && IdenticalZero(left.value_))
{ // 0 * dynamic
result.value_ = Base(0.0);
} else if( (!dyn_right) && IdenticalZero(right.value_))
{ // dynamic * 0
result.value_ = Base(0.0);
} else if( (!dyn_left) && IdenticalOne(left.value_))
{ // 1 * dynamic
result.make_dynamic(right.tape_id_, right.taddr_);
} else if( (!dyn_right) && IdenticalOne(right.value_))
{ // dynamic * 1
result.make_dynamic(left.tape_id_, left.taddr_);
} else
{
addr_t arg0 = left.taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
arg0 = tape->Rec_.put_con_par(left.value_);
if( ! dyn_right )
if( ! dyn_right )
arg1 = tape->Rec_.put_con_par(right.value_);
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::mul_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::mul_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
}
}
return result;
}
Expand Down
33 changes: 23 additions & 10 deletions include/cppad/core/mul_eq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,32 @@ AD<Base>& AD<Base>::operator *= (const AD<Base> &right)
}
}
else if( dyn_left | dyn_right )
{ addr_t arg0 = taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
{ if( (!dyn_right) && IdenticalOne(right.value_))
{ // dynamic *= 1, so do nothing
} else if( (!dyn_right) && IdenticalZero(right.value_))
{ // dynamic *= 0, so remove from tape
tape_id_ = 0;
} else if( (!dyn_left) && IdenticalOne(left))
{ // 1 *= dynamic
make_dynamic(right.tape_id_, right.taddr_);
} else if( (!dyn_left) && IdenticalZero(left))
{ // 0 *= dynamic, so do nothing
} else
{
addr_t arg0 = taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
arg0 = tape->Rec_.put_con_par(left);
if( ! dyn_right )
if( ! dyn_right )
arg1 = tape->Rec_.put_con_par(right.value_);
//
// parameters with a dynamic parameter results
taddr_ = tape->Rec_.put_dyn_par(
//
// parameters with a dynamic parameter results
taddr_ = tape->Rec_.put_dyn_par(
value_, local::mul_dyn, arg0, arg1
);
tape_id_ = tape_id;
ad_type_ = dynamic_enum;
);
tape_id_ = tape_id;
ad_type_ = dynamic_enum;
}
}
return *this;
}
Expand Down
29 changes: 18 additions & 11 deletions include/cppad/core/sub.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,26 @@ AD<Base> operator - (const AD<Base> &left , const AD<Base> &right)
result.ad_type_ = variable_enum;
}
else if( dyn_left | dyn_right )
{ addr_t arg0 = left.taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
{ if( (! dyn_right) && IdenticalZero(right.value_) )
{ // this is dynamic - 0
result.make_dynamic(left.tape_id_, left.taddr_);
}
else
{
addr_t arg0 = left.taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
arg0 = tape->Rec_.put_con_par(left.value_);
if( ! dyn_right )
if( ! dyn_right )
arg1 = tape->Rec_.put_con_par(right.value_);
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::sub_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
//
// parameters with a dynamic parameter result
result.taddr_ = tape->Rec_.put_dyn_par(
result.value_, local::sub_dyn, arg0, arg1
);
result.tape_id_ = tape_id;
result.ad_type_ = dynamic_enum;
}
}
return result;
}
Expand Down
26 changes: 16 additions & 10 deletions include/cppad/core/sub_eq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,25 @@ AD<Base>& AD<Base>::operator -= (const AD<Base> &right)
ad_type_ = variable_enum;
}
else if( dyn_left | dyn_right )
{ addr_t arg0 = taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
{ if( (! dyn_right) && IdenticalZero(right.value_) )
{ // this is left -= 0, so do nothing
}
else
{
addr_t arg0 = taddr_;
addr_t arg1 = right.taddr_;
if( ! dyn_left )
arg0 = tape->Rec_.put_con_par(left);
if( ! dyn_right )
if( ! dyn_right )
arg1 = tape->Rec_.put_con_par(right.value_);
//
// parameters with a dynamic parameter results
taddr_ = tape->Rec_.put_dyn_par(
//
// parameters with a dynamic parameter results
taddr_ = tape->Rec_.put_dyn_par(
value_, local::sub_dyn, arg0, arg1
);
tape_id_ = tape_id;
ad_type_ = dynamic_enum;
);
tape_id_ = tape_id;
ad_type_ = dynamic_enum;
}
}
return *this;
}
Expand Down