Skip to content

Commit

Permalink
Update unpack tests with 2d and u8 unpacks
Browse files Browse the repository at this point in the history
  • Loading branch information
smirnov-alexey committed Aug 29, 2024
1 parent ac746d2 commit e42fc00
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 5 deletions.
25 changes: 24 additions & 1 deletion src/plugins/intel_npu/tests/unit/npuw/unpack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ const auto TestCasesScaleAndZeroPoints3 = ::testing::Combine(
::testing::ValuesIn({3lu, 0lu}),
::details::ShapesIn({Tensors{input={1, 32, 128}; scale = {1, 32, 1}; zerop = {1, 32, 1};},
Tensors{input={16, 64, 64}; scale = {16, 64, 1}; zerop = {16, 64, 1};},
Tensors{input={1, 1024, 4}; scale = {1, 64, 1}; zerop = {1, 32, 1};}}),
Tensors{input={1, 1024, 4}; scale = {1, 64, 1}; zerop = {1, 32, 1};},
Tensors{input={32, 128}; scale = {32, 1}; zerop = {32, 1};},
Tensors{input={64, 64}; scale = {64, 1}; zerop = {64, 1};},
Tensors{input={1024, 4}; scale = {64, 1}; zerop = {32, 1};}}),
::testing::ValuesIn({true, false}),
::testing::ValuesIn({true, false})
);
Expand All @@ -97,4 +100,24 @@ INSTANTIATE_TEST_CASE_P(UnpackTestsWithScaleAndZeroPointTest3, UnpackTestsWithSc
TestCasesScaleAndZeroPoints3,
UnpackTestsWithScaleAndZeroPointTest3::getTestCaseName);

const auto TestCasesScaleAndZeroPoints4 = ::testing::Combine(
::testing::ValuesIn({ov::element::Type_t::u8}),
::testing::ValuesIn({ov::element::Type_t::f16}),
::testing::ValuesIn({ov::element::Type_t::f16}),
::testing::ValuesIn({ov::element::Type_t::u8}),
::testing::ValuesIn({3lu, 0lu}),
::details::ShapesIn({Tensors{input={1, 32, 128}; scale = {1, 32, 1}; zerop = {1, 32, 1};},
Tensors{input={16, 64, 64}; scale = {16, 64, 1}; zerop = {16, 64, 1};},
Tensors{input={1, 1024, 4}; scale = {1, 64, 1}; zerop = {1, 32, 1};},
Tensors{input={32, 128}; scale = {32, 1}; zerop = {32, 1};},
Tensors{input={64, 64}; scale = {64, 1}; zerop = {64, 1};},
Tensors{input={1024, 4}; scale = {64, 1}; zerop = {32, 1};}}),
::testing::ValuesIn({true, false}),
::testing::ValuesIn({true, false})
);

INSTANTIATE_TEST_CASE_P(UnpackTestsWithScaleAndZeroPointTest4, UnpackTestsWithScaleAndZeroPointTest4,
TestCasesScaleAndZeroPoints4,
UnpackTestsWithScaleAndZeroPointTest4::getTestCaseName);

} // anonymous namespace
81 changes: 77 additions & 4 deletions src/plugins/intel_npu/tests/unit/npuw/unpack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ void unpack_u4f32(const int8_t* in, float* out, int size) {
}
}

void unpack_u8f32(const int8_t* in, float* out, int size) {
for (int i = 0; i < size; i++) {
*(out++) = static_cast<float>(*in);
in++;
}
}

template<typename T>
::testing::AssertionResult fp16ArraysMatch(const T &actual,
const T &expected,
Expand Down Expand Up @@ -201,10 +208,12 @@ class UnpackTestsBase {
// Determine the size of the storage based on the type and resize the storage vector
if (zeropType == ov::element::Type_t::u4) {
zeropStorage.resize((nElements + 1) / 2, 0); // Each u4 zeropoint is 4 bits, so two zeropoints fit in one byte
} else if (zeropType == ov::element::Type_t::u8) {
zeropStorage.resize(nElements * sizeof(float), 0);
} else if (zeropType == ov::element::Type_t::f32) {
zeropStorage.resize(nElements * sizeof(float), 0);
} else {
ASSERT_TRUE(zeropType == ov::element::u4 || zeropType == ov::element::f32);
ASSERT_TRUE(zeropType == ov::element::u4 || zeropType == ov::element::u8 || zeropType == ov::element::f32);
}

// Fill the storage with the appropriate values
Expand All @@ -218,6 +227,11 @@ class UnpackTestsBase {
zeropStorage[byteIndex] = (zeropValueU4 << 4);
}
}
} else if (zeropType == ov::element::Type_t::u8) {
float* ptrWork = reinterpret_cast<float*>(zeropStorage.data());
for (size_t i = 0; i < nElements; ++i) {
ptrWork[i] = zeropValues[i % zeropValues.size()];
}
} else if (zeropType == ov::element::Type_t::f32) {
float* ptrWork = reinterpret_cast<float*>(zeropStorage.data());
for (size_t i = 0; i < nElements; ++i) {
Expand Down Expand Up @@ -559,9 +573,9 @@ TEST_P(UnpackTestsWithScaleAndZeroPointTest2, u4) {
class UnpackTestsWithScaleAndZeroPoint3 : public UnpackTestsWithScaleAndZeroPointBase {
protected:
bool isNegative() const override {
if (scale_shape.size() != 3 || zerop_shape.size() != 3) return true;
if (input_shape[2] % 64 || input_shape.size() != 3) return true;

if (scale_shape.size() != 3 && scale_shape.size() != 2) return true;
if (input_shape.back() % 64) return true;
return false;
}

Expand Down Expand Up @@ -615,6 +629,65 @@ TEST_P(UnpackTestsWithScaleAndZeroPointTest3, u4) {
}
}

class UnpackTestsWithScaleAndZeroPoint4 : public UnpackTestsWithScaleAndZeroPointBase {
protected:
bool isNegative() const override {
if (scale_shape.size() != 3 && scale_shape.size() != 2) return true;
if (input_shape.back() % 64) return true;

return false;
}

void make_ref_output() override {
if (isNegative()) return;

size_t nElements = from->get_size();

const size_t nOutputElementsPerScale = ref_output.size() / (toType.bitwidth() / 8) / scale->get_size();

std::vector<float> floatRef(nElements);
details::unpack_u8f32(input.data(), floatRef.data(), nElements);


// lets apply per channel scale
uint16_t * pRef = reinterpret_cast<uint16_t*>(ref_output.data());
const uint8_t* pZer = static_cast<uint8_t*>(zerop->data());
float * pFloatRef = reinterpret_cast<float*>(floatRef.data());
const uint16_t * pScale_f16 = reinterpret_cast<uint16_t*>(scale->data());
const float * pScale_f32 = reinterpret_cast<float*>(scale->data());

for (size_t i = 0; i < scale->get_size(); i++) {
float zeroPointValue = static_cast<float>(pZer[i]);
for (size_t sc = 0; sc != nOutputElementsPerScale; sc++) {
// applying zeropoint
float ref_scaled = *pFloatRef - zeroPointValue;

if (scaleType == ov::element::f32) {
ref_scaled *= pScale_f32[0];
} else if (scaleType == ov::element::f16) {
ref_scaled *= details::half_to_float(pScale_f16[0]);
}
*pRef = details::float_to_half(ref_scaled);

pFloatRef++;
pRef++;
}
pScale_f32++;
pScale_f16++;
}
}
};

using UnpackTestsWithScaleAndZeroPointTest4 = UnpackTestsTmpl<UnpackTestsWithScaleAndZeroPoint4>;

TEST_P(UnpackTestsWithScaleAndZeroPointTest4, u8) {
ASSERT_NO_THROW_IF(!isNegative(),
ov::npuw::util::unpack(from, zerop, scale, to, ov::npuw::util::UnpackOptions{useParallelFor, nPartitions, strictPartitions}));
if (!isNegative()) {
ASSERT_TRUE(details::fp16ArraysMatch(output, ref_output, input, false));
}
}

#define Tensors [](std::vector<int>& input, std::vector<int>&scale, std::vector<int>&zerop)


Expand Down

0 comments on commit e42fc00

Please sign in to comment.