/
vuron
/
adept
Обзор
Документация
Войти
/
vuron
/
adept
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
with_cpu
tests/arithmetic_tests.cpp
263 строки
9 KB
kolkir
Make arithmetics tests support multiple backends
06 апр 2025, 19:44
06 апр 2025, 19:44
2f2f330
Код
Авторство
О чём код?
#include <adept/tensor.hpp> #include <adept/tensor_print.hpp> #include <adept/types.hpp> #include "catch.hpp" #include "test_utils.hpp" using namespace adept; using namespace adept::test; TEMPLATE_TEST_CASE_SIG("Tensors add", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); auto [dx, dy, dz] = make_test_data<T, std::plus>(); auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto y = Tensor::from_blob(dy.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto z = x + y; equals(dz, z.cpu()); } TEMPLATE_TEST_CASE_SIG("Tensors add not pow2 aligned", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); std::vector<T> dx(1 * 10 * 10, 0); auto x = Tensor::from_blob(dx.data(), {.shape = {1, 10, 10}, .device = Device, .dtype = to_dtype<T>()}); std::vector<T> dy(10, 5); auto y = Tensor::from_blob(dy.data(), {.shape = {1, 10}, .device = Device, .dtype = to_dtype<T>()}); REQUIRE_NOTHROW(x + y); } TEMPLATE_TEST_CASE_SIG("Tensor add scalar", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); auto [dx, dy, dz] = make_scalar_test_data<T, std::plus>(); auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto z = x + dy[0]; equals(dz, z.cpu()); x += dy[0]; equals(dz, x.cpu()); } TEMPLATE_TEST_CASE_SIG("Tensors sub", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); auto [dx, dy, dz] = make_test_data<T, std::minus>(); auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto y = Tensor::from_blob(dy.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto z = x - y; equals(dz, z.cpu()); x -= y; equals(dz, x.cpu()); } TEMPLATE_TEST_CASE_SIG("Tensor sub scalar", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); auto [dx, dy, dz] = make_scalar_test_data<T, std::minus>(); auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto z = x - dy[0]; equals(dz, z.cpu()); x -= dy[0]; equals(dz, x.cpu()); } TEMPLATE_TEST_CASE_SIG("Tensors mul", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); auto [dx, dy, dz] = make_test_data<T, std::multiplies>(); auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto y = Tensor::from_blob(dy.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto z = x * y; equals(dz, z.cpu()); x *= y; equals(dz, x.cpu()); } TEMPLATE_TEST_CASE_SIG("Tensor mul scalar", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); auto [dx, dy, dz] = make_scalar_test_data<T, std::multiplies>(); auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto z = x * dy[0]; equals(dz, z.cpu()); x *= dy[0]; equals(dz, x.cpu()); } TEMPLATE_TEST_CASE_SIG("Tensors div", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); auto [dx, dy, dz] = make_test_data<T, std::divides>(); auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto y = Tensor::from_blob(dy.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto z = x / y; equals(dz, z.cpu()); x /= y; equals(dz, x.cpu()); } TEMPLATE_TEST_CASE_SIG("Tensor div scalar", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); auto [dx, dy, dz] = make_scalar_test_data<T, std::divides>(); auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); auto z = x / dy[0]; equals(dz, z.cpu()); x /= dy[0]; equals(dz, x.cpu()); } TEMPLATE_TEST_CASE_SIG("Tensor gt scalar", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); Data<T> dx = {1, 2, 1, 2, 1, 2, 1, 2, 1}; auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); Tensor z = x > 1.0f; z = z.cpu(); REQUIRE_THAT(z.at<T>({0, 0}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 0}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 0}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 1}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 1}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 1}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 2}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 2}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 2}), Catch::WithinRel(0.f, 0.001f)); } TEMPLATE_TEST_CASE_SIG("Tensor gt scalar 2", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); Data<T> dx(2048, 1); auto x = Tensor::from_blob(dx.data(), {.shape = {32, 64, 1}, .device = Device, .dtype = to_dtype<T>()}); Tensor z = x > 2.0f; z = z.cpu(); for (size_t n = 0; n < 32; ++n) { for (size_t r = 0; r < 64; ++r) { REQUIRE_THAT(z.at<T>({n, r, 0}), Catch::WithinRel(0.f, 0.001f)); } } } TEMPLATE_TEST_CASE_SIG("Tensor ge scalar", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); Data<T> dx = {-1, 2, 0, 2, -1, 2, 0, 2, -1}; auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); Tensor z = x >= 0.0f; z = z.cpu(); REQUIRE_THAT(z.at<T>({0, 0}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 0}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 0}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 1}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 1}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 1}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 2}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 2}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 2}), Catch::WithinRel(0.f, 0.001f)); } TEMPLATE_TEST_CASE_SIG("Tensor lt scalar", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); Data<T> dx = {1, 2, 1, 2, 1, 2, 1, 2, 1}; auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); Tensor z = x < 2.0f; z = z.cpu(); REQUIRE_THAT(z.at<T>({0, 0}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 0}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 0}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 1}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 1}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 1}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 2}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 2}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 2}), Catch::WithinRel(1.f, 0.001f)); } TEMPLATE_TEST_CASE_SIG("Tensor le scalar", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); Data<T> dx = {-1, 2, 0, 2, -1, 2, 0, 2, -1}; auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); Tensor z = x <= 0.0f; z = z.cpu(); REQUIRE_THAT(z.at<T>({0, 0}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 0}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 0}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 1}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 1}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 1}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 2}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 2}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 2}), Catch::WithinRel(1.f, 0.001f)); } TEMPLATE_TEST_CASE_SIG("Tensor neg", "[arithmetics]", TEST_VARIANTS) { apply_backend(Device, Backend); Data<T> dx = {-1, 2, 0, 2, -1, 2, 0, 2, -1}; auto x = Tensor::from_blob(dx.data(), {.shape = {3, 3}, .device = Device, .dtype = to_dtype<T>()}); Tensor z = -x; z = z.cpu(); REQUIRE_THAT(z.at<T>({0, 0}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 0}), Catch::WithinRel(-2.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 0}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 1}), Catch::WithinRel(-2.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 1}), Catch::WithinRel(1.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 1}), Catch::WithinRel(-2.f, 0.001f)); REQUIRE_THAT(z.at<T>({0, 2}), Catch::WithinRel(0.f, 0.001f)); REQUIRE_THAT(z.at<T>({1, 2}), Catch::WithinRel(-2.f, 0.001f)); REQUIRE_THAT(z.at<T>({2, 2}), Catch::WithinRel(1.f, 0.001f)); }