Beispiel #1
0
StatusCode Xtbmv<T>::DoTbmv(const Layout layout, const Triangle triangle,
                            const Transpose a_transpose, const Diagonal diagonal,
                            const size_t n, const size_t k,
                            const Buffer<T> &a_buffer, const size_t a_offset, const size_t a_ld,
                            const Buffer<T> &x_buffer, const size_t x_offset, const size_t x_inc) {

  // Creates a copy of X: a temporary scratch buffer
  auto scratch_buffer = Buffer<T>(context_, n*x_inc + x_offset);
  try {
    x_buffer.CopyTo(queue_, n*x_inc + x_offset, scratch_buffer);
  } catch (...) { } // Continues: error-code is returned in MatVec

  // The data is either in the upper or lower triangle
  size_t is_upper = ((triangle == Triangle::kUpper && layout != Layout::kRowMajor) ||
                     (triangle == Triangle::kLower && layout == Layout::kRowMajor));

  // Adds '2' to the parameter if the diagonal is unit
  auto parameter = (diagonal == Diagonal::kUnit) ? is_upper + 2 : is_upper;

  // Runs the generic matrix-vector multiplication, disabling the use of fast vectorized kernels.
  // The specific triangular banded matrix-accesses are implemented in the kernel guarded by the
  // ROUTINE_TBMV define.
  auto fast_kernels = false;
  auto status = MatVec(layout, a_transpose,
                       n, n, static_cast<T>(1),
                       a_buffer, a_offset, a_ld,
                       scratch_buffer, x_offset, x_inc, static_cast<T>(0),
                       x_buffer, x_offset, x_inc,
                       fast_kernels, fast_kernels,
                       parameter, false, k, 0);

  // Returns the proper error code (renames vector Y to X)
  switch(status) {
    case StatusCode::kInvalidVectorY:      return StatusCode::kInvalidVectorX;
    case StatusCode::kInvalidIncrementY:   return StatusCode::kInvalidIncrementX;
    case StatusCode::kInsufficientMemoryY: return StatusCode::kInsufficientMemoryX;
    default: return status;
  }
}
Beispiel #2
0
void Xspmv<T>::DoSpmv(const Layout layout, const Triangle triangle,
                      const size_t n,
                      const T alpha,
                      const Buffer<T> &ap_buffer, const size_t ap_offset,
                      const Buffer<T> &x_buffer, const size_t x_offset, const size_t x_inc,
                      const T beta,
                      const Buffer<T> &y_buffer, const size_t y_offset, const size_t y_inc) {

  // The data is either in the upper or lower triangle
  size_t is_upper = ((triangle == Triangle::kUpper && layout != Layout::kRowMajor) ||
                     (triangle == Triangle::kLower && layout == Layout::kRowMajor));

  // Runs the generic matrix-vector multiplication, disabling the use of fast vectorized kernels.
  // The specific symmetric packed matrix-accesses are implemented in the kernel guarded by the
  // ROUTINE_SPMV define.
  bool fast_kernels = false;
  MatVec(layout, Transpose::kNo,
         n, n, alpha,
         ap_buffer, ap_offset, n,
         x_buffer, x_offset, x_inc, beta,
         y_buffer, y_offset, y_inc,
         fast_kernels, fast_kernels,
         is_upper, true, 0, 0);
}
Beispiel #3
0
PetscErrorCode FiberFieldInitLocalFiber( FiberField fibers, int numVerticies, PetscReal l0,
    FiberTypeID vertexType, FiberTypeID edgeType, FiberTypeID bendingEdgeType )
{
  int i;
  int flen = numVerticies;
  Array fiber = fibers->fiber;
  Vertex v0;
  Vertex v1;
  Vertex v2;
  PetscRandom rnd = fibers->rnd;
  PetscBool hitBoundary;
  Coor rndSphere;
  Coor n;
  Coor r;
  Coor s;
  Coor d;
  Coor lmin = fibers->localBounds.min;
  Coor lmax = fibers->localBounds.max;
  PetscReal NORTH_HEMISPHERE = 0.65;
  const PetscReal WHOLE_SPHERE = 0.0;
  const PetscReal DELTA = PETSC_SMALL;
  PetscErrorCode ierr;

  PetscFunctionBegin;
  ierr = ArraySetSize(fiber, 0); CHKERRQ(ierr);
  ierr = ArraySetMaxSize( fibers->verts, flen + ArrayLength(fibers->verts) ); CHKERRQ(ierr);

  // add small delta
  lmin.x += DELTA;
  lmin.y += DELTA;
  lmin.z += DELTA;
  lmax.x -= DELTA;
  lmax.y -= DELTA;
  lmax.z -= DELTA;

  ierr = PetscOptionsGetReal(0,"-fiber_bend",&NORTH_HEMISPHERE,0); CHKERRQ(ierr);

  // Initialize v0 anywhere in the local bbox
  ierr = FiberFieldAddVertex( fibers, vertexType, &v0); CHKERRQ(ierr);
  ierr = ArrayAppendPtr( fiber, v0); CHKERRQ(ierr);
  PetscRandomGetValue(rnd,&v0->X.x); // [0,1]
  PetscRandomGetValue(rnd,&v0->X.y); // [0,1]
  PetscRandomGetValue(rnd,&v0->X.z); // [0,1]
  // map [0, 1] to local bbox [lmin, lmax]
  v0->X.x = (1-v0->X.x) * lmin.x + v0->X.x * lmax.x;
  v0->X.y = (1-v0->X.y) * lmin.y + v0->X.y * lmax.y;
  v0->X.z = (1-v0->X.z) * lmin.z + v0->X.z * lmax.z;

  // Initialize v1 anywhere spherically from v0
  ierr = FiberFieldAddVertex( fibers, vertexType, &v1); CHKERRQ(ierr);
  ierr = ArrayAppendPtr( fiber, v1); CHKERRQ(ierr);
  SphericalDistribution(rnd, WHOLE_SPHERE, &d);
  v1->X.x = v0->X.x + l0*d.x;
  v1->X.y = v0->X.y + l0*d.y;
  v1->X.z = v0->X.z + l0*d.z;
  BoundaryCheck( lmin, lmax, &v1->X, &hitBoundary );
  if (hitBoundary) {
    ierr = FiberFieldAddEdge( fibers, v0, v1, edgeType, l0 ); CHKERRQ(ierr);
    PetscFunctionReturn(0);
  }

  for (i = 1; i < flen-1; i++ ) {
    ierr = FiberFieldAddVertex( fibers, vertexType, &v2); CHKERRQ(ierr);
    ierr = ArrayAppendPtr( fiber, v2); CHKERRQ(ierr);

    SphericalDistribution(rnd, NORTH_HEMISPHERE, &rndSphere);
    Rotation(v0->X,v1->X,&n,&r,&s);
    MatVec(&n,&r,&s,&rndSphere, &d);

    v2->X.x = v1->X.x + l0*d.x;
    v2->X.y = v1->X.y + l0*d.y;
    v2->X.z = v1->X.z + l0*d.z;

    BoundaryCheck( lmin, lmax, &v2->X, &hitBoundary );
    if (hitBoundary) {
      break;
    }

    v0 = v1;
    v1 = v2;
  }

  flen = ArrayLength( fiber );
  Vertex *v = ArrayGetData( fiber );
  // Link fiber edges: v_i -- v_i+1
  for (i = 0; i < flen-1; i++) {
    ierr = FiberFieldAddEdge( fibers, v[i], v[i+1], edgeType, l0 ); CHKERRQ(ierr);
  }

  // Link bending edges: v_i-1 -- v_i+1
  for (i = 1; i < flen-1; i++) {
    ierr = FiberFieldAddEdge( fibers, v[i-1], v[i+1], bendingEdgeType, 2*l0 ); CHKERRQ(ierr);
  }

  PetscFunctionReturn(0);
}