Changeset 2574 in Sophya for trunk/SophyaLib/TArray
- Timestamp:
- Jul 29, 2004, 10:40:49 AM (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/TArray/tmatrix.cc
r2421 r2574 1 // $Id: tmatrix.cc,v 1.2 4 2003-08-08 13:07:06 ansariExp $1 // $Id: tmatrix.cc,v 1.25 2004-07-29 08:40:49 cmv Exp $ 2 2 // C.Magneville 04/99 3 3 #include "machdefs.h" … … 6 6 #include "pexceptions.h" 7 7 #include "tmatrix.h" 8 9 //#define DO_NOT_OPTIMIZE_PRODUCT 8 10 9 11 /*! … … 411 413 \param mm : define the memory mapping type for the return matrix 412 414 */ 415 ////////////// Routine de base sans optimisation ////////////// 416 /* 413 417 template <class T> 414 418 TMatrix<T> TMatrix<T>::Multiply(const TMatrix<T>& b, short mm) const … … 437 441 return rm; 438 442 } 443 */ 444 445 ////////////// Routine optimisee ////////////// 446 template <class T> 447 TMatrix<T> TMatrix<T>::Multiply(const TMatrix<T>& b, short mm) const 448 { 449 if (NCols() != b.NRows()) 450 throw(SzMismatchError("TMatrix<T>::Multiply(b) NCols() != b.NRows() ") ); 451 452 // Commentaire: pas de difference de vitesse notable selon les mappings choisis pour la matrice produit "rm" 453 if (mm == SameMemoryMapping) mm = GetMemoryMapping(); 454 TMatrix<T> rm(NRows(), b.NCols(), mm); 455 rm = (T) 0; // Rien ne garantit que rm soit mise a zero a la creation ! 456 457 // Les "steps" pour l'adressage des colonnes de A et des lignes de B 458 sa_size_t stepa = Step(ColsKA()); 459 sa_size_t stepb = b.Step(b.RowsKA()); 460 461 // On decide si on optimise ou non selon les dimensions de A et B 462 // (il semble que optimiser ou non ne degrade pas notablement la vitesse pour les petites matrices) 463 #ifdef DO_NOT_OPTIMIZE_PRODUCT 464 bool no_optim = true; 465 #else 466 bool no_optim = false; 467 //NON juste pour memoire: if((stepa+stepb)*NCols()*sizeof(T)<100000) no_optim=true; 468 #endif 469 470 // Calcul de C=rm = A*B (A=*this) 471 // Remember: C-like matrices are column packed 472 // Fortan-like matrices are line packed 473 sa_size_t r,c,k; 474 T sum; 475 const T * pe; 476 477 // Pas d'optimisation demandee 478 if( no_optim ) { 479 //cout<<"no_optim("<<no_optim<<") "<<stepa<<" "<<stepb<<endl; 480 const T * pea; 481 const T * peb; 482 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A 483 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B 484 sum = 0; 485 pea = &((*this)(r,0)); 486 peb = &(b(0,c)); 487 // On gagne un peu en remplacant "pea[k*stepa]" par "pea+=stepa" pour les grosses matrices 488 //for(k=0; k<NCols(); k++) sum += pea[k*stepa]*peb[k*stepb]; 489 for(k=0; k<NCols(); k++) {sum += (*pea)*(*peb); pea+=stepa; peb+=stepb;} 490 rm(r,c) = sum; 491 } 492 } 493 } 494 // A.col est packed et B.row est packed (on a interet a optimiser quand meme) 495 else if(stepa==1 && stepb==1) { 496 //cout<<"A.col packed && B.row not packed "<<stepa<<" "<<stepb<<endl; 497 T * pea = new T[rm.NCols()]; 498 const T * peb; 499 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A 500 pe = &((*this)(r,0)); 501 for(k=0; k<NCols(); k++) {pea[k] = *(pe++);} 502 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B 503 sum = 0; 504 peb = &(b(0,c)); 505 for(k=0; k<NCols(); k++) sum += *(peb++)*pea[k]; 506 rm(r,c) = sum; 507 } 508 } 509 delete [] pea; 510 } 511 // A.col est packed et B.row n'est pas packed 512 else if(stepa==1 && stepb!=1) { 513 //cout<<"A.col packed && B.row not packed "<<stepa<<" "<<stepb<<endl; 514 const T * pea; 515 T * peb = new T[rm.NCols()]; 516 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B 517 pe = &(b(0,c)); 518 for(k=0; k<NCols(); k++) {peb[k] = *pe; pe+=stepb;} 519 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A 520 sum = 0; 521 pea = &((*this)(r,0)); 522 for(k=0; k<NCols(); k++) sum += pea[k]*peb[k]; 523 rm(r,c) = sum; 524 } 525 } 526 delete [] peb; 527 } 528 // A.col n'est pas packed et B.row est packed 529 else if(stepa!=1 && stepb==1) { 530 //cout<<"A.col not packed && B.row packed "<<stepa<<" "<<stepb<<endl; 531 T * pea = new T[rm.NCols()]; 532 const T * peb; 533 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A 534 pe = &((*this)(r,0)); 535 for(k=0; k<NCols(); k++) {pea[k] = *pe; pe+=stepa;} 536 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B 537 sum = 0; 538 peb = &(b(0,c)); 539 for(k=0; k<NCols(); k++) sum += pea[k]*peb[k]; 540 rm(r,c) = sum; 541 } 542 } 543 delete [] pea; 544 } 545 // A.col n'est pas packed et B.row n'est pas packed, stepb>stepa 546 else if(stepa!=1 && stepb!=1 && stepb>stepa) { 547 //cout<<"A.col not packed && B.row not packed ==> optimize on B "<<stepa<<" "<<stepb<<endl; 548 const T * pea; 549 T * peb = new T[rm.NCols()]; 550 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B 551 pe = &(b(0,c)); 552 for(k=0; k<NCols(); k++) {peb[k] = *pe; pe+=stepb;} 553 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A 554 sum = 0; 555 pea = &((*this)(r,0)); 556 for(k=0; k<NCols(); k++) {sum += (*pea)*peb[k]; pea+=stepa;} 557 rm(r,c) = sum; 558 } 559 } 560 delete [] peb; 561 } 562 // A.col n'est pas packed et B.row n'est pas packed, stepa>=stepb 563 else if(stepa!=1 && stepb!=1) { 564 //cout<<"A.col not packed && B.row not packed ==> optimize on A "<<stepa<<" "<<stepb<<endl; 565 T * pea = new T[rm.NCols()]; 566 const T * peb; 567 for(r=0; r<rm.NRows(); r++) { // Boucle sur les lignes de A 568 pe = &((*this)(r,0)); 569 for(k=0; k<NCols(); k++) {pea[k] = *pe; pe+=stepa;} 570 for(c=0; c<rm.NCols(); c++) { // Boucle sur les colonnes de B 571 sum = 0; 572 peb = &(b(0,c)); 573 for(k=0; k<NCols(); k++) {sum += pea[k]*(*peb); peb+=stepb;} 574 rm(r,c) = sum; 575 } 576 } 577 delete [] pea; 578 } 579 else { 580 cout<<"TMatrix<T>::Multiply(b) Optimize case not treated... Please report BUG !!! "<<endl; 581 throw(SzMismatchError("TMatrix<T>::Multiply(b) Optimize case not treated... Please report BUG !!! ") ); 582 } 583 584 return rm; 585 } 439 586 440 587 ///////////////////////////////////////////////////////////////
Note:
See TracChangeset
for help on using the changeset viewer.