Commit 5a22f833 authored by Catheriany's avatar Catheriany
Browse files

issue/228: infiniop-test框架支持0步长

parent 8b59f4fe
...@@ -29,8 +29,8 @@ DECLARE_INFINIOP_TEST(add) ...@@ -29,8 +29,8 @@ DECLARE_INFINIOP_TEST(add)
REGISTER_INFINIOP_TEST(random_sample) \ REGISTER_INFINIOP_TEST(random_sample) \
REGISTER_INFINIOP_TEST(add) \ REGISTER_INFINIOP_TEST(add) \
REGISTER_INFINIOP_TEST(mul) \ REGISTER_INFINIOP_TEST(mul) \
REGISTER_INFINIOP_TEST(swiglu) REGISTER_INFINIOP_TEST(swiglu) \
} }
namespace infiniop_test { namespace infiniop_test {
......
...@@ -58,7 +58,8 @@ private: ...@@ -58,7 +58,8 @@ private:
public: public:
Tensor(const GGUFTensorInfo *info, Tensor(const GGUFTensorInfo *info,
const void *ggml_ptr, const void *ggml_ptr,
const GGUFKeyValue *strides_meta = nullptr); const GGUFKeyValue *strides_meta = nullptr,
const GGUFKeyValue *shapes_meta = nullptr);
Tensor(std::shared_ptr<Memory> memory, size_t offset, Tensor(std::shared_ptr<Memory> memory, size_t offset,
const std::vector<size_t> &shape, const std::vector<size_t> &shape,
const std::vector<ptrdiff_t> &strides, const std::vector<ptrdiff_t> &strides,
......
...@@ -98,7 +98,8 @@ void *Tensor::data() const { ...@@ -98,7 +98,8 @@ void *Tensor::data() const {
Tensor::Tensor(const GGUFTensorInfo *info, Tensor::Tensor(const GGUFTensorInfo *info,
const void *ggml_ptr, const void *ggml_ptr,
const GGUFKeyValue *strides_meta) { const GGUFKeyValue *strides_meta,
const GGUFKeyValue *shapes_meta) {
_ggml_type = info->ggml_type; _ggml_type = info->ggml_type;
_offset = 0; _offset = 0;
size_t ndim = static_cast<size_t>(info->ndim); size_t ndim = static_cast<size_t>(info->ndim);
...@@ -120,7 +121,6 @@ Tensor::Tensor(const GGUFTensorInfo *info, ...@@ -120,7 +121,6 @@ Tensor::Tensor(const GGUFTensorInfo *info,
} }
} else { } else {
for (size_t i = 0; i < ndim; i++) { for (size_t i = 0; i < ndim; i++) {
_shape[i] = static_cast<size_t>(info->shape[ndim - 1 - i]);
if (strides_meta->gguf_type == GGUF_TYPE_INT64) { if (strides_meta->gguf_type == GGUF_TYPE_INT64) {
_strides[i] = (ptrdiff_t)(reinterpret_cast<const int64_t *>( _strides[i] = (ptrdiff_t)(reinterpret_cast<const int64_t *>(
strides_meta->value.data())[ndim - 1 - i]); strides_meta->value.data())[ndim - 1 - i]);
...@@ -145,6 +145,23 @@ Tensor::Tensor(const GGUFTensorInfo *info, ...@@ -145,6 +145,23 @@ Tensor::Tensor(const GGUFTensorInfo *info,
contiguous_strides.data(), contiguous_strides.data(),
ndim, ndim,
ggmlTypeSize(_ggml_type)); ggmlTypeSize(_ggml_type));
if (shapes_meta != nullptr) {
for (size_t i = 0; i < ndim; i++) {
if (shapes_meta->gguf_type == GGUF_TYPE_INT64) {
_shape[i] = (ptrdiff_t)(reinterpret_cast<const int64_t *>(
shapes_meta->value.data())[i]);
} else if (shapes_meta->gguf_type == GGUF_TYPE_INT32) {
_shape[i] = (ptrdiff_t)(reinterpret_cast<const int32_t *>(
shapes_meta->value.data())[i]);
} else {
throw std::runtime_error("Error Creating Tensor: Unsupported shape type");
}
}
}
} }
Tensor::Tensor(std::shared_ptr<Memory> memory, size_t offset, Tensor::Tensor(std::shared_ptr<Memory> memory, size_t offset,
......
...@@ -94,10 +94,13 @@ std::shared_ptr<Result> runTest(const GGUFFileReader &gguf_reader, ...@@ -94,10 +94,13 @@ std::shared_ptr<Result> runTest(const GGUFFileReader &gguf_reader,
auto info = tensor_info.find("test." + std::to_string(test_id) + "." + tensor_name); auto info = tensor_info.find("test." + std::to_string(test_id) + "." + tensor_name);
if (info != tensor_info.end()) { if (info != tensor_info.end()) {
auto strides = meta.find("test." + std::to_string(test_id) + "." + tensor_name + ".strides"); auto strides = meta.find("test." + std::to_string(test_id) + "." + tensor_name + ".strides");
auto shape = meta.find("test." + std::to_string(test_id) + "." + tensor_name + ".shape");
tensors[tensor_name] = std::make_shared<Tensor>( tensors[tensor_name] = std::make_shared<Tensor>(
info->second.get(), info->second.get(),
gguf_reader.getGgmlStart(), gguf_reader.getGgmlStart(),
strides != meta.end() ? strides->second.get() : nullptr); strides != meta.end() ? strides->second.get() : nullptr,
shape != meta.end() ? shape->second.get() : nullptr);
} }
} }
std::shared_ptr<infiniop_test::base::Test> test; std::shared_ptr<infiniop_test::base::Test> test;
......
...@@ -2,6 +2,7 @@ from ast import List ...@@ -2,6 +2,7 @@ from ast import List
import numpy as np import numpy as np
import gguf import gguf
from typing import List from typing import List
from numpy.lib.stride_tricks import as_strided
from .. import InfiniopTestWriter, InfiniopTestCase, np_dtype_to_ggml, gguf_strides from .. import InfiniopTestWriter, InfiniopTestCase, np_dtype_to_ggml, gguf_strides
...@@ -12,22 +13,48 @@ def add( ...@@ -12,22 +13,48 @@ def add(
): ):
return a + b return a + b
def process_tensors(a, a_stride, b, b_stride):
def _rearrange(tensor, strides):
if strides and 0 in strides:
byte_strides = tuple(s * tensor.itemsize for s in strides)
return as_strided(tensor, shape=tensor.shape, strides=byte_strides)
else:
return tensor
a = _rearrange(a, a_stride)
b = _rearrange(b, b_stride)
return a, b
def get_effective_shape(shape, strides):
effective_shape = tuple(dim if stride != 0 else 1 for dim, stride in zip(shape, strides))
return effective_shape
class AddTestCase(InfiniopTestCase): class AddTestCase(InfiniopTestCase):
def __init__( def __init__(
self, self,
a: np.ndarray, a: np.ndarray,
a_rearranged:np.ndarray,
stride_a: List[int] | None, stride_a: List[int] | None,
shape_a: List[int] | None,
b: np.ndarray, b: np.ndarray,
b_rearranged:np.ndarray,
stride_b: List[int] | None, stride_b: List[int] | None,
shape_b: List[int] | None,
c: np.ndarray, c: np.ndarray,
stride_c: List[int] | None, stride_c: List[int] | None,
): ):
super().__init__("add") super().__init__("add")
self.a = a self.a = a
self.a_rearranged = a_rearranged
self.stride_a = stride_a self.stride_a = stride_a
self.shape_a = shape_a
self.b = b self.b = b
self.b_rearranged = b_rearranged
self.stride_b = stride_b self.stride_b = stride_b
self.shape_b = shape_b
self.c = c self.c = c
self.stride_c = stride_c self.stride_c = stride_c
...@@ -40,6 +67,10 @@ class AddTestCase(InfiniopTestCase): ...@@ -40,6 +67,10 @@ class AddTestCase(InfiniopTestCase):
test_writer.add_array(test_writer.gguf_key("b.strides"), self.stride_b) test_writer.add_array(test_writer.gguf_key("b.strides"), self.stride_b)
if self.stride_c is not None: if self.stride_c is not None:
test_writer.add_array(test_writer.gguf_key("c.strides"), self.stride_c) test_writer.add_array(test_writer.gguf_key("c.strides"), self.stride_c)
if self.shape_a is not None:
test_writer.add_array(test_writer.gguf_key("a.shape"), self.shape_a)
if self.shape_b is not None:
test_writer.add_array(test_writer.gguf_key("b.shape"), self.shape_b)
test_writer.add_tensor( test_writer.add_tensor(
test_writer.gguf_key("a"), self.a, raw_dtype=np_dtype_to_ggml(self.a.dtype) test_writer.gguf_key("a"), self.a, raw_dtype=np_dtype_to_ggml(self.a.dtype)
) )
...@@ -50,8 +81,8 @@ class AddTestCase(InfiniopTestCase): ...@@ -50,8 +81,8 @@ class AddTestCase(InfiniopTestCase):
test_writer.gguf_key("c"), self.c, raw_dtype=np_dtype_to_ggml(self.c.dtype) test_writer.gguf_key("c"), self.c, raw_dtype=np_dtype_to_ggml(self.c.dtype)
) )
ans = add( ans = add(
self.a.astype(np.float64), self.a_rearranged.astype(np.float64),
self.b.astype(np.float64), self.b_rearranged.astype(np.float64),
) )
test_writer.add_tensor( test_writer.add_tensor(
test_writer.gguf_key("ans"), ans, raw_dtype=gguf.GGMLQuantizationType.F64 test_writer.gguf_key("ans"), ans, raw_dtype=gguf.GGMLQuantizationType.F64
...@@ -69,28 +100,50 @@ if __name__ == "__main__": ...@@ -69,28 +100,50 @@ if __name__ == "__main__":
# shape, a_stride, b_stride, c_stride # shape, a_stride, b_stride, c_stride
((13, 4), None, None, None), ((13, 4), None, None, None),
((13, 4), gguf_strides(10, 1), gguf_strides(10, 1), gguf_strides(10, 1)), ((13, 4), gguf_strides(10, 1), gguf_strides(10, 1), gguf_strides(10, 1)),
((13, 4), gguf_strides(0, 1), None, None),
((13, 4, 4), None, None, None), ((13, 4, 4), None, None, None),
((13, 4, 4), gguf_strides(20, 4, 1), gguf_strides(20, 4, 1), gguf_strides(20, 4, 1)), ((13, 4, 4), gguf_strides(20, 4, 1), gguf_strides(20, 4, 1), gguf_strides(20, 4, 1)),
((13, 4, 4), gguf_strides(4, 0, 1), gguf_strides(0, 4, 1), None),
((16, 5632), None, None, None), ((16, 5632), None, None, None),
((16, 5632), gguf_strides(13312, 1), gguf_strides(13312, 1), gguf_strides(13312, 1)), ((16, 5632), gguf_strides(13312, 1), gguf_strides(13312, 1), gguf_strides(13312, 1)),
((4, 4, 5632), None, None, None), ((4, 4, 5632), None, None, None),
((4, 4, 5632), gguf_strides(45056, 5632, 1), gguf_strides(45056, 5632, 1), gguf_strides(45056, 5632, 1)), ((4, 4, 5632), gguf_strides(45056, 5632, 1), gguf_strides(45056, 5632, 1), gguf_strides(45056, 5632, 1)),
] ]
_TENSOR_DTYPES_ = [np.float16, np.float32] _TENSOR_DTYPES_ = [np.float32] # np.float16
for dtype in _TENSOR_DTYPES_: for dtype in _TENSOR_DTYPES_:
for shape, stride_a, stride_b, stride_c in _TEST_CASES_: for shape, stride_a, stride_b, stride_c in _TEST_CASES_:
a = np.random.rand(*shape).astype(dtype) a = np.random.rand(*shape).astype(dtype)
b = np.random.rand(*shape).astype(dtype) b = np.random.rand(*shape).astype(dtype)
c = np.random.rand(*shape).astype(dtype) c = np.random.rand(*shape).astype(dtype)
# Reverse strides to match internal layout expectations
reversed_stride_a = tuple(reversed(stride_a)) if stride_a else None
reversed_stride_b = tuple(reversed(stride_b)) if stride_b else None
a_rearranged, b_rearranged = process_tensors(a, reversed_stride_a, b, reversed_stride_b)
effective_shape_a = get_effective_shape(a_rearranged.shape, tuple(s // a.itemsize for s in a_rearranged.strides))
effective_shape_b = get_effective_shape(b_rearranged.shape, tuple(s // b.itemsize for s in b_rearranged.strides))
# Extract unique data region (eliminate broadcast repetition)
slices_a = tuple(slice(0, 1) if dim == 1 else slice(None) for dim in effective_shape_a)
slices_b = tuple(slice(0, 1) if dim == 1 else slice(None) for dim in effective_shape_b)
a_unique = a_rearranged[slices_a]
b_unique = b_rearranged[slices_b]
test_case = AddTestCase( test_case = AddTestCase(
a=a, a=a_unique,
a_rearranged=a_rearranged,
stride_a=stride_a, stride_a=stride_a,
b=b, shape_a=shape,
b=b_unique,
b_rearranged=b_rearranged,
stride_b=stride_b, stride_b=stride_b,
shape_b=shape,
c=c, c=c,
stride_c=stride_c, stride_c=stride_c,
) )
test_cases.append(test_case) test_cases.append(test_case)
test_writer.add_tests(test_cases) test_writer.add_tests(test_cases)
test_writer.save() test_writer.save()
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment