Skip to content

Commit e07f9df

Browse files
[executorch][cuda] Add AOTI tensor zero shim (pytorch#23130)
This PR was created by the merge bot to help merge the original PR into the main branch. ghstack PR number: pytorch#23083 by @Gasoonjia ^ Please use this as the source of truth for the PR details, comments, and reviews ghstack PR base: https://github.com/pytorch/executorch/tree/gh/Gasoonjia/27/base ghstack PR head: https://github.com/pytorch/executorch/tree/gh/Gasoonjia/27/head Merge bot PR base: https://github.com/pytorch/executorch/tree/main Merge bot PR head: https://github.com/pytorch/executorch/tree/gh/Gasoonjia/27/orig Differential Revision: [D120071924](https://our.internmc.facebook.com/intern/diff/D120071924/) @diff-train-skip-merge Co-authored-by: gasoonjia <gasoonjia@icloud.com>
1 parent 7970222 commit e07f9df

6 files changed

Lines changed: 122 additions & 0 deletions

File tree

‎backends/cuda/runtime/shims/memory.cpp‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
#include <executorch/backends/cuda/runtime/shims/memory.h>
1111
#include <type_traits>
1212

13+
#if defined(CUDA_AVAILABLE)
14+
#include <executorch/backends/aoti/slim/c10/cuda/Exception.h>
15+
#include <executorch/backends/aoti/slim/cuda/guard.h>
16+
#endif
17+
1318
#include <executorch/backends/aoti/slim/factory/empty.h>
1419
#include <executorch/backends/aoti/slim/factory/from_blob.h>
1520
#include <executorch/backends/aoti/slim/util/array_ref_util.h>
@@ -402,6 +407,27 @@ aoti_torch_copy_(SlimTensor* self, SlimTensor* src, int32_t non_blocking) {
402407
return Error::Ok;
403408
}
404409

410+
AOTITorchError aoti_torch_zero_(SlimTensor* self) {
411+
ET_CHECK_OR_RETURN_ERROR(
412+
self != nullptr && self->is_contiguous(),
413+
InvalidArgument,
414+
"aoti_torch_zero_: expected a contiguous tensor");
415+
if (self->nbytes() == 0) {
416+
return Error::Ok;
417+
}
418+
#if defined(CUDA_AVAILABLE)
419+
if (self->device().is_cuda()) {
420+
auto stream = getCurrentCUDAStream(self->device_index());
421+
ET_CHECK_OK_OR_RETURN_ERROR(stream.error());
422+
ET_CUDA_CHECK_OR_RETURN_ERROR(
423+
cudaMemsetAsync(self->data_ptr(), 0, self->nbytes(), stream.get()));
424+
return Error::Ok;
425+
}
426+
#endif
427+
ET_CHECK_OR_RETURN_ERROR(
428+
false, NotSupported, "aoti_torch_zero_: only CUDA tensors are supported");
429+
}
430+
405431
#define ET_CUDA_DEFINE_ITEM_SHIM(SUFFIX, CTYPE) \
406432
AOTITorchError aoti_torch_item_##SUFFIX( \
407433
SlimTensor* tensor, CTYPE* ret_value) { \

‎backends/cuda/runtime/shims/memory.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ AOTI_SHIM_EXPORT AOTITorchError aoti_torch__reinterpret_tensor(
195195
AOTI_SHIM_EXPORT AOTITorchError
196196
aoti_torch_copy_(SlimTensor* self, SlimTensor* src, int32_t non_blocking);
197197

198+
/// Zeros a contiguous CUDA tensor on the current AOTI stream. Inductor uses it
199+
/// to clear split-scan workspaces.
200+
AOTI_SHIM_EXPORT AOTITorchError aoti_torch_zero_(SlimTensor* self);
201+
198202
/// See aoti_torch_item_uint8.
199203
AOTI_SHIM_EXPORT AOTITorchError
200204
aoti_torch_item_bool(SlimTensor* tensor, bool* ret_value);

‎backends/cuda/runtime/shims/tests/CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ set(CUDA_SHIM_TESTS
4242
test_aoti_torch_delete_tensor_object
4343
test_aoti_torch__reinterpret_tensor
4444
test_aoti_torch_copy_
45+
test_aoti_torch_zero_
4546
test_aoti_torch_cuda_rand
4647
test_aoti_torch_new_tensor_handle
4748
test_aoti_torch_item_bool

‎backends/cuda/runtime/shims/tests/targets.bzl‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def define_common_targets(is_fbcode = False):
4040
cuda_shim_cpp_unittest("aoti_torch_create_tensor_from_blob_v2")
4141
cuda_shim_cpp_unittest("aoti_torch__reinterpret_tensor")
4242
cuda_shim_cpp_unittest("aoti_torch_copy_")
43+
cuda_shim_cpp_unittest("aoti_torch_zero_")
4344
cuda_shim_cpp_unittest("aoti_torch_cuda_guard")
4445
cuda_shim_cpp_unittest("aoti_torch_cuda__weight_int4pack_mm")
4546
cuda_shim_cpp_unittest("aoti_torch_cuda_rand")
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#include <cuda_runtime.h>
10+
#include <gtest/gtest.h>
11+
#include <vector>
12+
13+
#include <executorch/backends/aoti/common_shims_slim.h>
14+
#include <executorch/backends/aoti/slim/c10/core/Device.h>
15+
#include <executorch/backends/aoti/slim/c10/core/ScalarType.h>
16+
#include <executorch/backends/cuda/runtime/shims/memory.h>
17+
#include <executorch/runtime/core/error.h>
18+
#include <executorch/runtime/platform/platform.h>
19+
20+
using namespace executorch::backends::cuda;
21+
using namespace executorch::backends::aoti;
22+
using executorch::runtime::Error;
23+
24+
namespace slim_c10 = executorch::backends::aoti::slim::c10;
25+
26+
class AOTITorchZeroTest : public ::testing::Test {
27+
protected:
28+
void SetUp() override {
29+
et_pal_init();
30+
int device_count = 0;
31+
if (cudaGetDeviceCount(&device_count) != cudaSuccess || device_count == 0) {
32+
GTEST_SKIP() << "CUDA not available";
33+
}
34+
}
35+
36+
Tensor* create(
37+
const std::vector<int64_t>& sizes,
38+
const std::vector<int64_t>& strides,
39+
slim_c10::DeviceType device_type) {
40+
Tensor* tensor = nullptr;
41+
EXPECT_EQ(
42+
aoti_torch_empty_strided(
43+
sizes.size(),
44+
sizes.data(),
45+
strides.data(),
46+
static_cast<int32_t>(slim_c10::ScalarType::Float),
47+
static_cast<int32_t>(device_type),
48+
0,
49+
&tensor),
50+
Error::Ok);
51+
return tensor;
52+
}
53+
};
54+
55+
TEST_F(AOTITorchZeroTest, ZerosContiguousCudaTensor) {
56+
Tensor* tensor = create({2, 3}, {3, 1}, slim_c10::DeviceType::CUDA);
57+
const std::vector<float> ones(6, 1.0f);
58+
ASSERT_EQ(
59+
cudaMemcpy(
60+
tensor->data_ptr(),
61+
ones.data(),
62+
sizeof(float) * ones.size(),
63+
cudaMemcpyHostToDevice),
64+
cudaSuccess);
65+
66+
EXPECT_EQ(aoti_torch_zero_(tensor), Error::Ok);
67+
68+
std::vector<float> actual(6, 1.0f);
69+
ASSERT_EQ(
70+
cudaMemcpy(
71+
actual.data(),
72+
tensor->data_ptr(),
73+
sizeof(float) * actual.size(),
74+
cudaMemcpyDeviceToHost),
75+
cudaSuccess);
76+
EXPECT_EQ(actual, std::vector<float>(6, 0.0f));
77+
aoti_torch_delete_tensor_object(tensor);
78+
}
79+
80+
TEST_F(AOTITorchZeroTest, RejectsNullAndNonContiguousTensors) {
81+
EXPECT_EQ(aoti_torch_zero_(nullptr), Error::InvalidArgument);
82+
Tensor* tensor = create({2, 3}, {1, 2}, slim_c10::DeviceType::CUDA);
83+
EXPECT_EQ(aoti_torch_zero_(tensor), Error::InvalidArgument);
84+
aoti_torch_delete_tensor_object(tensor);
85+
}

‎extension/cuda/runtime_api.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ inline cudaError_t cudaMemGetInfo(size_t* free, size_t* total) {
122122
return hipMemGetInfo(free, total);
123123
}
124124

125+
inline cudaError_t
126+
cudaMemsetAsync(void* ptr, int value, size_t size, cudaStream_t stream) {
127+
return hipMemsetAsync(ptr, value, size, stream);
128+
}
129+
125130
inline cudaError_t cudaPointerGetAttributes(
126131
cudaPointerAttributes* attributes,
127132
const void* ptr) {

0 commit comments

Comments
 (0)