001: /* ///////////////////////////// P /// L /// A /// S /// M /// A /////////////////////////////// */
002: /* ///                    PLASMA auxiliary routines (version 2.1.0)                          ///
003:  * ///                    Author: Jakub Kurzak                                               ///
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: #include "descriptor.h"
011: 
012: #include <stdlib.h>
013: 
014: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
015: //  Internal static descriptor initializer
016: PLASMA_desc plasma_desc_init(void *mat, PLASMA_enum dtyp, int mb, int nb, int bsiz, int lm, int ln,
017:                              int i, int j, int m, int n)
018: {
019:     PLASMA_desc desc;
020: 
021:     // Matrix address
022:     desc.mat = mat;
023:     // Matrix properties
024:     desc.dtyp = dtyp;
025:     desc.mb = mb;
026:     desc.nb = nb;
027:     desc.bsiz = bsiz;
028:     // Large matrix parameters
029:     desc.lm = lm;
030:     desc.ln = ln;
031:     // Large matrix derived parameters
032:     desc.lmt = (lm%nb==0) ? (lm/nb) : (lm/nb+1);
033:     desc.lnt = (ln%nb==0) ? (ln/nb) : (ln/nb+1);
034:     // Submatrix parameters
035:     desc.i = i;
036:     desc.j = j;
037:     desc.m = m;
038:     desc.n = n;
039:     // Submatrix derived parameters
040:     desc.mt = (i+m-1)/nb - i/nb + 1;
041:     desc.nt = (j+n-1)/nb - j/nb + 1;
042:     return desc;
043: }
044: 
045: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
046: //  Internal static descriptor initializer for submatrices
047: PLASMA_desc plasma_desc_submatrix(PLASMA_desc descA, int i, int j, int m, int n)
048: {
049:     PLASMA_desc descB;
050:     int nb;
051: 
052:     descB = descA;
053:     nb = descA.nb;
054:     // Submatrix parameters
055:     descB.i = i;
056:     descB.j = j;
057:     descB.m = m;
058:     descB.n = n;
059:     // Submatrix derived parameters
060:     descB.mt = (i+m-1)/nb - i/nb + 1;
061:     descB.nt = (j+n-1)/nb - j/nb + 1;
062:     return descB;
063: }
064: 
065: /* ///////////////////////////////////////////////////////////////////////////////////////////// */
066: //  Check for descriptor correctness
067: int plasma_desc_check(PLASMA_desc *desc)
068: {
069:     if (desc->mat == NULL) {
070:         plasma_error("plasma_desc_check", "NULL matrix pointer");
071:         return PLASMA_ERR_UNALLOCATED;
072:     }
073:     if (desc->dtyp != PlasmaRealFloat &&
074:         desc->dtyp != PlasmaRealDouble &&
075:         desc->dtyp != PlasmaComplexFloat &&
076:         desc->dtyp != PlasmaComplexDouble  ) {
077:         plasma_error("plasma_desc_check", "invalid matrix type");
078:         return PLASMA_ERR_ILLEGAL_VALUE;
079:     }
080:     if (desc->mb <= 0 || desc->nb <= 0) {
081:         plasma_error("plasma_desc_check", "negative tile dimension");
082:         return PLASMA_ERR_ILLEGAL_VALUE;
083:     }
084:     if (desc->bsiz < desc->mb*desc->nb) {
085:         plasma_error("plasma_desc_check", "tile memory size smaller than the product of dimensions");
086:         return PLASMA_ERR_ILLEGAL_VALUE;
087:     }
088:     if (desc->lm <= 0 || desc->ln <= 0) {
089:         plasma_error("plasma_desc_check", "negative matrix dimension");
090:         return PLASMA_ERR_ILLEGAL_VALUE;
091:     }
092:     if (desc->i >= desc->lm || desc->j >= desc->ln) {
093:         plasma_error("plasma_desc_check", "beginning of the matrix out of scope");
094:         return PLASMA_ERR_ILLEGAL_VALUE;
095:     }
096:     if (desc->i+desc->m > desc->lm || desc->j+desc->n > desc->ln) {
097:         plasma_error("plasma_desc_check", "submatrix out of scope");
098:         return PLASMA_ERR_ILLEGAL_VALUE;
099:     }
100:     return PLASMA_SUCCESS;
101: }
102: 
103: /* /////////////////////////// P /// U /// R /// P /// O /// S /// E /////////////////////////// */
104: // PLASMA_Desc_Create - Create matrix descriptor.
105: 
106: /* ///////////////////// A /// R /// G /// U /// M /// E /// N /// T /// S ///////////////////// */
107: // desc     PLASMA_desc** (OUT)
108: //          On exit, descriptor of the matrix.
109: //
110: // mat      void* (IN)
111: //          Memory location of the matrix.
112: //
113: // dtyp     PLASMA_enum (IN)
114: //          Data type of the matrix:
115: //          = PlasmaRealFloat:     single precision real (S),
116: //          = PlasmaRealDouble:    double precision real (D),
117: //          = PlasmaComplexFloat:  single precision complex (C),
118: //          = PlasmaComplexDouble: double precision complex (Z).
119: //
120: // mb       int (IN)
121: //          Number of rows in a tile.
122: //
123: // nb       int (IN)
124: //          Number of columns in a tile.
125: //
126: // bsiz     int (IN)
127: //          Nize in elements including padding.
128: //
129: // lm       int (IN)
130: //          Number of rows of the entire matrix.
131: //
132: // ln       int (IN)
133: //          Number of columns of the entire matrix.
134: //
135: // i        int (IN)
136: //          Row index to the beginning of the submatrix.
137: //
138: // j        int (IN)
139: //          Column indes to the beginning of the submatrix.
140: //
141: // m        int (IN)
142: //          Number of rows of the submatrix.
143: //
144: // n        int (IN)
145: //          Number of columns of the submatrix.
146: 
147: /* ///////////// R /// E /// T /// U /// R /// N /////// V /// A /// L /// U /// E ///////////// */
148: //          = PLASMA_SUCCESS: successful exit
149: 
150: /* //////////////////////////////////// C /// O /// D /// E //////////////////////////////////// */
151: int PLASMA_Desc_Create(PLASMA_desc **desc, void *mat, PLASMA_enum dtyp, int mb, int nb, int bsiz,
152:                        int lm, int ln, int i, int j, int m, int n)
153: {
154:     plasma_context_t *plasma;
155:     int status;
156: 
157:     plasma = plasma_context_self();
158:     if (plasma == NULL) {
159:         plasma_error("PLASMA_Desc_Create", "PLASMA not initialized");
160:         return PLASMA_ERR_NOT_INITIALIZED;
161:     }
162:     /* Allocate memory and initialize the descriptor */
163:     *desc = (PLASMA_desc*)malloc(sizeof(PLASMA_desc));
164:     if (*desc == NULL) {
165:         plasma_error("PLASMA_Desc_Create", "malloc() failed");
166:         return PLASMA_ERR_OUT_OF_RESOURCES;
167:     }
168:     **desc = plasma_desc_init(mat, dtyp, mb, nb, bsiz, lm, ln, i, j, m, n);
169:     status = plasma_desc_check(*desc);
170:     if (status != PLASMA_SUCCESS) {
171:         plasma_error("PLASMA_Desc_Create", "invalid descriptor");
172:         return status;
173:     }
174:     return PLASMA_SUCCESS;
175: }
176: 
177: /* /////////////////////////// P /// U /// R /// P /// O /// S /// E /////////////////////////// */
178: // PLASMA_Desc_Destroy - Destroys matrix descriptor.
179: 
180: /* ///////////////////// A /// R /// G /// U /// M /// E /// N /// T /// S ///////////////////// */
181: // desc     PLASMA_desc** (IN)
182: //          Matrix descriptor.
183: 
184: /* ///////////// R /// E /// T /// U /// R /// N /////// V /// A /// L /// U /// E ///////////// */
185: //          = PLASMA_SUCCESS: successful exit
186: 
187: /* //////////////////////////////////// C /// O /// D /// E //////////////////////////////////// */
188: int PLASMA_Desc_Destroy(PLASMA_desc **desc)
189: {
190:     plasma_context_t *plasma;
191: 
192:     plasma = plasma_context_self();
193:     if (plasma == NULL) {
194:         plasma_error("PLASMA_Desc_Destroy", "PLASMA not initialized");
195:         return PLASMA_ERR_NOT_INITIALIZED;
196:     }
197:     if (*desc == NULL) {
198:         plasma_error("PLASMA_Desc_Destroy", "attempting to destroy a NULL descriptor");
199:         return PLASMA_ERR_UNALLOCATED;
200:     }
201:     free(*desc);
202:     *desc = NULL;
203:     return PLASMA_SUCCESS;
204: }
205: