apply_lapack_eigh Class — pytorch Architecture
Architecture documentation for the apply_lapack_eigh class in BatchLinearAlgebraKernel.cpp from the pytorch codebase.
Entity Profile
Source Code
aten/src/ATen/native/BatchLinearAlgebraKernel.cpp lines 298–368
template <typename scalar_t>
void apply_lapack_eigh(const Tensor& values, const Tensor& vectors, const Tensor& infos, bool upper, bool compute_eigenvectors) {
#if !AT_BUILD_WITH_LAPACK()
TORCH_CHECK(
false,
"Calling torch.linalg.eigh or eigvalsh on a CPU tensor requires compiling ",
"PyTorch with LAPACK. Please use PyTorch built with LAPACK support.");
#else
using value_t = typename c10::scalar_value_type<scalar_t>::type;
char uplo = upper ? 'U' : 'L';
char jobz = compute_eigenvectors ? 'V' : 'N';
auto n = vectors.size(-1);
auto lda = std::max<int64_t>(1, n);
auto batch_size = batchCount(vectors);
auto vectors_stride = matrixStride(vectors);
auto values_stride = values.size(-1);
auto vectors_data = vectors.data_ptr<scalar_t>();
auto values_data = values.data_ptr<value_t>();
auto infos_data = infos.data_ptr<int>();
// Using 'int' instead of int32_t or int64_t is consistent with the current LAPACK interface
// It really should be changed in the future to something like lapack_int that depends on the specific LAPACK library that is linked
// or switch to supporting only 64-bit indexing by default.
int lwork = -1;
int lrwork = -1;
int liwork = -1;
scalar_t lwork_query;
value_t rwork_query;
int iwork_query = 0;
// call lapackSyevd once to get the optimal size for work data
lapackSyevd<scalar_t, value_t>(jobz, uplo, n, vectors_data, lda, values_data,
&lwork_query, lwork, &rwork_query, lrwork, &iwork_query, liwork, infos_data);
lwork = lapack_work_to_int(lwork_query);
Tensor work = at::empty({lwork}, vectors.options());
auto work_data = work.mutable_data_ptr<scalar_t>();
liwork = std::max<int>(1, iwork_query);
Tensor iwork = at::empty({liwork}, vectors.options().dtype(at::kInt));
auto iwork_data = iwork.mutable_data_ptr<int>();
Tensor rwork;
value_t* rwork_data = nullptr;
if (vectors.is_complex()) {
lrwork = lapack_work_to_int(rwork_query);
rwork = at::empty({lrwork}, values.options());
rwork_data = rwork.mutable_data_ptr<value_t>();
}
// Now call lapackSyevd for each matrix in the batched input
for (const auto i : c10::irange(batch_size)) {
scalar_t* vectors_working_ptr = &vectors_data[i * vectors_stride];
value_t* values_working_ptr = &values_data[i * values_stride];
int* info_working_ptr = &infos_data[i];
lapackSyevd<scalar_t, value_t>(jobz, uplo, n, vectors_working_ptr, lda, values_working_ptr,
work_data, lwork, rwork_data, lrwork, iwork_data, liwork, info_working_ptr);
// The current behaviour for Linear Algebra functions to raise an error if something goes wrong
// or input doesn't satisfy some requirement
// therefore return early since further computations will be wasted anyway
if (*info_working_ptr != 0) {
return;
}
}
#endif
}
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free