|
34 | 34 | #include <ATen/ops/_linalg_svd_meta.h>
|
35 | 35 | #include <ATen/ops/_linalg_svd_native.h>
|
36 | 36 | #include <ATen/ops/_lu_with_info_native.h>
|
37 |
| -#include <ATen/ops/_symeig_helper.h> |
38 |
| -#include <ATen/ops/_symeig_helper_native.h> |
39 | 37 | #include <ATen/ops/all.h>
|
40 | 38 | #include <ATen/ops/arange.h>
|
41 | 39 | #include <ATen/ops/cat.h>
|
|
110 | 108 | #include <ATen/ops/resize_as_native.h>
|
111 | 109 | #include <ATen/ops/sum.h>
|
112 | 110 | #include <ATen/ops/svd_native.h>
|
113 |
| -#include <ATen/ops/symeig.h> |
114 |
| -#include <ATen/ops/symeig_native.h> |
115 | 111 | #include <ATen/ops/triangular_solve_meta.h>
|
116 | 112 | #include <ATen/ops/triangular_solve_native.h>
|
117 | 113 | #include <ATen/ops/tril.h>
|
@@ -289,12 +285,6 @@ extern "C" void cunmqr_(char *side, char *trans, int *m, int *n, int *k, std::co
|
289 | 285 | extern "C" void dormqr_(char *side, char *trans, int *m, int *n, int *k, double *a, int *lda, double *tau, double *c, int *ldc, double *work, int *lwork, int *info);
|
290 | 286 | extern "C" void sormqr_(char *side, char *trans, int *m, int *n, int *k, float *a, int *lda, float *tau, float *c, int *ldc, float *work, int *lwork, int *info);
|
291 | 287 |
|
292 |
| -// syev |
293 |
| -extern "C" void zheev_(char *jobz, char *uplo, int *n, std::complex<double> *a, int *lda, double *w, std::complex<double> *work, int *lwork, double *rwork, int *info); |
294 |
| -extern "C" void cheev_(char *jobz, char *uplo, int *n, std::complex<float> *a, int *lda, float *w, std::complex<float> *work, int *lwork, float *rwork, int *info); |
295 |
| -extern "C" void dsyev_(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *info); |
296 |
| -extern "C" void ssyev_(char *jobz, char *uplo, int *n, float *a, int *lda, float *w, float *work, int *lwork, int *info); |
297 |
| - |
298 | 288 | // syevd
|
299 | 289 | extern "C" void zheevd_(char *jobz, char *uplo, int *n, std::complex<double> *a, int *lda, double *w, std::complex<double> *work, int *lwork, double *rwork, int *lrwork, int *iwork, int *liwork, int *info);
|
300 | 290 | extern "C" void cheevd_(char *jobz, char *uplo, int *n, std::complex<float> *a, int *lda, float *w, std::complex<float> *work, int *lwork, float *rwork, int *lrwork, int *iwork, int *liwork, int *info);
|
@@ -910,24 +900,6 @@ template<> void lapackOrmqr<float>(char side, char trans, int m, int n, int k, f
|
910 | 900 | sormqr_(&side, &trans, &m, &n, &k, a, &lda, tau, c, &ldc, work, &lwork, info);
|
911 | 901 | }
|
912 | 902 |
|
913 |
| -template<> void lapackSymeig<c10::complex<double>, double>(char jobz, char uplo, int n, c10::complex<double> *a, int lda, double *w, c10::complex<double> *work, int lwork, double *rwork, int *info) { |
914 |
| - zheev_(&jobz, &uplo, &n, reinterpret_cast<std::complex<double>*>(a), &lda, w, reinterpret_cast<std::complex<double>*>(work), &lwork, rwork, info); |
915 |
| -} |
916 |
| - |
917 |
| -template<> void lapackSymeig<c10::complex<float>, float>(char jobz, char uplo, int n, c10::complex<float> *a, int lda, float *w, c10::complex<float> *work, int lwork, float *rwork, int *info) { |
918 |
| - cheev_(&jobz, &uplo, &n, reinterpret_cast<std::complex<float>*>(a), &lda, w, reinterpret_cast<std::complex<float>*>(work), &lwork, rwork, info); |
919 |
| -} |
920 |
| - |
921 |
| -template<> void lapackSymeig<double>(char jobz, char uplo, int n, double *a, int lda, double *w, double *work, int lwork, double* rwork, int *info) { |
922 |
| - (void)rwork; // unused |
923 |
| - dsyev_(&jobz, &uplo, &n, a, &lda, w, work, &lwork, info); |
924 |
| -} |
925 |
| - |
926 |
| -template<> void lapackSymeig<float>(char jobz, char uplo, int n, float *a, int lda, float *w, float *work, int lwork, float* rwork, int *info) { |
927 |
| - (void)rwork; // unused |
928 |
| - ssyev_(&jobz, &uplo, &n, a, &lda, w, work, &lwork, info); |
929 |
| -} |
930 |
| - |
931 | 903 | template<> void lapackSyevd<c10::complex<double>, double>(char jobz, char uplo, int n, c10::complex<double> *a, int lda, double *w, c10::complex<double> *work, int lwork, double *rwork, int lrwork, int *iwork, int liwork, int *info) {
|
932 | 904 | zheevd_(&jobz, &uplo, &n, reinterpret_cast<std::complex<double>*>(a), &lda, w, reinterpret_cast<std::complex<double>*>(work), &lwork, rwork, &lrwork, iwork, &liwork, info);
|
933 | 905 | }
|
@@ -2815,134 +2787,6 @@ Tensor& linalg_eigvalsh_out(const Tensor& A, c10::string_view uplo, Tensor& L) {
|
2815 | 2787 | return L;
|
2816 | 2788 | }
|
2817 | 2789 |
|
2818 |
| -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ symeig ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2819 |
| - |
2820 |
| -template <typename scalar_t> |
2821 |
| -static void apply_symeig(Tensor& self, Tensor& eigvals, bool eigenvectors, bool upper, int* infos) { |
2822 |
| -#if !AT_BUILD_WITH_LAPACK() |
2823 |
| - AT_ERROR("symeig: LAPACK library not found in compilation"); |
2824 |
| -#else |
2825 |
| - using value_t = typename c10::scalar_value_type<scalar_t>::type; |
2826 |
| - auto self_data = self.data_ptr<scalar_t>(); |
2827 |
| - auto eigvals_data = eigvals.data_ptr<value_t>(); |
2828 |
| - auto self_matrix_stride = matrixStride(self); |
2829 |
| - auto eigvals_stride = eigvals.size(-1); |
2830 |
| - auto batch_size = batchCount(self); |
2831 |
| - auto n = self.size(-1); |
2832 |
| - |
2833 |
| - char uplo = upper ? 'U' : 'L'; |
2834 |
| - char jobz = eigenvectors ? 'V' : 'N'; |
2835 |
| - |
2836 |
| - // NOLINTNEXTLINE(cppcoreguidelines-init-variables) |
2837 |
| - int info; |
2838 |
| - // Run once, first to get the optimum work size. |
2839 |
| - // Since we deal with batches of matrices with the same dimensions, doing this outside |
2840 |
| - // the loop saves (batch_size - 1) workspace queries which would provide the same result |
2841 |
| - // and (batch_size - 1) calls to allocate and deallocate workspace using at::empty() |
2842 |
| - int lwork = -1; |
2843 |
| - scalar_t wkopt; |
2844 |
| - |
2845 |
| - Tensor rwork; |
2846 |
| - value_t* rwork_data = nullptr; |
2847 |
| - if (isComplexType(at::typeMetaToScalarType(self.dtype()))) { |
2848 |
| - int64_t lrwork = std::max(int64_t(1), 3 * n - 2); |
2849 |
| - ScalarType dtype = toRealValueType(typeMetaToScalarType(self.dtype())); |
2850 |
| - rwork = at::empty({lrwork}, self.options().dtype(dtype)); |
2851 |
| - rwork_data = rwork.data_ptr<value_t>(); |
2852 |
| - } |
2853 |
| - |
2854 |
| - lapackSymeig<scalar_t, value_t>(jobz, uplo, n, self_data, n, eigvals_data, &wkopt, lwork, rwork_data, &info); |
2855 |
| - lwork = std::max<int>(1, real_impl<scalar_t, value_t>(wkopt)); |
2856 |
| - Tensor work = at::empty({lwork}, self.options()); |
2857 |
| - |
2858 |
| - for (const auto i : c10::irange(batch_size)) { |
2859 |
| - scalar_t* self_working_ptr = &self_data[i * self_matrix_stride]; |
2860 |
| - value_t* eigvals_working_ptr = &eigvals_data[i * eigvals_stride]; |
2861 |
| - |
2862 |
| - // now compute the eigenvalues and the eigenvectors (optionally) |
2863 |
| - lapackSymeig<scalar_t, value_t>(jobz, uplo, n, self_working_ptr, n, eigvals_working_ptr, work.data_ptr<scalar_t>(), lwork, rwork_data, &info); |
2864 |
| - infos[i] = info; |
2865 |
| - if (info != 0) { |
2866 |
| - return; |
2867 |
| - } |
2868 |
| - } |
2869 |
| -#endif |
2870 |
| -} |
2871 |
| - |
2872 |
| -std::tuple<Tensor, Tensor> _symeig_helper_cpu(const Tensor& self, bool eigenvectors, bool upper) { |
2873 |
| - auto infos = at::zeros({batchCount(self)}, self.options().dtype(kInt)); |
2874 |
| - |
2875 |
| - auto self_sizes = self.sizes().vec(); |
2876 |
| - self_sizes.pop_back(); |
2877 |
| - ScalarType dtype = toRealValueType(typeMetaToScalarType(self.dtype())); |
2878 |
| - auto eigvals = at::empty(self_sizes, self.options().dtype(dtype)); |
2879 |
| - |
2880 |
| - if (self.numel() == 0) { |
2881 |
| - return std::tuple<Tensor, Tensor>(eigvals, at::empty_like(self, LEGACY_CONTIGUOUS_MEMORY_FORMAT)); |
2882 |
| - } |
2883 |
| - |
2884 |
| - auto self_working_copy = cloneBatchedColumnMajor(self); |
2885 |
| - AT_DISPATCH_FLOATING_AND_COMPLEX_TYPES(self.scalar_type(), "symeig_cpu", [&]{ |
2886 |
| - apply_symeig<scalar_t>(self_working_copy, eigvals, eigenvectors, upper, infos.data_ptr<int>()); |
2887 |
| - }); |
2888 |
| - |
2889 |
| - at::_linalg_check_errors(infos, "symeig", self.dim() == 2); |
2890 |
| - if (eigenvectors) { |
2891 |
| - return std::tuple<Tensor, Tensor>(eigvals, self_working_copy); |
2892 |
| - } else { |
2893 |
| - return std::tuple<Tensor, Tensor>(eigvals, at::empty({0}, self.options())); |
2894 |
| - } |
2895 |
| -} |
2896 |
| - |
2897 |
| -std::tuple<Tensor, Tensor> symeig(const Tensor& self, bool eigenvectors, bool upper) { |
2898 |
| - TORCH_WARN_ONCE( |
2899 |
| - "torch.symeig is deprecated in favor of torch.linalg.eigh and will be removed in a future ", |
2900 |
| - "PyTorch release.\n", |
2901 |
| - "The default behavior has changed from using the upper triangular portion of the matrix by default ", |
2902 |
| - "to using the lower triangular portion.\n", |
2903 |
| - "L, _ = torch.symeig(A, upper=upper)\n", |
2904 |
| - "should be replaced with\n", |
2905 |
| - "L = torch.linalg.eigvalsh(A, UPLO='U' if upper else 'L')\n", |
2906 |
| - "and\n", |
2907 |
| - "L, V = torch.symeig(A, eigenvectors=True)\n" |
2908 |
| - "should be replaced with\n", |
2909 |
| - "L, V = torch.linalg.eigh(A, UPLO='U' if upper else 'L')" |
2910 |
| - ); |
2911 |
| - squareCheckInputs(self, "linalg.symeig"); |
2912 |
| - return at::_symeig_helper(self, eigenvectors, upper); |
2913 |
| -} |
2914 |
| - |
2915 |
| -std::tuple<Tensor&, Tensor&> symeig_out(const Tensor& self, bool eigenvectors, bool upper, Tensor& vals, Tensor& vecs) { |
2916 |
| - TORCH_WARN_ONCE( |
2917 |
| - "torch.symeig is deprecated in favor of torch.linalg.eigh and will be removed in a future ", |
2918 |
| - "PyTorch release.\n", |
2919 |
| - "The default behavior has changed from using the upper triangular portion of the matrix by default ", |
2920 |
| - "to using the lower triangular portion.\n", |
2921 |
| - "L, _ = torch.symeig(A, upper=upper)\n", |
2922 |
| - "should be replaced with\n", |
2923 |
| - "L = torch.linalg.eigvalsh(A, UPLO='U' if upper else 'L')\n", |
2924 |
| - "and\n", |
2925 |
| - "L, V = torch.symeig(A, eigenvectors=True)\n" |
2926 |
| - "should be replaced with\n", |
2927 |
| - "L, V = torch.linalg.eigh(A, UPLO='U' if upper else 'L')" |
2928 |
| - ); |
2929 |
| - checkSameDevice("symeig", vals, self, "eigenvalues"); |
2930 |
| - checkSameDevice("symeig", vecs, self, "eigenvectors"); |
2931 |
| - checkLinalgCompatibleDtype("symeig", vecs, self, "eigenvectors"); |
2932 |
| - // eigenvalues are always real-valued here |
2933 |
| - ScalarType real_dtype = toRealValueType(self.scalar_type()); |
2934 |
| - checkLinalgCompatibleDtype("symeig", vals.scalar_type(), real_dtype, "eigenvalues"); |
2935 |
| - |
2936 |
| - Tensor vals_tmp, vecs_tmp; |
2937 |
| - std::tie(vals_tmp, vecs_tmp) = at::symeig(self, eigenvectors, upper); |
2938 |
| - |
2939 |
| - at::native::resize_output(vals, vals_tmp.sizes()); |
2940 |
| - at::native::resize_output(vecs, vecs_tmp.sizes()); |
2941 |
| - vals.copy_(vals_tmp); |
2942 |
| - vecs.copy_(vecs_tmp); |
2943 |
| - return std::tuple<Tensor&, Tensor&>(vals, vecs); |
2944 |
| -} |
2945 |
| - |
2946 | 2790 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linalg_eig ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2947 | 2791 |
|
2948 | 2792 | // This function returns complex-valued eigenvectors that is obtained from LAPACK GEEV's real-valued output
|
|
0 commit comments