Commits

Karl Rupp committed 67c87b7

ViennaCL: Fixed issues if size 0 is passed.

  • Participants
  • Parent commits 3db98f8

Comments (0)

Files changed (2)

src/mat/impls/aij/seq/seqviennacl/aijviennacl.cxx

 
 
   PetscFunctionBegin;
-  if (A->valid_GPU_matrix == PETSC_VIENNACL_UNALLOCATED || A->valid_GPU_matrix == PETSC_VIENNACL_CPU) {
-    ierr = PetscLogEventBegin(MAT_ViennaCLCopyToGPU,A,0,0,0);CHKERRQ(ierr);
+  if (A->rmap->n > 0 && A->cmap->n > 0) { //some OpenCL SDKs have issues with buffers of size 0
+    if (A->valid_GPU_matrix == PETSC_VIENNACL_UNALLOCATED || A->valid_GPU_matrix == PETSC_VIENNACL_CPU) {
+      ierr = PetscLogEventBegin(MAT_ViennaCLCopyToGPU,A,0,0,0);CHKERRQ(ierr);
 
-    try {
-      //viennaclstruct->nonzerorow=0;
-      //for (PetscInt j = 0; j<m; j++) viennaclstruct->nonzerorow += (a->i[j+1] > a->i[j]);
+      try {
+        //viennaclstruct->nonzerorow=0;
+        //for (PetscInt j = 0; j<m; j++) viennaclstruct->nonzerorow += (a->i[j+1] > a->i[j]);
 
-      viennaclstruct->mat = new ViennaCLAIJMatrix();
-      if (a->compressedrow.use) {
-        //m    = a->compressedrow.nrows;
-        ii   = a->compressedrow.i;
-        //ridx = a->compressedrow.rindex;
-        
-        viennaclstruct->mat->set(ii, a->j, a->a, A->rmap->n, A->cmap->n, a->nz);
-        
-        // TODO: Either convert to full CSR (inefficient), or hold row indices in temporary vector (requires additional bookkeeping for matrix-vector multiplications)
-        
-        SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: Compressed CSR (only nonzero rows) not yet supported");
-      } else {
-        
-        // Since PetscInt is in general different from cl_uint, we have to convert:
-        viennacl::backend::mem_handle dummy;
-        
-        viennacl::backend::typesafe_host_array<unsigned int> row_buffer; row_buffer.raw_resize(dummy, A->rmap->n+1);
-        for (PetscInt i=0; i<=A->rmap->n; ++i)
-          row_buffer.set(i, (a->i)[i]);
-        
-        viennacl::backend::typesafe_host_array<unsigned int> col_buffer; col_buffer.raw_resize(dummy, a->nz);
-        for (PetscInt i=0; i<a->nz; ++i)
-          col_buffer.set(i, (a->j)[i]);
-        
-        viennaclstruct->mat->set(row_buffer.get(), col_buffer.get(), a->a, A->rmap->n, A->cmap->n, a->nz);
+        viennaclstruct->mat = new ViennaCLAIJMatrix();
+        if (a->compressedrow.use) {
+          //m    = a->compressedrow.nrows;
+          ii   = a->compressedrow.i;
+          //ridx = a->compressedrow.rindex;
+
+          viennaclstruct->mat->set(ii, a->j, a->a, A->rmap->n, A->cmap->n, a->nz);
+
+          // TODO: Either convert to full CSR (inefficient), or hold row indices in temporary vector (requires additional bookkeeping for matrix-vector multiplications)
+
+          SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: Compressed CSR (only nonzero rows) not yet supported");
+        } else {
+
+          // Since PetscInt is in general different from cl_uint, we have to convert:
+          viennacl::backend::mem_handle dummy;
+
+          viennacl::backend::typesafe_host_array<unsigned int> row_buffer; row_buffer.raw_resize(dummy, A->rmap->n+1);
+          for (PetscInt i=0; i<=A->rmap->n; ++i)
+            row_buffer.set(i, (a->i)[i]);
+
+          viennacl::backend::typesafe_host_array<unsigned int> col_buffer; col_buffer.raw_resize(dummy, a->nz);
+          for (PetscInt i=0; i<a->nz; ++i)
+            col_buffer.set(i, (a->j)[i]);
+
+          viennaclstruct->mat->set(row_buffer.get(), col_buffer.get(), a->a, A->rmap->n, A->cmap->n, a->nz);
+        }
+      } catch(char *ex) {
+        SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
       }
-    } catch(char *ex) {
-      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
-    }
 
-    A->valid_GPU_matrix = PETSC_VIENNACL_BOTH;
+      A->valid_GPU_matrix = PETSC_VIENNACL_BOTH;
 
-    ierr = PetscLogEventEnd(MAT_ViennaCLCopyToGPU,A,0,0,0);CHKERRQ(ierr);
+      ierr = PetscLogEventEnd(MAT_ViennaCLCopyToGPU,A,0,0,0);CHKERRQ(ierr);
+    }
   }
   PetscFunctionReturn(0);
 }
 
         /* Copy data back from GPU */
         viennacl::backend::typesafe_host_array<unsigned int> row_buffer; row_buffer.raw_resize(Agpu->handle1(), Agpu->size1() + 1);
-        
+
         // copy row array
         viennacl::backend::memory_read(Agpu->handle1(), 0, row_buffer.raw_size(), row_buffer.get());
         (a->i)[0] = row_buffer[0];
           (a->i)[i+1] = row_buffer[i+1];
           a->imax[i]  = a->ilen[i] = a->i[i+1] - a->i[i];  //Set imax[] and ilen[] arrays at the same time as i[] for better cache reuse
         }
-        
+
         // copy column indices
         viennacl::backend::typesafe_host_array<unsigned int> col_buffer; col_buffer.raw_resize(Agpu->handle2(), Agpu->nnz());
         viennacl::backend::memory_read(Agpu->handle2(), 0, col_buffer.raw_size(), col_buffer.get());
         for (PetscInt i=0; i < (PetscInt)Agpu->nnz(); ++i)
           (a->j)[i] = col_buffer[i];
-        
+
         // copy nonzero entries directly to destination (no conversion required)
         viennacl::backend::memory_read(Agpu->handle(), 0, sizeof(PetscScalar)*Agpu->nnz(), a->a);
-        
+
         /* TODO: What about a->diag? */
       }
     } catch(char *ex) {
   ViennaCLVector     *xgpu=NULL,*ygpu=NULL;
 
   PetscFunctionBegin;
-  ierr = VecViennaCLGetArrayRead(xx,&xgpu);CHKERRQ(ierr);
-  ierr = VecViennaCLGetArrayWrite(yy,&ygpu);CHKERRQ(ierr);
-  try {
-    *ygpu = viennacl::linalg::prod(*viennaclstruct->mat,*xgpu);
-  } catch (char *ex) {
-    SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+  if (A->rmap->n > 0 && A->cmap->n > 0) {
+    ierr = VecViennaCLGetArrayRead(xx,&xgpu);CHKERRQ(ierr);
+    ierr = VecViennaCLGetArrayWrite(yy,&ygpu);CHKERRQ(ierr);
+    try {
+      *ygpu = viennacl::linalg::prod(*viennaclstruct->mat,*xgpu);
+    } catch (char *ex) {
+      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+    }
+    ierr = VecViennaCLRestoreArrayRead(xx,&xgpu);CHKERRQ(ierr);
+    ierr = VecViennaCLRestoreArrayWrite(yy,&ygpu);CHKERRQ(ierr);
+    ierr = PetscLogFlops(2.0*a->nz - viennaclstruct->mat->nnz());CHKERRQ(ierr);
   }
-  ierr = VecViennaCLRestoreArrayRead(xx,&xgpu);CHKERRQ(ierr);
-  ierr = VecViennaCLRestoreArrayWrite(yy,&ygpu);CHKERRQ(ierr);
-  ierr = PetscLogFlops(2.0*a->nz - viennaclstruct->mat->nnz());CHKERRQ(ierr);
   PetscFunctionReturn(0);
 }
 
   ViennaCLVector     *xgpu=NULL,*ygpu=NULL,*zgpu=NULL;
 
   PetscFunctionBegin;
-  try {
-    ierr = VecViennaCLGetArrayRead(xx,&xgpu);CHKERRQ(ierr);
-    ierr = VecViennaCLGetArrayRead(yy,&ygpu);CHKERRQ(ierr);
-    ierr = VecViennaCLGetArrayWrite(zz,&zgpu);CHKERRQ(ierr);
-
-    if (a->compressedrow.use) {
-        SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: Compressed CSR (only nonzero rows) not yet supported");
-    } else {
-      if (zz == xx || zz == yy) { //temporary required
-        ViennaCLVector temp = viennacl::linalg::prod(*viennaclstruct->mat, *xgpu);
-        *zgpu = *ygpu + temp;
+  if (A->rmap->n > 0 && A->cmap->n > 0) {
+    try {
+      ierr = VecViennaCLGetArrayRead(xx,&xgpu);CHKERRQ(ierr);
+      ierr = VecViennaCLGetArrayRead(yy,&ygpu);CHKERRQ(ierr);
+      ierr = VecViennaCLGetArrayWrite(zz,&zgpu);CHKERRQ(ierr);
+
+      if (a->compressedrow.use) {
+          SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: Compressed CSR (only nonzero rows) not yet supported");
       } else {
-        *zgpu = viennacl::linalg::prod(*viennaclstruct->mat, *xgpu);
-        *zgpu += *ygpu;
+        if (zz == xx || zz == yy) { //temporary required
+          ViennaCLVector temp = viennacl::linalg::prod(*viennaclstruct->mat, *xgpu);
+          *zgpu = *ygpu + temp;
+        } else {
+          *zgpu = viennacl::linalg::prod(*viennaclstruct->mat, *xgpu);
+          *zgpu += *ygpu;
+        }
       }
-    }
 
-    ierr = VecViennaCLRestoreArrayRead(xx,&xgpu);CHKERRQ(ierr);
-    ierr = VecViennaCLRestoreArrayRead(yy,&ygpu);CHKERRQ(ierr);
-    ierr = VecViennaCLRestoreArrayWrite(zz,&zgpu);CHKERRQ(ierr);
+      ierr = VecViennaCLRestoreArrayRead(xx,&xgpu);CHKERRQ(ierr);
+      ierr = VecViennaCLRestoreArrayRead(yy,&ygpu);CHKERRQ(ierr);
+      ierr = VecViennaCLRestoreArrayWrite(zz,&zgpu);CHKERRQ(ierr);
 
-  } catch(char *ex) {
-    SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+    } catch(char *ex) {
+      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+    }
+    ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
   }
-  ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr);
   PetscFunctionReturn(0);
 }
 

src/vec/vec/impls/seq/seqviennacl/vecviennacl.cxx

 
   PetscFunctionBegin;
   ierr = VecViennaCLAllocateCheck(v);CHKERRQ(ierr);
-  if (v->valid_GPU_array == PETSC_VIENNACL_CPU) {
-    ierr = PetscLogEventBegin(VEC_ViennaCLCopyToGPU,v,0,0,0);CHKERRQ(ierr);
-    try {
-      ViennaCLVector *vec = ((Vec_ViennaCL*)v->spptr)->GPUarray;
-      viennacl::fast_copy(*(PetscScalar**)v->data, *(PetscScalar**)v->data + v->map->n, vec->begin());
-      //ierr = WaitForGPU();CHKERRViennaCL(ierr);  //copy does not return before data is safe. No need to wait.
-    } catch(char *ex) {
-      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+  if (v->map->n > 0) {
+    if (v->valid_GPU_array == PETSC_VIENNACL_CPU) {
+      ierr = PetscLogEventBegin(VEC_ViennaCLCopyToGPU,v,0,0,0);CHKERRQ(ierr);
+      try {
+        ViennaCLVector *vec = ((Vec_ViennaCL*)v->spptr)->GPUarray;
+        viennacl::fast_copy(*(PetscScalar**)v->data, *(PetscScalar**)v->data + v->map->n, vec->begin());
+        //ierr = WaitForGPU();CHKERRViennaCL(ierr);  //copy does not return before data is safe. No need to wait.
+      } catch(char *ex) {
+        SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+      }
+      ierr = PetscLogEventEnd(VEC_ViennaCLCopyToGPU,v,0,0,0);CHKERRQ(ierr);
+      v->valid_GPU_array = PETSC_VIENNACL_BOTH;
     }
-    ierr = PetscLogEventEnd(VEC_ViennaCLCopyToGPU,v,0,0,0);CHKERRQ(ierr);
-    v->valid_GPU_array = PETSC_VIENNACL_BOTH;
   }
   PetscFunctionReturn(0);
 }
   PetscErrorCode ierr;
 
   PetscFunctionBegin;
-  if (alpha != 0.0) {
+  if (alpha != 0.0 && xin->map->n > 0) {
     ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
     ierr = VecViennaCLGetArrayReadWrite(yin,&ygpu);CHKERRQ(ierr);
     try {
   PetscErrorCode ierr;
 
   PetscFunctionBegin;
-  if (alpha != 0.0) {
+  if (alpha != 0.0 && xin->map->n > 0) {
     ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
     ierr = VecViennaCLGetArrayReadWrite(yin,&ygpu);CHKERRQ(ierr);
     try {
   PetscErrorCode ierr;
 
   PetscFunctionBegin;
-  ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  ierr = VecViennaCLGetArrayRead(yin,&ygpu);CHKERRQ(ierr);
-  ierr = VecViennaCLGetArrayWrite(win,&wgpu);CHKERRQ(ierr);
-  try {
-    *wgpu = viennacl::linalg::element_div(*xgpu, *ygpu);
-  } catch(char *ex) {
-    SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+  if (xin->map->n > 0) {
+    ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
+    ierr = VecViennaCLGetArrayRead(yin,&ygpu);CHKERRQ(ierr);
+    ierr = VecViennaCLGetArrayWrite(win,&wgpu);CHKERRQ(ierr);
+    try {
+      *wgpu = viennacl::linalg::element_div(*xgpu, *ygpu);
+    } catch(char *ex) {
+      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+    }
+    ierr = PetscLogFlops(win->map->n);CHKERRQ(ierr);
+    ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
+    ierr = VecViennaCLRestoreArrayRead(yin,&ygpu);CHKERRQ(ierr);
+    ierr = VecViennaCLRestoreArrayWrite(win,&wgpu);CHKERRQ(ierr);
   }
-  ierr = PetscLogFlops(win->map->n);CHKERRQ(ierr);
-  ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  ierr = VecViennaCLRestoreArrayRead(yin,&ygpu);CHKERRQ(ierr);
-  ierr = VecViennaCLRestoreArrayWrite(win,&wgpu);CHKERRQ(ierr);
   PetscFunctionReturn(0);
 }
 
   PetscErrorCode ierr;
 
   PetscFunctionBegin;
-  if (alpha == 0.0) {
+  if (alpha == 0.0 && xin->map->n > 0) {
     ierr = VecCopy_SeqViennaCL(yin,win);CHKERRQ(ierr);
   } else {
     ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
   PetscErrorCode ierr;
 
   PetscFunctionBegin;
-  ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  ierr = VecViennaCLGetArrayRead(yin,&ygpu);CHKERRQ(ierr);
-  try {
-    *z = viennacl::linalg::inner_prod(*xgpu,*ygpu);
-  } catch(char *ex) {
-    SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
-  }
-  if (xin->map->n >0) {
-    ierr = PetscLogFlops(2.0*xin->map->n-1);CHKERRQ(ierr);
-  }
-  ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  ierr = VecViennaCLRestoreArrayRead(yin,&ygpu);CHKERRQ(ierr);
+  if (xin->map->n > 0) {
+    ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
+    ierr = VecViennaCLGetArrayRead(yin,&ygpu);CHKERRQ(ierr);
+    try {
+      *z = viennacl::linalg::inner_prod(*xgpu,*ygpu);
+    } catch(char *ex) {
+      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+    }
+    if (xin->map->n >0) {
+      ierr = PetscLogFlops(2.0*xin->map->n-1);CHKERRQ(ierr);
+    }
+    ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
+    ierr = VecViennaCLRestoreArrayRead(yin,&ygpu);CHKERRQ(ierr);
+  } else *z = 0.0;
   PetscFunctionReturn(0);
 }
 
   Vec            *yyin = (Vec*)yin;
 
   PetscFunctionBegin;
-  ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  for (i=0; i<nv; i++) {
-    ierr = VecViennaCLGetArrayRead(yyin[i],&ygpu);CHKERRQ(ierr);
-    try {
-      z[i] = viennacl::linalg::inner_prod(*xgpu,*ygpu);
-    } catch(char *ex) {
-      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+  if (xin->map->n > 0) {
+    ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
+    for (i=0; i<nv; i++) {
+      ierr = VecViennaCLGetArrayRead(yyin[i],&ygpu);CHKERRQ(ierr);
+      try {
+        z[i] = viennacl::linalg::inner_prod(*xgpu,*ygpu);
+      } catch(char *ex) {
+        SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+      }
+      ierr = VecViennaCLRestoreArrayRead(yyin[i],&ygpu);CHKERRQ(ierr);
     }
-    ierr = VecViennaCLRestoreArrayRead(yyin[i],&ygpu);CHKERRQ(ierr);
+
+    ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
+    ierr = PetscLogFlops(PetscMax(nv*(2.0*n-1),0.0));CHKERRQ(ierr);
+  } else {
+    for (i=0; i<nv; i++) z[i] = 0.0;
   }
-  
-  ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  ierr = PetscLogFlops(PetscMax(nv*(2.0*n-1),0.0));CHKERRQ(ierr);
   PetscFunctionReturn(0);
 }
 
   PetscErrorCode ierr;
 
   PetscFunctionBegin;
-  ierr = VecViennaCLGetArrayWrite(xin,&xgpu);CHKERRQ(ierr);
-  try {
-    *xgpu = viennacl::scalar_vector<PetscScalar>(xgpu->size(), alpha);
-  } catch(char *ex) {
-    SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+  if (xin->map->n > 0) {
+    ierr = VecViennaCLGetArrayWrite(xin,&xgpu);CHKERRQ(ierr);
+    try {
+      *xgpu = viennacl::scalar_vector<PetscScalar>(xgpu->size(), alpha);
+    } catch(char *ex) {
+      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+    }
+    ierr = VecViennaCLRestoreArrayWrite(xin,&xgpu);
   }
-  ierr = VecViennaCLRestoreArrayWrite(xin,&xgpu);
   PetscFunctionReturn(0);
 }
 
   PetscErrorCode ierr;
 
   PetscFunctionBegin;
-  if (alpha == 0.0) {
+  if (alpha == 0.0 && xin->map->n > 0) {
     ierr = VecSet_SeqViennaCL(xin,alpha);CHKERRQ(ierr);
     ierr = PetscLogFlops(xin->map->n);CHKERRQ(ierr);
-  } else if (alpha != 1.0) {
+  } else if (alpha != 1.0 && xin->map->n > 0) {
     ierr = VecViennaCLGetArrayReadWrite(xin,&xgpu);CHKERRQ(ierr);
     try {
       *xgpu *= alpha;
   PetscErrorCode ierr;
 
   PetscFunctionBegin;
-  if (xin != yin) {
+  if (xin != yin && xin->map->n > 0) {
     if (xin->valid_GPU_array == PETSC_VIENNACL_GPU) {
       ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
       ierr = VecViennaCLGetArrayWrite(yin,&ygpu);CHKERRQ(ierr);
   ViennaCLVector *xgpu,*ygpu;
 
   PetscFunctionBegin;
-  if (xin != yin) {
+  if (xin != yin && xin->map->n > 0) {
     ierr = VecViennaCLGetArrayReadWrite(xin,&xgpu);CHKERRQ(ierr);
     ierr = VecViennaCLGetArrayReadWrite(yin,&ygpu);CHKERRQ(ierr);
 
   ViennaCLVector *xgpu,*ygpu;
 
   PetscFunctionBegin;
-  if (a == 0.0) {
+  if (a == 0.0 && xin->map->n > 0) {
     ierr = VecScale_SeqViennaCL(yin,beta);CHKERRQ(ierr);
-  } else if (b == 1.0) {
+  } else if (b == 1.0 && xin->map->n > 0) {
     ierr = VecAXPY_SeqViennaCL(yin,alpha,xin);CHKERRQ(ierr);
-  } else if (a == 1.0) {
+  } else if (a == 1.0 && xin->map->n > 0) {
     ierr = VecAYPX_SeqViennaCL(yin,beta,xin);CHKERRQ(ierr);
-  } else if (b == 0.0) {
+  } else if (b == 0.0 && xin->map->n > 0) {
     ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
     ierr = VecViennaCLGetArrayReadWrite(yin,&ygpu);CHKERRQ(ierr);
     try {
     ierr = PetscLogFlops(xin->map->n);CHKERRQ(ierr);
     ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
     ierr = VecViennaCLRestoreArrayReadWrite(yin,&ygpu);CHKERRQ(ierr);
-  } else {
+  } else if (xin->map->n > 0) {
     ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
     ierr = VecViennaCLGetArrayReadWrite(yin,&ygpu);CHKERRQ(ierr);
     try {
   ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
   ierr = VecViennaCLGetArrayRead(yin,&ygpu);CHKERRQ(ierr);
   ierr = VecViennaCLGetArrayReadWrite(zin,&zgpu);CHKERRQ(ierr);
-  if (alpha == 0.0) {
+  if (alpha == 0.0 && xin->map->n > 0) {
     try {
       if (beta == 0.0) {
         *zgpu = gamma * *zgpu;
       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
     }
     ierr = PetscLogFlops(3.0*n);CHKERRQ(ierr);
-  } else if (beta == 0.0) {
+  } else if (beta == 0.0 && xin->map->n > 0) {
     try {
       if (gamma == 0.0) {
         *zgpu = alpha * *xgpu;
     } catch(char *ex) {
       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
     }
-  } else if (gamma == 0.0) {
+  } else if (gamma == 0.0 && xin->map->n > 0) {
     try {
       *zgpu = alpha * *xgpu + beta * *ygpu;
     } catch(char *ex) {
       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
     }
     ierr = PetscLogFlops(3.0*n);CHKERRQ(ierr);
-  } else {
+  } else if (xin->map->n > 0) {
     try {
       /* Split operation into two steps. This is not completely ideal, but avoids temporaries (which are far worse) */
       *zgpu *= gamma;
   ViennaCLVector *xgpu,*ygpu,*wgpu;
 
   PetscFunctionBegin;
-  ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  ierr = VecViennaCLGetArrayRead(yin,&ygpu);CHKERRQ(ierr);
-  ierr = VecViennaCLGetArrayReadWrite(win,&wgpu);CHKERRQ(ierr);
-  try {
-    *wgpu = viennacl::linalg::element_prod(*xgpu, *ygpu);
-  } catch(char *ex) {
-    SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+  if (xin->map->n > 0) {
+    ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
+    ierr = VecViennaCLGetArrayRead(yin,&ygpu);CHKERRQ(ierr);
+    ierr = VecViennaCLGetArrayReadWrite(win,&wgpu);CHKERRQ(ierr);
+    try {
+      *wgpu = viennacl::linalg::element_prod(*xgpu, *ygpu);
+    } catch(char *ex) {
+      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+    }
+    ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
+    ierr = VecViennaCLRestoreArrayRead(yin,&ygpu);CHKERRQ(ierr);
+    ierr = VecViennaCLRestoreArrayReadWrite(win,&wgpu);CHKERRQ(ierr);
+    ierr = PetscLogFlops(n);CHKERRQ(ierr);
   }
-  ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  ierr = VecViennaCLRestoreArrayRead(yin,&ygpu);CHKERRQ(ierr);
-  ierr = VecViennaCLRestoreArrayReadWrite(win,&wgpu);CHKERRQ(ierr);
-  ierr = PetscLogFlops(n);CHKERRQ(ierr);
   PetscFunctionReturn(0);
 }
 
   ViennaCLVector    *xgpu;
 
   PetscFunctionBegin;
-  ierr = PetscBLASIntCast(n,&bn);CHKERRQ(ierr);
-  ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  if (type == NORM_2 || type == NORM_FROBENIUS) {
-    try {
-      *z = viennacl::linalg::norm_2(*xgpu);
-    } catch(char *ex) {
-      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
-    }
-    ierr = PetscLogFlops(PetscMax(2.0*n-1,0.0));CHKERRQ(ierr);
-  } else if (type == NORM_INFINITY) {
+  if (xin->map->n > 0) {
+    ierr = PetscBLASIntCast(n,&bn);CHKERRQ(ierr);
     ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
-    try {
-      *z = viennacl::linalg::norm_inf(*xgpu);
-    } catch(char *ex) {
-      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+    if (type == NORM_2 || type == NORM_FROBENIUS) {
+      try {
+        *z = viennacl::linalg::norm_2(*xgpu);
+      } catch(char *ex) {
+        SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+      }
+      ierr = PetscLogFlops(PetscMax(2.0*n-1,0.0));CHKERRQ(ierr);
+    } else if (type == NORM_INFINITY) {
+      ierr = VecViennaCLGetArrayRead(xin,&xgpu);CHKERRQ(ierr);
+      try {
+        *z = viennacl::linalg::norm_inf(*xgpu);
+      } catch(char *ex) {
+        SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+      }
+      ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
+    } else if (type == NORM_1) {
+      try {
+        *z = viennacl::linalg::norm_1(*xgpu);
+      } catch(char *ex) {
+        SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+      }
+      ierr = PetscLogFlops(PetscMax(n-1.0,0.0));CHKERRQ(ierr);
+    } else if (type == NORM_1_AND_2) {
+      try {
+        *z     = viennacl::linalg::norm_1(*xgpu);
+        *(z+1) = viennacl::linalg::norm_2(*xgpu);
+      } catch(char *ex) {
+        SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
+      }
+      ierr = PetscLogFlops(PetscMax(2.0*n-1,0.0));CHKERRQ(ierr);
+      ierr = PetscLogFlops(PetscMax(n-1.0,0.0));CHKERRQ(ierr);
     }
     ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  } else if (type == NORM_1) {
-    try {
-      *z = viennacl::linalg::norm_1(*xgpu);
-    } catch(char *ex) {
-      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
-    }
-    ierr = PetscLogFlops(PetscMax(n-1.0,0.0));CHKERRQ(ierr);
   } else if (type == NORM_1_AND_2) {
-    try {
-      *z     = viennacl::linalg::norm_1(*xgpu);
-      *(z+1) = viennacl::linalg::norm_2(*xgpu);
-    } catch(char *ex) {
-      SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"ViennaCL error: %s", ex);
-    }
-    ierr = PetscLogFlops(PetscMax(2.0*n-1,0.0));CHKERRQ(ierr);
-    ierr = PetscLogFlops(PetscMax(n-1.0,0.0));CHKERRQ(ierr);
-  }
-  ierr = VecViennaCLRestoreArrayRead(xin,&xgpu);CHKERRQ(ierr);
-  //printf("VecNorm_SeqViennaCL=%1.5g\n",*z);
+    *z      = 0.0;
+    *(z+1)  = 0.0;
+  } else *z = 0.0;
   PetscFunctionReturn(0);
 }