Skip to content

Commit aaaf45b

Browse files
Nikku, Deepikavarajago
authored andcommitted
AOCL LAPACK: dgesvd fix to make singular values positive (flame#97)
* AOCL LAPACK: dgesvd fix to make singular values positive Added code changes for making singular values non negative and ctest fixes in potri, hetrf AMD-Internal: CPUPL-7326, CPUPL-7316 Signed-off-by: dnikku <Deepika.Nikku@amd.com>
1 parent 3f1eb81 commit aaaf45b

8 files changed

Lines changed: 72 additions & 5 deletions

File tree

src/lapack/dec/svd/ext/flamec/lapack_dbdsqr.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,11 @@
831831
for (i__ = 1;
832832
i__ <= i__1;
833833
++i__) {
834-
if (d__[i__] < 0.) {
834+
if (d__[i__] == 0.) {
835+
/* Avoid -ZERO */
836+
d__[i__] = 0.;
837+
}
838+
else if (d__[i__] < 0.) {
835839
d__[i__] = -d__[i__];
836840
/* Change sign of singular vectors, if desired */
837841
if (*ncvt > 0) {

src/lapack/dec/svd/ext/flamec/lapack_dbdsqr_small.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,12 @@ int lapack_dbdsqr_small(char *uplo, integer *n, integer *ncvt, integer *nru,
806806
i__1 = *n;
807807
for(i__ = 1; i__ <= i__1; ++i__)
808808
{
809-
if(d__[i__] < 0.)
809+
if(d__[i__] == 0.)
810+
{
811+
/* Avoid -ZERO */
812+
d__[i__] = 0.;
813+
}
814+
else if(d__[i__] < 0.)
810815
{
811816
d__[i__] = -d__[i__];
812817
/* Change sign of singular vectors, if desired */

src/lapack/x86/avx2/fla_dgesvd_nn_small10_avx2.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#if FLA_ENABLE_AMD_OPT
1313

14+
1415
extern void dlartg_(doublereal *da, doublereal *db, doublereal *c__, doublereal *s, doublereal *r);
1516
extern void dlasq1_(integer *, doublereal *, doublereal *, doublereal *, integer *);
1617

@@ -163,13 +164,23 @@ void fla_dgesvd_xx_small10_avx2(integer wntu, integer wntv, integer *m, integer
163164
u[1 + 2 * *ldu] = -(p3 + p2);
164165
u[2 + 2 * *ldu] = p0 - p1;
165166
}
167+
168+
/* Normalize singular values and scale corresponding vectors for 2x2 case */
169+
FLA_NORMALIZE_SINGULAR_VALUE_AND_VECTORS_2X2(1, wntu);
170+
FLA_NORMALIZE_SINGULAR_VALUE_AND_VECTORS_2X2(2, wntu);
166171
}
167172
else
168173
{
169174
if(ncvt == 0 && nru == 0)
170175
{
171176
/* Compute Singular Values excluding computation of Singular Vectors */
172177
dlasq1_(n, &s[1], &e[1], &work[itauq - 1], info);
178+
179+
/* Ensure singular values are positive */
180+
if(*info == 0)
181+
{
182+
FLA_ENSURE_POSITIVE_SINGULAR_VALUES(*n);
183+
}
173184
}
174185
else
175186
{

src/lapack/x86/avx2/fla_dgesvd_small6_avx2.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,23 @@ void fla_dgesvd_small6_avx2(integer wntus, integer wntvs, integer *m, integer *n
122122
{
123123
fla_drot_avx2(&nru, &u[1 + *ldu], &c__1, &u[1 + 2 * *ldu], &c__1, &cosl, &sinl);
124124
}
125+
126+
/* Normalize singular values and scale corresponding vectors for 2x2 case */
127+
FLA_NORMALIZE_SINGULAR_VALUE_AND_VECTORS_2X2(1, wntus);
128+
FLA_NORMALIZE_SINGULAR_VALUE_AND_VECTORS_2X2(2, wntus);
125129
}
126130
else
127131
{
128132
if(ncvt == 0 && nru == 0)
129133
{
130134
/* Compute Singular Values excluding computation of Singular Vectors */
131135
dlasq1_(n, &s[1], &e[1], &work[itau - 1], info);
136+
137+
/* Ensure singular values are positive */
138+
if(*info == 0)
139+
{
140+
FLA_ENSURE_POSITIVE_SINGULAR_VALUES(*n);
141+
}
132142
}
133143
else
134144
{

src/lapack/x86/avx2/fla_dgesvd_small_avx2.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,38 @@ doublereal d_sign(doublereal *, doublereal *);
7979
vt[1 + 2 * *ldvt] = scl1 * sr; \
8080
vt[2 + 2 * *ldvt] = scl2 * cr;
8181

82+
/* Macro to normalize singular value sign and
83+
scale corresponding singular vectors for 2x2 matrices */
84+
#define FLA_NORMALIZE_SINGULAR_VALUE_AND_VECTORS_2X2(idx, wntu_var) \
85+
if(s[idx] == 0.0) \
86+
{ \
87+
s[idx] = 0.0; /* Avoid -ZERO */ \
88+
} \
89+
else if(s[idx] < 0.0) \
90+
{ \
91+
s[idx] = -s[idx]; /* Make singular value positive */ \
92+
if(wntu_var && u != NULL) \
93+
{ \
94+
/* Negate corresponding left singular vector column */ \
95+
u[1 + (idx) * *ldu] = -u[1 + (idx) * *ldu]; \
96+
u[2 + (idx) * *ldu] = -u[2 + (idx) * *ldu]; \
97+
} \
98+
}
99+
100+
/* Macro to ensure all singular values are positive
101+
(values only, no vector adjustments) */
102+
#define FLA_ENSURE_POSITIVE_SINGULAR_VALUES(n_vals) \
103+
for(integer i__ = 1; i__ <= (n_vals); i__++) \
104+
{ \
105+
if(s[i__] == 0.0) \
106+
{ \
107+
s[i__] = 0.0; /* Avoid -ZERO */ \
108+
} \
109+
else if(s[i__] < 0.0) \
110+
{ \
111+
s[i__] = -s[i__]; /* Make positive */ \
112+
} \
113+
}
114+
82115
#endif /* FLA_ENABLE_AMD_OPT */
83116
#endif /* FLA_DGESVD_SMALL_AVX2_DEFS_H */

test/main/src/test_gesdd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ void fla_test_gesdd_experiment(char *tst_api, test_params_t *params, integer dat
227227
}
228228
create_realtype_vector(datatype, &s, fla_min(m, n));
229229
create_matrix(datatype, LAPACK_COL_MAJOR, m, n, &A_test, lda);
230-
create_realtype_vector(datatype, &s_in, fla_min(m, n));
231230
create_vector(get_realtype(datatype), &scal, 1);
232231

233232
if(!FLA_BRT_VERIFICATION_RUN)
@@ -238,6 +237,7 @@ void fla_test_gesdd_experiment(char *tst_api, test_params_t *params, integer dat
238237
}
239238
else
240239
{
240+
create_realtype_vector(datatype, &s_in, fla_min(m, n));
241241
/* Generate matrix A from known singular values */
242242
create_svd_matrix(datatype, 'A', m, n, A, lda, s_in, s_one, s_one, i_one, i_one, info);
243243
if(FLA_OVERFLOW_UNDERFLOW_TEST)

test/main/validate_src/test_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3037,7 +3037,7 @@ void print_matrix(char *desc, char *order, integer datatype, integer M, integer
30373037
integer i, j, row_max = M, col_max = N, ldc = lda, ldr = 1;
30383038

30393039
/* early return */
3040-
if(M <= 0 || N <= 0 || lda < M || A == NULL || desc == NULL || order == NULL)
3040+
if(M <= 0 || N <= 0 || lda <= 0 || A == NULL || desc == NULL || order == NULL)
30413041
{
30423042
return;
30433043
}

test/main/validate_src/test_overflow_underflow.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ void scale_matrix_overflow_underflow_hetrf(integer datatype, integer m, void *A,
653653
}
654654
else if(m < 200)
655655
{
656-
tuning_val = 37.0;
656+
tuning_val = 45.0;
657657
}
658658
else
659659
{
@@ -2526,6 +2526,10 @@ void scale_matrix_overflow_underflow_potri(integer datatype, integer n, void *A,
25262526
else if(same_char(imatrix_char, 'O'))
25272527
{
25282528
get_max_from_matrix(datatype, A, max_min, n, n, lda);
2529+
if (n < 100 && datatype == COMPLEX)
2530+
{
2531+
tuning_val = 2.0;
2532+
}
25292533
}
25302534
calculate_scale_value(datatype, scal, max_min, tuning_val, imatrix_char);
25312535

0 commit comments

Comments
 (0)