MCPcopy Create free account
hub / github.com/MegEngine/MegEngine / do_softmax

Function do_softmax

dnn/src/fallback/softmax/opr_impl.cpp:10–142  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

8namespace fallback {
9
10static void do_softmax(
11 const float* sptr, float* dptr, size_t A, size_t B, size_t C,
12 _megdnn_workspace workspace) {
13 constexpr auto float_min = std::numeric_limits<float>::min();
14 constexpr auto step = GI_SIMD_LEN_BYTE / sizeof(float);
15 // TODO: When C=2,3,4..., src_ptr span is relatively large, the performance may
16 // be poor
17
18 if (C != 1) {
19 WorkspaceBundle workspace_bundle{
20 workspace.raw_ptr, {A * C * sizeof(float), A * C * sizeof(float)}};
21 float* max = workspace_bundle.get_workspace(0).raw_ptr->as<float>();
22 GI_FLOAT32_t v_max = GiBroadcastFloat32(float_min);
23 size_t i = 0;
24 for (; i + step <= A * C; i += step)
25 GiStoreFloat32(max + i, v_max);
26 for (; i < A * C; i++)
27 max[i] = float_min;
28
29 for (size_t a = 0; a < A; a++) {
30 for (size_t b = 0; b < B; b++) {
31 auto max_ptr = max + a * C;
32 auto limit = max_ptr + C;
33 auto src_ptr = sptr + a * B * C + b * C;
34
35 for (; max_ptr + step <= limit; max_ptr += step, src_ptr += step) {
36 GI_FLOAT32_t v_p = GiLoadFloat32(src_ptr);
37 GI_FLOAT32_t v_max = GiLoadFloat32(max_ptr);
38 v_max = GiMaximumFloat32(v_max, v_p);
39 GiStoreFloat32(max_ptr, v_max);
40 }
41 for (; max_ptr < limit; ++max_ptr, ++src_ptr) {
42 *max_ptr = std::max(*src_ptr, *max_ptr);
43 }
44 }
45 }
46
47 float* sum = workspace_bundle.get_workspace(1).raw_ptr->as<float>();
48 memset(sum, 0, A * C * sizeof(float));
49 for (size_t a = 0; a < A; a++) {
50 for (size_t b = 0; b < B; b++) {
51 auto max_ptr = max + a * C;
52 auto limit = max_ptr + C;
53 auto sum_ptr = sum + a * C;
54 auto src_ptr = sptr + a * B * C + C * b;
55 auto dst_ptr = dptr + a * B * C + C * b;
56 for (; max_ptr + step <= limit; max_ptr += step, sum_ptr += step,
57 src_ptr += step, dst_ptr += step) {
58 GI_FLOAT32_t v_p = GiLoadFloat32(src_ptr);
59 GI_FLOAT32_t v_max = GiLoadFloat32(max_ptr);
60 GI_FLOAT32_t v_sum = GiLoadFloat32(sum_ptr);
61 v_p = GiExpPsFloat32(GiSubtractFloat32(v_p, v_max));
62 v_sum = GiAddFloat32(v_p, v_sum);
63 GiStoreFloat32(dst_ptr, v_p);
64 GiStoreFloat32(sum_ptr, v_sum);
65 }
66 for (; max_ptr < limit; ++max_ptr, ++sum_ptr, ++src_ptr, ++dst_ptr) {
67 *dst_ptr = exp(*src_ptr - *max_ptr);

Callers 1

execMethod · 0.85

Calls 8

GiStoreFloat32Function · 0.85
maxFunction · 0.85
GiExpPsFloat32Function · 0.85
GiReduceMaxNanFloat32Function · 0.85
GiReduceAddFloat32Function · 0.85
minFunction · 0.50
expFunction · 0.50
get_workspaceMethod · 0.45

Tested by

no test coverage detected