source: branches/opt_cond_exp/cppad/local/op_code.hpp @ 2979

Last change on this file since 2979 was 2979, checked in by bradbell, 7 years ago
  1. Add operator index to trace output.
  2. Check that new operator values have been set and are valid.
  3. Reinitialize cskip_op_ after optimization.

optimize.hpp: Add test of entirely removing an atomic call.

  • Property svn:keywords set to Id
File size: 19.9 KB
Line 
1/* $Id: op_code.hpp 2979 2013-10-20 18:00:28Z bradbell $ */
2# ifndef CPPAD_OP_CODE_INCLUDED
3# define CPPAD_OP_CODE_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
7
8CppAD is distributed under multiple licenses. This distribution is under
9the terms of the
10                    Eclipse Public License Version 1.0.
11
12A copy of this license is included in the COPYING file of this distribution.
13Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14-------------------------------------------------------------------------- */
15# include <string>
16# include <sstream>
17# include <iomanip>
18
19# include <cppad/local/define.hpp>
20# include <cppad/local/cppad_assert.hpp>
21
22// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
23# include <cppad/thread_alloc.hpp>
24
25namespace CppAD { // BEGIN_CPPAD_NAMESPACE
26/*!
27\defgroup op_code_hpp op_code.hpp
28\{
29\file op_code.hpp
30Defines the OpCode enum type and functions related to it.
31
32*/
33
34
35/*!
36Type used to distinguish different AD< \a Base > atomic operations.
37
38Each of the operators ends with the characters Op. Ignoring the Op at the end,
39the operators appear in alphabetical order. Binary operation where both
40operands have type AD< \a Base > use the following convention for thier endings:
41\verbatim
42    Ending  Left-Operand  Right-Operand
43      pvOp     parameter       variable 
44      vpOp      variable      parameter 
45      vvOp      variable       variable 
46\endverbatim
47For example, AddpvOp represents the addition operator where the left
48operand is a parameter and the right operand is a variable.
49*/
50enum OpCode {
51        AbsOp,    //  abs(variable)
52        AcosOp,   // asin(variable)
53        AddpvOp,  //      parameter  + variable
54        AddvvOp,  //      variable   + variable
55        AsinOp,   // asin(variable)
56        AtanOp,   // atan(variable)
57        BeginOp,  // used to mark the beginning of the tape
58        CExpOp,   // CondExpRel(left, right, trueCase, falseCase)
59        // arg[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
60        // arg[1] & 1 = is left a variable
61        // arg[1] & 2 = is right a variable
62        // arg[1] & 4 = is trueCase a variable
63        // arg[1] & 8 = is falseCase a variable
64        // arg[2]     = index correspoding to left
65        // arg[3]     = index correspoding to right
66        // arg[4]     = index correspoding to trueCase
67        // arg[5]     = index correspoding to falseCase
68        ComOp,    // Compare(cop, result, left, right)
69        CosOp,    //  cos(variable)
70        CoshOp,   // cosh(variable)
71        CSkipOp,  // Conditional skip
72        // arg[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
73        // arg[1] & 1 = is left a variable
74        // arg[1] & 2 = is right a variable
75        // arg[2]     = index correspoding to left
76        // arg[3]     = index correspoding to right
77        // arg[4] = number of operations to skip if CExpOp comparision is true
78        // arg[5] = number of operations to skip if CExpOp comparision is false
79        // arg[6] -> arg[5+arg[4]]               = skip operations if true
80        // arg[6+arg[4]] -> arg[5+arg[4]+arg[5]] = skip operations if false
81        // arg[6+arg[4]+arg[5]] = arg[4] + arg[5]
82        CSumOp,   // Cummulative summation
83        // arg[0] = number of addition variables in summation
84        // arg[1] = number of subtraction variables in summation
85        // arg[2] = index of parameter that initializes summation
86        // arg[3] -> arg[2+arg[0]] = index for positive variables
87        // arg[3+arg[0]] -> arg[2+arg[0]+arg[1]] = index for minus variables
88        // arg[3+arg[0]+arg[1]] = arg[0] + arg[1]
89        DisOp,    //  discrete::eval(index, variable)
90        DivpvOp,  //      parameter  / variable
91        DivvpOp,  //      variable   / parameter
92        DivvvOp,  //      variable   / variable
93        EndOp,    //  used to mark the end of the tape
94        ExpOp,    //  exp(variable)
95        InvOp,    //                             independent variable
96        LdpOp,    //    z[parameter]
97        LdvOp,    //    z[variable]
98        LogOp,    //  log(variable)
99        MulpvOp,  //      parameter  * variable
100        MulvvOp,  //      variable   * variable
101        ParOp,    //      parameter
102        PowpvOp,  //  pow(parameter,   variable)
103        PowvpOp,  //  pow(variable,    parameter)
104        PowvvOp,  //  pow(variable,    variable)
105        PriOp,    //  PrintFor(text, parameter or variable, parameter or variable)
106        SignOp,   // sign(variable)
107        SinOp,    //  sin(variable)
108        SinhOp,   // sinh(variable)
109        SqrtOp,   // sqrt(variable)
110        StppOp,   //    z[parameter] = parameter
111        StpvOp,   //    z[parameter] = variable
112        StvpOp,   //    z[variable]  = parameter
113        StvvOp,   //    z[variable]  = variable
114        SubpvOp,  //      parameter  - variable
115        SubvpOp,  //      variable   - parameter
116        SubvvOp,  //      variable   - variable
117        TanOp,    //  tan(variable)
118        TanhOp,   //  tan(variable)
119        // user atomic operation codes
120        UserOp,   //  start of a user atomic operaiton
121        // arg[0] = index of the operation if atomic_base<Base> class
122        // arg[1] = extra information passed trough by deprecated old atomic class
123        // arg[2] = number of arguments to this atomic function
124        // arg[3] = number of results for this atomic function
125        UsrapOp,  //  this user atomic argument is a parameter
126        UsravOp,  //  this user atomic argument is a variable
127        UsrrpOp,  //  this user atomic result is a parameter
128        UsrrvOp,  //  this user atomic result is a variable
129        NumberOp
130};
131// Note that bin/check_op_code.sh assumes the pattern '^\tNumberOp$' occurs
132// at the end of this list and only at the end of this list.
133
134/*!
135Table containing number of arguments for the corresponding operator.
136
137The i-th element in this table specifes the number of arguments stored for each
138occurance of the operator that is the i-th value in the OpCode enum type.
139For example, for the first three OpCode enum values we have
140\verbatim
141OpCode   j   NumArgTable[j]  Meaning
142AbsOp    0                1  index of variable we are taking absolute value of
143AcosOp   1                1  index of variable we are taking cosine of
144AddpvOp  1                2  indices of parameter and variable we are adding
145\endverbatim
146Note that the meaning of the arguments depends on the operator.
147*/
148const size_t NumArgTable[] = {
149        1, // AbsOp
150        1, // AcosOp
151        2, // AddpvOp
152        2, // AddvvOp
153        1, // AsinOp
154        1, // AtanOp
155        0, // BeginOp
156        6, // CExpOp
157        4, // ComOp
158        1, // CosOp
159        1, // CoshOp
160        0, // CSkipOp  (actually has a variable number of arguments, not zero)
161        0, // CSumOp   (actually has a variable number of arguments, not zero)
162        2, // DisOp
163        2, // DivpvOp
164        2, // DivvpOp
165        2, // DivvvOp
166        0, // EndOp
167        1, // ExpOp
168        0, // InvOp
169        3, // LdpOp
170        3, // LdvOp
171        1, // LogOp
172        2, // MulpvOp
173        2, // MulvvOp
174        1, // ParOp
175        2, // PowpvOp
176        2, // PowvpOp
177        2, // PowvvOp
178        5, // PriOp
179        1, // SignOp
180        1, // SinOp
181        1, // SinhOp
182        1, // SqrtOp
183        3, // StppOp
184        3, // StpvOp
185        3, // StvpOp
186        3, // StvvOp
187        2, // SubpvOp
188        2, // SubvpOp
189        2, // SubvvOp
190        1, // TanOp
191        1, // TanhOp
192        4, // UserOp
193        1, // UsrapOp
194        1, // UsravOp
195        1, // UsrrpOp
196        0  // UsrrvOp
197};
198
199/*!
200Fetch the number of arguments for a specified operator.
201
202\return
203Number of arguments corresponding to the specified operator.
204
205\param op
206Operator for which we are fetching the number of arugments.
207
208- Check that argument taple size equal to NumberOp
209- Check that \c CPPAD_OP_CODE_TYPE can support all the operator codes.
210- Check that \c op is a valid operator value.
211*/
212inline size_t NumArg( OpCode op)
213{       CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
214# ifndef NDEBUG
215        // only do these checks once to save time
216        static bool first = true;
217        if( first )
218        {       CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) ==
219                        sizeof(NumArgTable) / sizeof(NumArgTable[0])
220                );
221                CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) <=
222                        std::numeric_limits<CPPAD_OP_CODE_TYPE>::max()
223                );
224                first = false;
225        }
226        // do this check every time
227        CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
228# endif
229
230        return NumArgTable[(size_t) op];
231}
232
233/*!
234Number of variables resulting from the corresponding operation.
235
236The i-th element in this table specifes the number of varibles for each
237occurance of the operator that is the i-th value in the OpCode enum type.
238For example, for the first three OpCode enum values we have
239\verbatim
240OpCode   j   NumResTable[j]  Meaning
241AbsOp    0                1  variable that is the result of the absolute value
242AcosOp   1                2  acos(x) and sqrt(1-x*x) are required for this op
243AddpvOp  1                1  variable that is the result of the addition
244\endverbatim
245*/
246// alphabetical order (ignoring the Op at the end)
247const size_t NumResTable[] = {
248        1, // AbsOp
249        2, // AcosOp
250        1, // AddpvOp
251        1, // AddvvOp
252        2, // AsinOp
253        2, // AtanOp
254        1, // BeginOp  offsets first variable to have index one (not zero)
255        1, // CExpOp
256        0, // ComOp
257        2, // CosOp
258        2, // CoshOp
259        0, // CSkipOp
260        1, // CSumOp
261        1, // DisOp
262        1, // DivpvOp
263        1, // DivvpOp
264        1, // DivvvOp
265        0, // EndOp
266        1, // ExpOp
267        1, // InvOp
268        1, // LdpOp
269        1, // LdvOp
270        1, // LogOp
271        1, // MulpvOp
272        1, // MulvvOp
273        1, // ParOp
274        3, // PowpvOp
275        3, // PowvpOp
276        3, // PowvvOp
277        0, // PriOp
278        1, // SignOp
279        2, // SinOp
280        2, // SinhOp
281        1, // SqrtOp
282        0, // StppOp
283        0, // StpvOp
284        0, // StvpOp
285        0, // StvvOp
286        1, // SubpvOp
287        1, // SubvpOp
288        1, // SubvvOp
289        2, // TanOp
290        2, // TanhOp
291        0, // UserOp
292        0, // UsrapOp
293        0, // UsravOp
294        0, // UsrrpOp
295        1, // UsrrvOp
296        0  // Last entry not used: avoids warning by g++ 4.3.2 when pycppad builds
297};
298
299/*!
300Fetch the number of variables resulting from the specified operation.
301
302\return
303number of variables resulting from the specified operator.
304
305\param op
306Operator for which we are fetching the number of result variables.
307*/
308inline size_t NumRes(OpCode op)
309{       // check ensuring conversion to size_t is as expected
310        CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) == 
311                sizeof(NumResTable) / sizeof(NumResTable[0]) - 1
312        );
313        // this test ensures that all indices are within the table
314        CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
315
316        return NumResTable[(size_t) op];
317}
318
319/*!
320Prints a single field corresponding to an operator.
321
322A specified leader is printed in front of the value
323and then the value is left justified in the following width character.
324
325\tparam Type
326is the type of the value we are printing.
327
328\param os
329is the stream that we are printing to.
330
331\param leader
332are characters printed before the value.
333
334\param value
335is the value being printed.
336
337\param width
338is the number of character to print the value in.
339If the value does not fit in the width, the value is replace
340by width '*' characters.
341*/
342template <class Type>
343void printOpField(
344        std::ostream      &os , 
345        const char *   leader ,
346        const Type     &value , 
347        size_t          width )
348{
349        std::ostringstream buffer;
350        std::string        str;
351
352        // first print the leader
353        os << leader;
354
355        // print the value into an internal buffer
356        buffer << std::setw(width) << value;
357        str = buffer.str();
358
359        // length of the string
360        size_t len = str.size();
361        if( len > width )
362        {       size_t i;
363                for(i = 0; i < width-1; i++)
364                        os << str[i];
365                os << "*";
366                return;
367        }
368
369        // count number of spaces at begining
370        size_t nspace = 0; 
371        while(str[nspace] == ' ' && nspace < len)
372                nspace++;
373
374        // left justify the string
375        size_t i = nspace;
376        while( i < len )
377                os << str[i++];
378
379        i = width - len + nspace;
380        while(i--)
381                os << " "; 
382}
383
384/*!
385Prints a single operator, its operands, and the corresponding result values.
386
387\tparam Base
388Is the base type for these AD< \a Base > operations.
389
390\tparam Value
391Determines the type of the values that we are printing.
392
393\param os
394is the output stream that the information is printed on.
395
396\param Rec
3972DO: change this name from Rec to play (becuase it is a player
398and not a recorder).
399Is the entire recording for the tape that this operator is in.
400
401\param i_op
402is the index for the operator corresponding to this operation.
403
404\param i_var
405is the index for the variable corresponding to the result of this operation
406(ignored if NumRes(op) == 0).
407
408\param op
409The operator code (OpCode) for this operation.
410
411\param ind
412is the vector of argument indices for this operation
413(must have NumArg(op) elements).
414
415\param nfz
416is the number of forward sweep calculated values of type Value
417that correspond to this operation
418(ignored if NumRes(op) == 0).
419
420\param fz
421points to the first forward calculated value
422that correspond to this operation
423(ignored if NumRes(op) == 0).
424
425\param nrz
426is the number of reverse sweep calculated values of type Value
427that correspond to this operation
428(ignored if NumRes(op) == 0).
429
430\param rz
431points to the first reverse calculated value
432that correspond to this operation
433(ignored if NumRes(op) == 0).
434
435\par 2DO
436print the operator index (in addition to the variables index).
437*/
438template <class Base, class Value>
439void printOp(
440        std::ostream          &os     , 
441        const player<Base>   *Rec     ,
442        size_t                 i_op   , 
443        size_t                 i_var  , 
444        OpCode                 op     ,
445        const addr_t          *ind    ,
446        size_t                 nfz    ,
447        const  Value          *fz     ,
448        size_t                 nrz    ,
449        const  Value          *rz     )
450{       size_t i;
451       
452        CPPAD_ASSERT_KNOWN(
453                ! thread_alloc::in_parallel() ,
454                "cannot print trace of AD operations in parallel mode"
455        );
456        static const char *CompareOpName[] = 
457                { "Lt", "Le", "Eq", "Ge", "Gt", "Ne" };
458        static const char *OpName[] = {
459                "Abs"   ,
460                "Acos"  ,
461                "Addpv" ,
462                "Addvv" ,
463                "Asin"  ,
464                "Atan"  ,
465                "Begin" ,
466                "CExp"  ,
467                "Com"   ,
468                "Cos"   ,
469                "Cosh"  ,
470                "CSkip" ,
471                "CSum"  ,
472                "Dis"   ,
473                "Divpv" ,
474                "Divvp" ,
475                "Divvv" ,
476                "End"   ,
477                "Exp"   ,
478                "Inv"   ,
479                "Ldp"   ,
480                "Ldv"   ,
481                "Log"   ,
482                "Mulpv" ,
483                "Mulvv" ,
484                "Par"   ,
485                "Powpv" ,
486                "Powvp" ,
487                "Powvv" ,
488                "Pri"   ,
489                "Sign"  ,
490                "Sin"   ,
491                "Sinh"  ,
492                "Sqrt"  ,
493                "Stpp"  ,
494                "Stpv"  ,
495                "Stvp"  ,
496                "Stvv"  ,
497                "Subpv" ,
498                "Subvp" ,
499                "Subvv" ,
500                "Tan"   ,
501                "Tanh"  ,
502                "User"  ,
503                "Usrap" ,
504                "Usrav" ,
505                "Usrrp" ,
506                "Usrrv"
507        };
508        CPPAD_ASSERT_UNKNOWN( 
509                size_t(NumberOp) == sizeof(OpName) / sizeof(OpName[0])
510        );
511
512        // print operator
513        printOpField(os,  "o=",      i_op,  5);
514        printOpField(os,  "v=",      i_var, 5);
515        if( op == CExpOp || op == CSkipOp || op == ComOp )
516        {       printOpField(os, "", OpName[op], 5); 
517                printOpField(os, "", CompareOpName[ ind[0] ], 3);
518        }
519        else    printOpField(os, "", OpName[op], 8); 
520
521        // print other fields
522        size_t ncol = 5;
523        switch( op )
524        {
525                case CSkipOp:
526                /*
527                ind[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
528                ind[1] & 1 = is left a variable
529                ind[1] & 2 = is right a variable
530                ind[2]     = index correspoding to left
531                ind[3]     = index correspoding to right
532                ind[4] = number of operations to skip if CExpOp comparision is true
533                ind[5] = number of operations to skip if CExpOp comparision is false
534                ind[6] -> ind[5+ind[4]]               = skip operations if true
535                ind[6+ind[4]] -> ind[5+ind[4]+ind[5]] = skip operations if false
536                ind[6+ind[4]+ind[5]] = ind[4] + ind[5]
537                */
538                CPPAD_ASSERT_UNKNOWN( ind[6+ind[4]+ind[5]] == ind[4]+ind[5] );
539                CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
540                if( ind[1] & 1 )
541                        printOpField(os, " vl=", ind[2], ncol);
542                else    printOpField(os, " pl=", Rec->GetPar(ind[2]), ncol);
543                if( ind[1] & 2 )
544                        printOpField(os, " vr=", ind[3], ncol);
545                else    printOpField(os, " pr=", Rec->GetPar(ind[3]), ncol);
546                for(i = 0; i < size_t(ind[4]); i++)
547                         printOpField(os, " ot=", ind[6+i], ncol);
548                for(i = 0; i < size_t(ind[5]); i++)
549                         printOpField(os, " of=", ind[6+ind[4]+i], ncol);
550                break;
551
552                case CSumOp:
553                /*
554                ind[0] = number of addition variables in summation
555                ind[1] = number of subtraction variables in summation
556                ind[2] = index of parameter that initializes summation
557                ind[3], ... , ind[2+ind[0]] = index for positive variables
558                ind[3+ind[0]], ..., ind[2+ind[0]+ind[1]] = negative variables
559                ind[3+ind[0]+ind[1]] == ind[0] + ind[1]
560                */
561                CPPAD_ASSERT_UNKNOWN( ind[3+ind[0]+ind[1]] == ind[0]+ind[1] );
562                printOpField(os, " pr=", Rec->GetPar(ind[2]), ncol);
563                for(i = 0; i < size_t(ind[0]); i++)
564                         printOpField(os, " +v=", ind[3+i], ncol);
565                for(i = 0; i < size_t(ind[1]); i++)
566                         printOpField(os, " -v=", ind[3+ind[0]+i], ncol);
567                break;
568
569                case LdpOp:
570                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
571                printOpField(os, "off=", ind[0], ncol);
572                printOpField(os, "idx=", ind[1], ncol);
573                break;
574
575                case LdvOp:
576                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
577                printOpField(os, "off=", ind[0], ncol);
578                printOpField(os, "  v=", ind[1], ncol);
579                break;
580
581                case StppOp:
582                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
583                printOpField(os, "off=", ind[0], ncol);
584                printOpField(os, "idx=", ind[1], ncol);
585                printOpField(os, " pr=", Rec->GetPar(ind[2]), ncol);
586                break;
587
588                case StpvOp:
589                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
590                printOpField(os, "off=", ind[0], ncol);
591                printOpField(os, "idx=", ind[1], ncol);
592                printOpField(os, " vr=", ind[2], ncol);
593                break;
594
595                case StvpOp:
596                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
597                printOpField(os, "off=", ind[0], ncol);
598                printOpField(os, " vl=", ind[1], ncol);
599                printOpField(os, " pr=", Rec->GetPar(ind[2]), ncol);
600                break;
601
602                case StvvOp:
603                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
604                printOpField(os, "off=", ind[0], ncol);
605                printOpField(os, " vl=", ind[1], ncol);
606                printOpField(os, " vr=", ind[2], ncol);
607                break;
608
609                case AddvvOp:
610                case DivvvOp:
611                case MulvvOp:
612                case PowvvOp:
613                case SubvvOp:
614                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
615                printOpField(os, " vl=", ind[0], ncol);
616                printOpField(os, " vr=", ind[1], ncol);
617                break;
618
619                case AddpvOp:
620                case SubpvOp:
621                case MulpvOp:
622                case PowpvOp:
623                case DivpvOp:
624                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
625                printOpField(os, " pl=", Rec->GetPar(ind[0]), ncol);
626                printOpField(os, " vr=", ind[1], ncol);
627                break;
628
629                case DivvpOp:
630                case PowvpOp:
631                case SubvpOp:
632                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
633                printOpField(os, " vl=", ind[0], ncol);
634                printOpField(os, " pr=", Rec->GetPar(ind[1]), ncol);
635                break;
636
637                case AbsOp:
638                case AcosOp:
639                case AsinOp:
640                case AtanOp:
641                case CosOp:
642                case CoshOp:
643                case ExpOp:
644                case LogOp:
645                case SignOp:
646                case SinOp:
647                case SinhOp:
648                case SqrtOp:
649                case UsravOp:
650                case TanOp:
651                case TanhOp:
652                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
653                printOpField(os, "  v=", ind[0], ncol);
654                break;
655
656                case ParOp:
657                case UsrapOp:
658                case UsrrpOp:
659                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
660                printOpField(os, "  p=", Rec->GetPar(ind[0]), ncol);
661                break;
662
663                case UserOp:
664                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 );
665                {       std::string name =  atomic_base<Base>::class_name(ind[0]);
666                        printOpField(os, " f=",   name.c_str(), ncol);
667                        printOpField(os, " i=", ind[1], ncol);
668                        printOpField(os, " n=", ind[2], ncol);
669                        printOpField(os, " m=", ind[3], ncol);
670                }
671                break;
672
673                case PriOp:
674                CPPAD_ASSERT_NARG_NRES(op, 5, 0);
675                if( ind[0] & 1 )
676                        printOpField(os, " v=", ind[1], ncol);
677                else    printOpField(os, " p=", Rec->GetPar(ind[1]), ncol);
678                os << "before=\"" << Rec->GetTxt(ind[2]) << "\"";
679                if( ind[0] & 2 )
680                        printOpField(os, " v=", ind[3], ncol);
681                else    printOpField(os, " p=", Rec->GetPar(ind[3]), ncol);
682                os << "after=\"" << Rec->GetTxt(ind[4]) << "\"";
683                break;
684
685                case BeginOp:
686                case EndOp:
687                case InvOp:
688                case UsrrvOp:
689                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 );
690                break;
691
692                case DisOp:
693                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
694                {       const char* name = discrete<Base>::name(ind[0]);
695                        printOpField(os, " f=", name, ncol);
696                        printOpField(os, " x=", ind[1], ncol);
697                }
698                break;
699       
700
701                case CExpOp:
702                CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
703                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 6 );
704                if( ind[1] & 1 )
705                        printOpField(os, " vl=", ind[2], ncol);
706                else    printOpField(os, " pl=", Rec->GetPar(ind[2]), ncol);
707                if( ind[1] & 2 )
708                        printOpField(os, " vr=", ind[3], ncol);
709                else    printOpField(os, " pr=", Rec->GetPar(ind[3]), ncol);
710                if( ind[1] & 4 )
711                        printOpField(os, " vt=", ind[4], ncol);
712                else    printOpField(os, " pt=", Rec->GetPar(ind[4]), ncol);
713                if( ind[1] & 8 )
714                        printOpField(os, " vf=", ind[5], ncol);
715                else    printOpField(os, " pf=", Rec->GetPar(ind[5]), ncol);
716                break;
717
718                case ComOp:
719                CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
720                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 );
721                if( ind[1] & 1 )
722                        printOpField(os, "res=", 1, ncol);
723                else    printOpField(os, "res=", 0, ncol);
724                if( ind[1] & 2 )
725                        printOpField(os, " vl=", ind[2], ncol);
726                else    printOpField(os, " pl=", Rec->GetPar(ind[2]), ncol);
727                if( ind[1] & 4 )
728                        printOpField(os, " vr=", ind[3], ncol);
729                else    printOpField(os, " pr=", Rec->GetPar(ind[3]), ncol);
730                break;
731
732                default:
733                CPPAD_ASSERT_UNKNOWN(0);
734        }
735        size_t k;
736        if( NumRes(op) > 0 && (op != BeginOp) )
737        { 
738                for(k = 0; k < nfz; k++)
739                        std::cout << "| fz[" << k << "]=" << fz[k];
740                for(k = 0; k < nrz; k++)
741                        std::cout << "| rz[" << k << "]=" << rz[k];
742        }
743        std::cout << std::endl;
744}
745
746/*! \} */
747} // END_CPPAD_NAMESPACE
748# endif
Note: See TracBrowser for help on using the repository browser.