@@ -60,10 +60,14 @@ namespace rir {
6060 int call_count_in_ctxt = 0 ;
6161 int successful_compilation_count = 0 ;
6262 int failed_compilation_count = 0 ;
63+ double time_spent_in_compilation = 0 ;
64+ double time_wasted_in_compilation = 0 ;
6365 // Count the number of time the version for the context C
6466 // has been called in this context in
6567 // version_called_count[C]
6668 unordered_map<Context, int > version_called_count;
69+ unordered_map<Context, int > version_success_run_count;
70+ unordered_map<Context, double > version_runtime;
6771 };
6872
6973 class Entry {
@@ -88,7 +92,7 @@ namespace rir {
8892 string runId = runId_ss.str ();
8993
9094 myfile.open (" profile/" + runId + " .csv" );
91- myfile << " ID,NAME,CONTEXT,N_CALL,CMP_SUCCESS,CMP_FAIL,DISPATCHED FUNCTIONS\n " ;
95+ myfile << " ID,NAME,CONTEXT,N_CALL,TOTAL_RUNTIME, CMP_SUCCESS,SUCCESS_TIME, CMP_FAIL,FAIL_TIME,GOODNESS ,DISPATCHED FUNCTIONS\n " ;
9296 }
9397
9498 static size_t getEntryKey (SEXP callee) {
@@ -186,30 +190,71 @@ namespace rir {
186190 ctxt_data.version_called_count [version_context]++;
187191 }
188192
193+ void addFunctionDispatchRuntime (
194+ size_t id,
195+ Context call_context,
196+ Function const & f,
197+ std::chrono::duration<double > duration
198+ ) {
199+ Context version_context = f.context ();
200+
201+ // find entry for this function
202+ // entry must have been previously created by a call to createEntry
203+ auto & entry = entries.at (id);
204+
205+ // create or get call context data
206+ auto & ctxt_data = entry.dispatch_data [call_context];
207+
208+ // count one call in the context callContextId to version compiled for funContextId
209+
210+ ctxt_data.version_success_run_count [version_context]++;
211+ ctxt_data.version_runtime [version_context] += duration.count ();
212+ }
213+
189214 // For the two functions below: function entry must have been previously
190215 // created by createEntry, context entry may not exist yet
191216 void countSuccessfulCompilation (
192217 SEXP callee,
193- Context call_ctxt
218+ Context call_ctxt,
219+ std::chrono::duration<double > duration
194220 ) {
195221 size_t entry_key = getEntryKey (callee);
196222
197223 auto & entry = entries.at (entry_key);
198224 auto & dispatch_data = entry.dispatch_data [call_ctxt];
199225
200226 dispatch_data.successful_compilation_count ++;
227+
228+ dispatch_data.time_spent_in_compilation += duration.count ();
229+
230+ }
231+
232+ bool compileOnlyOnce (
233+ size_t entry_key,
234+ Context call_context
235+ ) {
236+ auto & entry = entries.at (entry_key);
237+ auto & dispatch_data = entry.dispatch_data [call_context];
238+
239+ if (dispatch_data.successful_compilation_count > 0 || dispatch_data.failed_compilation_count > 0 ) {
240+ return false ;
241+ } else {
242+ return true ;
243+ }
201244 }
202245
203246 void countFailedCompilation (
204247 SEXP callee,
205- Context call_ctxt
248+ Context call_ctxt,
249+ std::chrono::duration<double > duration
206250 ) {
207251 size_t entry_key = getEntryKey (callee);
208252
209253 auto & entry = entries.at (entry_key);
210254 auto & dispatch_data = entry.dispatch_data [call_ctxt];
211255
212256 dispatch_data.failed_compilation_count ++;
257+ dispatch_data.time_wasted_in_compilation += duration.count ();
213258 }
214259
215260
@@ -329,6 +374,7 @@ namespace rir {
329374 }
330375
331376 ~FileLogger () {
377+ double total_time_in_compilation = 0 ;
332378 for (auto const & ir : entries) {
333379 auto fun_id = ir.first ;
334380 auto & entry = ir.second ;
@@ -344,6 +390,12 @@ namespace rir {
344390
345391 stringstream contextsDispatched;
346392
393+ double totalRuntimeUnderContext = 0 ;
394+
395+ double goodness = false ;
396+ double baselineAvgRuntime = 0 ;
397+ int otherRuntimeCount = 0 ;
398+ double otherAvgRuntime = 0 ;
347399
348400 // iterate over dispatched functions under this context
349401 for (auto const & itr1 : dispatch_data.version_called_count ) {
@@ -352,7 +404,32 @@ namespace rir {
352404 int functionContextCallCount = itr1.second ; // current function context __call count
353405 string currContextString = getContextString (version_context); // current function context __string
354406
355- contextsDispatched << " [" << functionContextCallCount << " ]" << currContextString << " " ;
407+ unordered_map<Context, int > version_success_run_count = dispatch_data.version_success_run_count ;
408+ unordered_map<Context, double > version_runtime = dispatch_data.version_runtime ;
409+
410+ double success_runs = version_success_run_count[version_context];
411+ double success_runtime = version_runtime[version_context];
412+ double avg_runtime = 0 ;
413+ totalRuntimeUnderContext += success_runtime;
414+
415+ if (success_runs > 0 ) {
416+ avg_runtime = success_runtime / success_runs;
417+ }
418+ bool baseline = version_context.toI () == 0 ? true : false ;
419+
420+ if (baseline) {
421+ baselineAvgRuntime = avg_runtime;
422+ } else {
423+ otherRuntimeCount++;
424+ otherAvgRuntime += avg_runtime;
425+ }
426+
427+ contextsDispatched << " [" << functionContextCallCount << " ]{" << avg_runtime << " }" << currContextString << " " ;
428+ }
429+ otherAvgRuntime = otherAvgRuntime / otherRuntimeCount;
430+ total_time_in_compilation += dispatch_data.time_spent_in_compilation ;
431+ if (otherAvgRuntime < baselineAvgRuntime) {
432+ goodness = true ;
356433 }
357434 // print row
358435 myfile
@@ -364,14 +441,33 @@ namespace rir {
364441 << del
365442 << dispatch_data.call_count_in_ctxt // call context count
366443 << del
444+ << totalRuntimeUnderContext // total runtime under context
445+ << del
367446 << dispatch_data.successful_compilation_count // number of successful compilations in this context
368447 << del
448+ << dispatch_data.time_spent_in_compilation // time spent for successful compilation
449+ << del
369450 << dispatch_data.failed_compilation_count // number of failed compilations in this context
370451 << del
452+ << dispatch_data.time_wasted_in_compilation // time wasted trying to compile
453+ << del
454+ << goodness
455+ << del
371456 << contextsDispatched.str () // functions dispatched under this context
372457 << " \n " ;
373458 }
374459 }
460+ myfile
461+ << del
462+ << del
463+ << del
464+ << del
465+ << del
466+ << total_time_in_compilation // Total time in compilation
467+ << del
468+ << del
469+ << del
470+ << " \n " ;
375471 myfile.close ();
376472 }
377473
@@ -420,21 +516,51 @@ void ContextualProfiling::addFunctionDispatchInfo(
420516
421517void ContextualProfiling::countSuccessfulCompilation (
422518 SEXP callee,
423- Context assumptions
519+ Context assumptions,
520+ std::chrono::duration<double > duration
424521) {
425522 if (fileLogger) {
426- fileLogger->countSuccessfulCompilation (callee, assumptions);
523+ fileLogger->countSuccessfulCompilation (callee, assumptions, duration );
427524 }
428525}
429526
430527void ContextualProfiling::countFailedCompilation (
431528 SEXP callee,
432- Context assumptions
529+ Context assumptions,
530+ std::chrono::duration<double > duration
433531) {
434532 if (fileLogger) {
435- fileLogger->countFailedCompilation (callee, assumptions);
533+ fileLogger->countFailedCompilation (callee, assumptions, duration );
436534 }
437535}
438536
537+ bool ContextualProfiling::compileFlag (
538+ size_t id,
539+ Context contextCaller
540+ ) {
541+ if (getenv (" SKIP_ALL_COMPILATION" )) {
542+ return false ;
543+ }
544+ if (!getenv (" COMPILE_ONLY_ONCE" )) {
545+ return true ;
546+ }
547+ if (fileLogger) {
548+ return fileLogger->compileOnlyOnce (id, contextCaller);
549+ } else {
550+ return true ;
551+ }
552+ }
553+
554+ void ContextualProfiling::addFunctionDispatchRuntime (
555+ size_t id,
556+ Context contextCaller,
557+ Function const &f,
558+ std::chrono::duration<double > duration
559+
560+ ) {
561+ if (fileLogger) {
562+ return fileLogger->addFunctionDispatchRuntime (id, contextCaller, f, duration);
563+ }
564+ }
439565
440566} // namespace rir
0 commit comments