testing_zgemm.c 8.24 KB
Newer Older
1
/**
2 3
 *
 * @file testing_zgemm.c
4
 *
Mathieu Faverge's avatar
Mathieu Faverge committed
5 6
 * @copyright 2009-2014 The University of Tennessee and The University of
 *                      Tennessee Research Foundation. All rights reserved.
Mathieu Faverge's avatar
Mathieu Faverge committed
7
 * @copyright 2012-2018 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8
 *                      Univ. Bordeaux. All rights reserved.
9
 *
Mathieu Faverge's avatar
Mathieu Faverge committed
10
 ***
11
 *
Mathieu Faverge's avatar
Mathieu Faverge committed
12
 * @brief Chameleon zgemm testing
13
 *
Mathieu Faverge's avatar
Mathieu Faverge committed
14
 * @version 1.0.0
15
 * @comment This file has been automatically generated
Mathieu Faverge's avatar
Mathieu Faverge committed
16
 *          from Plasma 2.5.0 for CHAMELEON 1.0.0
17 18 19 20 21 22
 * @author Mathieu Faverge
 * @author Emmanuel Agullo
 * @author Cedric Castagnede
 * @date 2010-11-15
 * @precisions normal z -> c d s
 *
23
 */
24 25 26 27 28
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

Mathieu Faverge's avatar
Mathieu Faverge committed
29
#include <chameleon.h>
30 31 32
#include <coreblas/cblas.h>
#include <coreblas/lapacke.h>
#include <coreblas.h>
33
#include "testing_zauxiliary.h"
34
#if defined(CHAMELEON_USE_MPI)
35 36 37
#include <mpi.h>
#endif

Mathieu Faverge's avatar
Mathieu Faverge committed
38 39 40
static int check_solution(cham_trans_t transA, cham_trans_t transB, int M, int N, int K,
                          CHAMELEON_Complex64_t alpha, CHAMELEON_Complex64_t *A, int LDA,
                          CHAMELEON_Complex64_t *B, int LDB,
Mathieu Faverge's avatar
Mathieu Faverge committed
41
                          CHAMELEON_Complex64_t beta, CHAMELEON_Complex64_t *Cref, CHAMELEON_Complex64_t *Ccham, int LDC);
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

int testing_zgemm(int argc, char **argv)
{
    int hres = 0;
    /* Check for number of arguments*/
    if ( argc < 8) {
        USAGE("GEMM", "alpha beta M N K LDA LDB LDC",
              "   - alpha  : alpha coefficient\n"
              "   - beta   : beta coefficient\n"
              "   - M      : number of rows of matrices A and C\n"
              "   - N      : number of columns of matrices B and C\n"
              "   - K      : number of columns of matrix A / number of rows of matrix B\n"
              "   - LDA    : leading dimension of matrix A\n"
              "   - LDB    : leading dimension of matrix B\n"
              "   - LDC    : leading dimension of matrix C\n");
        return -1;
    }

Mathieu Faverge's avatar
Mathieu Faverge committed
60 61
    CHAMELEON_Complex64_t alpha = (CHAMELEON_Complex64_t) atol(argv[0]);
    CHAMELEON_Complex64_t beta = (CHAMELEON_Complex64_t) atol(argv[1]);
62 63 64 65 66 67 68 69 70 71 72 73 74 75
    int M     = atoi(argv[2]);
    int N     = atoi(argv[3]);
    int K     = atoi(argv[4]);
    int LDA   = atoi(argv[5]);
    int LDB   = atoi(argv[6]);
    int LDC   = atoi(argv[7]);

    double eps;
    int info_solution;
    int i, j, ta, tb;
    int LDAxK = LDA*max(M,K);
    int LDBxN = LDB*max(K,N);
    int LDCxN = LDC*N;

Mathieu Faverge's avatar
Mathieu Faverge committed
76 77 78 79 80
    CHAMELEON_Complex64_t *A      = (CHAMELEON_Complex64_t *)malloc(LDAxK*sizeof(CHAMELEON_Complex64_t));
    CHAMELEON_Complex64_t *B      = (CHAMELEON_Complex64_t *)malloc(LDBxN*sizeof(CHAMELEON_Complex64_t));
    CHAMELEON_Complex64_t *C      = (CHAMELEON_Complex64_t *)malloc(LDCxN*sizeof(CHAMELEON_Complex64_t));
    CHAMELEON_Complex64_t *Cinit  = (CHAMELEON_Complex64_t *)malloc(LDCxN*sizeof(CHAMELEON_Complex64_t));
    CHAMELEON_Complex64_t *Cfinal = (CHAMELEON_Complex64_t *)malloc(LDCxN*sizeof(CHAMELEON_Complex64_t));
81 82

    /* Check if unable to allocate memory */
Mathieu Faverge's avatar
Mathieu Faverge committed
83
    if ( (!A) || (!B) || (!C) || (!Cinit) || (!Cfinal) )
84
    {
Mathieu Faverge's avatar
Mathieu Faverge committed
85
        free(A); free(B); free(C);
86
        free(Cinit); free(Cfinal);
87 88 89 90 91 92
        printf("Out of Memory \n ");
        return -2;
    }

    eps = LAPACKE_dlamch_work('e');

Mathieu Faverge's avatar
Mathieu Faverge committed
93
    if (CHAMELEON_My_Mpi_Rank() == 0){
94
        printf("\n");
95
        printf("------ TESTS FOR CHAMELEON ZGEMM ROUTINE -------  \n");
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
        printf("            Size of the Matrix %d by %d\n", M, N);
        printf("\n");
        printf(" The matrix A is randomly generated for each test.\n");
        printf("============\n");
        printf(" The relative machine precision (eps) is to be %e \n",eps);
        printf(" Computational tests pass if scaled residuals are less than 10.\n");
    }

    /*----------------------------------------------------------
     *  TESTING ZGEMM
     */

    /* Initialize A, B, C */
    LAPACKE_zlarnv_work(IONE, ISEED, LDAxK, A);
    LAPACKE_zlarnv_work(IONE, ISEED, LDBxN, B);
    LAPACKE_zlarnv_work(IONE, ISEED, LDCxN, C);

113
#if defined(PRECISION_z) || defined(PRECISION_c)
114 115 116 117 118 119 120 121 122 123 124 125 126
    for (ta=0; ta<3; ta++) {
        for (tb=0; tb<3; tb++) {
#else
    for (ta=0; ta<2; ta++) {
        for (tb=0; tb<2; tb++) {
#endif
            for ( i = 0; i < M; i++)
                for (  j = 0; j < N; j++)
                    Cinit[LDC*j+i] = C[LDC*j+i];
            for ( i = 0; i < M; i++)
                for (  j = 0; j < N; j++)
                    Cfinal[LDC*j+i] = C[LDC*j+i];

Mathieu Faverge's avatar
Mathieu Faverge committed
127 128
            /* CHAMELEON ZGEMM */
            CHAMELEON_zgemm(trans[ta], trans[tb], M, N, K, alpha, A, LDA, B, LDB, beta, Cfinal, LDC);
129 130

            /* Check the solution */
PRUVOST Florent's avatar
PRUVOST Florent committed
131
            info_solution = check_solution(trans[ta], trans[tb], M, N, K,
132
                                           alpha, A, LDA, B, LDB, beta, Cinit, Cfinal, LDC);
Mathieu Faverge's avatar
Mathieu Faverge committed
133
            if (CHAMELEON_My_Mpi_Rank() == 0){
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
                if (info_solution == 0) {
                    printf("***************************************************\n");
                    printf(" ---- TESTING ZGEMM (%s, %s) ............... PASSED !\n", transstr[ta], transstr[tb]);
                    printf("***************************************************\n");
                }
                else {
                    printf("************************************************\n");
                    printf(" - TESTING ZGEMM (%s, %s) ... FAILED !\n", transstr[ta], transstr[tb]);    hres++;
                    printf("************************************************\n");
                }
            }
        }
    }
#ifdef _UNUSED_
    }}
#endif
    free(A); free(B); free(C);
    free(Cinit); free(Cfinal);

    return hres;
}

/*--------------------------------------------------------------
 * Check the solution
 */

Mathieu Faverge's avatar
Mathieu Faverge committed
160 161 162
static int check_solution(cham_trans_t transA, cham_trans_t transB, int M, int N, int K,
                          CHAMELEON_Complex64_t alpha, CHAMELEON_Complex64_t *A, int LDA,
                          CHAMELEON_Complex64_t *B, int LDB,
Mathieu Faverge's avatar
Mathieu Faverge committed
163
                          CHAMELEON_Complex64_t beta, CHAMELEON_Complex64_t *Cref, CHAMELEON_Complex64_t *Ccham, int LDC)
164 165
{
    int info_solution;
Mathieu Faverge's avatar
Mathieu Faverge committed
166
    double Anorm, Bnorm, Cinitnorm, Cchamnorm, Clapacknorm, Rnorm, result;
167
    double eps;
Mathieu Faverge's avatar
Mathieu Faverge committed
168
    CHAMELEON_Complex64_t beta_const;
169 170 171 172 173 174

    double *work = (double *)malloc(max(K,max(M, N))* sizeof(double));
    int Am, An, Bm, Bn;

    beta_const  = -1.0;

Mathieu Faverge's avatar
Mathieu Faverge committed
175
    if (transA == ChamNoTrans) {
176 177 178 179
        Am = M; An = K;
    } else {
        Am = K; An = M;
    }
Mathieu Faverge's avatar
Mathieu Faverge committed
180
    if (transB == ChamNoTrans) {
181 182 183 184 185
        Bm = K; Bn = N;
    } else {
        Bm = N; Bn = K;
    }

186 187 188
    Anorm       = LAPACKE_zlange_work(LAPACK_COL_MAJOR, 'I', Am, An, A,       LDA, work);
    Bnorm       = LAPACKE_zlange_work(LAPACK_COL_MAJOR, 'I', Bm, Bn, B,       LDB, work);
    Cinitnorm   = LAPACKE_zlange_work(LAPACK_COL_MAJOR, 'I', M,  N,  Cref,    LDC, work);
Mathieu Faverge's avatar
Mathieu Faverge committed
189
    Cchamnorm  = LAPACKE_zlange_work(LAPACK_COL_MAJOR, 'I', M,  N,  Ccham, LDC, work);
190 191 192 193

    cblas_zgemm(CblasColMajor, (CBLAS_TRANSPOSE)transA, (CBLAS_TRANSPOSE)transB, M, N, K, 
                CBLAS_SADDR(alpha), A, LDA, B, LDB, CBLAS_SADDR(beta), Cref, LDC);

194
    Clapacknorm = LAPACKE_zlange_work(LAPACK_COL_MAJOR, 'I', M, N, Cref, LDC, work);
195

Mathieu Faverge's avatar
Mathieu Faverge committed
196
    cblas_zaxpy(LDC * N, CBLAS_SADDR(beta_const), Ccham, 1, Cref, 1);
197

198
    Rnorm = LAPACKE_zlange_work(LAPACK_COL_MAJOR, 'I', M, N, Cref, LDC, work);
199 200

    eps = LAPACKE_dlamch_work('e');
Mathieu Faverge's avatar
Mathieu Faverge committed
201
    if (CHAMELEON_My_Mpi_Rank() == 0)
Mathieu Faverge's avatar
Mathieu Faverge committed
202 203
        printf("Rnorm %e, Anorm %e, Bnorm %e, Cinitnorm %e, Cchamnorm %e, Clapacknorm %e\n",
               Rnorm, Anorm, Bnorm, Cinitnorm, Cchamnorm, Clapacknorm);
204 205

    result = Rnorm / ((Anorm + Bnorm + Cinitnorm) * N * eps);
Mathieu Faverge's avatar
Mathieu Faverge committed
206
    if (CHAMELEON_My_Mpi_Rank() == 0){
207 208
        printf("============\n");
        printf("Checking the norm of the difference against reference ZGEMM \n");
Mathieu Faverge's avatar
Mathieu Faverge committed
209
        printf("-- ||Ccham - Clapack||_oo/((||A||_oo+||B||_oo+||C||_oo).N.eps) = %e \n",
210 211 212 213
               result);
    }

    if (  isnan(Rnorm) || isinf(Rnorm) || isnan(result) || isinf(result) || (result > 10.0) ) {
Mathieu Faverge's avatar
Mathieu Faverge committed
214
         if (CHAMELEON_My_Mpi_Rank() == 0)
215 216 217 218
             printf("-- The solution is suspicious ! \n");
         info_solution = 1;
    }
    else {
Mathieu Faverge's avatar
Mathieu Faverge committed
219 220
    	 //printf("CHAMELEON_My_Mpi_Rank() : %d\n",CHAMELEON_My_Mpi_Rank());
         if (CHAMELEON_My_Mpi_Rank() == 0)
221 222 223 224 225 226 227 228
             printf("-- The solution is CORRECT ! \n");
         info_solution= 0 ;
    }

    free(work);

    return info_solution;
}