Commit f6e8476b authored by Ziminli's avatar Ziminli
Browse files

issue/428: accommodate the changes to c/gguf tests

parent 86515765
#include "infiniop/ops/rope.h"
#include "ops.hpp" #include "ops.hpp"
#include "utils.hpp" #include "utils.hpp"
#include <infinirt.h> #include <infinirt.h>
...@@ -6,6 +7,8 @@ ...@@ -6,6 +7,8 @@
namespace infiniop_test::rope { namespace infiniop_test::rope {
struct Test::Attributes { struct Test::Attributes {
infiniopRoPEAlgo_t algo;
std::shared_ptr<Tensor> y; std::shared_ptr<Tensor> y;
std::shared_ptr<Tensor> x; std::shared_ptr<Tensor> x;
std::shared_ptr<Tensor> pos_ids; std::shared_ptr<Tensor> pos_ids;
...@@ -21,7 +24,7 @@ std::shared_ptr<Test> Test::build( ...@@ -21,7 +24,7 @@ std::shared_ptr<Test> Test::build(
auto test = std::shared_ptr<Test>(new Test(rtol, atol)); auto test = std::shared_ptr<Test>(new Test(rtol, atol));
test->_attributes = new Attributes(); test->_attributes = new Attributes();
if (tensors.find("y") == tensors.end() if (!check_names(attributes, Test::attribute_names()) || tensors.find("y") == tensors.end()
|| tensors.find("x") == tensors.end() || tensors.find("x") == tensors.end()
|| tensors.find("pos_ids") == tensors.end() || tensors.find("pos_ids") == tensors.end()
|| tensors.find("sin_table") == tensors.end() || tensors.find("sin_table") == tensors.end()
...@@ -30,6 +33,8 @@ std::shared_ptr<Test> Test::build( ...@@ -30,6 +33,8 @@ std::shared_ptr<Test> Test::build(
throw std::runtime_error("Invalid Test"); throw std::runtime_error("Invalid Test");
} }
test->_attributes->algo = *reinterpret_cast<infiniopRoPEAlgo_t *>(attributes["algo"].data());
test->_attributes->y = tensors["y"]; test->_attributes->y = tensors["y"];
test->_attributes->x = tensors["x"]; test->_attributes->x = tensors["x"];
test->_attributes->pos_ids = tensors["pos_ids"]; test->_attributes->pos_ids = tensors["pos_ids"];
...@@ -43,6 +48,7 @@ std::shared_ptr<Test> Test::build( ...@@ -43,6 +48,7 @@ std::shared_ptr<Test> Test::build(
std::shared_ptr<infiniop_test::Result> Test::run( std::shared_ptr<infiniop_test::Result> Test::run(
infiniopHandle_t handle, infiniDevice_t device, int device_id, size_t warm_ups, size_t iterations) { infiniopHandle_t handle, infiniDevice_t device, int device_id, size_t warm_ups, size_t iterations) {
infiniopRoPEDescriptor_t op_desc; infiniopRoPEDescriptor_t op_desc;
infiniopRoPEAlgo_t algo = _attributes->algo;
auto y = _attributes->y->to(device, device_id); auto y = _attributes->y->to(device, device_id);
auto x = _attributes->x->to(device, device_id); auto x = _attributes->x->to(device, device_id);
auto pos_ids = _attributes->pos_ids->to(device, device_id); auto pos_ids = _attributes->pos_ids->to(device, device_id);
...@@ -54,7 +60,8 @@ std::shared_ptr<infiniop_test::Result> Test::run( ...@@ -54,7 +60,8 @@ std::shared_ptr<infiniop_test::Result> Test::run(
x->desc(), x->desc(),
pos_ids->desc(), pos_ids->desc(),
sin_table->desc(), sin_table->desc(),
cos_table->desc()), cos_table->desc(),
algo),
return TEST_FAILED(OP_CREATION_FAILED, "Failed to create op descriptor.")); return TEST_FAILED(OP_CREATION_FAILED, "Failed to create op descriptor."));
size_t workspace_size; size_t workspace_size;
...@@ -101,7 +108,7 @@ std::shared_ptr<infiniop_test::Result> Test::run( ...@@ -101,7 +108,7 @@ std::shared_ptr<infiniop_test::Result> Test::run(
} }
std::vector<std::string> Test::attribute_names() { std::vector<std::string> Test::attribute_names() {
return {}; return {"algo"};
} }
std::vector<std::string> Test::tensor_names() { std::vector<std::string> Test::tensor_names() {
...@@ -120,6 +127,7 @@ std::string Test::toString() const { ...@@ -120,6 +127,7 @@ std::string Test::toString() const {
oss << "- pos_ids: " << _attributes->pos_ids->info() << std::endl; oss << "- pos_ids: " << _attributes->pos_ids->info() << std::endl;
oss << "- sin_table: " << _attributes->sin_table->info() << std::endl; oss << "- sin_table: " << _attributes->sin_table->info() << std::endl;
oss << "- cos_table: " << _attributes->cos_table->info() << std::endl; oss << "- cos_table: " << _attributes->cos_table->info() << std::endl;
oss << "- algo: " << _attributes->algo << std::endl;
oss << std::scientific << std::setprecision(2); oss << std::scientific << std::setprecision(2);
oss << "- rtol=" << _rtol << ", atol=" << _atol << std::endl; oss << "- rtol=" << _rtol << ", atol=" << _atol << std::endl;
return oss.str(); return oss.str();
......
...@@ -2,27 +2,48 @@ from ast import List ...@@ -2,27 +2,48 @@ 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 enum import Enum
from .. import InfiniopTestWriter, InfiniopTestCase, np_dtype_to_ggml, gguf_strides, contiguous_gguf_strides from .. import InfiniopTestWriter, InfiniopTestCase, np_dtype_to_ggml, gguf_strides, contiguous_gguf_strides
class Algorithm(Enum):
GPT_J = 0
GPT_NEOX = 1
def rotary_embedding(t, sin, cos):
dh = t.shape[2]
assert dh % 2 == 0, "Embedding dimension must be even."
t_even = t[..., 0::2] # [seq_len, n_head, dh // 2] def rotary_embedding(t, sin, cos, algo):
t_odd = t[..., 1::2] # [seq_len, n_head, dh // 2] def _rope(sin, cos, t1, t2):
cos = np.expand_dims(cos, axis=1) # [seq_len, 1, dh // 2]
sin = np.expand_dims(sin, axis=1) # [seq_len, 1, dh // 2]
cos = np.expand_dims(cos, axis=1) # [seq_len, 1, dh // 2] t_out_1 = t1 * cos - t2 * sin
sin = np.expand_dims(sin, axis=1) # [seq_len, 1, dh // 2] t_out_2 = t1 * sin + t2 * cos
t_out_even = t_even * cos - t_odd * sin return t_out_1, t_out_2
t_out_odd = t_even * sin + t_odd * cos
dh = t.shape[-1]
assert dh % 2 == 0, "Embedding dimension must be even."
t_out = np.empty_like(t) t_out = np.empty_like(t)
t_out[..., 0::2] = t_out_even
t_out[..., 1::2] = t_out_odd if algo == Algorithm.GPT_J.value:
t_even = t[..., 0::2] # [seq_len, n_head, dh // 2]
t_odd = t[..., 1::2] # [seq_len, n_head, dh // 2]
t_out_even, t_out_odd = _rope(sin, cos, t_even, t_odd)
t_out[..., 0::2] = t_out_even
t_out[..., 1::2] = t_out_odd
else:
half_dim = dh // 2
t_first = t[..., :half_dim]
t_second = t[..., half_dim:]
t_out_first, t_out_second = _rope(sin, cos, t_first, t_second)
t_out[..., :half_dim] = t_out_first
t_out[..., half_dim:] = t_out_second
return t_out return t_out
...@@ -52,6 +73,7 @@ class RoPETestCase(InfiniopTestCase): ...@@ -52,6 +73,7 @@ class RoPETestCase(InfiniopTestCase):
pos_ids: np.ndarray, pos_ids: np.ndarray,
sin_table: np.ndarray, sin_table: np.ndarray,
cos_table: np.ndarray, cos_table: np.ndarray,
algo: int,
): ):
super().__init__("rope") super().__init__("rope")
self.y = y self.y = y
...@@ -63,10 +85,12 @@ class RoPETestCase(InfiniopTestCase): ...@@ -63,10 +85,12 @@ class RoPETestCase(InfiniopTestCase):
self.pos_ids = pos_ids self.pos_ids = pos_ids
self.sin_table = sin_table self.sin_table = sin_table
self.cos_table = cos_table self.cos_table = cos_table
self.algo = algo
def write_test(self, test_writer: "InfiniopTestWriter"): def write_test(self, test_writer: "InfiniopTestWriter"):
super().write_test(test_writer) super().write_test(test_writer)
test_writer.add_int32(test_writer.gguf_key("algo"), self.algo)
test_writer.add_tensor( test_writer.add_tensor(
test_writer.gguf_key("y"), self.y, raw_dtype=np_dtype_to_ggml(self.y.dtype) test_writer.gguf_key("y"), self.y, raw_dtype=np_dtype_to_ggml(self.y.dtype)
) )
...@@ -97,6 +121,7 @@ class RoPETestCase(InfiniopTestCase): ...@@ -97,6 +121,7 @@ class RoPETestCase(InfiniopTestCase):
self.x.astype(np.float64), self.x.astype(np.float64),
self.sin_table.astype(np.float64), self.sin_table.astype(np.float64),
self.cos_table.astype(np.float64), self.cos_table.astype(np.float64),
self.algo,
) )
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
...@@ -121,27 +146,35 @@ if __name__ == "__main__": ...@@ -121,27 +146,35 @@ if __name__ == "__main__":
((3, 32, 128), (8000, 200, 1), (7000, 128, 1)), ((3, 32, 128), (8000, 200, 1), (7000, 128, 1)),
] ]
_ALGO = [
Algorithm.GPT_J,
Algorithm.GPT_NEOX,
]
_TENSOR_DTYPES_ = [np.float16, np.float32] _TENSOR_DTYPES_ = [np.float16, np.float32]
test_writer = InfiniopTestWriter("rope.gguf") test_writer = InfiniopTestWriter("rope.gguf")
test_cases = [] test_cases = []
for dtype in _TENSOR_DTYPES_: for algo in _ALGO:
for shape, stride_x, stride_y in _TEST_CASES_: for dtype in _TENSOR_DTYPES_:
x = np.random.rand(*shape).astype(dtype) for shape, stride_x, stride_y in _TEST_CASES_:
y = np.empty(tuple(0 for _ in shape), dtype=dtype) x = np.random.rand(*shape).astype(dtype)
pos_ids = np.arange(0, x.shape[0], dtype=np.int32) y = np.empty(tuple(0 for _ in shape), dtype=dtype)
sin_table, cos_table = sin_cos_table(pos_ids, x.shape[2], theta=1e5, dtype=dtype) pos_ids = np.arange(0, x.shape[0], dtype=np.int32)
test_case = RoPETestCase( sin_table, cos_table = sin_cos_table(pos_ids, x.shape[2], theta=1e5, dtype=dtype)
y=y, test_case = RoPETestCase(
x=x, y=y,
shape_y=shape, x=x,
shape_x=shape, shape_y=shape,
stride_y=stride_y, shape_x=shape,
stride_x=stride_x, stride_y=stride_y,
pos_ids=pos_ids, stride_x=stride_x,
sin_table=sin_table, pos_ids=pos_ids,
cos_table=cos_table, sin_table=sin_table,
) cos_table=cos_table,
test_cases.append(test_case) algo=algo.value,
)
test_cases.append(test_case)
test_writer.add_tests(test_cases) test_writer.add_tests(test_cases)
test_writer.save() test_writer.save()
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