523 {
525
526
527
528
529
530 std::string testUndeclaredOutputsDir;
531 if (
char* envVar =
std::getenv(
"TEST_UNDECLARED_OUTPUTS_DIR")) {
532 testUndeclaredOutputsDir = envVar;
533 }
534 bool isBazelTest = !testUndeclaredOutputsDir.empty();
535
536
539
540
541 std::string surfaceConfig = FLAGS_surfaceConfig[0];
542
543
544 std::string outputDir =
545 FLAGS_outputDir.isEmpty() ? testUndeclaredOutputsDir : FLAGS_outputDir[0];
546
547 std::string cpuName = FLAGS_cpuName.isEmpty() ? "" : FLAGS_cpuName[0];
548 std::string gpuName = FLAGS_gpuName.isEmpty() ? "" : FLAGS_gpuName[0];
549
550
551
552
555
556 if (FLAGS_gitHash.size() == 1) {
557 jsonWriter.addGitHash(FLAGS_gitHash[0]);
558 } else {
560 "Warning: No --gitHash flag was specified. Perf ingestion ignores JSON files that "
561 "do not specify a Git hash. This is fine for local debugging, but CI tasks should "
562 "always set the --gitHash flag.");
563 }
564 if (FLAGS_issue.size() == 1 && FLAGS_patchset.size() == 1) {
565 jsonWriter.addChangelistInfo(FLAGS_issue[0], FLAGS_patchset[0]);
566 }
567
568
569 std::map<std::string, std::string> keyValuePairs = {
570
571
572 {"build_system", "bazel"},
573 };
574 for (
int i = 1;
i < FLAGS_key.size();
i += 2) {
575 keyValuePairs[FLAGS_key[
i - 1]] = FLAGS_key[
i];
576 }
578 jsonWriter.addKey(keyValuePairs);
579
580
581 if (FLAGS_links.size()) {
582 std::map<std::string, std::string> links;
583 for (
int i = 1;
i < FLAGS_links.size();
i += 2) {
584 links[FLAGS_links[
i - 1]] = FLAGS_links[
i];
585 }
586 jsonWriter.addLinks(links);
587 }
588
589 int runs = 0;
590 bool missingCpuOrGpuWarningLogged = false;
592 std::unique_ptr<Benchmark>
benchmark(benchmarkFactory(
nullptr));
593
596 continue;
597 }
598
600
601 std::unique_ptr<BenchmarkTarget>
target =
604
606
608 !missingCpuOrGpuWarningLogged) {
610 "Warning: The surface is CPU-bound, but flag --cpuName was not provided. "
611 "Perf traces will omit keys \"cpu_or_gpu\" and \"cpu_or_gpu_value\".");
612 missingCpuOrGpuWarningLogged = true;
613 }
615 !missingCpuOrGpuWarningLogged) {
617 "Warning: The surface is GPU-bound, but flag --gpuName was not provided. "
618 "Perf traces will omit keys \"cpu_or_gpu\" and \"cpu_or_gpu_value\".");
619 missingCpuOrGpuWarningLogged = true;
620 }
621
622
623 int loops;
628
630 continue;
631 }
632
633 if (FLAGS_writePNGs) {
634
635
637 }
638
639
640
641 const bool want_plot = !FLAGS_quiet && !FLAGS_ms;
643
645
648
649
650 {
"name", std::string(
benchmark->getName())},
651
652
653 {"surface_config", surfaceConfig},
654
655
656
657
658
659
660 {"source_type", "bench"},
661 {"bench_type", "micro"},
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
692 };
693 result.key.merge(
target->getKeyValuePairs(cpuName, gpuName));
694 result.measurements[
"ms"] = {
695
696
697 {.value =
"min", .measurement =
stats.min},
698 {.value = "ratio",
700 };
701 if (!statKeys.
empty()) {
702
703
704
705
707 result.measurements[
"stats"] = {};
708 for (
int i = 0;
i < statKeys.
size();
i++) {
709 result.measurements[
"stats"].push_back(
710 {.value = statKeys[
i].c_str(), .measurement = statValues[
i]});
711 }
712 }
713 jsonWriter.addResult(
result);
714
715 runs++;
716 if (runs % FLAGS_flushEvery == 0) {
717 jsonWriter.flush();
718 }
719
721 } else {
722 if (FLAGS_verbose) {
723 TestRunner::Log(
"Skipping \"%s\" because backend \"%s\" was unsuitable.\n",
724 target->getBenchmark()->getUniqueName(),
725 surfaceConfig.c_str());
726 }
727 }
728 }
729
731
733
734
735
736 jsonWriter.addResult({
737 .key =
738 {
739 {"name", "memory_usage"},
740 },
741 .measurements =
742 {
743 {"resident_set_size_mb",
744 {{.value = "max",
746 },
747 });
748
751
752 return 0;
753}
static void maybe_write_png(BenchmarkTarget *target, std::string outputDir)
static void validate_flags(bool isBazelTest)
static void print_benchmark_stats(Stats *stats, skia_private::TArray< double > *samples, BenchmarkTarget *target, std::string surfaceConfig, int loops)
static int sample_benchmark(BenchmarkTarget *target, int *loops, skia_private::TArray< double > *samples, skia_private::TArray< SkString > *statKeys, skia_private::TArray< double > *statValues)
std::map< std::string, std::string > GetCompilationModeGoldAndPerfKeyValuePairs()
#define SkASSERT_RELEASE(cond)
static constexpr double sk_ieee_double_divide(double numer, double denom)
static std::unique_ptr< BenchmarkTarget > FromConfig(std::string surfaceConfig, Benchmark *benchmark)
static void printGlobalStats()
static void Parse(int argc, const char *const *argv)
static void PurgeAllCaches()
static SkString Join(const char *rootPath, const char *relativePath)
const char * c_str() const
bool ShouldRunTestCase(const char *name, CommandLineFlags::StringArray &matchFlag, CommandLineFlags::StringArray &skipFlag)
void Log(const char *format,...) SK_PRINTF_LIKE(1
void InitAndLogCmdlineArgs(int argc, char **argv)