/*
 * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 * SPDX-License-Identifier: LicenseRef-NvidiaProprietary
 *
 * NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
 * property and proprietary rights in and to this material, related
 * documentation and any modifications thereto. Any use, reproduction,
 * disclosure or distribution of this material and related documentation
 * without an express license agreement from NVIDIA CORPORATION or
 * its affiliates is strictly prohibited.
 */

#pragma once

namespace __nvhpc_std {

namespace __cb = __cublas_std;

// Scaling/conjugate/transpose has been done before calling this!
template< class _SyncType
        , class _ElementType_A
        , class _SizeType_A
        , ::std::size_t ... _ext_A
        , class _Layout_A
        , class _Accessor_A
        , class _ElementType_B
        , class _SizeType_B
        , ::std::size_t ... _ext_B
        , class _Layout_B
        , class _Accessor_B
        >
void __copy_matrix_impl( __nvhpc_exec< __cublas_exec_space< _SyncType > > __exec
                       , char __uplo
                       , std::mdspan< _ElementType_A, std::extents<_SizeType_A, _ext_A ...>, _Layout_A, _Accessor_A > __A
                       , std::mdspan< _ElementType_B, std::extents<_SizeType_B, _ext_B ...>, _Layout_B, _Accessor_B > __B
                       )
{
#ifdef STDBLAS_VERBOSE
    __STDBLAS_BACKEND_MESSAGE( lacpy, cuBLAS );
#endif
    static_assert (__A.rank() == 2);
    static_assert (__B.rank() == 2);

    __cb::__check_cublas_status( __cb::__cublas_lacpy( __cb::__get_cublas_handle()
                                                     , __uplo
                                                     , __A.extent(0)
                                                     , __A.extent(1)
                                                     , __A.data_handle()
                                                     , std::linalg::__get_leading_dim( __A )
                                                     , __B.data_handle()
                                                     , std::linalg::__get_leading_dim( __B )
                                                     )
                               , "lacpy"
                               , "cublas_lacpy"
                               );

    __cb::__synchronize( __exec );
}

}
