MCPcopy Create free account
hub / github.com/Oneflow-Inc/oneflow / Compute

Method Compute

oneflow/user/kernels/mode_kernel.cpp:34–87  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

32
33 private:
34 void Compute(user_op::KernelComputeContext* ctx) const override {
35 const user_op::Tensor* in = ctx->Tensor4ArgNameAndIndex("input", 0);
36 const int64_t num_axes = in->shape_view().NumAxes();
37 const int64_t size = in->shape_view().elem_cnt();
38 if (size == 0) return;
39 const int64_t stride = in->shape_view().At(num_axes - 1);
40 const int64_t instance_num = size / stride;
41 user_op::Tensor* values = ctx->Tensor4ArgNameAndIndex("values", 0);
42 user_op::Tensor* indices = ctx->Tensor4ArgNameAndIndex("indices", 0);
43 user_op::Tensor* tmp_buffer = ctx->Tensor4ArgNameAndIndex("tmp_buffer", 0);
44
45 auto memcpy = NewMemcpyPrimitive(ctx);
46 CHECK(memcpy);
47 memcpy->Launch(ctx->stream(), tmp_buffer->mut_dptr<void>(), in->dptr<void>(), size * sizeof(T));
48 const int64_t thread_num =
49 std::min(instance_num, (int64_t)Singleton<ThreadPool>::Get()->thread_num());
50 const BalancedSplitter bs(instance_num, thread_num);
51 BlockingCounter bc(thread_num);
52 FOR_RANGE(int64_t, thread_id, 0, thread_num) {
53 const Range range = bs.At(thread_id);
54 Singleton<ThreadPool>::Get()->AddWork([=, &bc]() {
55 FOR_RANGE(int64_t, i, range.begin(), range.end()) {
56 T* in_ptr = tmp_buffer->mut_dptr<T>() + i * stride;
57 T* val_ptr = values->mut_dptr<T>() + i;
58 int64_t* ind_ptr = indices->mut_dptr<int64_t>() + i;
59 std::vector<std::pair<T, int64_t>> elements(stride);
60 T mode = 0;
61 int64_t mode_idx = 0;
62 int64_t temp_freq = 0;
63 int64_t max_freq = 0;
64 FOR_RANGE(int64_t, idx, 0, stride) {
65 elements[idx] = std::make_pair(*(in_ptr + idx), idx);
66 }
67 std::sort(elements.begin(), elements.end(),
68 [=](const auto& i, const auto& j) { return i.first < j.first; });
69 FOR_RANGE(int64_t, idx, 0, stride) {
70 temp_freq++;
71 if ((idx == stride - 1) || (elements[idx].first != elements[idx + 1].first)) {
72 if (temp_freq > max_freq) {
73 mode = elements[idx].first;
74 mode_idx = elements[idx].second;
75 max_freq = temp_freq;
76 }
77 temp_freq = 0;
78 }
79 }
80 *val_ptr = mode;
81 *ind_ptr = mode_idx;
82 }
83 bc.Decrease();
84 });
85 }
86 bc.WaitForeverUntilCntEqualZero();
87 }
88 bool AlwaysComputeWhenAllOutputsEmpty() const override { return false; }
89};
90

Callers

nothing calls this directly

Calls 11

GetFunction · 0.85
thread_numMethod · 0.80
NewMemcpyPrimitiveFunction · 0.70
NumAxesMethod · 0.45
shape_viewMethod · 0.45
elem_cntMethod · 0.45
AtMethod · 0.45
LaunchMethod · 0.45
streamMethod · 0.45

Tested by

no test coverage detected