File: profiler.cpp

package info (click to toggle)
halide 21.0.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 55,752 kB
  • sloc: cpp: 289,334; ansic: 22,751; python: 7,486; makefile: 4,299; sh: 2,508; java: 1,549; javascript: 282; pascal: 207; xml: 127; asm: 9
file content (92 lines) | stat: -rw-r--r-- 2,562 bytes parent folder | download | duplicates (3)
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
#include "Halide.h"
#include <stdio.h>

using namespace Halide;

float percentage = 0;
float ms = 0;
void my_print(JITUserContext *, const char *msg) {
    float this_ms;
    float this_percentage;
    int val = sscanf(msg, " fn13: %fms (%f", &this_ms, &this_percentage);
    if (val != 2) {
        val = sscanf(msg, " fn13$1: %fms (%f", &this_ms, &this_percentage);
    }
    if (val == 2) {
        ms = this_ms;
        percentage = this_percentage;
    }
}

int run_test(bool use_timer_profiler) {
    ms = 0;
    // Make a long chain of finely-interleaved Funcs, of which one is very expensive.
    Func f[30];
    Var c, x;
    for (int i = 0; i < 30; i++) {
        f[i] = Func("fn" + std::to_string(i));
        if (i == 0) {
            f[i](c, x) = cast<float>(x + c);
        } else if (i == 13) {
            Expr e = f[i - 1](c, x);
            for (int j = 0; j < 200; j++) {
                e = sin(e);
            }
            f[i](c, x) = e;
        } else {
            f[i](c, x) = f[i - 1](c, x) * 2.0f;
        }
    }

    Func out;
    out(c, x) = 0.0f;
    const int iters = 100;
    RDom r(0, iters);
    out(c, x) += r * f[29](c, x);

    out.jit_handlers().custom_print = my_print;
    out.compute_root();
    out.update().reorder(c, x, r);
    for (int i = 0; i < 30; i++) {
        f[i].compute_at(out, x);
    }

    Target t = get_jit_target_from_environment()
                   .with_feature(use_timer_profiler ? Target::ProfileByTimer : Target::Profile);
    Buffer<float> im = out.realize({10, 1000}, t);

    // out.compile_to_assembly("/dev/stdout", {}, t.with_feature(Target::JIT));

    printf("Time spent in fn13: %fms\n", ms);

    if (percentage < 40.0f) {
        printf("Percentage of runtime spent in f13: %.1f%%\n"
               "This is suspiciously low. It should be more like 66%%\n",
               percentage);
        return 1;
    }
    return 0;
}

int main(int argc, char **argv) {
    Target target = get_jit_target_from_environment();
    if (target.arch == Target::WebAssembly) {
        printf("[SKIP] Performance tests are meaningless and/or misleading under WebAssembly interpreter.\n");
        return 0;
    }

    printf("Testing thread based profiler.\n");
    int result = run_test(false);
    if (result != 0) {
        return 1;
    }
    if (get_jit_target_from_environment().os == Target::Linux) {
        printf("Testing timer based profiler.\n");
        result = run_test(true);
        if (result != 0) {
            return 1;
        }
    }
    printf("Success!\n");
    return 0;
}