001: /* ///////////////////////////// P /// L /// A /// S /// M /// A /////////////////////////////// */
002: /* ///                    PLASMA auxiliary routines (version 2.1.0)                          ///
003:  * ///                    Author: Jakub Kurzak, Piotr Luszczek, Emmanuel Agullo              ///
004:  * ///                    Release Date: November, 15th 2009                                  ///
005:  * ///                    PLASMA is a software package provided by Univ. of Tennessee,       ///
006:  * ///                    Univ. of California Berkeley and Univ. of Colorado Denver          /// */
007: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
008: #include "common.h"
009: #include "auxiliary.h"
010: 
011: #include <stdio.h>
012: #include <stdlib.h>
013: 
014: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
015: //  User's erroneous action without severe consequences.
016: //  Problems occuring while PLASMA is being used correctly.
017: //  Indicates a recoverable problem.
018: //  Context aware.
019: void plasma_warning(char *func_name, char* msg_text)
020: {
021:     plasma_context_t *plasma;
022: 
023:     plasma = plasma_context_self();
024:     if (plasma == NULL)
025:         plasma_fatal_error("plasma_warning", "PLASMA not initialized");
026:     if (plasma->warnings_enabled)
027:         fprintf(stderr, "PLASMA WARNING: %s(): %s\n", func_name, msg_text);
028: }
029: 
030: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
031: //  User's erroneous action with potentially severe consequences.
032: //  Problems occuring due to incorrect use of PLASMA.
033: //  Indicates a recoverable problem.
034: //  Context aware.
035: void plasma_error(char *func_name, char* msg_text)
036: {
037:     plasma_context_t *plasma;
038: 
039:     plasma = plasma_context_self();
040:     if (plasma == NULL)
041:         plasma_fatal_error("plasma_error", "PLASMA not initialized");
042:     if (plasma->errors_enabled)
043:         fprintf(stderr, "PLASMA ERROR: %s(): %s\n", func_name, msg_text);
044: }
045: 
046: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
047: //  Unexpected behavior within the library.
048: //  Unrecoverable user errors.
049: //  Context oblivious.
050: void plasma_fatal_error(char *func_name, char* msg_text)
051: {
052:     fprintf(stderr, "PLASMA FATAL ERROR: %s(): %s\n", func_name, msg_text);
053:     exit(0);
054: }
055: 
056: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
057: int plasma_element_size(int type)
058: {
059:     switch(type) {
060:         case PlasmaByte:          return          1;
061:         case PlasmaInteger:       return   sizeof(int);
062:         case PlasmaRealFloat:     return   sizeof(float);
063:         case PlasmaRealDouble:    return   sizeof(double);
064:         case PlasmaComplexFloat:  return 2*sizeof(float);
065:         case PlasmaComplexDouble: return 2*sizeof(double);
066:         default: plasma_fatal_error("plasma_element_size", "undefined type");
067:                  return PLASMA_ERR_ILLEGAL_VALUE;
068: 
069:     }
070: }
071: 
072: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
073: void plasma_memcpy(void *dst, void *src, PLASMA_size size, int type)
074: {
075:     memcpy(dst, src, size*plasma_element_size(type));
076: }
077: 
078: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
079: void plasma_memzero(void *memptr, PLASMA_size size, int type)
080: {
081:     memset(memptr, 0, size*plasma_element_size(type));
082: }
083: 
084: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
085: void plasma_memset_int(int *mem, int size, int value)
086: {
087:     int i;
088: 
089:     for (i = 0; i < size; i++)
090:         mem[i] = value;
091: }
092: 
093: //* ///////////////////////////////////////////////////////////////////////////////////////////// */
094: //  Returns core id
095: int plasma_rank(plasma_context_t *plasma)
096: {
097:     int rank;
098:     pthread_t thread_id;
099: 
100:     thread_id = pthread_self();
101:     for (rank = 0; rank < plasma->world_size; rank++)
102:         if (pthread_equal(plasma->thread_id[rank], thread_id))
103:             return rank;
104:     return PLASMA_ERR_NOT_FOUND;
105: }
106: 
107: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
108: //  Tune block size nb and internal block size ib
109: int plasma_tune(PLASMA_enum func, int M, int N, int NRHS)
110: {
111:     plasma_context_t *plasma;
112: 
113:     plasma = plasma_context_self();
114:     if (plasma == NULL) {
115:         plasma_fatal_error("plasma_tune", "PLASMA not initialized");
116:         return PLASMA_ERR_NOT_INITIALIZED;
117:     }
118: 
119:     if (!plasma->autotuning_enabled)
120:         return PLASMA_SUCCESS;
121: 
122:     switch (func) {
123:         case PLASMA_FUNC_SGEMM:
124:         case PLASMA_FUNC_DGEMM:
125:         case PLASMA_FUNC_CGEMM:
126:         case PLASMA_FUNC_ZGEMM:
127:             plasma->nb = 120;
128:             plasma->ib = 120;  // not used in GEMM
129:             break;
130:         case PLASMA_FUNC_SPOSV:
131:         case PLASMA_FUNC_DPOSV:
132:         case PLASMA_FUNC_CPOSV:
133:         case PLASMA_FUNC_ZPOSV:
134:             plasma->nb = 120;
135:             plasma->ib = 120;  // not used in Cholesky
136:             break;
137:         case PLASMA_FUNC_SGELS:
138:         case PLASMA_FUNC_DGELS:
139:         case PLASMA_FUNC_CGELS:
140:         case PLASMA_FUNC_ZGELS:
141:             plasma->nb = 144;
142:             plasma->ib =  48;
143:             break;
144:         case PLASMA_FUNC_SGESV:
145:         case PLASMA_FUNC_DGESV:
146:         case PLASMA_FUNC_CGESV:
147:         case PLASMA_FUNC_ZGESV:
148:         case PLASMA_TUNE_ZCGESV:
149:         case PLASMA_TUNE_DSGESV:
150:             plasma->nb = 200;
151:             plasma->ib =  40;
152:             break;
153:         default:
154:             plasma_fatal_error("plasma_tune", "illegal parameter value");
155:             return PLASMA_ERR_ILLEGAL_VALUE;
156:     }
157:     /* Calculate A, B tile size and round up to cache line size */
158:     /* round up for the smallest type (float) - will hold for all */
159:     plasma->nbnbsize = plasma->nb * plasma->nb; // * sizeof(float);
160: //  plasma->nbnbsize = roundup(plasma->nbnbsize, CACHE_LINE_SIZE);
161: //  plasma->nbnbsize /= sizeof(float);
162:     /* Calculate T, L tile size and round up to cache line size */
163:     /* round up for the smallest type (float) - will hold for all */
164:     plasma->ibnbsize = plasma->ib * plasma->nb; // * sizeof(float);
165: //  plasma->ibnbsize = roundup(plasma->ibnbsize, CACHE_LINE_SIZE);
166: //  plasma->ibnbsize /= sizeof(float);
167:     return PLASMA_SUCCESS;
168: }
169: 
170: /* /////////////////////////// P /// U /// R /// P /// O /// S /// E /////////////////////////// */
171: // PLASMA_Version - Reports PLASMA version number.
172: 
173: /* ///////////////////// A /// R /// G /// U /// M /// E /// N /// T /// S ///////////////////// */
174: // ver_major    int (OUT)
175: //              PLASMA major version number.
176: //
177: // ver_minor    int (OUT)
178: //              PLASMA minor version number.
179: //
180: // ver_micro    int (OUT)
181: //              PLASMA micro version number.
182: 
183: /* ///////////// R /// E /// T /// U /// R /// N /////// V /// A /// L /// U /// E ///////////// */
184: //          = PLASMA_SUCCESS: successful exit
185: 
186: /* //////////////////////////////////// C /// O /// D /// E //////////////////////////////////// */
187: int PLASMA_Version(int *ver_major, int *ver_minor, int *ver_micro)
188: {
189:     if (! ver_major && ! ver_minor && ! ver_micro)
190:         return  PLASMA_ERR_ILLEGAL_VALUE;
191: 
192:     if (ver_major)
193:         *ver_major = PLASMA_VERSION_MAJOR;
194: 
195:     if (ver_minor)
196:         *ver_minor = PLASMA_VERSION_MINOR;
197: 
198:     if (ver_micro)
199:         *ver_micro = PLASMA_VERSION_MICRO;
200: 
201:     return PLASMA_SUCCESS;
202: }
203: