@@ -6,20 +6,20 @@ namespace Experimental {
66namespace SOFIE {
77
88// The constructor now just registers the necessary C++ libraries.
9- RModelProfiler::RModelProfiler (RModel &model) : fModel ( model)
9+ void RModelProfiler::AddNeededStdLibs (RModel &model)
1010{
11- fModel .AddNeededStdLib (" chrono" ); // for timing operators
12- fModel .AddNeededStdLib (" vector" ); // for storing profiling results
13- fModel .AddNeededStdLib (" string" ); // for operator names
14- fModel .AddNeededStdLib (" map" ); // for the results map
15- fModel .AddNeededStdLib (" iostream" ); // for printing results
16- fModel .AddNeededStdLib (" iomanip" ); // for printing results
11+ model .AddNeededStdLib (" chrono" ); // for timing operators
12+ model .AddNeededStdLib (" vector" ); // for storing profiling results
13+ model .AddNeededStdLib (" string" ); // for operator names
14+ model .AddNeededStdLib (" map" ); // for the results map
15+ model .AddNeededStdLib (" iostream" ); // for printing results
16+ model .AddNeededStdLib (" iomanip" ); // for printing results
1717}
1818
1919// This function generates the helper functions inside the Session struct.
20- void RModelProfiler::GenerateUtilityFunctions ()
20+ std::string RModelProfiler::GenerateUtilityFunctions ()
2121{
22- auto &gc = fModel . fProfilerGC ;
22+ std::string gc ;
2323
2424 // Generate PrintProfilingResults function
2525 gc += " // generate code for printing operator results. By default order according to time (from higher to lower)\n " ;
@@ -107,68 +107,50 @@ void RModelProfiler::GenerateUtilityFunctions()
107107 gc += " \n " ;
108108 gc += " return variance;\n " ;
109109 gc += " }\n " ;
110+
111+ return gc;
110112}
111113
114+ // Generate code for adding session member
115+
112116// Main generation function for the profiler.
113- void RModelProfiler::Generate ()
117+ std::string RModelProfiler::GenerateSessionMembers ()
114118{
115- // Clear the profiler's code string to start fresh.
116- fModel .fProfilerGC .clear ();
117- auto &gc = fModel .fProfilerGC ;
118-
119- // 1. Add the data member to the Session struct to store results.
120- gc += " public:\n " ;
119+ std::string gc;
121120 gc += " // Maps an operator name to a vector of its execution times (in microseconds).\n " ;
122121 gc += " std::map<std::string, std::vector<double>> fProfilingResults;\n\n " ;
123-
124- // 2. Generate and add the utility functions like PrintProfilingResults.
125- GenerateUtilityFunctions ();
126-
127- // 3. Generate the signature for the profiled doInfer method.
128- std::string doInferSignature = fModel .GenerateInferSignature ();
129- if (!doInferSignature.empty ()) doInferSignature += " , " ;
130- for (auto const &name : fModel .GetOutputTensorNames ()) {
131- doInferSignature += " std::vector<" + ConvertTypeToString (fModel .GetTensorType (name)) + " > &output_tensor_" + name + " ," ;
132- }
133- if (!fModel .GetOutputTensorNames ().empty ()) {
134- doInferSignature.back () = ' ' ;
135- }
136- gc += " void doInfer(" + doInferSignature + " ) {\n " ;
137-
138- // 4. Generate the body of the doInfer method with timing instrumentation.
122+ return gc;
123+ }
124+ std::string RModelProfiler::GenerateBeginInferCode () {
125+ std::string gc;
126+ // 1. Add necessary code for instrumenting with timers
139127 gc += " // Timer variable for profiling\n " ;
140128 gc += " std::chrono::steady_clock::time_point tp_start, tp_overall_start;\n\n " ;
141129 gc += " tp_overall_start = std::chrono::steady_clock::now();\n\n " ;
130+ return gc;
131+ }
132+ std::string RModelProfiler::GenerateOperatorCode (ROperator &op, size_t op_idx) {
133+ std::string gc;
134+ gc += " // -- Profiling for operator " + op.Name () + " --\n " ;
135+ gc += " tp_start = std::chrono::steady_clock::now();\n\n " ;
142136
143- for (size_t op_idx = 0 ; op_idx < fModel .fOperators .size (); ++op_idx) {
144- const auto & op = fModel .fOperators [op_idx];
145- gc += " // -- Profiling for operator " + op->name + " --\n " ;
146- gc += " tp_start = std::chrono::steady_clock::now();\n\n " ;
147-
148- // Add the actual operator inference code
149- gc += op->Generate (std::to_string (op_idx));
150-
151- // Add the code to stop the timer and store the result
152- gc += " \n fProfilingResults[\" " + op->name + " \" ].push_back(\n " ;
153- gc += " std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(\n " ;
154- gc += " std::chrono::steady_clock::now() - tp_start).count());\n\n " ;
155- }
137+ // Add the actual operator inference code
138+ gc += op.Generate (std::to_string (op_idx));
156139
157- // 5. Generate the code to fill the output tensors.
158- gc += " using TMVA::Experimental::SOFIE::UTILITY::FillOutput;\n\n " ;
159- for (std::string const &name : fModel .GetOutputTensorNames ()) {
160- bool isIntermediate = fModel .fIntermediateTensorInfos .count (name) > 0 ;
161- std::string n = isIntermediate ? std::to_string (ConvertShapeToLength (fModel .GetTensorShape (name)))
162- : ConvertDynamicShapeToLength (fModel .GetDynamicTensorShape (name));
163- gc += " FillOutput(tensor_" + name + " , output_tensor_" + name + " , " + n + " );\n " ;
164- }
140+ // Add the code to stop the timer and store the result
141+ gc += " \n fProfilingResults[\" " + op.Name () + " \" ].push_back(\n " ;
142+ gc += " std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(\n " ;
143+ gc += " std::chrono::steady_clock::now() - tp_start).count());\n\n " ;
144+ return gc;
145+ }
165146
147+ std::string RModelProfiler::GenerateEndInferCode () {
148+ std::string gc;
166149 gc += " \n // -- Record overall inference time --\n " ;
167150 gc += " fProfilingResults[\" Overall_Time\" ].push_back(\n " ;
168151 gc += " std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(\n " ;
169152 gc += " std::chrono::steady_clock::now() - tp_overall_start).count());\n " ;
170-
171- gc += " }\n\n " ; // End of doInfer function
153+ return gc;
172154}
173155
174156} // namespace SOFIE
0 commit comments