File: json_writer.cpp

package info (click to toggle)
cppad 2025.00.00.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,552 kB
  • sloc: cpp: 112,594; sh: 5,972; ansic: 179; python: 71; sed: 12; makefile: 10
file content (235 lines) | stat: -rw-r--r-- 8,668 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-22 Bradley M. Bell
// ----------------------------------------------------------------------------

# include <cppad/local/pod_vector.hpp>
# include <cppad/core/cppad_assert.hpp>
# include <cppad/core/graph/cpp_graph.hpp>
# include <cppad/utility/to_string.hpp>
# include <cppad/utility/vector.hpp>

// documentation for this routine is in the file below
# include <cppad/local/graph/json_writer.hpp>

void CppAD::local::graph::json_writer(
   std::string&                              json                   ,
   const cpp_graph&                          graph_obj              )
{  using std::string;
   // --------------------------------------------------------------------
   const string&  function_name( graph_obj.function_name_get() );
   const size_t&  n_dynamic_ind( graph_obj.n_dynamic_ind_get() );
   const size_t&  n_variable_ind( graph_obj.n_variable_ind_get() );
   // --------------------------------------------------------------------
   //
   // set: n_usage
   size_t n_usage = graph_obj.operator_vec_size();
   //
   // set: is_graph_op_used
   pod_vector<bool> is_graph_op_used(n_graph_op);
   for(size_t i = 0; i < n_graph_op; ++i)
      is_graph_op_used[i] = false;
   for(size_t i = 0; i < n_usage; ++i)
      is_graph_op_used[ graph_obj.operator_vec_get(i) ] = true;
   //
   // set: n_define and graph_code
   size_t n_define = 0;
   pod_vector<size_t> graph_code(n_graph_op);
   for(size_t i = 0; i < n_graph_op; ++i)
   {  graph_code[i] = 0;
      if( is_graph_op_used[i] )
         graph_code[i] = ++n_define;
   }
   // ----------------------------------------------------------------------
   // output: starting '{' for this graph
   json = "{\n";
   //
   // output: function_name
   json += "'function_name' : '" + function_name + "',\n";
   //
   // output: op_define_vec
   json += "'op_define_vec' : [ " + to_string(n_define) + ", [\n";
   size_t count_define = 0;
   for(size_t i = 0; i < n_graph_op; ++i)
   {  if( is_graph_op_used[i] )
      {  ++count_define;
         const string name = op_enum2name[i];
         size_t op_code    = graph_code[i];
         size_t n_arg      = op_enum2fixed_n_arg[i];
         json += "{ 'op_code':" + to_string(op_code);
         json += ", 'name':'" + name + "'";
         if( n_arg != 0 )
            json += ", 'n_arg':" + to_string(n_arg);
         json += " }";
         if( count_define < n_define )
            json += ",\n";
      }
   }
   json += " ]\n] ,\n";
   //
   // output: n_dynamic_ind
   json += "'n_dynamic_ind' : " + to_string( n_dynamic_ind ) + ",\n";
   //
   // output: n_variable_ind
   json += "'n_variable_ind' : " + to_string( n_variable_ind ) + ",\n";
   //
   // output: constant_vec
   size_t n_constant = graph_obj.constant_vec_size();
   json += "'constant_vec' : [ " + to_string(n_constant) + ", [\n";
   for(size_t i = 0; i < n_constant; ++i)
   {  json += to_string( graph_obj.constant_vec_get(i) );
      if( i + 1 < n_constant )
         json += ",\n";
   }
   json += " ] ],\n";
   // -----------------------------------------------------------------------
   //
   // defined here to avoid memory re-allocation for each operator
   vector<size_t> arg;
   //
   // defined here because not using as loop index
   cpp_graph::const_iterator graph_itr;
   //
   // output: op_usage_vec
   json += "'op_usage_vec' : [ " + to_string(n_usage) + ", [\n";
   for(size_t op_index = 0; op_index < n_usage; ++op_index)
   {  // op_enum, str_index, n_result, arg_node
      if( op_index == 0 )
         graph_itr = graph_obj.begin();
      else
         ++graph_itr;
      //
      cpp_graph::const_iterator::value_type itr_value = *graph_itr;
      const vector<size_t>& str_index( *itr_value.str_index_ptr );
      graph_op_enum op_enum    = itr_value.op_enum;
      size_t        call_id    = itr_value.call_id;
      size_t        n_result   = itr_value.n_result;
      size_t        n_arg      = itr_value.arg_node_ptr->size();
      arg.resize(n_arg);
      arg                      = *(itr_value.arg_node_ptr);
      CPPAD_ASSERT_UNKNOWN( n_arg > 0 );
      //
      // op_code
      size_t op_code = graph_code[op_enum];
      //
      switch( op_enum )
      {
         // --------------------------------------------------------------
         // sum
         case sum_graph_op:
         json += "[ " + to_string(op_code) + ", 1, ";
         json += to_string(n_arg) + ", [ ";
         for(size_t j = 0; j < n_arg; ++j)
         {  json += to_string( arg[j] );
            if( j + 1 < n_arg )
               json += ", ";
         }
         json += "] ]";
         break;

         // --------------------------------------------------------------
         // atom, atom4
         case atom_graph_op:
         case atom4_graph_op:
         {  size_t name_index = str_index[0];
            string name = graph_obj.atomic_name_vec_get(name_index);
            json += "[ " + to_string(op_code) + ", ";
            json += "'" + name + "', ";
         }
         if( op_enum == atom4_graph_op )
            json += to_string(call_id) + ", ";
         json += to_string(n_result) + ", ";
         json += to_string(n_arg) + ", [";
         for(size_t j = 0; j < n_arg; ++j)
         {  json += to_string( arg[j] );
            if( j + 1 < n_arg )
               json += ", ";
                 else
               json += " ]";
         }
         json += " ]";
         break;

         // --------------------------------------------------------------
         // comparison operators
         case comp_eq_graph_op:
         case comp_ne_graph_op:
         case comp_lt_graph_op:
         case comp_le_graph_op:
         CPPAD_ASSERT_UNKNOWN( n_result == 0 );
         CPPAD_ASSERT_UNKNOWN( n_arg == 2 );
         json += "[ " + to_string(op_code) + ", 0, 2, [ ";
         json += to_string( arg[0] ) + ", ";
         json += to_string( arg[1] ) + " ] ]";
         break;

         // --------------------------------------------------------------
         // discrete
         case discrete_graph_op:
         CPPAD_ASSERT_UNKNOWN( n_result == 1 );
         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );
         {  size_t name_index = str_index[0];
            string name = graph_obj.discrete_name_vec_get(name_index);
            json += "[ " + to_string(op_code) + ", ";
            json += "'" + name + "', ";
         }
         json += to_string(n_result) + ", ";
         json += to_string(n_arg) + ", [ ";
         json += to_string( arg[0] ) + " ] ]";
         break;
         // --------------------------------------------------------------
         // print_op
         case print_graph_op:
         CPPAD_ASSERT_UNKNOWN( n_result == 0 );
         CPPAD_ASSERT_UNKNOWN( n_arg == 2 );
         {  size_t before_index = str_index[0];
            size_t after_index  = str_index[1];
            string before  = graph_obj.print_text_vec_get(before_index);
            string after   = graph_obj.print_text_vec_get(after_index);
            json += "[ " + to_string(op_code) + ", ";
            json += "'" + before + "', ";
            json += "'" + after + "', 0, 2, [ ";
            json += to_string( arg[0] ) + ", ";
            json += to_string( arg[1] ) + " ] ]";
         }
         break;

         // --------------------------------------------------------------
         default:
         CPPAD_ASSERT_UNKNOWN( n_result == 1 );
         CPPAD_ASSERT_UNKNOWN( op_enum2fixed_n_arg[op_enum] == n_arg );
         json += "[ " + to_string(op_code) + ", ";
         for(size_t j = 0; j < n_arg; ++j)
         {  json += to_string( arg[j] );
            if( j + 1 < n_arg )
               json += ", ";
                 else
               json += " ]";
         }
         break;

      } // end switch
      if( op_index + 1 < n_usage )
         json += ",\n";
   }
   json += "\n] ],\n";
   // ----------------------------------------------------------------------
   // output: dependent_vec
   size_t n_dependent = graph_obj.dependent_vec_size();
   json += "'dependent_vec' : [ " + to_string(n_dependent) + ", [ ";
   for(size_t i = 0; i < n_dependent; ++i)
   {  json += to_string( graph_obj.dependent_vec_get(i) );
      if( i + 1 < n_dependent )
         json += ", ";
   }
   json += " ] ]\n";
   //
   // output: ending '}' for this graph
   json += "}\n";
   // ----------------------------------------------------------------------
   // Convert the single quote to double quote
   for(size_t i = 0; i < json.size(); ++i)
      if( json[i] == '\'' ) json[i] = '"';
   //
   return;
}