Subversion Repositories slepc-dev

Rev

Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2522 eromero 1
/*
2
   Basic implementation of MatDense class
3
 
4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
6
   Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
7
 
8
   This file is part of SLEPc.
9
 
10
   SLEPc is free software: you can redistribute it and/or modify it under  the
11
   terms of version 3 of the GNU Lesser General Public License as published by
12
   the Free Software Foundation.
13
 
14
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
15
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
16
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
17
   more details.
18
 
19
   You  should have received a copy of the GNU Lesser General  Public  License
20
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
21
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22
*/
23
 
24
#include <private/matdenseimpl.h>            /*I "slepcmatdense.h" I*/
25
#include <slepcblaslapack.h>
26
 
27
typedef struct {
28
  PetscScalar *v;
2852 eromero 29
  PetscBool   user_allocated;
2544 eromero 30
  PetscInt    siblings;
2522 eromero 31
} MatDense_Basic;
32
 
2547 eromero 33
static PetscErrorCode  MatDenseCreateBasic_Private(MatDense A, MatDense_Basic *b,PetscScalar *data);
2544 eromero 34
 
2522 eromero 35
#undef __FUNCT__
2544 eromero 36
#define __FUNCT__ "MatDenseBlasMatMult_Basic"
2852 eromero 37
/*
38
A ------C  B ------C  ret C ---   Operations
39
ExplHermN  ExplHermN  ExplNormN   hemm L | hemm R
40
ExplHermN  ExplHermC  ""          hemm R
41
ExplHermN  ImplHermN  ""          hemm R
42
ExplHermN  ImplHermC  ""          hemm R
43
ExplHermN  ExplTriaN  ""          hemm L | trmm R
44
ExplHermN  ExplTriaC  ""          trmm R
45
ExplHermN  ImplTriaN  ""          trmm R
46
ExplHermN  ImplTriaC  ""          trmm R
47
ExplHermN  ExplNormN  ""          hemm L
48
ExplHermN  ExplNormC  ""          gemm
49
 
50
ExplHermC  ExplHermN  ""          hemm L
51
ExplHermC  ExplHermC  ""          gemm
52
ExplHermC  ImplHermN  ""          expl B, gemm
53
ExplHermC  ImplHermC  ""          expl B, gemm
54
ExplHermC  ExplTriaN  ""          hemm L
55
ExplHermC  ExplTriaC  ""          gemm
56
ExplHermC  ImplTriaN  ""          expl B, gemm
57
ExplHermC  ImplTriaC  ""          expl B, gemm
58
ExplHermC  ExplNormN  ""          hemm L
59
ExplHermC  ExplNormC  ""          gemm
60
 
61
ImplHermN  ExplHermN  ""          hemm L
62
ImplHermN  ExplHermC  ""          expl A, hemm R | expl A, gemm
63
ImplHermN  ImplHermN  ""          expl B, hemm L | expl AB, gemm
64
ImplHermN  ImplHermC  ""          expl A, hemm R | expl AB, gemm
65
ImplHermN  ExplTriaN  ""          hemm L
66
ImplHermN  ExplTriaC  ""          expl A, trmm R | expl A, gemm
67
ImplHermN  ImplTriaN  ""          expl B, hemm L | expl A, trmm R | expl AB, gemm
68
ImplHermN  ImplTriaC  ""          expl A, trmm R | expl AB, gemm
69
ImplHermN  ExplNormN  ""          hemm L
70
ImplHermN  ExplNormC  ""          expl A, gemm
71
 
72
ImplHermC  ExplHermN  ""          hemm L
73
ImplHermC  ExplHermC  ""          expl A, hemm R | expl A, gemm
74
ImplHermC  ImplHermN  ""          expl B, hemm L | expl AB, gemm
75
ImplHermC  ImplHermC  ""          expl AB, gemm
76
ImplHermC  ExplTriaN  ""          hemm L
77
ImplHermC  ExplTriaC  ""          expl A, gemm
78
ImplHermC  ImplTriaN  ""          expl B, hemm L | expl AB, gemm
79
ImplHermC  ImplTriaC  ""          expl AB, gemm
80
ImplHermC  ExplNormN  ""          hemm L
81
ImplHermC  ExplNormC  ""          expl A, gemm
82
 
83
ExplTriaN  ExplHermN  ""          hemm R | trmm L
84
ExplTriaN  ExplHermC  ""          hemm R
85
ExplTriaN  ImplHermN  ""          hemm R
86
ExplTriaN  ImplHermC  ""          hemm R
87
ExplTriaN  ExplTriaN  ""          trmm L | trmm R
88
ExplTriaN  ExplTriaC  ""          trmm R
89
ExplTriaN  ImplTriaN  ""          trmm R
90
ExplTriaN  ImplTriaC  ""          trmm R
91
ExplTriaN  ExplNormN  ""          trmm L
92
ExplTriaN  ExplNormC  ""          trmm R
93
 
94
ExplTriaC  ExplHermN  ""          trmm L
95
ExplTriaC  ExplHermC  ""          gemm
96
ExplTriaC  ImplHermN  ""          expl B, trmm L | expl B, gemm
97
ExplTriaC  ImplHermC  ""          expl B, gemm
98
ExplTriaC  ExplTriaN  ""          trmm L
99
ExplTriaC  ExplTriaC  ""          gemm
100
ExplTriaC  ImplTriaN  ""          trmm L
101
ExplTriaC  ImplTriaC  ""          expl B, gemm
102
ExplTriaC  ExplNormN  ""          trmm L
103
ExplTriaC  ExplNormC  ""          gemm
104
 
105
ImplTriaN  ExplHermN  ""          trmm L
106
ImplTriaN  ExplHermC  ""          expl A, hemm R | expl A, gemm
107
ImplTriaN  ImplHermN  ""          expl B, trmm L | expl A, hemm R | expl AB, gemm
108
ImplTriaN  ImplHermC  ""          expl A, hemm R | expl AB, gemm
109
ImplTriaN  ExplTriaN  ""          trmm L
110
ImplTriaN  ExplTriaC  ""          expl A, trmm R | expl A, gemm
111
ImplTriaN  ImplTriaN  ""          expl B, trmm L | expl AB, gemm
112
ImplTriaN  ImplTriaC  ""          expl A, trmm R | expl AB, gemm
113
ImplTriaN  ExplNormN  ""          trmm L
114
ImplTriaN  ExplNormC  ""          expl A, gemm
115
 
116
ImplTriaC  ExplHermN  ""          trmm L
117
ImplTriaC  ExplHermC  ""          expl A, gemm
118
ImplTriaC  ImplHermN  ""          expl A, hemm R | expl AB, gemm
119
ImplTriaC  ImplHermC  ""          expl AB, gemm
120
ImplTriaC  ExplTriaN  ""          trmm L
121
ImplTriaC  ExplTriaC  ""          expl A, gemm
122
ImplTriaC  ImplTriaN  ""          expl B, trmm L | expl AB, gemm
123
ImplTriaC  ImplTriaC  ""          expl AB, gemm
124
ImplTriaC  ExplNormN  ""          trmm L
125
ImplTriaC  ExplNormC  ""          expl A, gemm
126
 
127
ExplNormN  ExplHermN  ""          hemm R
128
ExplNormN  ExplHermC  ""          hemm R
129
ExplNormN  ImplHermN  ""          hemm R
130
ExplNormN  ImplHermC  ""          hemm R
131
ExplNormN  ExplTriaN  ""          trmm R
132
ExplNormN  ExplTriaC  ""          trmm R
133
ExplNormN  ImplTriaN  ""          trmm R
134
ExplNormN  ImplTriaC  ""          trmm R
135
ExplNormN  ExplNormN  ""          gemm
136
ExplNormN  ExplNormC  ""          gemm
137
 
138
ExplNormC  ExplHermN  ""          gemm
139
ExplNormC  ExplHermC  ""          gemm
140
ExplNormC  ImplHermN  ""          expl B, gemm
141
ExplNormC  ImplHermC  ""          expl B, gemm
142
ExplNormC  ExplTriaN  ""          gemm
143
ExplNormC  ExplTriaC  ""          gemm
144
ExplNormC  ImplTriaN  ""          expl B, gemm
145
ExplNormC  ImplTriaC  ""          expl B, gemm
146
ExplNormC  ExplNormN  ""          gemm
147
ExplNormC  ExplNormC  ""          gemm
148
*/
2544 eromero 149
PetscErrorCode  MatDenseBlasMatMult_Basic(MatDense C,PetscScalar alpha,PetscScalar beta,MatDense A,PetscBool At,MatDense B,PetscBool Bt)
2522 eromero 150
{
151
  PetscErrorCode ierr;
152
  PetscBLASInt   mA,nA,mB,nB,ldA,ldB,ldC;
2852 eromero 153
  PetscScalar    *vC_,*vC;
2544 eromero 154
  const PetscScalar
2852 eromero 155
                 *vA,*vA_,*vB,*vB_;
2522 eromero 156
  const char     *N = "N", *T = "C", *qA = N, *qB = N;
157
 
158
  PetscFunctionBegin;
2852 eromero 159
  ierr = MatDenseGetArrayRead(A,&vA_);CHKERRQ(ierr);
160
  ierr = MatDenseGetArrayRead(B,&vB_);CHKERRQ(ierr);
161
  ierr = MatDenseGetArray(C,&vC_);CHKERRQ(ierr);
162
  vA = &vA_[A->ld*A->n0+A->m0];
163
  vB = &vB_[B->ld*B->n0+B->m0];
164
  vC = &vC_[C->ld*C->n0+C->m0];
2522 eromero 165
 
166
  mA = At == PETSC_TRUE ? A->n : A->m;
167
  nA = At == PETSC_TRUE ? A->m : A->n;
168
  mB = Bt == PETSC_TRUE ? B->n : B->m;
169
  nB = Bt == PETSC_TRUE ? B->m : B->n;
170
  ldA = A->ld;
171
  ldB = B->ld;
172
  ldC = C->ld;
173
  qA = At == PETSC_TRUE ? T : N;
174
  qB = Bt == PETSC_TRUE ? T : N;
175
 
176
  if (mA == 1 && nA == 1 && nB == 1) {
177
    if (!At && !Bt)     *vC =           *vA  *           *vB;
178
    else if (At && !Bt) *vC = PetscConj(*vA) *           *vB;
179
    else if (!At && Bt) *vC =           *vA  * PetscConj(*vB);
180
    else if (At && Bt)  *vC = PetscConj(*vA) * PetscConj(*vB);
181
    ierr = PetscLogFlops(1);CHKERRQ(ierr);
2852 eromero 182
  /* A Hermitian, B !trans) */
183
  } else if (A->use_impl && A->is_hermitian && !Bt) {
184
    if (B->is_impl) { ierr = MatDenseSetExplicit(B);CHKERRQ(ierr); }
2544 eromero 185
    BLAShemm_("L","U",&mA,&nB,&alpha,(PetscScalar*)vA,&ldA,(PetscScalar*)vB,&ldB,&beta,vC,&ldC);
2522 eromero 186
    ierr = PetscLogFlops(mA*nB*nA);CHKERRQ(ierr);
2852 eromero 187
  /* A !trans, B Hermitian) */
188
  } else if (A->use_impl && !At && B->is_hermitian) {
189
    if (A->is_impl) { ierr = MatDenseSetExplicit(A);CHKERRQ(ierr); }
2544 eromero 190
    BLAShemm_("R","U",&mA,&nB,&alpha,(PetscScalar*)vB,&ldB,(PetscScalar*)vA,&ldA,&beta,vC,&ldC);
2522 eromero 191
    ierr = PetscLogFlops(mA*nB*nA);CHKERRQ(ierr);
2852 eromero 192
  /* A triangular, B !trans) */
193
  } else if (A->use_impl && A->is_triangular && !Bt) {
194
    if (B->is_impl) { ierr = MatDenseSetExplicit(B);CHKERRQ(ierr); }
2544 eromero 195
    BLAStrmm_("L","U",qA,"N",&mB,&nB,&alpha,(PetscScalar*)vA,&ldA,(PetscScalar*)vB,&ldB);
2522 eromero 196
    ierr = PetscLogFlops(mA*nB*nA);CHKERRQ(ierr);
2852 eromero 197
  /* A !trans, B triangular) */
198
  } else if (A->use_impl && !At && B->is_triangular) {
199
    if (A->is_impl) { ierr = MatDenseSetExplicit(A);CHKERRQ(ierr); }
2544 eromero 200
    BLAStrmm_("R","U",qB,"N",&mA,&nA,&alpha,(PetscScalar*)vB,&ldB,(PetscScalar*)vA,&ldA);
2522 eromero 201
    ierr = PetscLogFlops(mA*nB*nA);CHKERRQ(ierr);
2852 eromero 202
  /* otherwise */
2522 eromero 203
  } else {
2544 eromero 204
    if (A->is_impl) { ierr = MatDenseSetExplicit(A);CHKERRQ(ierr); }
205
    if (B->is_impl) { ierr = MatDenseSetExplicit(B);CHKERRQ(ierr); }
206
    BLASgemm_(qA,qB,&mA,&nB,&nA,&alpha,(PetscScalar*)vA,&ldA,(PetscScalar*)vB,&ldB,&beta,vC,&ldC);
207
    ierr = PetscLogFlops(mA*nB*2.0*nA);CHKERRQ(ierr);
2522 eromero 208
  }
209
  C->is_hermitian = C->is_triangular = C->is_impl = PETSC_FALSE;
210
 
2852 eromero 211
  ierr = MatDenseRestoreArray(C,&vC_);CHKERRQ(ierr);
212
  ierr = MatDenseRestoreArrayRead(B,&vB_);CHKERRQ(ierr);
213
  ierr = MatDenseRestoreArrayRead(A,&vA_);CHKERRQ(ierr);
2522 eromero 214
  PetscFunctionReturn(0);
215
}
216
 
217
#undef __FUNCT__  
218
#define __FUNCT__ "MatDenseBlasCopy_Basic"
219
PetscErrorCode  MatDenseBlasCopy_Basic(PetscInt n,MatDense A,PetscInt dA,PetscInt iA,MatDense B,PetscInt dB,PetscInt iB)
220
{
221
  PetscErrorCode ierr;
2852 eromero 222
  PetscScalar    *vB,*vB_;
2544 eromero 223
  const PetscScalar
2852 eromero 224
                 *vA,*vA_;
2522 eromero 225
  PetscBLASInt   n_=PetscBLASIntCast(n),incA=PetscBLASIntCast(iA),incB=PetscBLASIntCast(iB);
226
 
227
  PetscFunctionBegin;
2852 eromero 228
  ierr = MatDenseGetArrayRead(A,&vA_);CHKERRQ(ierr);
229
  ierr = MatDenseGetArray(B,&vB_);CHKERRQ(ierr);
230
  vA = &vA_[A->ld*A->n0+A->m0];
231
  vB = &vB_[B->ld*B->n0+B->m0];
2544 eromero 232
  BLAScopy_(&n_,(PetscScalar*)&vA[dA],&incA,&vB[dB],&incB);
2852 eromero 233
  ierr = MatDenseRestoreArray(B,&vB_);CHKERRQ(ierr);
234
  ierr = MatDenseRestoreArrayRead(A,&vA_);CHKERRQ(ierr);
2522 eromero 235
  PetscFunctionReturn(0);
236
}
237
 
238
#undef __FUNCT__  
239
#define __FUNCT__ "MatDenseBlasAXPY_Basic"
240
PetscErrorCode  MatDenseBlasAXPY_Basic(PetscInt n,PetscScalar a,MatDense X,PetscInt dX,PetscInt iX,MatDense Y,PetscInt dY,PetscInt iY)
241
{
242
  PetscErrorCode ierr;
2852 eromero 243
  PetscScalar    *vY,*vY_;
2544 eromero 244
  const PetscScalar
2852 eromero 245
                 *vX,*vX_;
2522 eromero 246
  PetscBLASInt   n_=PetscBLASIntCast(n),incX=PetscBLASIntCast(iX),incY=PetscBLASIntCast(iY);
247
 
248
  PetscFunctionBegin;
2852 eromero 249
  ierr = MatDenseGetArrayRead(X,&vX_);CHKERRQ(ierr);
250
  ierr = MatDenseGetArray(Y,&vY_);CHKERRQ(ierr);
251
  vX = &vX_[X->ld*X->n0+X->m0];
252
  vY = &vY_[Y->ld*Y->n0+Y->m0];
2544 eromero 253
  BLASaxpy_(&n_,&a,(PetscScalar*)&vX[dX],&incX,&vY[dY],&incY);
2852 eromero 254
  ierr = MatDenseRestoreArray(Y,&vY_);CHKERRQ(ierr);
255
  ierr = MatDenseRestoreArrayRead(X,&vX_);CHKERRQ(ierr);
2544 eromero 256
  ierr = PetscLogFlops(2*n);CHKERRQ(ierr);
2522 eromero 257
  PetscFunctionReturn(0);
258
}
259
 
260
#undef __FUNCT__  
261
#define __FUNCT__ "MatDenseSetExplicit_Basic"
262
PetscErrorCode  MatDenseSetExplicit_Basic(MatDense A)
263
{
264
  PetscErrorCode ierr;
2852 eromero 265
  PetscScalar    *vA,*vA_;
2522 eromero 266
  PetscInt       i;
267
  PetscBLASInt   n,incX,one=1;
268
 
269
  PetscFunctionBegin;
2852 eromero 270
  ierr = MatDenseGetArray(A,&vA_);CHKERRQ(ierr);
271
  vA = &vA_[A->ld*A->n0+A->m0];
2522 eromero 272
  if (MatDenseIsImplicitHermitian(A)) {
273
    for (i=0; i<A->n; i++) {
274
      n=A->n-i-1; incX=A->ld;
275
      BLAScopy_(&n,&vA[i],&incX,&vA[A->ld*i+i+1],&one);
276
    }
277
  } else if (MatDenseIsImplicitTriangular(A)) {
278
    for (i=0; i<A->n; i++) {
279
      ierr = PetscMemzero(&vA[A->ld*i+i+1],(A->n-i-1)*sizeof(PetscScalar));CHKERRQ(ierr);
280
    }
281
  }
282
  A->is_impl = PETSC_FALSE;
283
 
2852 eromero 284
  ierr = MatDenseRestoreArray(A,&vA_);CHKERRQ(ierr);
2522 eromero 285
  PetscFunctionReturn(0);
286
}
287
 
288
 
289
#undef __FUNCT__
290
#define __FUNCT__ "MatDenseDestroy_Basic"
2533 eromero 291
PetscErrorCode  MatDenseDestroy_Basic(MatDense A)
2522 eromero 292
{
293
  PetscErrorCode ierr;
2533 eromero 294
  MatDense_Basic *data = (MatDense_Basic*)A->data;
2522 eromero 295
 
296
  PetscFunctionBegin;
2547 eromero 297
  if (--data->siblings <= 0) {
298
    if (!data->user_allocated) { ierr = PetscFree(data->v);CHKERRQ(ierr); }
299
    ierr = PetscFree(data);CHKERRQ(ierr);
300
  }
2522 eromero 301
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatDenseBlasAXPY_*_*_C","",PETSC_NULL);CHKERRQ(ierr);
302
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatDenseBlasCopy_*_*_C","",PETSC_NULL);CHKERRQ(ierr);
303
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatDenseMatMatMult_*_*_C","",PETSC_NULL);CHKERRQ(ierr);
304
  PetscFunctionReturn(0);
305
}
306
 
307
#undef __FUNCT__  
308
#define __FUNCT__ "MatDenseGetArray_Basic"
309
PetscErrorCode  MatDenseGetArray_Basic(MatDense A,PetscScalar *v[])
310
{
311
  MatDense_Basic *data = (MatDense_Basic*)A->data;
312
 
313
  PetscFunctionBegin;
314
  *v = data->v;
315
  PetscFunctionReturn(0);
316
}
317
 
318
#undef __FUNCT__  
319
#define __FUNCT__ "MatDenseRestoreArray_Basic"
320
PetscErrorCode  MatDenseRestoreArray_Basic(MatDense A,PetscScalar *v[])
321
{
322
  PetscFunctionBegin;
323
  PetscFunctionReturn(0);
324
}
325
 
326
#undef __FUNCT__  
327
#define __FUNCT__ "MatDenseGetArrayRead_Basic"
2544 eromero 328
PetscErrorCode  MatDenseGetArrayRead_Basic(MatDense A,const PetscScalar *v[])
2522 eromero 329
{
330
  MatDense_Basic *data = (MatDense_Basic*)A->data;
331
 
332
  PetscFunctionBegin;
333
  *v = data->v;
334
  PetscFunctionReturn(0);
335
}
336
 
337
#undef __FUNCT__  
338
#define __FUNCT__ "MatDenseRestoreArrayRead_Basic"
2544 eromero 339
PetscErrorCode  MatDenseRestoreArrayRead_Basic(MatDense A,const PetscScalar *v[])
2522 eromero 340
{
341
  PetscFunctionBegin;
342
  PetscFunctionReturn(0);
343
}
344
 
345
 
346
#undef __FUNCT__  
347
#define __FUNCT__ "MatDenseDuplicate_Basic"
348
PetscErrorCode  MatDenseDuplicate_Basic(MatDense A,MatDenseDuplicateOption op,MatDense *M)
349
{
350
  MatDense_Basic *data = (MatDense_Basic*)A->data;
351
  PetscErrorCode ierr;
352
 
353
  PetscFunctionBegin;
354
  ierr = MatDenseCreate(((PetscObject)A)->comm,M);CHKERRQ(ierr);
355
  ierr = MatDenseSetMaxSizes(*M,A->m,A->n);CHKERRQ(ierr);
356
  ierr = MatDenseSetSizes(*M,0,0,A->m,A->n);CHKERRQ(ierr);
2547 eromero 357
  ierr = MatDenseCreateBasic_Private(*M,op == MATDENSE_MAKE_SIBLING ? data : PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2544 eromero 358
  if (op == MATDENSE_COPY_VALUES) {
359
    ierr = MatDenseSetUpPreallocation(*M);CHKERRQ(ierr);
360
    ierr = MatDenseCopy(A,*M);CHKERRQ(ierr);
361
  }
2522 eromero 362
  PetscFunctionReturn(0);
363
}
364
 
365
 
366
#undef __FUNCT__  
367
#define __FUNCT__ "MatDenseSetFromOptions_Basic"
368
PetscErrorCode  MatDenseSetFromOptions_Basic(MatDense A)
369
{
370
  PetscFunctionBegin;
371
  PetscFunctionReturn(0);
372
}
373
 
374
 
375
#undef __FUNCT__  
376
#define __FUNCT__ "MatDenseSetUpPreallocation_Basic"
377
PetscErrorCode  MatDenseSetUpPreallocation_Basic(MatDense B)
378
{
379
  PetscErrorCode ierr;
380
  MatDense_Basic *data = (MatDense_Basic*)B->data;
381
 
382
  PetscFunctionBegin;
2547 eromero 383
  if (data->v) PetscFunctionReturn(0);
2522 eromero 384
  ierr = PetscMalloc(B->ld*B->Nmax*sizeof(PetscScalar),&data->v);CHKERRQ(ierr);
385
  ierr = PetscLogObjectMemory(B,B->ld*B->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
386
  PetscFunctionReturn(0);
387
}
388
 
2852 eromero 389
#undef __FUNCT__  
390
#define __FUNCT__ "MatDenseSerialize_Basic"
391
PetscErrorCode  MatDenseSerialize_Basic(MatDense A,PetscInt *length,PetscScalar *array)
392
{
393
  PetscErrorCode ierr;
394
  const PetscScalar *vA,*vA_;
395
  PetscInt       i;
396
  PetscBLASInt   n,one=1;
397
 
398
  PetscFunctionBegin;
399
  ierr = MatDenseGetArrayRead(A,&vA_);CHKERRQ(ierr);
400
  vA = &vA_[A->ld*A->n0+A->m0];
401
  if (A->use_impl && A->m == A->n && (A->is_hermitian || A->is_triangular)) {
402
    if (length) *length = A->n*(A->n+1)/2;
403
    if (array) {
404
      for (i=0; i<A->n; i++) {
405
        n = i+1;
406
        BLAScopy_(&n,&vA[A->ld*i],&one,array,&one);
407
        array+= i+1;
408
      }
409
    }
410
  } else {
411
    if (length) *length = A->n*A->m;
412
    if (array) {
413
      n = PetscBLASIntCast(A->m);
414
      for (i=0; i<A->n; i++) {
415
        BLAScopy_(&n,&vA[A->ld*i],&one,array,&one);
416
        array+= A->m;
417
      }
418
    }
419
  }
420
  ierr = MatDenseRestoreArrayRead(A,&vA_);CHKERRQ(ierr);
421
  PetscFunctionReturn(0);
422
}
423
 
424
#undef __FUNCT__  
425
#define __FUNCT__ "MatDenseDeserialize_Basic"
426
PetscErrorCode  MatDenseDeserialize_Basic(MatDense A,PetscInt length,PetscScalar *array)
427
{
428
  PetscErrorCode ierr;
429
  PetscScalar *vA,*vA_;
430
  PetscInt       i;
431
  PetscBLASInt   n,one=1;
432
 
433
  PetscFunctionBegin;
434
  ierr = MatDenseGetArray(A,&vA_);CHKERRQ(ierr);
435
  vA = &vA_[A->ld*A->n0+A->m0];
436
  if (A->use_impl && A->m == A->n && (A->is_hermitian || A->is_triangular)) {
437
    if (length >= 0 && length != A->n*(A->n+1)/2) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Invalid array length to deseralize, that has to be %D!",A->n*(A->n+1)/2);
438
    for (i=0; i<A->n; i++) {
439
      n = i+1;
440
      BLAScopy_(&n,array,&one,&vA[A->ld*i],&one);
441
      array+= i+1;
442
    }
443
  } else {
444
    if (length >= 0 && length != A->n*A->m) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Invalid array length to deseralize, that has to be %D!",A->n*A->m);
445
    n = PetscBLASIntCast(A->m);
446
    for (i=0; i<A->n; i++) {
447
      BLAScopy_(&n,array,&one,&vA[A->ld*i],&one);
448
      array+= A->m;
449
    }
450
  }
451
  ierr = MatDenseRestoreArray(A,&vA_);CHKERRQ(ierr);
452
  PetscFunctionReturn(0);
453
}
454
 
2522 eromero 455
static struct _MatDenseOps MatDenseOps_Basic = {
456
  /* 0*/
457
       MatDenseGetArray_Basic,
458
       MatDenseRestoreArray_Basic,
459
       MatDenseGetArrayRead_Basic,
460
       MatDenseRestoreArrayRead_Basic,
461
       MatDenseDuplicate_Basic,
462
  /* 5 */
463
       0/*MatDenseAXPY_Basic*/,
464
       0/*MatDenseCopy_Basic*/,
465
       MatDenseSetExplicit_Basic,
466
       MatDenseBlasAXPY_Basic,
467
       MatDenseBlasCopy_Basic,
468
  /* 10 */
469
       MatDenseDestroy_Basic,
470
       0/*MatDenseView_Basic*/,
471
       MatDenseSetFromOptions_Basic,
2544 eromero 472
       0/*MatDenseMatMult_Basic*/,
473
       MatDenseBlasMatMult_Basic,
474
  /* 15 */
2522 eromero 475
       0/*MatDenseSetSizes_Basic*/,
476
       MatDenseSetUpPreallocation_Basic,
2544 eromero 477
       0/*MatDenseAreSiblings_Basic*/,
2852 eromero 478
       MatDenseSerialize_Basic,
479
       MatDenseDeserialize_Basic,
2522 eromero 480
 
481
};
482
 
2544 eromero 483
#undef __FUNCT__  
484
#define __FUNCT__ "MatDenseCreateBasic_Private"
2547 eromero 485
static PetscErrorCode  MatDenseCreateBasic_Private(MatDense A, MatDense_Basic *b, PetscScalar *v)
2544 eromero 486
{
487
  PetscErrorCode ierr;
488
 
489
  PetscFunctionBegin;
490
  if (b) { b->siblings++; }
491
  else {
492
    ierr = PetscNewLog(A,MatDense_Basic,&b);CHKERRQ(ierr);
2547 eromero 493
    b->v = v;
494
    b->user_allocated = v?PETSC_TRUE:PETSC_FALSE;
2544 eromero 495
    b->siblings = 1;
496
  }
497
  A->data = (void*)b;
498
  ierr = PetscMemcpy(A->ops,&MatDenseOps_Basic,sizeof(struct _MatDenseOps));CHKERRQ(ierr);
499
 
500
  ierr = PetscObjectChangeTypeName((PetscObject)A,MATDENSEBASIC);CHKERRQ(ierr);
2547 eromero 501
  A->is_allocated = b->v?PETSC_TRUE:PETSC_FALSE;
2544 eromero 502
 
503
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatDenseBlasAXPY_*_*_C","MatDenseBlasAXPY_Basic",MatDenseBlasAXPY_Basic);CHKERRQ(ierr);
504
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatDenseBlasCopy_*_*_C","MatDenseBlasCopy_Basic",MatDenseBlasCopy_Basic);CHKERRQ(ierr);
505
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatDenseBlasMatMult_*_*_C","MatDenseMatMult_Basic",MatDenseBlasMatMult_Basic);CHKERRQ(ierr);
506
 
507
  PetscFunctionReturn(0);
508
}
509
 
2522 eromero 510
/*MC
511
   MATDENSEBASIC - A basic implementation of dense matrix using standard BLAS
512
                   and LAPACK functions.
513
 
514
  Level: advanced
515
 
516
.seealso: MatDenseCreateBasic()
517
 
518
M*/
519
 
520
EXTERN_C_BEGIN
521
#undef __FUNCT__  
522
#define __FUNCT__ "MatDenseCreate_Basic"
523
PetscErrorCode  MatDenseCreate_Basic(MatDense A)
524
{
525
  PetscErrorCode ierr;
526
 
527
  PetscFunctionBegin;
2547 eromero 528
  ierr = MatDenseCreateBasic_Private(A,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2522 eromero 529
  PetscFunctionReturn(0);
530
}
531
EXTERN_C_END
532
 
533
#undef __FUNCT__  
534
#define __FUNCT__ "MatDenseCreateBasic"
535
/*@C
536
   MatDenseCreateBasic - Creates a new dense matrix that uses standard BLAS
537
                         and LAPACK functions.
538
 
539
  Collective on MPI_Comm
540
 
541
   Input Parameters:
542
+  comm - MPI communicator
543
.  M - maximum number of rows
544
.  N - maximum number of columns
545
.  m - current number of rows
2547 eromero 546
.  n - current number of columns
547
-  data - optional location of the matrix data. Set to PETSC_NULL for PETSc
548
   to control its memory allocation.
2522 eromero 549
 
550
   Output Parameter:
551
.  A - the matrix
552
 
553
   Level: advanced
554
 
555
.keywords: matrix, mat, create
556
 
557
.seealso: MATDENSEBASIC
558
@*/
2547 eromero 559
PetscErrorCode  MatDenseCreateBasic(MPI_Comm comm,PetscInt M,PetscInt N,PetscInt m,PetscInt n,PetscScalar *data,MatDense *A)
2522 eromero 560
{
561
  PetscErrorCode ierr;
562
 
563
  PetscFunctionBegin;
564
  ierr = MatDenseCreate(comm,A);CHKERRQ(ierr);
565
  ierr = MatDenseSetMaxSizes(*A,M,N);CHKERRQ(ierr);
2547 eromero 566
  ierr = MatDenseCreateBasic_Private(*A,PETSC_NULL,data);CHKERRQ(ierr);
2522 eromero 567
  ierr = MatDenseSetSizes(*A,0,0,m,n);CHKERRQ(ierr);
568
  ierr = MatDenseSetUpPreallocation(*A);CHKERRQ(ierr);
569
  PetscFunctionReturn(0);
570
}
571