Ejemplo n.º 1
0
/*
 * Solves lapl(u) x = b, for x, given b, using Conjugate Gradient
 */
void
cg(latparams lp, field **x, field **b, link **g)
{
  size_t L = lp.L;
  int max_iter = 100;
  float tol = 1e-9;

  /* Temporary fields needed for CG */
  field **r = new_field(lp);
  field **p = new_field(lp);
  field **Ap = new_field(lp);

  /* Initial residual and p-vector */
  lapl(lp, r, x, g);
  xmy(lp, b, r);
  xeqy(lp, p, r);

  /* Initial r-norm and b-norm */
  float rr = xdotx(lp, r);  
  float bb = xdotx(lp, b);
  double t_lapl = 0;
  int iter = 0;
  for(iter=0; iter<max_iter; iter++) {
    printf(" %6d, res = %+e\n", iter, rr/bb);
    if(sqrt(rr/bb) < tol)
      break;
    double t = stop_watch(0);
    lapl(lp, Ap, p, g);
    t_lapl += stop_watch(t);
    float pAp = xdoty(lp, p, Ap);
    float alpha = rr/pAp;
    axpy(lp, alpha, p, x);
    axpy(lp, -alpha, Ap, r);
    float r1r1 = xdotx(lp, r);
    float beta = r1r1/rr;
    xpay(lp, r, beta, p);
    rr = r1r1;
  }

  /* Recompute residual after convergence */
  lapl(lp, r, x, g);
  xmy(lp, b, r);
  rr = xdotx(lp, r);

  double beta_fp = 50*((double)L*L*L)/(t_lapl/(double)iter)*1e-9;
  double beta_io = 40*((double)L*L*L)/(t_lapl/(double)iter)*1e-9;
  printf(" Converged after %6d iterations, res = %+e\n", iter, rr/bb);  
  printf(" Time in lapl(): %+6.3e sec/call, %4.2e Gflop/s, %4.2e GB/s\n",
	 t_lapl/(double)iter, beta_fp, beta_io);  

  del_field(r);
  del_field(p);
  del_field(Ap);
  return;
}
Ejemplo n.º 2
0
int
main(int argc, char *argv[])
{
  if(argc != 4) {
    usage(argv);
    exit(1);
  }

  char *e;
  size_t L = (int)strtoul(argv[1], &e, 10);
  if(*e != '\0') {
    usage(argv);
    exit(2);
  }
  
  size_t Sy = (int)strtoul(argv[2], &e, 10);
  if(*e != '\0') {
    usage(argv);
    exit(2);
  }
  
  size_t Sx = (int)strtoul(argv[3], &e, 10);
  if(*e != '\0') {
    usage(argv);
    exit(2);
  }

  latparams lp = init_latparams(L, Sy, Sx);
  field **b = new_field(lp);
  field **x = new_field(lp);
  link **g = new_links(lp);

  rand_links(lp, g);
  rand_field(lp, b);
  zero_field(lp, x);

  cg(lp, x, b, g);
  
  del_field(b);
  del_field(x);
  del_links(g);
  return 0;
}
Ejemplo n.º 3
0
static void vscroll_fields( a_field **ht, SAREA use, int incr )
{
    a_field             **p;
    a_field             **next;

    if( incr == 0 )
        return;
    for( p = ht; *p && (*p)->area.row < use.row + use.height ; p = next ) {
        next = &((*p)->next);
        if( (*p)->area.row >= use.row ) {
            if((incr > 0 && (*p)->area.row < use.row + incr )
            || (incr < 0 && (*p)->area.row - incr >= use.row + use.height) ) {
                next = p;
                del_field( *ht, p, true );
            } else {
                (*p)->area.row -= incr;
            }
        }
    }
}
Ejemplo n.º 4
0
static void free_fields( a_field **ht )
{
    while( *ht != NULL ) {
        del_field( *ht, ht, false );
    }
}
Ejemplo n.º 5
0
void OldDatabaseBackend::submit(DBOperation *operation)
{
    std::lock_guard<std::mutex> lock(m_submit_lock);
    switch(operation->type()) {
    case DBOperation::OperationType::CREATE_OBJECT: {
        ObjectData dbo(operation->dclass()->get_id());
        dbo.fields = operation->set_fields();

        doid_t doid = create_object(dbo);
        if(doid == INVALID_DO_ID || doid < m_min_id || doid > m_max_id) {
            operation->on_failure();
        } else {
            operation->on_complete(doid);
        }
        return;
    }
    break;
    case DBOperation::OperationType::DELETE_OBJECT: {
        delete_object(operation->doid());
        operation->on_complete();
        return;
    }
    break;
    case DBOperation::OperationType::GET_OBJECT:
    case DBOperation::OperationType::GET_FIELDS: {
        ObjectData dbo;
        if(!get_object(operation->doid(), dbo)) {
            operation->on_failure();
            return;
        }

        const dclass::Class *dclass = g_dcf->get_class_by_id(dbo.dc_id);
        if(!dclass || !operation->verify_class(dclass)) {
            operation->on_failure();
            return;
        }

        // Send object to server
        DBObjectSnapshot *snap = new DBObjectSnapshot();
        snap->m_dclass = dclass;
        snap->m_fields = dbo.fields;
        operation->on_complete(snap);
        return;
    }
    break;
    case DBOperation::OperationType::SET_FIELDS: {
        // Check the object's class and fields
        const dclass::Class *dclass = get_class(operation->doid());
        if(!dclass || !operation->verify_class(dclass)) {
            operation->on_failure();
            return;
        }

        // If everthing checks out, update our fields
        for(auto it = operation->set_fields().begin(); it != operation->set_fields().end(); ++it) {
            if(!it->second.empty()) {
                set_field(operation->doid(), it->first, it->second);
            } else {
                del_field(operation->doid(), it->first);
            }
        }

        operation->on_complete();
        return;
    }
    break;
    case DBOperation::UPDATE_FIELDS: {
        // TODO: This can be implemented *much* more efficiently, but for now:
        ObjectData dbo;
        if(!get_object(operation->doid(), dbo)) {
            operation->on_failure();
            return;
        }

        // Make sure all the fields are valid for the class
        const dclass::Class *dclass = g_dcf->get_class_by_id(dbo.dc_id);
        if(!dclass || !operation->verify_class(dclass)) {
            operation->on_failure();
            return;
        }

        // Check to make sure the update is valid
        for(auto it = operation->criteria_fields().begin(); it != operation->criteria_fields().end();
            ++it) {
            if(dbo.fields[it->first] != it->second) {
                DBObjectSnapshot *snap = new DBObjectSnapshot();
                snap->m_fields = dbo.fields;
                operation->on_criteria_mismatch(snap);
                return;
            }
        }

        // Everything checks out, so update the fields
        for(auto it = operation->set_fields().begin(); it != operation->set_fields().end(); ++it) {
            if(!it->second.empty()) {
                set_field(operation->doid(), it->first, it->second);
            } else {
                del_field(operation->doid(), it->first);
            }
        }

        operation->on_complete();
        return;
    }
    }
}