1c4762a1bSJed Brown static char help[] = "Test ViennaCL Matrix Conversions"; 2c4762a1bSJed Brown 3c4762a1bSJed Brown #include <petscmat.h> 4c4762a1bSJed Brown 5d71ae5a4SJacob Faibussowitsch int main(int argc, char **args) 6d71ae5a4SJacob Faibussowitsch { 7c4762a1bSJed Brown PetscMPIInt rank, size; 8c4762a1bSJed Brown 9327415f7SBarry Smith PetscFunctionBeginUser; 10c8025a54SPierre Jolivet PetscCall(PetscInitialize(&argc, &args, NULL, help)); 11c4762a1bSJed Brown 129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 139566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 14c4762a1bSJed Brown 15c4762a1bSJed Brown /* Construct a sequential ViennaCL matrix and vector */ 16dd400576SPatrick Sanan if (rank == 0) { 17c4762a1bSJed Brown Mat A_vcl; 18c4762a1bSJed Brown Vec v_vcl, r_vcl; 19c4762a1bSJed Brown PetscInt n = 17, m = 31, nz = 5, i, cnt, j; 20c4762a1bSJed Brown const PetscScalar val = 1.0; 21c4762a1bSJed Brown 229566063dSJacob Faibussowitsch PetscCall(MatCreateSeqAIJViennaCL(PETSC_COMM_SELF, m, n, nz, NULL, &A_vcl)); 23c4762a1bSJed Brown 24c4762a1bSJed Brown /* Add nz arbitrary entries per row in arbitrary columns */ 25c4762a1bSJed Brown for (i = 0; i < m; ++i) { 26c4762a1bSJed Brown for (cnt = 0; cnt < nz; ++cnt) { 27c4762a1bSJed Brown j = (19 * cnt + (7 * i + 3)) % n; 289566063dSJacob Faibussowitsch PetscCall(MatSetValue(A_vcl, i, j, (PetscScalar)(0.3 * i + j), INSERT_VALUES)); 29c4762a1bSJed Brown } 30c4762a1bSJed Brown } 319566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A_vcl, MAT_FINAL_ASSEMBLY)); 329566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A_vcl, MAT_FINAL_ASSEMBLY)); 33c4762a1bSJed Brown 349566063dSJacob Faibussowitsch PetscCall(VecCreateSeqViennaCL(PETSC_COMM_SELF, n, &v_vcl)); 359566063dSJacob Faibussowitsch PetscCall(VecCreateSeqViennaCL(PETSC_COMM_SELF, m, &r_vcl)); 369566063dSJacob Faibussowitsch PetscCall(VecSet(v_vcl, val)); 37c4762a1bSJed Brown 389566063dSJacob Faibussowitsch PetscCall(MatMult(A_vcl, v_vcl, r_vcl)); 39c4762a1bSJed Brown 409566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v_vcl)); 419566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r_vcl)); 429566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A_vcl)); 43c4762a1bSJed Brown } 44c4762a1bSJed Brown 45c4762a1bSJed Brown /* Create a sequential AIJ matrix on rank 0 convert it to a new ViennaCL matrix, and apply it to a ViennaCL vector */ 46dd400576SPatrick Sanan if (rank == 0) { 47c4762a1bSJed Brown Mat A, A_vcl; 48c4762a1bSJed Brown Vec v, r, v_vcl, r_vcl, d_vcl; 49c4762a1bSJed Brown PetscInt n = 17, m = 31, nz = 5, i, cnt, j; 50c4762a1bSJed Brown const PetscScalar val = 1.0; 51c4762a1bSJed Brown PetscReal dnorm; 52c4762a1bSJed Brown const PetscReal tol = 1e-5; 53c4762a1bSJed Brown 549566063dSJacob Faibussowitsch PetscCall(MatCreateSeqAIJ(PETSC_COMM_SELF, m, n, nz, NULL, &A)); 55c4762a1bSJed Brown 56c4762a1bSJed Brown /* Add nz arbitrary entries per row in arbitrary columns */ 57c4762a1bSJed Brown for (i = 0; i < m; ++i) { 58c4762a1bSJed Brown for (cnt = 0; cnt < nz; ++cnt) { 59c4762a1bSJed Brown j = (19 * cnt + (7 * i + 3)) % n; 609566063dSJacob Faibussowitsch PetscCall(MatSetValue(A, i, j, (PetscScalar)(0.3 * i + j), INSERT_VALUES)); 61c4762a1bSJed Brown } 62c4762a1bSJed Brown } 639566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 649566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 65c4762a1bSJed Brown 669566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "Sequential CPU Matrix")); 67c4762a1bSJed Brown 689566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, n, &v)); 699566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, m, &r)); 709566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)r, "CPU result vector")); 719566063dSJacob Faibussowitsch PetscCall(VecSet(v, val)); 729566063dSJacob Faibussowitsch PetscCall(MatMult(A, v, r)); 73c4762a1bSJed Brown 749566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATSEQAIJVIENNACL, MAT_INITIAL_MATRIX, &A_vcl)); 759566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A_vcl, "New ViennaCL Matrix")); 76c4762a1bSJed Brown 779566063dSJacob Faibussowitsch PetscCall(VecCreateSeqViennaCL(PETSC_COMM_SELF, n, &v_vcl)); 789566063dSJacob Faibussowitsch PetscCall(VecCreateSeqViennaCL(PETSC_COMM_SELF, m, &r_vcl)); 799566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)r_vcl, "ViennaCL result vector")); 809566063dSJacob Faibussowitsch PetscCall(VecSet(v_vcl, val)); 819566063dSJacob Faibussowitsch PetscCall(MatMult(A_vcl, v_vcl, r_vcl)); 82c4762a1bSJed Brown 839566063dSJacob Faibussowitsch PetscCall(VecDuplicate(r_vcl, &d_vcl)); 849566063dSJacob Faibussowitsch PetscCall(VecCopy(r_vcl, d_vcl)); 859566063dSJacob Faibussowitsch PetscCall(VecAXPY(d_vcl, -1.0, r_vcl)); 869566063dSJacob Faibussowitsch PetscCall(VecNorm(d_vcl, NORM_INFINITY, &dnorm)); 8708401ef6SPierre Jolivet PetscCheck(dnorm <= tol, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "Sequential CPU and MPI ViennaCL vector results incompatible with inf norm greater than tolerance of %g", tol); 88c4762a1bSJed Brown 899566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v)); 909566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r)); 919566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v_vcl)); 929566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r_vcl)); 939566063dSJacob Faibussowitsch PetscCall(VecDestroy(&d_vcl)); 949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 959566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A_vcl)); 96c4762a1bSJed Brown } 97c4762a1bSJed Brown 98c4762a1bSJed Brown /* Create a sequential AIJ matrix on rank 0 convert it inplace to a new ViennaCL matrix, and apply it to a ViennaCL vector */ 99dd400576SPatrick Sanan if (rank == 0) { 100c4762a1bSJed Brown Mat A; 101c4762a1bSJed Brown Vec v, r, v_vcl, r_vcl, d_vcl; 102c4762a1bSJed Brown PetscInt n = 17, m = 31, nz = 5, i, cnt, j; 103c4762a1bSJed Brown const PetscScalar val = 1.0; 104c4762a1bSJed Brown PetscReal dnorm; 105c4762a1bSJed Brown const PetscReal tol = 1e-5; 106c4762a1bSJed Brown 1079566063dSJacob Faibussowitsch PetscCall(MatCreateSeqAIJ(PETSC_COMM_SELF, m, n, nz, NULL, &A)); 108c4762a1bSJed Brown 109c4762a1bSJed Brown /* Add nz arbitrary entries per row in arbitrary columns */ 110c4762a1bSJed Brown for (i = 0; i < m; ++i) { 111c4762a1bSJed Brown for (cnt = 0; cnt < nz; ++cnt) { 112c4762a1bSJed Brown j = (19 * cnt + (7 * i + 3)) % n; 1139566063dSJacob Faibussowitsch PetscCall(MatSetValue(A, i, j, (PetscScalar)(0.3 * i + j), INSERT_VALUES)); 114c4762a1bSJed Brown } 115c4762a1bSJed Brown } 1169566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 1179566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 118c4762a1bSJed Brown 1199566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "Sequential CPU Matrix")); 120c4762a1bSJed Brown 1219566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, n, &v)); 1229566063dSJacob Faibussowitsch PetscCall(VecCreateSeq(PETSC_COMM_SELF, m, &r)); 1239566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)r, "CPU result vector")); 1249566063dSJacob Faibussowitsch PetscCall(VecSet(v, val)); 1259566063dSJacob Faibussowitsch PetscCall(MatMult(A, v, r)); 126c4762a1bSJed Brown 1279566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATSEQAIJVIENNACL, MAT_INPLACE_MATRIX, &A)); 1289566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "Converted ViennaCL Matrix")); 129c4762a1bSJed Brown 1309566063dSJacob Faibussowitsch PetscCall(VecCreateSeqViennaCL(PETSC_COMM_SELF, n, &v_vcl)); 1319566063dSJacob Faibussowitsch PetscCall(VecCreateSeqViennaCL(PETSC_COMM_SELF, m, &r_vcl)); 1329566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)r_vcl, "ViennaCL result vector")); 1339566063dSJacob Faibussowitsch PetscCall(VecSet(v_vcl, val)); 1349566063dSJacob Faibussowitsch PetscCall(MatMult(A, v_vcl, r_vcl)); 135c4762a1bSJed Brown 1369566063dSJacob Faibussowitsch PetscCall(VecDuplicate(r_vcl, &d_vcl)); 1379566063dSJacob Faibussowitsch PetscCall(VecCopy(r_vcl, d_vcl)); 1389566063dSJacob Faibussowitsch PetscCall(VecAXPY(d_vcl, -1.0, r_vcl)); 1399566063dSJacob Faibussowitsch PetscCall(VecNorm(d_vcl, NORM_INFINITY, &dnorm)); 14008401ef6SPierre Jolivet PetscCheck(dnorm <= tol, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "MPI CPU and MPI ViennaCL Vector results incompatible with inf norm greater than tolerance of %g", tol); 141c4762a1bSJed Brown 1429566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v)); 1439566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r)); 1449566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v_vcl)); 1459566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r_vcl)); 1469566063dSJacob Faibussowitsch PetscCall(VecDestroy(&d_vcl)); 1479566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 148c4762a1bSJed Brown } 149c4762a1bSJed Brown 150c4762a1bSJed Brown /* Create a parallel AIJ matrix, convert it to a new ViennaCL matrix, and apply it to a ViennaCL vector */ 151c4762a1bSJed Brown if (size > 1) { 152c4762a1bSJed Brown Mat A, A_vcl; 153c4762a1bSJed Brown Vec v, r, v_vcl, r_vcl, d_vcl; 154c4762a1bSJed Brown PetscInt N = 17, M = 31, nz = 5, i, cnt, j, rlow, rhigh; 155c4762a1bSJed Brown const PetscScalar val = 1.0; 156c4762a1bSJed Brown PetscReal dnorm; 157c4762a1bSJed Brown const PetscReal tol = 1e-5; 158c4762a1bSJed Brown 1599566063dSJacob Faibussowitsch PetscCall(MatCreateAIJ(PETSC_COMM_WORLD, PETSC_DETERMINE, PETSC_DETERMINE, M, N, nz, NULL, nz, NULL, &A)); 160c4762a1bSJed Brown 161c4762a1bSJed Brown /* Add nz arbitrary entries per row in arbitrary columns */ 1629566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rlow, &rhigh)); 163c4762a1bSJed Brown for (i = rlow; i < rhigh; ++i) { 164c4762a1bSJed Brown for (cnt = 0; cnt < nz; ++cnt) { 165c4762a1bSJed Brown j = (19 * cnt + (7 * i + 3)) % N; 1669566063dSJacob Faibussowitsch PetscCall(MatSetValue(A, i, j, (PetscScalar)(0.3 * i + j), INSERT_VALUES)); 167c4762a1bSJed Brown } 168c4762a1bSJed Brown } 1699566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 1709566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 171c4762a1bSJed Brown 1729566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "MPI CPU Matrix")); 173c4762a1bSJed Brown 1749566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A, &v, &r)); 1759566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)r, "MPI CPU result vector")); 1769566063dSJacob Faibussowitsch PetscCall(VecSet(v, val)); 1779566063dSJacob Faibussowitsch PetscCall(MatMult(A, v, r)); 178c4762a1bSJed Brown 1799566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATMPIAIJVIENNACL, MAT_INITIAL_MATRIX, &A_vcl)); 1809566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A_vcl, "New MPI ViennaCL Matrix")); 181c4762a1bSJed Brown 1829566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A_vcl, &v_vcl, &r_vcl)); 1839566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)r_vcl, "ViennaCL result vector")); 1849566063dSJacob Faibussowitsch PetscCall(VecSet(v_vcl, val)); 1859566063dSJacob Faibussowitsch PetscCall(MatMult(A_vcl, v_vcl, r_vcl)); 186c4762a1bSJed Brown 1879566063dSJacob Faibussowitsch PetscCall(VecDuplicate(r_vcl, &d_vcl)); 1889566063dSJacob Faibussowitsch PetscCall(VecCopy(r_vcl, d_vcl)); 1899566063dSJacob Faibussowitsch PetscCall(VecAXPY(d_vcl, -1.0, r_vcl)); 1909566063dSJacob Faibussowitsch PetscCall(VecNorm(d_vcl, NORM_INFINITY, &dnorm)); 19108401ef6SPierre Jolivet PetscCheck(dnorm <= tol, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "MPI CPU and MPI ViennaCL Vector results incompatible with inf norm greater than tolerance of %g", tol); 192c4762a1bSJed Brown 1939566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v)); 1949566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r)); 1959566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v_vcl)); 1969566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r_vcl)); 1979566063dSJacob Faibussowitsch PetscCall(VecDestroy(&d_vcl)); 1989566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 1999566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A_vcl)); 200c4762a1bSJed Brown } 201c4762a1bSJed Brown 202c4762a1bSJed Brown /* Create a parallel AIJ matrix, convert it in-place to a ViennaCL matrix, and apply it to a ViennaCL vector */ 203c4762a1bSJed Brown if (size > 1) { 204c4762a1bSJed Brown Mat A; 205c4762a1bSJed Brown Vec v, r, v_vcl, r_vcl, d_vcl; 206c4762a1bSJed Brown PetscInt N = 17, M = 31, nz = 5, i, cnt, j, rlow, rhigh; 207c4762a1bSJed Brown const PetscScalar val = 1.0; 208c4762a1bSJed Brown PetscReal dnorm; 209c4762a1bSJed Brown const PetscReal tol = 1e-5; 210c4762a1bSJed Brown 2119566063dSJacob Faibussowitsch PetscCall(MatCreateAIJ(PETSC_COMM_WORLD, PETSC_DETERMINE, PETSC_DETERMINE, M, N, nz, NULL, nz, NULL, &A)); 212c4762a1bSJed Brown 213c4762a1bSJed Brown /* Add nz arbitrary entries per row in arbitrary columns */ 2149566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rlow, &rhigh)); 215c4762a1bSJed Brown for (i = rlow; i < rhigh; ++i) { 216c4762a1bSJed Brown for (cnt = 0; cnt < nz; ++cnt) { 217c4762a1bSJed Brown j = (19 * cnt + (7 * i + 3)) % N; 2189566063dSJacob Faibussowitsch PetscCall(MatSetValue(A, i, j, (PetscScalar)(0.3 * i + j), INSERT_VALUES)); 219c4762a1bSJed Brown } 220c4762a1bSJed Brown } 2219566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 2229566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 223c4762a1bSJed Brown 2249566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "MPI CPU Matrix")); 225c4762a1bSJed Brown 2269566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A, &v, &r)); 2279566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)r, "MPI CPU result vector")); 2289566063dSJacob Faibussowitsch PetscCall(VecSet(v, val)); 2299566063dSJacob Faibussowitsch PetscCall(MatMult(A, v, r)); 230c4762a1bSJed Brown 2319566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATMPIAIJVIENNACL, MAT_INPLACE_MATRIX, &A)); 2329566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "Converted MPI ViennaCL Matrix")); 233c4762a1bSJed Brown 2349566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A, &v_vcl, &r_vcl)); 2359566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)r_vcl, "ViennaCL result vector")); 2369566063dSJacob Faibussowitsch PetscCall(VecSet(v_vcl, val)); 2379566063dSJacob Faibussowitsch PetscCall(MatMult(A, v_vcl, r_vcl)); 238c4762a1bSJed Brown 2399566063dSJacob Faibussowitsch PetscCall(VecDuplicate(r_vcl, &d_vcl)); 2409566063dSJacob Faibussowitsch PetscCall(VecCopy(r_vcl, d_vcl)); 2419566063dSJacob Faibussowitsch PetscCall(VecAXPY(d_vcl, -1.0, r_vcl)); 2429566063dSJacob Faibussowitsch PetscCall(VecNorm(d_vcl, NORM_INFINITY, &dnorm)); 24308401ef6SPierre Jolivet PetscCheck(dnorm <= tol, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "MPI CPU and MPI ViennaCL Vector results incompatible with inf norm greater than tolerance of %g", tol); 244c4762a1bSJed Brown 2459566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v)); 2469566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r)); 2479566063dSJacob Faibussowitsch PetscCall(VecDestroy(&v_vcl)); 2489566063dSJacob Faibussowitsch PetscCall(VecDestroy(&r_vcl)); 2499566063dSJacob Faibussowitsch PetscCall(VecDestroy(&d_vcl)); 2509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 251c4762a1bSJed Brown } 252c4762a1bSJed Brown 2539566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 254b122ec5aSJacob Faibussowitsch return 0; 255c4762a1bSJed Brown } 256c4762a1bSJed Brown 257c4762a1bSJed Brown /*TEST 258c4762a1bSJed Brown 259c4762a1bSJed Brown build: 260c4762a1bSJed Brown requires: viennacl 261c4762a1bSJed Brown 262c4762a1bSJed Brown test: 263*3886731fSPierre Jolivet output_file: output/empty.out 264c4762a1bSJed Brown 265c4762a1bSJed Brown test: 266c4762a1bSJed Brown suffix: 2 267c4762a1bSJed Brown nsize: 2 268*3886731fSPierre Jolivet output_file: output/empty.out 269c4762a1bSJed Brown 270c4762a1bSJed Brown TEST*/ 271