2014-11-07 3 views
1

매트릭스 X 벡터 X 스칼라 내가 할 수있는 알고, 같은PETSc - MatMultScale? 내가 <strong>PETSc</strong>와 I를 사용하고

Equation

뭔가를하고 싶어 : 경우

Mat A 
Vec x,y 

MatMult(A,x,y) 
VecScale(y,0.5) 

난 그냥 궁금가 이 모든 것을 한 번에 수행 할 수있는 기능입니다. 루프를 저장하는 것처럼 보입니다.

MatMultScale(A,x,0.5,y) 

이러한 기능이 있습니까?

답변

1

이 기능 (또는 이상한 항목)은 functions operating on Mat 목록에없는 것 같습니다. 네 질문에 대한 간단한 대답은 ... 아니야.

종종 $ y = \ frac12 Ax $를 사용하는 경우 해결 방법은 MatScale(A,0.5);을 사용하여 모든 행렬을 한 번 스케일링하는 것입니다.

그러한 기능이 유용할까요? 이를 확인하는 한 가지 방법은 petsc의 -log_summary 옵션을 사용하여 프로파일 링 정보를 얻는 것입니다. 행렬이 빽빽하다면, MatMult()에서 보낸 시간이 VecScale()에서 보낸 시간보다 훨씬 더 큽니다. 이 질문은 희소 행렬을 처리 할 때만 의미가 있으며 줄당 null이 아닌 몇 가지 용어를 사용합니다.

static char help[] = "Tests solving linear system on 0 by 0 matrix.\n\n"; 

#include <petscksp.h> 

#undef __FUNCT__ 
#define __FUNCT__ "main" 
int main(int argc,char **args) 
{ 
    Vec   x, y;  
    Mat   A;   
    PetscReal  alpha=0.5; 
    PetscErrorCode ierr; 
    PetscInt n=42; 

    PetscInitialize(&argc,&args,(char*)0,help); 
    ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); 

    /* Create the vector*/ 
    ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); 
    ierr = VecSetSizes(x,PETSC_DECIDE,n);CHKERRQ(ierr); 
    ierr = VecSetFromOptions(x);CHKERRQ(ierr); 
    ierr = VecDuplicate(x,&y);CHKERRQ(ierr); 

    /* 
    Create matrix. When using MatCreate(), the matrix format can 
    be specified at runtime. 

    Performance tuning note: For problems of substantial size, 
    preallocation of matrix memory is crucial for attaining good 
    performance. See the matrix chapter of the users manual for details. 
    */ 
    ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); 
    ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); 
    ierr = MatSetFromOptions(A);CHKERRQ(ierr); 
    ierr = MatSetUp(A);CHKERRQ(ierr); 

    /* 
This matrix is diagonal, two times identity 
should have preallocated, shame 
    */ 
    PetscInt i,col; 
    PetscScalar value=2.0; 
    for (i=0; i<n; i++) { 
     col=i; 
     ierr = MatSetValues(A,1,&i,1,&col,&value,INSERT_VALUES);CHKERRQ(ierr); 
    } 

    ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 
    ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 

    /* 
    let's do this 42 times for nothing : 
    */ 
    for(i=0;i<42;i++){ 
     ierr = MatMult(A,x,y);CHKERRQ(ierr); 
     ierr = VecScale(y,alpha);CHKERRQ(ierr); 
    } 

    ierr = VecDestroy(&x);CHKERRQ(ierr); 
    ierr = VecDestroy(&y);CHKERRQ(ierr); 
    ierr = MatDestroy(&A);CHKERRQ(ierr); 

    ierr = PetscFinalize(); 
    return 0; 
} 

메이크 : 여기에 귀하의 질문에 대답 할 수 -log_summary의 결과로 두 줄

include ${PETSC_DIR}/conf/variables 
include ${PETSC_DIR}/conf/rules 
include ${PETSC_DIR}/conf/test 

CLINKER=g++ 

all : ex1 

ex1 : main.o chkopts 
    ${CLINKER} -w -o main main.o ${PETSC_LIB} 
    ${RM} main.o 

run : 
    mpirun -np 2 main -n 10000000 -log_summary -help -mat_type mpiaij 

그리고 :

여기

는 코드가 매트릭스 2xIdentity를 사용하여, 그것을 테스트하는 것입니다
Event    Count  Time (sec)  Flops        --- Global --- --- Stage --- Total 
        Max Ratio Max  Ratio Max Ratio Mess Avg len Reduct %T %F %M %L %R %T %F %M %L %R Mflop/s 
------------------------------------------------------------------------------------------------------------------------ 

--- Event Stage 0: Main Stage 

VecScale    42 1.0 1.0709e+00 1.0 2.10e+08 1.0 0.0e+00 0.0e+00 0.0e+00 4 50 0 0 0 4 50 0 0 0 392 
MatMult    42 1.0 5.7360e+00 1.1 2.10e+08 1.0 0.0e+00 0.0e+00 0.0e+00 20 50 0 0 0 20 50 0 0 0 73 

그래서 42 VecScale() 작업 42 MatMult() 작업이 5.7 초 걸리는 동안 1 초가 걸렸습니다. VecScale() 작업을 억제하면 최상의 경우 코드가 20 % 빨라집니다. for 루프로 인한 오버 헤드는 그보다 훨씬 작습니다. 나는 그것이이 함수가 존재하지 않는 이유라고 생각한다.

컴퓨터 성능이 좋지 않음 (392Mflops for VecScale() ...)에 대해 사과드립니다. 나는 너에게 무슨 일이 일어나는지 궁금하다.

+0

답장을 보내 주셔서 감사합니다. 나는 당신의 코드를 테스트했고 괜찮 았어. (몇 줄이 빠진 것을 제외하고). 효과가 작은 경우 구현하는 번거 로움이 없을 수도 있습니다. 흥미롭게도 MatMult (5.77s 73Mflop/s)와 VecScale (2.68s 156Mflop/s)의 경우 거의 동일한 결과를 얻었습니다. 내 컴퓨터가 더 나빠질 것 같아. – Miguel