// Copyright (c) Facebook, Inc. and its affiliates. // All rights reserved. // // Copyright 2019 Google LLC // // This source code is licensed under the BSD-style license found in the // LICENSE file in the root directory of this source tree. #pragma once #include #include #include #include #include #include #include #include #include #include #include class ZipMicrokernelTester { public: inline ZipMicrokernelTester& n(size_t n) { assert(n != 0); this->n_ = n; return *this; } inline size_t n() const { return this->n_; } inline ZipMicrokernelTester& g(size_t g) { assert(g != 0); this->g_ = g; return *this; } inline size_t g() const { return this->g_; } inline ZipMicrokernelTester& iterations(size_t iterations) { this->iterations_ = iterations; return *this; } inline size_t iterations() const { return this->iterations_; } void Test(xnn_x8_zipc_ukernel_function zip) const { std::random_device random_device; auto rng = std::mt19937(random_device()); auto u8rng = std::bind(std::uniform_int_distribution(0, std::numeric_limits::max()), rng); std::vector x(n() * g()); std::vector y(g() * n()); for (size_t iteration = 0; iteration < iterations(); iteration++) { std::generate(x.begin(), x.end(), std::ref(u8rng)); std::fill(y.begin(), y.end(), 0xA5); // Call optimized micro-kernel. zip(n() * sizeof(uint8_t), x.data(), y.data()); // Verify results. for (size_t i = 0; i < n(); i++) { for (size_t j = 0; j < g(); j++) { ASSERT_EQ(uint32_t(y[i * g() + j]), uint32_t(x[j * n() + i])) << "at element " << i << ", group " << j; } } } } void Test(xnn_x8_zipv_ukernel_function zip) const { std::random_device random_device; auto rng = std::mt19937(random_device()); auto u8rng = std::bind(std::uniform_int_distribution(0, std::numeric_limits::max()), rng); std::vector x(n() * g()); std::vector y(g() * n()); for (size_t iteration = 0; iteration < iterations(); iteration++) { std::generate(x.begin(), x.end(), std::ref(u8rng)); std::fill(y.begin(), y.end(), 0xA5); // Call optimized micro-kernel. zip(n() * sizeof(uint8_t), g(), x.data(), y.data()); // Verify results. for (size_t i = 0; i < n(); i++) { for (size_t j = 0; j < g(); j++) { ASSERT_EQ(uint32_t(y[i * g() + j]), uint32_t(x[j * n() + i])) << "at element " << i << ", group " << j; } } } } void Test(xnn_x32_zipc_ukernel_function zip) const { std::random_device random_device; auto rng = std::mt19937(random_device()); auto u32rng = std::bind(std::uniform_int_distribution(), rng); std::vector x(n() * g()); std::vector y(g() * n()); for (size_t iteration = 0; iteration < iterations(); iteration++) { std::generate(x.begin(), x.end(), std::ref(u32rng)); std::fill(y.begin(), y.end(), 0xA55A5AA5); // Call optimized micro-kernel. zip(n() * sizeof(uint32_t), x.data(), y.data()); // Verify results. for (size_t i = 0; i < n(); i++) { for (size_t j = 0; j < g(); j++) { ASSERT_EQ(y[i * g() + j], x[j * n() + i]) << "at element " << i << ", group " << j; } } } } void Test(xnn_x32_zipv_ukernel_function zip) const { std::random_device random_device; auto rng = std::mt19937(random_device()); auto u32rng = std::bind(std::uniform_int_distribution(), rng); std::vector x(n() * g()); std::vector y(g() * n()); for (size_t iteration = 0; iteration < iterations(); iteration++) { std::generate(x.begin(), x.end(), std::ref(u32rng)); std::fill(y.begin(), y.end(), 0xA55A5AA5); // Call optimized micro-kernel. zip(n() * sizeof(uint32_t), g(), x.data(), y.data()); // Verify results. for (size_t i = 0; i < n(); i++) { for (size_t j = 0; j < g(); j++) { ASSERT_EQ(y[i * g() + j], x[j * n() + i]) << "at element " << i << ", group " << j; } } } } private: size_t n_{1}; size_t g_{1}; size_t iterations_{3}; };