Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .ci/scripts/wheel/test_shared_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@
"aoti_torch_cuda_guard_set_index",
"aoti_torch_cuda_index_Tensor",
"aoti_torch_index_put_out",
"aoti_torch_cuda_scatter_reduce_two_out",
"aoti_torch_cuda_scatter_src_out",
)

_QUANTIZED_KERNEL_SYMBOLS = (
Expand Down
17 changes: 17 additions & 0 deletions backends/aoti/aoti_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ def _checked_data_name(data_name: str) -> str:
return data_name


def _written_buffer_options(program: ExportedProgram) -> Dict[str, Any]:
"""Inductor options for a program that writes a buffer.

They turn off Inductor's joint-graph constant folding for the whole
program, not only for the buffers it writes. Before torch 2.15, that
folding can turn the update of a one-element buffer, such as a counter,
into its value at export, so every call writes that same value
(https://github.com/pytorch/pytorch/pull/185077).

TODO: remove once the pinned torch is 2.15 or newer.
"""
if program.graph_signature.buffers_to_mutate:
return {"joint_graph_constant_folding": False}
return {}


@experimental(
"This API and all of aoti-driven backend related functionality are experimental."
)
Expand Down Expand Up @@ -292,6 +308,7 @@ def preprocess(
device_name = cls.get_device_name()
decomposition_table = cls.get_decomposition_table()
options = cls.get_aoti_compile_options(compile_specs)
options.update(_written_buffer_options(edge_program))

# Move the edge_program to the target device. Routed through a hook so
# backends can keep large non-parameter tensors (e.g. KV-cache buffers)
Expand Down
4 changes: 4 additions & 0 deletions backends/aoti/common_shims_slim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ int32_t aoti_torch_dtype_float32() {
return 6; // ScalarType::Float
}

int32_t aoti_torch_dtype_float64() {
return 7; // ScalarType::Double
}

int32_t aoti_torch_dtype_bfloat16() {
return 15; // ScalarType::BFloat16
}
Expand Down
1 change: 1 addition & 0 deletions backends/aoti/common_shims_slim.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ aoti_torch_get_device_index(Tensor* tensor, int32_t* ret_device_index);
// ============================================================

AOTI_SHIM_EXPORT int32_t aoti_torch_dtype_float32();
AOTI_SHIM_EXPORT int32_t aoti_torch_dtype_float64();
AOTI_SHIM_EXPORT int32_t aoti_torch_dtype_bfloat16();
AOTI_SHIM_EXPORT int32_t aoti_torch_dtype_float16();
AOTI_SHIM_EXPORT int32_t aoti_torch_dtype_int64();
Expand Down
14 changes: 11 additions & 3 deletions backends/aoti/slim/c10/core/ScalarType.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
#include <ostream>

#include <executorch/runtime/core/portable_type/bfloat16.h>
#include <executorch/runtime/core/portable_type/half.h>
#include <executorch/runtime/platform/assert.h>

namespace executorch::backends::aoti::slim::c10 {

// Import BFloat16 from ExecuTorch's portable_type
// Import BFloat16 and Half from ExecuTorch's portable_type
using BFloat16 = ::executorch::runtime::etensor::BFloat16;
using Half = ::executorch::runtime::etensor::Half;

/// Enum representing the scalar type (dtype) of tensor elements.
/// Note: Enum values must match PyTorch's c10::ScalarType for compatibility.
Expand All @@ -30,7 +32,7 @@ enum class ScalarType : int8_t {
Long = 4, // int64_t
Half = 5, // float16
Float = 6, // float
// Double = 7, // double - not currently needed
Double = 7, // double
// ComplexHalf = 8,
// ComplexFloat = 9,
// ComplexDouble = 10,
Expand All @@ -50,6 +52,7 @@ constexpr ScalarType kInt = ScalarType::Int;
constexpr ScalarType kLong = ScalarType::Long;
constexpr ScalarType kHalf = ScalarType::Half;
constexpr ScalarType kFloat = ScalarType::Float;
constexpr ScalarType kDouble = ScalarType::Double;
constexpr ScalarType kBool = ScalarType::Bool;
constexpr ScalarType kBFloat16 = ScalarType::BFloat16;

Expand All @@ -72,6 +75,8 @@ inline size_t elementSize(ScalarType t) {
return 2; // sizeof(__half) = 2 bytes
case ScalarType::Float:
return sizeof(float);
case ScalarType::Double:
return sizeof(double);
case ScalarType::Bool:
return sizeof(bool);
case ScalarType::BFloat16:
Expand Down Expand Up @@ -100,6 +105,8 @@ inline const char* toString(ScalarType t) {
return "Half";
case ScalarType::Float:
return "Float";
case ScalarType::Double:
return "Double";
case ScalarType::Bool:
return "Bool";
case ScalarType::BFloat16:
Expand All @@ -116,7 +123,7 @@ inline const char* toString(ScalarType t) {
/// @return true if the scalar type is floating point, false otherwise.
inline bool isFloatingType(ScalarType t) {
return t == ScalarType::Half || t == ScalarType::Float ||
t == ScalarType::BFloat16;
t == ScalarType::Double || t == ScalarType::BFloat16;
}

/// Checks if the scalar type is an integral type (including bool optionally).
Expand Down Expand Up @@ -157,6 +164,7 @@ inline bool isValidScalarType(ScalarType t) {
case ScalarType::Long:
case ScalarType::Half:
case ScalarType::Float:
case ScalarType::Double:
case ScalarType::Bool:
case ScalarType::BFloat16:
return true;
Expand Down
2 changes: 2 additions & 0 deletions backends/aoti/slim/c10/core/test/test_scalar_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const std::vector<ScalarTypeTestData> kAllScalarTypes = {
{ScalarType::Long, 4, 8, "Long", false, true, true, false},
{ScalarType::Half, 5, 2, "Half", true, false, false, false},
{ScalarType::Float, 6, 4, "Float", true, false, false, false},
{ScalarType::Double, 7, 8, "Double", true, false, false, false},
{ScalarType::Bool, 11, 1, "Bool", false, false, true, true},
{ScalarType::BFloat16, 15, 2, "BFloat16", true, false, false, false},
};
Expand Down Expand Up @@ -224,6 +225,7 @@ TEST_F(IsValidScalarTypeTest, AllSupportedTypesAreValid) {
EXPECT_TRUE(isValidScalarType(ScalarType::Long));
EXPECT_TRUE(isValidScalarType(ScalarType::Half));
EXPECT_TRUE(isValidScalarType(ScalarType::Float));
EXPECT_TRUE(isValidScalarType(ScalarType::Double));
EXPECT_TRUE(isValidScalarType(ScalarType::Bool));
EXPECT_TRUE(isValidScalarType(ScalarType::BFloat16));
}
Expand Down
6 changes: 3 additions & 3 deletions backends/aoti/slim/core/test/test_slimtensor_basic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,18 +508,18 @@ TEST(SlimTensorValidationTest, InvalidDtypeUndefined) {
"");
}

TEST(SlimTensorValidationTest, InvalidDtypeDouble) {
TEST(SlimTensorValidationTest, InvalidDtypeComplexFloat) {
std::vector<int64_t> sizes = {2, 3};
std::vector<int64_t> strides = {3, 1};
size_t nbytes = 6 * sizeof(double);
size_t nbytes = 6 * 2 * sizeof(float);
Storage storage = make_cpu_storage(nbytes);

EXPECT_DEATH(
SlimTensor(
std::move(storage),
makeArrayRef(sizes),
makeArrayRef(strides),
static_cast<c10::ScalarType>(7)), // Double = 7
static_cast<c10::ScalarType>(9)), // ComplexFloat = 9
"");
}

Expand Down
8 changes: 4 additions & 4 deletions backends/aoti/slim/factory/test/test_empty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,15 +249,15 @@ TEST(EmptyStridedTest, InvalidDtypeUndefined) {
"");
}

TEST(EmptyStridedTest, InvalidDtypeDouble) {
TEST(EmptyStridedTest, InvalidDtypeComplexFloat) {
std::vector<int64_t> sizes = {2, 3};
std::vector<int64_t> strides = {3, 1};

EXPECT_DEATH(
empty_strided(
makeArrayRef(sizes),
makeArrayRef(strides),
static_cast<c10::ScalarType>(7)), // Double = 7
static_cast<c10::ScalarType>(9)), // ComplexFloat = 9
"");
}

Expand All @@ -280,9 +280,9 @@ TEST(EmptyTest, InvalidDtypeUndefined) {
EXPECT_DEATH(empty({2, 3}, c10::ScalarType::Undefined), "");
}

TEST(EmptyTest, InvalidDtypeDouble) {
TEST(EmptyTest, InvalidDtypeComplexFloat) {
EXPECT_DEATH(
empty({2, 3}, static_cast<c10::ScalarType>(7)), // Double = 7
empty({2, 3}, static_cast<c10::ScalarType>(9)), // ComplexFloat = 9
"");
}

Expand Down
4 changes: 2 additions & 2 deletions backends/aoti/slim/factory/test/test_from_blob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,12 @@ TEST(FromBlobTest, InvalidDtypeUndefined) {
from_blob(external_data, {2, 3}, c10::ScalarType::Undefined), "");
}

TEST(FromBlobTest, InvalidDtypeDouble) {
TEST(FromBlobTest, InvalidDtypeComplexFloat) {
constexpr size_t kNumFloats = 6;
float external_data[kNumFloats];

EXPECT_DEATH(
from_blob(external_data, {2, 3}, static_cast<c10::ScalarType>(7)), "");
from_blob(external_data, {2, 3}, static_cast<c10::ScalarType>(9)), "");
}

TEST(FromBlobTest, InvalidDeviceType) {
Expand Down
36 changes: 36 additions & 0 deletions backends/aoti/tests/test_common_shims_slim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,28 @@ void runGetSizesTest(slim_c10::DeviceType device_type) {
delete tensor;
}

void runGetSizeTest(slim_c10::DeviceType device_type) {
std::vector<int64_t> sizes = {2, 3};
std::vector<int64_t> strides = calculateContiguousStrides(sizes);
slim_c10::Device device(device_type, 0);

Tensor* tensor = new Tensor(slim::empty_strided(
slim::makeArrayRef(sizes),
slim::makeArrayRef(strides),
slim_c10::ScalarType::Float,
device));

int64_t size = -1;
EXPECT_EQ(aoti_torch_get_size(tensor, 1, &size), Error::Ok);
EXPECT_EQ(size, 3);
EXPECT_EQ(aoti_torch_get_size(tensor, -2, &size), Error::Ok);
EXPECT_EQ(size, 2);
EXPECT_EQ(aoti_torch_get_size(tensor, 2, &size), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_size(tensor, -3, &size), Error::InvalidArgument);

delete tensor;
}

void runGetStridesTest(slim_c10::DeviceType device_type) {
std::vector<int64_t> sizes = {2, 3, 4};
std::vector<int64_t> strides = calculateContiguousStrides(sizes);
Expand Down Expand Up @@ -432,6 +454,10 @@ TEST_F(CommonShimsSlimTest, GetSizes_CPU) {
runGetSizesTest(slim_c10::DeviceType::CPU);
}

TEST_F(CommonShimsSlimTest, GetSize_CPU) {
runGetSizeTest(slim_c10::DeviceType::CPU);
}

TEST_F(CommonShimsSlimTest, GetStrides_CPU) {
runGetStridesTest(slim_c10::DeviceType::CPU);
}
Expand Down Expand Up @@ -483,6 +509,13 @@ TEST_F(CommonShimsSlimTest, GetSizes_CUDA) {
runGetSizesTest(slim_c10::DeviceType::CUDA);
}

TEST_F(CommonShimsSlimTest, GetSize_CUDA) {
if (!isCudaAvailable()) {
GTEST_SKIP() << "CUDA not available";
}
runGetSizeTest(slim_c10::DeviceType::CUDA);
}

TEST_F(CommonShimsSlimTest, GetStrides_CUDA) {
if (!isCudaAvailable()) {
GTEST_SKIP() << "CUDA not available";
Expand Down Expand Up @@ -555,6 +588,7 @@ TEST_F(CommonShimsSlimTest, NullTensorArgument) {
EXPECT_EQ(
aoti_torch_get_data_ptr(nullptr, &data_ptr), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_sizes(nullptr, &sizes), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_size(nullptr, 0, &numel), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_strides(nullptr, &strides), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_dtype(nullptr, &dtype), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_dim(nullptr, &dim), Error::InvalidArgument);
Expand All @@ -566,6 +600,7 @@ TEST_F(CommonShimsSlimTest, NullReturnPointer) {

EXPECT_EQ(aoti_torch_get_data_ptr(tensor, nullptr), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_sizes(tensor, nullptr), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_size(tensor, 0, nullptr), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_strides(tensor, nullptr), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_dtype(tensor, nullptr), Error::InvalidArgument);
EXPECT_EQ(aoti_torch_get_dim(tensor, nullptr), Error::InvalidArgument);
Expand Down Expand Up @@ -663,6 +698,7 @@ TEST_F(CommonShimsSlimTest, ConsistentPointerReturn) {
TEST_F(CommonShimsSlimTest, DTypeConstants) {
// Verify dtype constants match expected PyTorch ScalarType values
EXPECT_EQ(aoti_torch_dtype_float32(), 6); // ScalarType::Float
EXPECT_EQ(aoti_torch_dtype_float64(), 7); // ScalarType::Double
EXPECT_EQ(aoti_torch_dtype_bfloat16(), 15); // ScalarType::BFloat16
EXPECT_EQ(aoti_torch_dtype_int64(), 4); // ScalarType::Long
EXPECT_EQ(aoti_torch_dtype_int32(), 3); // ScalarType::Int
Expand Down
2 changes: 2 additions & 0 deletions backends/cuda/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,10 @@ fbcode_target(
"passes/__init__.py",
"passes/move_cond_predicate_to_cpu.py",
"passes/lower_offgraph_kv.py",
"passes/remove_assert_async.py",
"passes/replace_fused_sdpa.py",
"passes/replace_int64_floordiv.py",
"passes/replace_masked_copy_with_where.py",
],
visibility = [
"//executorch/backends/cuda/...",
Expand Down
Loading
Loading