/* * 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; }
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; }
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; } } } }
static void free_fields( a_field **ht ) { while( *ht != NULL ) { del_field( *ht, ht, false ); } }
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; } } }