         if((status = kblasXtrmm(handle, strIn, strOut,
                                 side, uplo, trans, diag,
                                 m1, n,
-                                alpha, Ac, incA, Ad,
-                                       Bc, incB, Bd, false, false
+                                alpha, h_A, incA, d_A,
+                                       h_B, incB, d_B, false, false
                                 )) != CUBLAS_STATUS_SUCCESS) return status;
 
         //if B is not already in, copy B block
-        if(!Bin)
-          check_error( status = cublasSetMatrixAsync( m2, n, sizeof(T), Bc + m1, incB, Bd + m1, incB, strIn), status);
+        if(!BIsIn)
+          check_error( status = cublasSetMatrixAsync( m2, n, sizeof(T), h_B + m1, incB, d_B + m1, incB, strIn), status);
         //copy in A block
-        check_error( status = cublasSetMatrixAsync( m1, m2, sizeof(T), Ac + m1 * incA, incA, Ad + m1 * incA, incA, strIn), status);
+        check_error( status = cublasSetMatrixAsync( m1, m2, sizeof(T), h_A + m1 * incA, incA, d_A + m1 * incA, incA, strIn), status);
         //wait for data to arrive
-        check_error( cudaEventRecord(eAin, strIn), CUBLAS_STATUS_INTERNAL_ERROR);
-        check_error( cudaStreamWaitEvent(strComp, eAin, 0), CUBLAS_STATUS_INTERNAL_ERROR);
+        check_error( cudaEventRecord(eDataIn, strIn), CUBLAS_STATUS_INTERNAL_ERROR);
+        check_error( cudaStreamWaitEvent(strComp, eDataIn, 0), CUBLAS_STATUS_INTERNAL_ERROR);
 
         if((status = cublasXgemm(handle,
                                  trans, noTrans,
                                  m1, n, m2,
-                                 alpha, Ad + m1 * incA, incA,
-                                        Bd + m1, incB,
-                                 &one,  Bd, incB)) != CUBLAS_STATUS_SUCCESS) return status;
-        //if stream is done computing and Bout, copy B back.
-        if(Bout){
+                                 alpha, d_A + m1 * incA, incA,
+                                        d_B + m1, incB,
+                                 &one,  d_B, incB)) != CUBLAS_STATUS_SUCCESS) return status;
+        //if stream is done computing and getBOut, copy B back.
+        if(getBOut){
           check_error( cudaEventRecord(eComp, strComp), CUBLAS_STATUS_INTERNAL_ERROR);
           check_error( cudaStreamWaitEvent(strOut, eComp, 0), CUBLAS_STATUS_INTERNAL_ERROR);
-          check_error( status = cublasGetMatrixAsync( m1, n, sizeof(T), Bd, incB, Bc, incB, strOut), status);
+          check_error( status = cublasGetMatrixAsync( m1, n, sizeof(T), d_B, incB, h_B, incB, strOut), status);
         }
 
         //B is already in, no need to copy in
         if((status = kblasXtrmm(handle, strIn, strOut,
                                 side, uplo, trans, diag,
                                 m2, n,
-                                alpha, Ac + m1 + m1 * incA, incA, Ad + m1 + m1 * incA,
-                                       Bc + m1, incB, Bd + m1, true, Bout
+                                alpha, h_A + m1 + m1 * incA, incA, d_A + m1 + m1 * incA,
+                                       h_B + m1, incB, d_B + m1, true, getBOut
                                 )) != CUBLAS_STATUS_SUCCESS) return status;
       }
       //Left / Upper / [Conj]Trans
       else{
-        if((status = kblasXtrmm(handle,
+        if((status = kblasXtrmm(handle, strIn, strOut,
                                 side, uplo, trans, diag,
                                 m2, n,
-                                alpha, Ac+m1+m1*incA, incA,
-                                       Bc+m1, incB
-                                )) != CUBLAS_STATUS_SUCCESS) return status;
+                                alpha, h_A+m1+m1*incA, incA, d_A+m1+m1*incA,
+                                       h_B+m1, incB, d_B+m1, false, false
+                                )) != CUBLAS_STATUS_SUCCESS) return status;
+
+        //if B is not already in, copy B block
+        if(!BIsIn)
+          check_error( status = cublasSetMatrixAsync( m1, n, sizeof(T), h_B, incB, d_B, incB, strIn), status);
+        //copy in A block
+        check_error( status = cublasSetMatrixAsync( m1, m2, sizeof(T), h_A + m1 * incA, incA, d_A + m1 * incA, incA, strIn), status);
+        //wait for data to arrive
+        check_error( cudaEventRecord(eDataIn, strIn), CUBLAS_STATUS_INTERNAL_ERROR);
+        check_error( cudaStreamWaitEvent(strComp, eDataIn, 0), CUBLAS_STATUS_INTERNAL_ERROR);
 
         if((status = cublasXgemm(handle,
                                  trans, noTrans,
                                  m2, n, m1,
-                                 alpha, Ac+m1*incA, incA,
-                                        Bc, incB,
-                                 &one,  Bc+m1, incB
-                                 )) != CUBLAS_STATUS_SUCCESS) return status;
-
-        if((status = kblasXtrmm(handle,
+                                 alpha, d_A+m1*incA, incA,
+                                        d_B, incB,
+                                 &one,  d_B+m1, incB
+                                 )) != CUBLAS_STATUS_SUCCESS) return status;
+
+        //if stream is done computing and getBOut, copy B back.
+        if(getBOut){
+          check_error( cudaEventRecord(eComp, strComp), CUBLAS_STATUS_INTERNAL_ERROR);
+          check_error( cudaStreamWaitEvent(strOut, eComp, 0), CUBLAS_STATUS_INTERNAL_ERROR);
+          check_error( status = cublasGetMatrixAsync( m2, n, sizeof(T), d_B+m1, incB, h_B+m1, incB, strOut), status);
+        }
+
+        if((status = kblasXtrmm(handle, strIn, strOut,
                                 side, uplo, trans, diag,
                                 m1, n,
-                                alpha, Ac, incA,
-                                       Bc, incB
+                                alpha, h_A, incA, d_A,
+                                       h_B, incB, d_B, true, getBOut
                                 )) != CUBLAS_STATUS_SUCCESS) return status;
       }
 

    cudaStream_t compStream;
    check_error( cublasGetStream_v2(handle, &compStream), CUBLAS_STATUS_INTERNAL_ERROR);
    check_error( cudaStreamSynchronize( compStream ), CUBLAS_STATUS_INTERNAL_ERROR);
    check_error( status = cublasGetMatrixAsync( m, n, sizeof(T), Bd, incB, Bc, incB, inStream), status);
  }
  //revoke streams
  check_error( cudaStreamDestroy( inStream ), CUBLAS_STATUS_INTERNAL_ERROR);
  if(DO_INLINE_BOUT)
    check_error( cudaStreamDestroy( outStream ), CUBLAS_STATUS_INTERNAL_ERROR);
  //free device memory
  check_error( cudaFree( Ad ), CUBLAS_STATUS_INTERNAL_ERROR );
  check_error( cudaFree( Bd ), CUBLAS_STATUS_INTERNAL_ERROR );  
  return CUBLAS_STATUS_SUCCESS;
}



    int Am = (side == CUBLAS_SIDE_LEFT) ? m : n;
    //if B is not already in, copy in B block
    if(!BIsIn)
      check_error( status = cublasSetMatrixAsync( m, n, sizeof(T), h_B, incB, d_B, incB, strIn ), status);
    //copy in A block
    check_error( status = cublasSetMatrixAsync( Am, Am, sizeof(T), h_A, incA, d_A, incA, strIn ), status);
    //wait for data to arrive
    check_error( cudaEventRecord(eDataIn, strIn), CUBLAS_STATUS_INTERNAL_ERROR);
    check_error( cudaStreamWaitEvent(strComp, eDataIn, 0), CUBLAS_STATUS_INTERNAL_ERROR);
  
    if( (status = Xtrmm( handle,
                         side, uplo, trans, diag,
                         m, n,
                         alpha, d_A, incA,
                                d_B, incB ) ) != CUBLAS_STATUS_SUCCESS ) return status;

    //if stream is done computing and getBOut, copy B back.
    if(getBOut){
      check_error( cudaEventRecord(eComp, strComp), CUBLAS_STATUS_INTERNAL_ERROR);
      check_error( cudaStreamWaitEvent(strOut, eComp, 0), CUBLAS_STATUS_INTERNAL_ERROR);
      check_error( status = cublasGetMatrixAsync( m, n, sizeof(T), d_B, incB, h_B, incB, strOut), status);
    }
  }else
  if(side == CUBLAS_SIDE_LEFT){
