Skip to content

Commit

Permalink
improve lrmat testing
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreMarchand20 committed Jul 30, 2024
1 parent 1264dde commit 9c1849b
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 214 deletions.
57 changes: 2 additions & 55 deletions tests/functional_tests/hmatrix/lrmat/test_lrmat_lrmat_product.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,65 +12,12 @@ using namespace std;
using namespace htool;

template <typename T, typename GeneratorTestType, class Compressor>
bool test_lrmat_lrmat_product(const TestCaseProduct<T, GeneratorTestType> &test_case, htool::underlying_type<T> epsilon, htool::underlying_type<T> additional_compression_tolerance, htool::underlying_type<T> additional_lrmat_sum_tolerance) {
bool test_lrmat_lrmat_product(char transa, char transb, T alpha, T beta, const LowRankMatrix<T> &A_auto_approximation, const LowRankMatrix<T> &B_auto_approximation, const LowRankMatrix<T> &C_auto_approximation, const Matrix<T> &C_dense, const Matrix<T> &matrix_result_w_matrix_sum, const Matrix<T> &matrix_result_wo_sum, const Matrix<T> &matrix_result_w_lrmat_sum, htool::underlying_type<T> epsilon, htool::underlying_type<T> additional_compression_tolerance, htool::underlying_type<T> additional_lrmat_sum_tolerance) {

bool is_error = false;
char transa = test_case.transa;
char transb = test_case.transb;

// ACA automatic building
Compressor compressor;
LowRankMatrix<T> A_auto_approximation(*test_case.operator_A, compressor, *test_case.root_cluster_A_output, *test_case.root_cluster_A_input, -1, epsilon);
LowRankMatrix<T> B_auto_approximation(*test_case.operator_B, compressor, *test_case.root_cluster_B_output, *test_case.root_cluster_B_input, -1, epsilon);
LowRankMatrix<T> C_auto_approximation(*test_case.operator_C, compressor, *test_case.root_cluster_C_output, *test_case.root_cluster_C_input, -1, epsilon);

// partialACA fixed rank
int reqrank_max = 10;
LowRankMatrix<T> A_fixed_approximation(*test_case.operator_A, compressor, *test_case.root_cluster_A_output, *test_case.root_cluster_A_input, std::max(A_auto_approximation.rank_of(), reqrank_max), epsilon);
LowRankMatrix<T> B_fixed_approximation(*test_case.operator_B, compressor, *test_case.root_cluster_B_output, *test_case.root_cluster_B_input, std::max(B_auto_approximation.rank_of(), reqrank_max), epsilon);
LowRankMatrix<T> C_fixed_approximation(*test_case.operator_C, compressor, *test_case.root_cluster_C_output, *test_case.root_cluster_C_input, std::max(C_auto_approximation.rank_of(), reqrank_max), epsilon);
Matrix<T> matrix_test, dense_lrmat_test;
LowRankMatrix<T> lrmat_test(epsilon);

// Random Input
htool::underlying_type<T> error;
T alpha(1), beta(1);
generate_random_scalar(alpha);
generate_random_scalar(beta);

// Reference matrix
Matrix<T> A_dense(test_case.no_A, test_case.ni_A), B_dense(test_case.no_B, test_case.ni_B), C_dense(test_case.no_C, test_case.ni_C);
test_case.operator_A->copy_submatrix(test_case.no_A, test_case.ni_A, 0, 0, A_dense.data());
test_case.operator_B->copy_submatrix(test_case.no_B, test_case.ni_B, 0, 0, B_dense.data());
test_case.operator_C->copy_submatrix(test_case.no_C, test_case.ni_C, 0, 0, C_dense.data());
Matrix<T> matrix_result_w_matrix_sum(C_dense), matrix_result_wo_sum(C_dense), dense_lrmat_test, matrix_test, matrix_result_w_lrmat_sum(C_dense);
C_auto_approximation.copy_to_dense(matrix_result_w_lrmat_sum.data());

add_matrix_matrix_product(transa, transb, alpha, A_dense, B_dense, beta, matrix_result_w_matrix_sum);
add_matrix_matrix_product(transa, transb, alpha, A_dense, B_dense, beta, matrix_result_w_lrmat_sum);
add_matrix_matrix_product(transa, transb, alpha, A_dense, B_dense, T(0), matrix_result_wo_sum);

// Product with fixed rank
matrix_test = C_dense;
add_lrmat_lrmat_product(transa, transb, alpha, A_fixed_approximation, B_fixed_approximation, beta, matrix_test);
error = normFrob(matrix_result_w_matrix_sum - matrix_test) / normFrob(matrix_result_w_matrix_sum);
is_error = is_error || !(error < A_fixed_approximation.get_epsilon() * (1 + additional_compression_tolerance));
cout << "> Errors on a lrmat lrmat product to matrix with fixed approximation: " << error << endl;

lrmat_test = C_fixed_approximation;
add_lrmat_lrmat_product(transa, transb, alpha, A_fixed_approximation, B_fixed_approximation, T(0), lrmat_test);
dense_lrmat_test.resize(lrmat_test.get_U().nb_rows(), lrmat_test.get_V().nb_cols());
lrmat_test.copy_to_dense(dense_lrmat_test.data());
error = normFrob(matrix_result_wo_sum - dense_lrmat_test) / normFrob(matrix_result_wo_sum);
is_error = is_error || !(error < A_fixed_approximation.get_epsilon() * (1 + additional_compression_tolerance));
cout << "> Errors on a lrmat lrmat product to lrmat with fixed approximation and without lrmat sum: " << error << endl;

lrmat_test = C_auto_approximation;
add_lrmat_lrmat_product(transa, transb, alpha, A_fixed_approximation, B_fixed_approximation, beta, lrmat_test);
dense_lrmat_test.resize(lrmat_test.get_U().nb_rows(), lrmat_test.get_V().nb_cols());
lrmat_test.copy_to_dense(dense_lrmat_test.data());
error = normFrob(matrix_result_w_lrmat_sum - dense_lrmat_test) / normFrob(matrix_result_w_lrmat_sum);
is_error = is_error || !(error < A_fixed_approximation.get_epsilon() * (1 + additional_compression_tolerance + additional_lrmat_sum_tolerance));
cout << "> Errors on a lrmat lrmat product to lrmat with fixed approximation and with lrmat sum: " << error << endl;

// Product with automatic rank
matrix_test = C_dense;
Expand Down
79 changes: 5 additions & 74 deletions tests/functional_tests/hmatrix/lrmat/test_lrmat_matrix_product.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,11 @@ using namespace std;
using namespace htool;

template <typename T, typename GeneratorTestType, class Compressor>
bool test_lrmat_matrix_product(const TestCaseProduct<T, GeneratorTestType> &test_case, htool::underlying_type<T> epsilon, htool::underlying_type<T> additional_compression_tolerance, htool::underlying_type<T> additional_lrmat_sum_tolerance) {
bool test_lrmat_matrix_product(char transa, char transb, T alpha, T beta, T scaling_coefficient, const LowRankMatrix<T> &A_auto_approximation, LowRankMatrix<T> &C_auto_approximation, const Matrix<T> &B_dense, const Matrix<T> &C_dense, const Matrix<T> &matrix_result_w_matrix_sum, const Matrix<T> &matrix_result_wo_sum, const Matrix<T> &matrix_result_w_lrmat_sum, htool::underlying_type<T> epsilon, htool::underlying_type<T> additional_compression_tolerance, htool::underlying_type<T> additional_lrmat_sum_tolerance) {
bool is_error = false;
char transa = test_case.transa;
char transb = test_case.transb;

// ACA automatic building
Compressor compressor;
LowRankMatrix<T> A_auto_approximation(*test_case.operator_A, compressor, *test_case.root_cluster_A_output, *test_case.root_cluster_A_input, -1, epsilon);
LowRankMatrix<T> C_auto_approximation(*test_case.operator_C, compressor, *test_case.root_cluster_C_output, *test_case.root_cluster_C_input, -1, epsilon);

// // partialACA fixed rank
// int reqrank_max = 10;
// LowRankMatrix<T> A_fixed_approximation(*test_case.operator_A, compressor, *test_case.root_cluster_A_output, *test_case.root_cluster_A_input, std::max(A_auto_approximation.rank_of(), reqrank_max), epsilon);
// LowRankMatrix<T> C_fixed_approximation(*test_case.operator_C, compressor, *test_case.root_cluster_C_output, *test_case.root_cluster_C_input, std::max(C_auto_approximation.rank_of(), reqrank_max), epsilon);
LowRankMatrix<T> lrmat_test(epsilon);

// Reference matrix
Matrix<T> A_dense(test_case.no_A, test_case.ni_A), B_dense(test_case.no_B, test_case.ni_B), C_dense(test_case.no_C, test_case.ni_C);
test_case.operator_A->copy_submatrix(test_case.no_A, test_case.ni_A, 0, 0, A_dense.data());
test_case.operator_B->copy_submatrix(test_case.no_B, test_case.ni_B, 0, 0, B_dense.data());
test_case.operator_C->copy_submatrix(test_case.no_C, test_case.ni_C, 0, 0, C_dense.data());
Matrix<T> matrix_test, dense_lrmat_test, transposed_B_dense(B_dense.nb_cols(), B_dense.nb_rows()), transposed_C_dense(C_dense.nb_cols(), C_dense.nb_rows());
transpose(B_dense, transposed_B_dense);
transpose(C_dense, transposed_C_dense);
Expand All @@ -41,67 +25,13 @@ bool test_lrmat_matrix_product(const TestCaseProduct<T, GeneratorTestType> &test
std::vector<T> B_vec, C_vec, test_vec;
B_vec = B_dense.get_col(0);
C_vec = C_dense.get_col(0);
T alpha(1), beta(1), scaling_coefficient;
generate_random_scalar(alpha);
generate_random_scalar(beta);
generate_random_scalar(scaling_coefficient);

// Reference matrix
Matrix<T> matrix_result_w_matrix_sum(C_dense), matrix_result_wo_sum(C_dense), matrix_result_w_lrmat_sum(C_dense);
Matrix<T> transposed_matrix_result_w_sum(transposed_C_dense);
C_auto_approximation.copy_to_dense(matrix_result_w_lrmat_sum.data());
add_matrix_matrix_product(transa, transb, alpha, A_dense, B_dense, beta, matrix_result_w_matrix_sum);
add_matrix_matrix_product(transa, transb, alpha, A_dense, B_dense, beta, matrix_result_w_lrmat_sum);
add_matrix_matrix_product(transa, transb, alpha, A_dense, B_dense, T(0), matrix_result_wo_sum);
transpose(matrix_result_w_matrix_sum, transposed_matrix_result_w_sum);

Matrix<T> scaled_matrix_result_w_matrix_sum(matrix_result_w_matrix_sum);
scale(scaling_coefficient, scaled_matrix_result_w_matrix_sum);

// // Tests for fixed rank
// if (transb == 'N') {
// test_vec = C_vec;
// add_lrmat_vector_product(transa, alpha, A_fixed_approximation, B_vec.data(), beta, test_vec.data());
// error = norm2(matrix_result_w_matrix_sum.get_col(0) - test_vec) / norm2(matrix_result_w_matrix_sum.get_col(0));
// is_error = is_error || !(error < epsilon * (1 + additional_compression_tolerance));
// cout << "> Errors on a lrmat vector product with fixed approximation: " << error << endl;
// }

// matrix_test = C_dense;
// add_lrmat_matrix_product(transa, transb, alpha, A_fixed_approximation, B_dense, beta, matrix_test);
// error = normFrob(matrix_result_w_matrix_sum - matrix_test) / normFrob(matrix_result_w_matrix_sum);
// is_error = is_error || !(error < epsilon * (1 + additional_compression_tolerance));
// cout << "> Errors on a lrmat matrix product to matrix with fixed approximation: " << error << endl;

// lrmat_test = C_fixed_approximation;
// add_lrmat_matrix_product(transa, transb, alpha, A_fixed_approximation, B_dense, T(0), lrmat_test);
// dense_lrmat_test.resize(lrmat_test.get_U().nb_rows(), lrmat_test.get_V().nb_cols());
// lrmat_test.copy_to_dense(dense_lrmat_test.data());
// error = normFrob(matrix_result_wo_sum - dense_lrmat_test) / normFrob(matrix_result_wo_sum);
// is_error = is_error || !(error < epsilon * (1 + additional_compression_tolerance));
// cout << "> Errors on a lrmat matrix product to lrmat with fixed approximation and without lrmat sum: " << error << endl;

// lrmat_test = C_fixed_approximation;
// add_lrmat_matrix_product(transa, transb, alpha, A_fixed_approximation, B_dense, beta, lrmat_test);
// dense_lrmat_test.resize(lrmat_test.get_U().nb_rows(), lrmat_test.get_V().nb_cols());
// lrmat_test.copy_to_dense(dense_lrmat_test.data());
// error = normFrob(matrix_result_w_lrmat_sum - dense_lrmat_test) / normFrob(matrix_result_w_lrmat_sum);
// is_error = is_error || !(error < epsilon * (1 + additional_compression_tolerance + additional_lrmat_sum_tolerance));
// cout << "> Errors on a lrmat matrix product to lrmat with fixed approximation and with lrmat sum: " << error << endl;

// matrix_test = transposed_C_dense;
// add_lrmat_matrix_product_row_major(transa, transb, alpha, A_fixed_approximation, transposed_B_dense.data(), beta, matrix_test.data(), C_dense.nb_cols());
// error = normFrob(transposed_matrix_result_w_sum - matrix_test) / normFrob(transposed_matrix_result_w_sum);
// is_error = is_error || !(error < epsilon * (1 + additional_compression_tolerance));
// cout << "> Errors on a lrmat matrix product to matrix with fixed approximation and row major input: " << error << endl;

// matrix_test = C_dense;
// scale(transa != 'C' ? scaling_coefficient : conj_if_complex(scaling_coefficient), A_fixed_approximation);
// add_lrmat_matrix_product(transa, transb, alpha, A_fixed_approximation, B_dense, scaling_coefficient * beta, matrix_test);
// error = normFrob(scaled_matrix_result_w_matrix_sum - matrix_test) / normFrob(scaled_matrix_result_w_matrix_sum);
// is_error = is_error || !(error < epsilon * (1 + additional_compression_tolerance));
// cout << "> Errors on a scaled lrmat matrix product with fixed approximation: " << error << endl;

// Tests for automatic rank
if (transb == 'N') {
test_vec = C_vec;
Expand Down Expand Up @@ -139,9 +69,10 @@ bool test_lrmat_matrix_product(const TestCaseProduct<T, GeneratorTestType> &test
is_error = is_error || !(error < epsilon * (1 + additional_compression_tolerance));
cout << "> Errors on a lrmat matrix product to matrix with auto approximation and row major input: " << error << endl;

matrix_test = C_dense;
scale(transa != 'C' ? scaling_coefficient : conj_if_complex(scaling_coefficient), A_auto_approximation);
add_lrmat_matrix_product(transa, transb, alpha, A_auto_approximation, B_dense, scaling_coefficient * beta, matrix_test);
matrix_test = C_dense;
LowRankMatrix<T> scaled_A_auto_approximation = A_auto_approximation;
scale(transa != 'C' ? scaling_coefficient : conj_if_complex(scaling_coefficient), scaled_A_auto_approximation);
add_lrmat_matrix_product(transa, transb, alpha, scaled_A_auto_approximation, B_dense, scaling_coefficient * beta, matrix_test);
error = normFrob(scaled_matrix_result_w_matrix_sum - matrix_test) / normFrob(scaled_matrix_result_w_matrix_sum);
is_error = is_error || !(error < epsilon * (1 + additional_compression_tolerance));
cout << "> Errors on a scaled lrmat matrix product with auto approximation: " << error << endl;
Expand Down
38 changes: 30 additions & 8 deletions tests/functional_tests/hmatrix/lrmat/test_lrmat_product.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,40 @@ using namespace htool;
template <typename T, typename GeneratorTestType, class Compressor>
bool test_lrmat_product(char transa, char transb, int n1, int n2, int n3, htool::underlying_type<T> epsilon, htool::underlying_type<T> additional_compression_tolerance, std::array<htool::underlying_type<T>, 4> additional_lrmat_sum_tolerances) {
bool is_error = false;
const int ndistance = 4;
const int ndistance = 2;
htool::underlying_type<T> distance[ndistance];
distance[0] = 15;
distance[1] = 20;
distance[2] = 30;
distance[3] = 40;
distance[1] = 40;
for (int idist = 0; idist < ndistance; idist++) {
TestCaseProduct<T, GeneratorTestType> test_case(transa, transb, n1, n2, n3, distance[idist], distance[idist] + 10);
is_error = is_error || test_lrmat_lrmat_product<T, GeneratorTestType, Compressor>(test_case, epsilon, additional_compression_tolerance, additional_lrmat_sum_tolerances[0]);
is_error = is_error || test_lrmat_matrix_product<T, GeneratorTestType, Compressor>(test_case, epsilon, additional_compression_tolerance, additional_lrmat_sum_tolerances[1]);
is_error = is_error || test_matrix_lrmat_product<T, GeneratorTestType, Compressor>(test_case, epsilon, additional_compression_tolerance, additional_lrmat_sum_tolerances[2]);
is_error = is_error || test_matrix_matrix_product<T, GeneratorTestType, Compressor>(test_case, epsilon, additional_compression_tolerance, additional_lrmat_sum_tolerances[3]);

T alpha(1), beta(1), scaling_coefficient;
generate_random_scalar(alpha);
generate_random_scalar(beta);
generate_random_scalar(scaling_coefficient);

// lrmat
Compressor compressor;
LowRankMatrix<T> A_auto_approximation(*test_case.operator_A, compressor, *test_case.root_cluster_A_output, *test_case.root_cluster_A_input, -1, epsilon);
LowRankMatrix<T> B_auto_approximation(*test_case.operator_B, compressor, *test_case.root_cluster_B_output, *test_case.root_cluster_B_input, -1, epsilon);
LowRankMatrix<T> C_auto_approximation(*test_case.operator_C, compressor, *test_case.root_cluster_C_output, *test_case.root_cluster_C_input, -1, epsilon);

// dense
Matrix<T> A_dense(test_case.no_A, test_case.ni_A), B_dense(test_case.no_B, test_case.ni_B), C_dense(test_case.no_C, test_case.ni_C);
test_case.operator_A->copy_submatrix(test_case.no_A, test_case.ni_A, 0, 0, A_dense.data());
test_case.operator_B->copy_submatrix(test_case.no_B, test_case.ni_B, 0, 0, B_dense.data());
test_case.operator_C->copy_submatrix(test_case.no_C, test_case.ni_C, 0, 0, C_dense.data());
Matrix<T> matrix_result_w_matrix_sum(C_dense), matrix_result_wo_sum(C_dense), dense_lrmat_test, matrix_test, matrix_result_w_lrmat_sum(C_dense);
C_auto_approximation.copy_to_dense(matrix_result_w_lrmat_sum.data());

add_matrix_matrix_product(transa, transb, alpha, A_dense, B_dense, beta, matrix_result_w_matrix_sum);
add_matrix_matrix_product(transa, transb, alpha, A_dense, B_dense, beta, matrix_result_w_lrmat_sum);
add_matrix_matrix_product(transa, transb, alpha, A_dense, B_dense, T(0), matrix_result_wo_sum);

is_error = is_error || test_lrmat_lrmat_product<T, GeneratorTestType, Compressor>(transa, transb, alpha, beta, A_auto_approximation, B_auto_approximation, C_auto_approximation, C_dense, matrix_result_w_matrix_sum, matrix_result_wo_sum, matrix_result_w_lrmat_sum, epsilon, additional_compression_tolerance, additional_lrmat_sum_tolerances[0]);
is_error = is_error || test_lrmat_matrix_product<T, GeneratorTestType, Compressor>(transa, transb, alpha, beta, scaling_coefficient, A_auto_approximation, C_auto_approximation, B_dense, C_dense, matrix_result_w_matrix_sum, matrix_result_wo_sum, matrix_result_w_lrmat_sum, epsilon, additional_compression_tolerance, additional_lrmat_sum_tolerances[1]);
is_error = is_error || test_matrix_lrmat_product<T, GeneratorTestType, Compressor>(transa, transb, alpha, beta, B_auto_approximation, C_auto_approximation, A_dense, C_dense, matrix_result_w_matrix_sum, matrix_result_wo_sum, matrix_result_w_lrmat_sum, epsilon, additional_compression_tolerance, additional_lrmat_sum_tolerances[2]);
is_error = is_error || test_matrix_matrix_product<T, GeneratorTestType, Compressor>(transa, transb, alpha, beta, C_auto_approximation, A_dense, B_dense, matrix_result_wo_sum, matrix_result_w_lrmat_sum, epsilon, additional_compression_tolerance, additional_lrmat_sum_tolerances[3]);
}

return is_error;
Expand Down
Loading

0 comments on commit 9c1849b

Please sign in to comment.