// SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../geometry.h" struct contiguous_tag{}; struct transpose_tag{}; template struct Matrix2x2_Offset; template struct Matrix2x2_Offset { static const uint32_t OFFSET = R * 2 + C; }; template struct Matrix2x2_Offset { static const uint32_t OFFSET = C * 2 + R; }; template struct Matrix2x2_Indexor { static const uint32_t OFFSET = Matrix2x2_Offset::OFFSET; static T &get(T *data) { return data[OFFSET]; } static const T get(const T *data) { return data[OFFSET]; } }; template struct Matrix2x2 { Matrix2x2() = default; Matrix2x2(T r0c0, T r0c1, T r1c0, T r1c1) : m_data{ r0c0, r0c1, r1c0, r1c1 } { } Matrix2x2(const Point_ &r0, const Point_ &r1) : m_data{ r0.X, r0.Y, r1.X, r1.Y } { } Matrix2x2(const Point_ &r0, const Point_ &r1, transpose_tag) : m_data{ r0.X, r1.X, r0.Y, r1.Y } { } inline T &operator[](uint32_t i) { return m_data[i]; } inline const T operator[](uint32_t i) const { return m_data[i]; } T m_data[4]; }; template struct Matrix2x2_View { Matrix2x2_View(const Matrix2x2 &m) : m_data(m.m_data) {} const T *m_data; }; template const T get(const Matrix2x2_View &m) { return Matrix2x2_Indexor::get(m.m_data); } template inline void matmul_fn(int64_t N, const get_pt_t &get_fn, const Matrix2x2 &mat, const callback_t &callback, layout_t lt = layout_t{}) { Matrix2x2_View m{ mat }; #pragma omp simd for (int64_t i = 0; i < N; ++i) { Point_ pt = get_fn(i); T x = pt.X * get<0, 0>(m) + pt.Y * get<1, 0>(m); T y = pt.X * get<0, 1>(m) + pt.Y * get<1, 1>(m); callback(i, Point_{ x, y }); } }