Changeset 3376


Ignore:
Timestamp:
Sep 29, 2014 4:25:22 AM (6 years ago)
Author:
bradbell
Message:

merge in bug fixes from trunk

Location:
branches/cache
Files:
1 deleted
10 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/cache

  • branches/cache/cppad/local/cskip_op.hpp

    r3301 r3376  
    121121        Base left, right;
    122122        if( arg[1] & 1 )
    123         {       CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) <= i_z );
     123        {       // If varialbe arg[2] <= i_z, it has already been computed,
     124                // but it will be skipped for higher orders.
    124125                left = taylor[ arg[2] * cap_order + 0 ];
    125126                CPPAD_ASSERT_UNKNOWN( IdenticalPar(left) );
     
    131132        }
    132133        if( arg[1] & 2 )
    133         {       CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) <= i_z );
     134        {       // If varialbe arg[3] <= i_z, it has already been computed,
     135                // but it will be skipped for higher orders.
    134136                right = taylor[ arg[3] * cap_order + 0 ];
    135137                CPPAD_ASSERT_UNKNOWN( IdenticalPar(right) );
  • branches/cache/cppad/local/forward0sweep.hpp

    r3363 r3376  
    265265                                play->forward_csum(op, arg, i_op, i_var);
    266266                        }
     267                        CPPAD_ASSERT_UNKNOWN( op != CSkipOp );
     268                        // if( op == CSkipOp )
     269                        // {    // CSkip has a variable number of arguments
     270                        //      play->forward_cskip(op, arg, i_op, i_var);
     271                        // }
    267272                        play->forward_next(op, arg, i_op, i_var);
    268273                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
  • branches/cache/cppad/local/forward1sweep.hpp

    r3363 r3376  
    315315                                play->forward_csum(op, arg, i_op, i_var);
    316316                        }
     317                        CPPAD_ASSERT_UNKNOWN( op != CSkipOp );
     318                        // if( op == CSkipOp )
     319                        // {    // CSkip has a variable number of arguments
     320                        //      play->forward_cskip(op, arg, i_op, i_var);
     321                        // }
    317322                        play->forward_next(op, arg, i_op, i_var);
    318323                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
  • branches/cache/cppad/local/forward2sweep.hpp

    r3363 r3376  
    253253                                play->forward_csum(op, arg, i_op, i_var);
    254254                        }
     255                        CPPAD_ASSERT_UNKNOWN( op != CSkipOp );
     256                        // if( op == CSkipOp )
     257                        // {    // CSkip has a variable number of arguments
     258                        //      play->forward_cskip(op, arg, i_op, i_var);
     259                        // }
    255260                        play->forward_next(op, arg, i_op, i_var);
    256261                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
  • branches/cache/cppad/local/optimize.hpp

    r3361 r3376  
    16521652                                info.n_op_true  = 0;
    16531653                                info.n_op_false = 0;
     1654                                info.i_arg      = 0; // case where no CSkipOp for this CExpOp
    16541655                                //
    16551656                                size_t index    = 0;
     
    18471848                                }
    18481849                                else    user_info[user_curr].connect_type = yes_connected;
     1850                                user_r_set[user_i].insert(0);
     1851                                user_r_bool[user_i] = true;
    18491852                                break;
    18501853
     
    18931896                                                " that contains the atomic function\n\t";
    18941897                                        s += user_atom->afun_name();
    1895                                         s += "\nCurrent atomoic_sparsity is set to";
     1898                                        s += "\nCurrent atomic_sparsity is set to";
    18961899                                        //
    18971900                                        if( user_set )
     
    19581961                CppAD::index_sort(keys, cskip_info_order);
    19591962        }
    1960         size_t cskip_info_next = 0;
     1963        // index in sorted order
     1964        size_t cskip_order_next = 0;
     1965        // index in order during reverse sweep
     1966        size_t cskip_info_index = cskip_info.size();
    19611967
    19621968
     
    20342040
    20352041                // determine if we should insert a conditional skip here
    2036                 bool skip = cskip_info_next < cskip_info.size();
    2037                 skip     &= (op != BeginOp) & (op != InvOp);
     2042                bool skip = cskip_order_next < cskip_info.size();
     2043                skip     &= op != BeginOp;
     2044                skip     &= op != InvOp;
     2045                skip     &= user_state == user_start;
    20382046                if( skip )
    2039                 {       j     = cskip_info_order[cskip_info_next];
     2047                {       j     = cskip_info_order[cskip_order_next];
    20402048                        if( NumRes(op) > 0 )
    20412049                                skip &= cskip_info[j].max_left_right < i_var;
     
    20442052                }
    20452053                if( skip )
    2046                 {       cskip_info_next++;
    2047                         skip &= cskip_info[j].skip_var_true.size() > 0 ||
    2048                                         cskip_info[j].skip_var_false.size() > 0;
     2054                {       cskip_order_next++;
     2055                        struct_cskip_info info = cskip_info[j];
     2056                        size_t n_true  = info.skip_var_true.size() + info.n_op_true;
     2057                        size_t n_false = info.skip_var_false.size() + info.n_op_false;
     2058                        skip &= n_true > 0 || n_false > 0;
    20492059                        if( skip )
    2050                         {       struct_cskip_info info = cskip_info[j];
    2051                                 CPPAD_ASSERT_UNKNOWN( NumRes(CSkipOp) == 0 );
    2052                                 size_t n_true  =
    2053                                         info.skip_var_true.size() + info.n_op_true;
    2054                                 size_t n_false =
    2055                                         info.skip_var_false.size() + info.n_op_false;
     2060                        {       CPPAD_ASSERT_UNKNOWN( NumRes(CSkipOp) == 0 );
    20562061                                size_t n_arg   = 7 + n_true + n_false;
    20572062                                // reserve space for the arguments to this operator but
     
    20612066                                rec->PutOp(CSkipOp);
    20622067                        }
    2063                         else    cskip_info[j].i_arg = 0;
    20642068                }
    20652069
     
    23522356                        tape[i_var].new_op  = rec->num_op_rec();
    23532357                        tape[i_var].new_var = rec->PutOp(op);
     2358                        //
     2359                        // The new addresses for left and right are used during
     2360                        // fill in the arguments for the CSkip operations. This does not
     2361                        // affect max_left_right which is used during this sweep.
     2362                        CPPAD_ASSERT_UNKNOWN( cskip_info_index > 0 );
     2363                        cskip_info_index--;
     2364                        cskip_info[ cskip_info_index ].left  = new_arg[2];
     2365                        cskip_info[ cskip_info_index ].right = new_arg[3];
    23542366                        break;
    23552367                        // ---------------------------------------------------
     
    25842596
    25852597        // fill in the arguments for the CSkip operations
    2586         CPPAD_ASSERT_UNKNOWN( cskip_info_next == cskip_info.size() );
     2598        CPPAD_ASSERT_UNKNOWN( cskip_order_next == cskip_info.size() );
    25872599        for(i = 0; i < cskip_info.size(); i++)
    25882600        {       struct_cskip_info info = cskip_info[i];
  • branches/cache/cppad/local/player.hpp

    r3363 r3376  
    663663                /*
    664664                The variables that need fixing are op_arg_ and op_arg. Currently,
    665                 op_arg points first argument for the previous operator.
     665                op_arg points to the last argument for the previous operator.
    666666                */
     667                // last argument for this csum operation
    667668                --op_arg;
     669                // first argument for this csum operation
    668670                op_arg      = op_arg_    -= (op_arg[0] + 4);
     671                // now op_arg points to the first argument for this csum operator
    669672
    670673                CPPAD_ASSERT_UNKNOWN(
    671674                op_arg[0] + op_arg[1] == op_arg[ 3 + op_arg[0] + op_arg[1] ]
    672675                );
     676
    673677                CPPAD_ASSERT_UNKNOWN( op_index_  < op_rec_.size() );
    674678                CPPAD_ASSERT_UNKNOWN( op_arg_rec_.data() <= op_arg_ );
     
    710714                /*
    711715                The variables that need fixing are op_arg_ and op_arg. Currently,
    712                 op_arg points first arugment for the previous operator.
     716                op_arg points to the last arugment for the previous operator.
    713717                */
     718                // last argument for this cskip operation
    714719                --op_arg;
    715                 op_arg      = op_arg_    -= (op_arg[0] + 4);
     720                // first argument for this cskip operation
     721                op_arg      = op_arg_    -= (op_arg[0] + 7);
    716722
    717723                CPPAD_ASSERT_UNKNOWN(
    718                 op_arg[1] + op_arg[2] == op_arg[ 3 + op_arg[1] + op_arg[2] ]
     724                op_arg[4] + op_arg[5] == op_arg[ 6 + op_arg[4] + op_arg[5] ]
    719725                );
    720726                CPPAD_ASSERT_UNKNOWN( op_index_  < op_rec_.size() );
  • branches/cache/cppad/local/reverse_sweep.hpp

    r3349 r3376  
    254254                                play->reverse_csum(op, arg, i_op, i_var);
    255255                        }
     256                        CPPAD_ASSERT_UNKNOWN( op != CSkipOp );
     257                        // if( op == CSkipOp )
     258                        // {    // CSkip has a variable number of arguments
     259                        //      play->reverse_cskip(op, arg, i_op, i_var);
     260                        // }
     261                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
    256262                        play->reverse_next(op, arg, i_op, i_var);
    257                         CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
    258263                }
    259264
    260265                // rest of informaiton depends on the case
    261266# if CPPAD_REVERSE_SWEEP_TRACE
     267                if( op == CSumOp )
     268                {       // CSumOp has a variable number of arguments
     269                        play->reverse_csum(op, arg, i_op, i_var);
     270                }
     271                if( op == CSkipOp )
     272                {       // CSkip has a variable number of arguments
     273                        play->reverse_cskip(op, arg, i_op, i_var);
     274                }
    262275                size_t       i_tmp  = i_var;
    263276                const Base*  Z_tmp  = Taylor + i_var * J;
     
    344357                        // forward_next thinks it one has one argument.
    345358                        // we must inform reverse_next of this special case.
     359# if ! CPPAD_REVERSE_SWEEP_TRACE
    346360                        play->reverse_cskip(op, arg, i_op, i_var);
     361# endif
    347362                        break;
    348363                        // -------------------------------------------------
     
    352367                        // reverse_next thinks it one has one argument.
    353368                        // We must inform reverse_next of this special case.
     369# if ! CPPAD_REVERSE_SWEEP_TRACE
    354370                        play->reverse_csum(op, arg, i_op, i_var);
     371# endif
    355372                        reverse_csum_op(
    356373                                d, i_var, arg, K, Partial
  • branches/cache/omh/whats_new/whats_new_14.omh

    r3361 r3376  
    6262sequence; i.e., $cref/f.size_var()/seq_property/size_var/$$ increased by one.
    6363
     64$head 09-28$$
     65Fix more bugs related to optimizing condition conditional expressions.
     66$list number$$
     67Using old instead of new operator indices.
     68$lnext
     69Not properly following dependence back through atomic operations.
     70$lnext
     71Aborting during forward order zero, when skipping computation for a variable
     72that was already completed (the skip is still useful for higher orders
     73and for reverse mode).
     74$lnext
     75Reverse mode not properly handling the variable number of arguments in the
     76conditional skip operation.
     77$lnext
     78Reverse mode tracing not properly handling the variable number
     79of argument operations; i.e., conditional skip and cumulative summation.
     80$lend
     81
     82$head 09-27$$
     83Fix a bug that occurred when
     84$cref/f.optimize/optimize/$$ was used with a function $icode f$$
     85that contained calls to user defined $cref atomic$$ operations
     86and $cref/conditional expressions/CondExp/$$.
     87
    6488$head 09-25$$
    65 Fix a bug when
     89Fix a bug that occurred when
    6690$cref/f.optimize/optimize/$$ was used with a function $icode f$$
    6791that contained $cref discrete$$ functions.
  • branches/cache/test_more/optimize.cpp

    r3361 r3376  
    14571457                return ok;
    14581458        }
     1459        // ----------------------------------------------------------------
     1460        void i_algo(
     1461                const CppAD::vector< CppAD::AD<double> >& ax ,
     1462                      CppAD::vector< CppAD::AD<double> >& ay )
     1463        {       ay[0] = 1.0 / ax[0]; }
     1464        //
     1465        // Test bug where atomic functions were not properly conditionally skipped.
     1466        bool cond_exp_skip_atomic(void)
     1467        {       bool ok = true;
     1468                using CppAD::AD;
     1469                using CppAD::vector;
     1470       
     1471                // Create a checkpoint version of the function i_algo
     1472                vector< AD<double> > au(1), av(1), aw(1);
     1473                au[0] = 1.0;
     1474                CppAD::checkpoint<double> i_check("i_check", i_algo, au, av);
     1475       
     1476                // independent variable vector
     1477                vector< AD<double> > ax(2), ay(1);
     1478                ax[0] = 1.0;
     1479                ax[1] = 2.0;
     1480                Independent(ax);
     1481       
     1482                // call atomic function that does not get used
     1483                au[0] = ax[0];
     1484                i_check(au, av);
     1485                au[0] = ax[1];
     1486                i_check(au, aw);
     1487                AD<double> zero = 0.0;
     1488                ay[0] = CondExpGt(av[0], zero, av[0], aw[0]);
     1489
     1490                // create function object f : ax -> ay
     1491                CppAD::ADFun<double> f(ax, ay);
     1492
     1493                // run case that skips the second call to afun
     1494                // (can use trace in forward0sweep.hpp to see this).
     1495                vector<double> x(2), y_before(1), y_after(1);
     1496                x[0]      = 1.0;
     1497                x[1]      = 2.0;
     1498                y_before  = f.Forward(0, x);
     1499                f.optimize();
     1500                y_after   = f.Forward(0, x);
     1501       
     1502                ok &= y_before[0] == y_after[0];
     1503               
     1504                return ok;
     1505        }
     1506        //
     1507        // Test bug where conditional dependence did not pass through
     1508        // atomic functions
     1509        bool cond_exp_atomic_dependence(void)
     1510        {       bool ok = true;
     1511                using CppAD::AD;
     1512                using CppAD::vector;
     1513       
     1514                // Create a checkpoint version of the function i_algo
     1515                vector< AD<double> > au(1), av(1), aw(1);
     1516                au[0] = 1.0;
     1517                CppAD::checkpoint<double> i_check("i_check", i_algo, au, av);
     1518       
     1519                vector< AD<double> > ax(2), ay(1);
     1520                AD<double> zero = 0.0; 
     1521                ax[0] = 1.0;
     1522                ax[1] = 1.0;
     1523                Independent(ax);
     1524                av[0] = ax[0] + ax[1];
     1525                i_check(av, aw);
     1526                ay[0] = CondExpGt(aw[0], zero, zero, aw[0]);
     1527                CppAD::ADFun<double> f;
     1528                f.Dependent(ax, ay);
     1529
     1530                // run case that skips the second call to afun
     1531                // (but not for order zero)
     1532                vector<double> x(2), y_before(1), y_after(1);
     1533                vector<double> dx(2), dy_before(1), dy_after(1);
     1534                x[0]      = 1.0;
     1535                x[1]      = 1.0;
     1536                y_before  = f.Forward(0, x);
     1537                dx[0]     = 2.0;
     1538                dx[1]     = 2.0;
     1539                dy_before = f.Forward(1, dx);
     1540                f.optimize();
     1541                y_after   = f.Forward(0, x);
     1542                dy_after  = f.Forward(1, dx);
     1543
     1544                ok &= y_before[0]  == y_after[0];
     1545                ok &= dy_before[0] == dy_after[0];
     1546
     1547                return ok;
     1548        }
    14591549        // -----------------------------------------------------------------------
     1550        // Test reverse mode conditionalay skipping commands.
     1551        template <class Type>
     1552        Type my_max(const CppAD::vector<Type>& arg)
     1553        {       Type res = arg[0];
     1554                for(size_t j = 0;j < arg.size(); j++)
     1555                res = CondExpGt(res, arg[j], res, arg[j]);
     1556                return res;
     1557        }
     1558        bool cond_exp_reverse(void)
     1559        {       bool ok = true;
     1560                size_t n = 3;
     1561                using CppAD::vector;
     1562                using CppAD::AD;
     1563       
     1564                vector< AD<double> > ax(n), ay(1);
     1565                for(size_t j = 0; j < n; j++)
     1566                        ax[j] = 1.0;
     1567                Independent(ax);
     1568                ay[0] = my_max(ax) + my_max(ax);
     1569                CppAD::ADFun<double> f(ax, ay);
     1570       
     1571                f.optimize();
     1572       
     1573                vector<double> x(n), w(1), dx(n);
     1574                for(size_t j = 0;j < n; j++)
     1575                        x[j] = double(j);
     1576                f.Forward(0, x);
     1577                w[0] = 1.0;
     1578                dx = f.Reverse(1, w);
     1579                for(size_t j = 0; j < n; j++)
     1580                {       if( j == n-1 )
     1581                                ok &= dx[j] == 2.0;
     1582                        else
     1583                                ok &= dx[j] == 0.0;
     1584                }
     1585                return ok;
     1586        }
    14601587}
    14611588
     
    15021629        // case where a discrete function is used
    15031630        ok     &= discrete_function();
     1631        // check conditional skip of an atomic function
     1632        ok     &= cond_exp_skip_atomic();
     1633        // check conditional dependence through atomic function
     1634        ok     &= cond_exp_atomic_dependence();
     1635        // check reverse mode conditional skipping
     1636        ok     &= cond_exp_reverse();
    15041637        //
    15051638        CppAD::user_atomic<double>::clear();
Note: See TracChangeset for help on using the changeset viewer.