Skip to content
This repository was archived by the owner on Apr 6, 2026. It is now read-only.

Commit 4e67580

Browse files
committed
Fix cmake, add relu CPU impl
1 parent 64c1959 commit 4e67580

5 files changed

Lines changed: 63 additions & 5 deletions

File tree

build2cmake/src/templates/cpu/kernel.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ endforeach()
2121
{% endif %}
2222

2323
# Add C++ sources to main source list
24-
list(APPEND SRC {{'"${' + kernel_name + '_CPP_SRC}"'}})
24+
list(APPEND SRC {{'"${' + kernel_name + '_SRC}"'}})
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <torch/all.h>
2+
3+
#ifdef __SSE__
4+
#include <xmmintrin.h>
5+
#endif
6+
7+
#ifdef __ARM_NEON
8+
#include <arm_neon.h>
9+
#endif
10+
11+
#ifdef __SSE__
12+
void relu_forward_sse(float* out, const float* input, size_t size) {
13+
size_t i = 0;
14+
15+
for (; i + 4 <= size; i += 4) {
16+
__m128 vec_input = _mm_load_ps(input + i);
17+
__m128 vec_zero = _mm_setzero_ps();
18+
__m128 vec_output = _mm_max_ps(vec_input, vec_zero);
19+
_mm_store_ps(out + i, vec_output);
20+
}
21+
22+
for (; i < size; ++i) {
23+
out[i] = input[i] > 0 ? input[i] : 0;
24+
}
25+
}
26+
#endif
27+
28+
#ifdef __ARM_NEON
29+
void relu_forward_neon(float* out, const float* input, size_t size) {
30+
size_t i = 0;
31+
32+
for (; i + 4 <= size; i += 4) {
33+
float32x4_t vec_input = vld1q_f32(input + i);
34+
float32x4_t vec_output = vmaxq_f32(vec_input, vdupq_n_f32(0));
35+
vst1q_f32(out + i, vec_output);
36+
}
37+
38+
for (; i < size; ++i) {
39+
out[i] = input[i] > 0 ? input[i] : 0;
40+
}
41+
}
42+
#endif
43+
44+
void relu(torch::Tensor &out, torch::Tensor const &input) {
45+
TORCH_CHECK(out.dtype() == torch::kFloat32, "Output tensor must be of dtype float");
46+
TORCH_CHECK(input.dtype() == torch::kFloat32, "Input tensor must be of dtype float");
47+
TORCH_CHECK(out.numel() == input.numel(), "Input and output tensors must have the same number of elements");
48+
49+
#if defined(__SSE__)
50+
relu_forward_sse(out.data_ptr<float>(), input.data_ptr<float>(), input.numel());
51+
#elif defined(__ARM_NEON)
52+
relu_forward_neon(out.data_ptr<float>(), input.data_ptr<float>(), input.numel());
53+
#else
54+
#error "Unsupported architecture; please use a CPU with SSE or ARM NEON support."
55+
#endif
56+
}

examples/relu/tests/test_relu.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ def test_relu():
1111
device = torch.device("mps")
1212
elif hasattr(torch, "xpu") and torch.xpu.is_available():
1313
device = torch.device("xpu")
14-
else:
14+
elif torch.version.cuda is not None and torch.cuda.is_available():
1515
device = torch.device("cuda")
16+
else:
17+
device = torch.device("cpu")
1618
x = torch.randn(1024, 1024, dtype=torch.float32, device=device)
1719
torch.testing.assert_allclose(F.relu(x), relu.relu(x))

examples/relu/torch-ext/torch_binding.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) {
77
ops.def("relu(Tensor! out, Tensor input) -> ()");
88
#if defined(CPU_KERNEL)
9-
ops.impl("relu", torch::kCUDA, &relu);
9+
ops.impl("relu", torch::kCPU, &relu);
1010
#elif defined(CUDA_KERNEL) || defined(ROCM_KERNEL)
1111
ops.impl("relu", torch::kCUDA, &relu);
1212
#elif defined(METAL_KERNEL)

overlay.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ final: prev: {
2525
src = final.fetchFromGitHub {
2626
owner = "huggingface";
2727
repo = "kernels";
28-
rev = "5d21b86a5d611100c10c10b79ffa7965edf567fd";
29-
sha256 = "sha256-lKQUVbjhpeXKj1SeZRxgPSsOtBUZ7zQeO6pRoA1h+W8=";
28+
rev = "0e18dbf076fc44de5dac4027616e9f3d9e2da45a";
29+
sha256 = "sha256-6N1W3jLQIS1yEAdNR2X9CuFdMw4Ia0yzBBVQ4Kujv8U=";
3030
};
3131
});
3232
}

0 commit comments

Comments
 (0)