-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
a unit test for NNLSSolver::solve_parallel_with_scalapack.
- Loading branch information
1 parent
e8ee2d1
commit 458baee
Showing
3 changed files
with
144 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/****************************************************************************** | ||
* | ||
* Copyright (c) 2013-2024, Lawrence Livermore National Security, LLC | ||
* and other libROM project developers. See the top-level COPYRIGHT | ||
* file for details. | ||
* | ||
* SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
* | ||
*****************************************************************************/ | ||
|
||
#ifdef CAROM_HAS_GTEST | ||
|
||
#include<gtest/gtest.h> | ||
#include "linalg/NNLS.h" | ||
#include <algorithm> | ||
#include <cmath> | ||
#include <cstdio> | ||
#include <cstring> // for memcpy | ||
#include <random> | ||
#include "mpi.h" | ||
#include "utils/mpi_utils.h" | ||
|
||
/** | ||
* Simple smoke test to make sure Google Test is properly linked | ||
*/ | ||
TEST(GoogleTestFramework, GoogleTestFrameworkFound) { | ||
SUCCEED(); | ||
} | ||
|
||
TEST(NNLS, solve_nnls_with_parallel) | ||
{ | ||
int nproc; | ||
int rank; | ||
MPI_Comm_size(MPI_COMM_WORLD, &nproc); | ||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); | ||
|
||
const int nrow = 12; | ||
const int ncol = 18; | ||
const int ncol_local = CAROM::split_dimension(ncol); | ||
std::vector<int> row_offset(nproc + 1); | ||
const int total_cols = CAROM::get_global_offsets(ncol_local, row_offset, | ||
MPI_COMM_WORLD); | ||
const double rel_tol = 0.3; | ||
const double nnls_tol = 1.0e-11; | ||
|
||
std::default_random_engine generator; | ||
generator.seed( | ||
1234); // fix the seed to keep the same result for different nproc. | ||
std::uniform_real_distribution<> uniform_distribution(0.0, 1.0); | ||
std::normal_distribution<double> normal_distribution(0.0, 1.0); | ||
|
||
// distribute from a global matrix to keep the same system for different nproc. | ||
CAROM::Matrix Gt(ncol, nrow, false); | ||
for (int i = 0; i < ncol; i++) | ||
for (int j = 0; j < nrow; j++) | ||
Gt(i, j) = normal_distribution(generator); | ||
Gt.distribute(ncol_local); | ||
|
||
CAROM::Vector fom_sol(ncol_local, true); | ||
CAROM::Vector rom_sol(ncol_local, true); | ||
CAROM::Vector rhs(nrow, false); | ||
|
||
// distribute from a global matrix to keep the same system for different nproc. | ||
CAROM::Vector fom_sol_serial(ncol, false); | ||
for (int c = 0; c < ncol; c++) | ||
fom_sol_serial(c) = uniform_distribution(generator); | ||
for (int c = 0; c < ncol_local; c++) | ||
fom_sol(c) = fom_sol_serial(row_offset[rank] + c); | ||
|
||
Gt.transposeMult(fom_sol, rhs); | ||
rom_sol = 0.0; | ||
|
||
CAROM::Vector rhs_lb(rhs); | ||
CAROM::Vector rhs_ub(rhs); | ||
|
||
for (int i = 0; i < rhs.dim(); ++i) | ||
{ | ||
double delta = rel_tol * abs(rhs(i)); | ||
rhs_lb(i) -= delta; | ||
rhs_ub(i) += delta; | ||
} | ||
|
||
CAROM::NNLSSolver nnls(nnls_tol, 0, 0, 2); | ||
nnls.solve_parallel_with_scalapack(Gt, rhs_lb, rhs_ub, rom_sol); | ||
|
||
int nnz = 0; | ||
for (int i = 0; i < rom_sol.dim(); ++i) | ||
{ | ||
if (rom_sol(i) != 0.0) | ||
{ | ||
nnz++; | ||
} | ||
} | ||
|
||
std::cout << rank << ": Number of nonzeros in NNLS solution: " << nnz | ||
<< ", out of " << rom_sol.dim() << std::endl; | ||
|
||
MPI_Allreduce(MPI_IN_PLACE, &nnz, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); | ||
|
||
if (rank == 0) | ||
std::cout << "Global number of nonzeros in NNLS solution: " << nnz << std::endl; | ||
|
||
// Check residual of NNLS solution | ||
CAROM::Vector res(Gt.numColumns(), false); | ||
Gt.transposeMult(rom_sol, res); | ||
|
||
const double normGsol = res.norm(); | ||
const double normRHS = rhs.norm(); | ||
|
||
res -= rhs; | ||
const double relNorm = res.norm() / std::max(normGsol, normRHS); | ||
std::cout << rank << ": relative residual norm for NNLS solution of Gs = Gw: " | ||
<< relNorm << std::endl; | ||
|
||
for (int k = 0; k < res.dim(); k++) | ||
{ | ||
// printf("rank %d, error(%d): %.3e\n", rank, k, abs(res(k) / rhs(k))); | ||
EXPECT_TRUE(abs(res(k)) < rel_tol * abs(rhs(k)) + nnls_tol); | ||
} | ||
} | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
::testing::InitGoogleTest(&argc, argv); | ||
MPI_Init(&argc, &argv); | ||
int result = RUN_ALL_TESTS(); | ||
MPI_Finalize(); | ||
return result; | ||
} | ||
|
||
#else // #ifndef CAROM_HAS_GTEST | ||
|
||
int main() | ||
{ | ||
std::cout << "libROM was compiled without Google Test support, so unit " | ||
<< "tests have been disabled. To enable unit tests, compile " | ||
<< "libROM with Google Test support." << std::endl; | ||
} | ||
|
||
#endif // #endif CAROM_HAS_GTEST |