/*------------------------------------------------------------------------ * gettime - Get xinu time in seconds past Jan 1, 1970 *------------------------------------------------------------------------ */ status gettime( uint32 *timvar /* Location to store the result */ ) { uint32 now; /* Current time (UCT) */ int32 retval; /* Return value from call */ /* Get current time in UCT representation (GMT) */ retval = getutime(&now); if (retval == SYSERR) { return SYSERR; } /* Adjust to xinu time and store result */ *timvar = utim2ltim(now); return OK; }
/*------------------------------------------------------------------------ * gettime - get local time in seconds past Jan 1, 1970 *------------------------------------------------------------------------ */ status gettime( uint32 *timvar /* location to store the result */ ) { uint32 now; /* current time (UCT) */ int32 retval; /* return value from call */ /* Get current time in UCT representation (GMT) */ retval = getutime(&now); if (retval == SYSERR) { return SYSERR; } /* Adjust to local time and store result */ *timvar = utim2ltim(now) + (Date.dt_daylight ? SECPERHR: 0); return OK; }
static void test_getutime() { long long t1 = getutime(); long long t2 = getutime(); CU_ASSERT_TRUE(t2 >= t1); }
double bundle_solve (bundle_t *bundle, int max_iterations, int max_qp_iterations, double subgnorm_opt_tol, double linerr_opt_tol, double z_cutoff, void *data, double (*bundle_callback) (void*, double*, double*), double init_scale, double acceptable_model_exactness, double *init_x, double init_z, double *init_subg) /* * Maximizes a convex non-differentiable function using the bundle method, until reaching a value or iteration threshold (z_cutoff and max_iterations, respectively), or until fulfilling optimality criteria (see subgnorm_opt_tol and linerr_opt_tol): * - max_qp_iterations: maximum enumerations of mask to solve QP * - subgnorm_opt_tol: threshold below which a subgradient norm are deemed to be zero, * - linerr_opt_tol: threshold below which a linearization error is deemed to be zero, * - z_cutoff: threshold above which z no longer needs to be maximized any further, * - data: a pointer passed on to bundle_callback (see bundle_step), * - init_scale: initial QP penalty, * - acceptable_model_exactness: if the ratio between actual and predicted improvement is above this value, then the bundle method performs a major step, * - init_x: initial values for best_x, may be NULL in which case 0 is used, * - init_z: initial value for best_z, ignored if init_x or init_subg are NULL, * - init_subg: subgradient at init_x, may be NULL. */ { int i; bundle_status_t status; // initialize the bundle if (NULL == init_x) { for (i = 0; i < bundle->n; i++) bundle->best_x[i] = 0.0; bundle->actual_z = bundle_callback(data, bundle->best_x, &bundle->a[0]); } else { memcpy(bundle->best_x, init_x, bundle->n * sizeof(double)); if (NULL == init_subg) { bundle->actual_z = bundle_callback(data, bundle->best_x, &bundle->a[0]); } else { memcpy(&bundle->a[0], init_subg, bundle->n * sizeof(double)); bundle->actual_z = init_z; } } bundle->max_z = bundle->best_z = bundle->actual_z; memcpy(bundle->max_x, bundle->best_x, bundle->n * sizeof(double)); memcpy(bundle->best_subg, &bundle->a[0], bundle->n * sizeof(double)); bundle->m = 1; bundle->most_recent_i = 0; bundle->b[0] = bundle->actual_z; bundle->aat[0] = ddot(bundle->n, &bundle->a[0], &bundle->a[0]); bundle->scale = init_scale; bundle->time_bundle = bundle->time_qp = bundle->time_callback = 0.0; //printf("it: 0\tpen: %f\tmax: %f\n", bundle->scale, bundle->actual_z); // find a maximum within max_iterations or until greater than z_cutoff bundle->time_bundle -= getutime(1); for (bundle->n_iterations = 1; bundle->n_iterations < max_iterations; bundle->n_iterations++) { // perform bundle step status = bundle_step(bundle, max_qp_iterations, subgnorm_opt_tol, linerr_opt_tol, z_cutoff, data, bundle_callback, init_scale, acceptable_model_exactness); // check for termination criteria if (bundle_status_cutoff == status || bundle_status_optimal == status || bundle_status_tolerably_optimal == status) break; } bundle->time_bundle += getutime(1); // terminate the bundle search return bundle->max_z; }
bundle_status_t bundle_step (bundle_t *bundle, int max_qp_iterations, double subgnorm_opt_tol, double linerr_opt_tol, double z_cutoff, void* data, double (*bundle_callback) (void*, double*, double*), double init_scale, double acceptable_model_exactness) /* * Performs one iteration of the bundle method: * - max_qp_iterations: maximum enumerations of mask to solve QP * - subgnorm_opt_tol: threshold below which a subgradient norm are deemed to be zero, * - linerr_opt_tol: threshold below which a linearization error is deemed to be zero, * - z_cutoff: threshold above which z no longer needs to be maximized any further, * - data: a pointer passed on to bundle_callback, * - double bundle_callback(void *data, double *x, double *subg): must evalute and return z at x, writing the subgradient at x in subg. * - init_scale: initial penalty parameter * - acceptable_model_exactness: if the ratio between actual and predicted improvement is above this value, then the bundle method performs a major step, */ { int new_subg_i = -1; double roh; double previous_best_z = bundle->best_z; double *new_subg = NULL; double subg_delta, linerr_opt_delta, agg_subg_square; int i; //printf("it: %i\tpen: %f\t", bundle->n_iterations, bundle->scale); // guess where the x yielding the optimal z lies bundle->time_qp -= getutime(1); bundle->guessed_z = bundle_guess(bundle, max_qp_iterations); bundle->time_qp += getutime(1); linerr_opt_delta = bundle->agg_b - bundle->best_z; agg_subg_square = ddot(bundle->n, bundle->agg_subg, bundle->agg_subg); //printf("z-est: %f ", bundle->guessed_z); // update the bundle new_subg_i = bundle_update(bundle, agg_subg_square); // evaluate guessed x and subgradient at guessed x new_subg = &bundle->a[new_subg_i * bundle->n]; bundle->time_callback -= getutime(1); bundle->actual_z = bundle_callback(data, bundle->x, new_subg); bundle->time_callback += getutime(1); // update maximums if (bundle->actual_z > bundle->max_z) { bundle->max_z = bundle->actual_z; memcpy(bundle->max_x, bundle->x, bundle->n * sizeof(double)); if (bundle->max_z >= z_cutoff) { //printf("(%f)*\tcutoff\n", bundle->actual_z); return bundle_status_cutoff; } } //printf("(%f)%c\t", bundle->actual_z, (bundle->actual_z == bundle->max_z) ? '*' : ' '); // update A.A^T with new subgradient for (i = 0; i < bundle->m; i++) bundle->aat[i * bundle->max_m + new_subg_i] = bundle->aat[new_subg_i * bundle->max_m + i] = ddot(bundle->n, &bundle->a[i * bundle->n], new_subg); // check for optimality, i.e. if new subgradient is a null vector if (bundle->aat[new_subg_i * bundle->max_m + new_subg_i] < bundle->epsilon) { //printf("optimal\n"); return bundle_status_optimal; } //printf("agg.err: %f\tagg.norm: %f\t", linerr_opt_delta, sqrt(agg_subg_square)); if (linerr_opt_delta <= linerr_opt_tol && agg_subg_square <= subgnorm_opt_tol * subgnorm_opt_tol) { //printf("optimal withing tolerances\n"); return bundle_status_tolerably_optimal; } // check improvement roh = (bundle->actual_z - previous_best_z) / (bundle->guessed_z - previous_best_z + bundle->epsilon); //printf("roh: %.2f\t", roh); if (roh >= acceptable_model_exactness) { // Major Step // update penalization parameter bundle->scale daxpy(bundle->n, -1.0, new_subg, bundle->best_subg); subg_delta = ddot(bundle->n, bundle->best_subg, bundle->best_subg); bundle->scale = (subg_delta == 0.0) ? init_scale : (1.0 / (1.0 / bundle->scale + ddot(bundle->n, bundle->kkt_x, bundle->best_subg) / subg_delta)); // center the penalized QP to new maximum bundle->best_z = bundle->actual_z; memcpy(bundle->best_x, bundle->x, bundle->n * sizeof(double)); memcpy(bundle->best_subg, new_subg, bundle->n * sizeof(double)); // update QP rhs for new center memcpy(bundle->b, bundle->next_b, bundle->max_m * sizeof(double)); bundle->b[new_subg_i] = bundle->actual_z; // the most recent subgradient may not be active bundle->most_recent_i = -1; //printf("major step\n"); return bundle_status_major_step; } else { // Minor Step // update rhs for new subgradient for existing center bundle->b[new_subg_i] = bundle->actual_z - ddot(bundle->n, new_subg, bundle->kkt_x); //printf("\n"); // the most recent subgradient is certainly active bundle->most_recent_i = new_subg_i; return bundle_status_minor_step; } }
double bundle_guess (bundle_t* bundle, int max_qp_iterations) /* * Guesses where the x giving the estimated best z lies by solving the penalized bundle QP. * * If the resolution of the QP takes more than max_qp_iterations mask guesses, it is aborted, * and the bundle is repopulated as if it were aggregated in the previous bundle iteration, * in other words reduced to only 2 subgradients, the previous aggregate and the previous evaluated subgradient. * The QP is then solved anew, and completely. * The procedure then computes x, the aggregate subgradient and the linearization error for this QP. * */ { int solved; int i, n_iter = max_qp_iterations; bundle->time_qp -= getutime(1); bundle->kkt_z = INFINITY; solved = bundle_qp_solve(bundle, 0ULL, bundle->m, &n_iter); if (!solved) { bundle->time_qp += getutime(1); ++bundle->n_iterations; //printf("trim\nit: %i\tpen: %f\t", bundle->n_iterations, bundle->scale); // trim a if (bundle->m != 2) memcpy(&bundle->a[bundle->n], &bundle->a[(bundle->m - 1) * bundle->n], bundle->n * sizeof(double)); memcpy(&bundle->a[0], bundle->agg_subg, bundle->n * sizeof(double)); // recompute aat bundle->aat[0] = ddot(bundle->n, bundle->agg_subg, bundle->agg_subg); bundle->aat[bundle->max_m + 1] = bundle->aat[(bundle->m - 1) * bundle->max_m + bundle->m - 1]; bundle->aat[1] = bundle->aat[bundle->max_m] = ddot(bundle->n, bundle->agg_subg, &bundle->a[bundle->n]); // trim b bundle->b[0] = (bundle->most_recent_i == -1) ? bundle->agg_next_b : bundle->agg_b; bundle->b[1] = bundle->b[bundle->m - 1]; // update bundle information and solve again bundle->most_recent_i = -1; bundle->m = 2; bundle->time_qp -= getutime(1); n_iter = (max_qp_iterations < 3) ? 3 : max_qp_iterations; bundle->kkt_z = INFINITY; solved = bundle_qp_solve(bundle, 0ULL, bundle->m, &n_iter); assert(solved); } // compute the aggregate subgradient using BLAS (in bundle->agg_subg[]) bundle->agg_b = bundle->agg_next_b = 0.0; bzero(bundle->agg_subg, bundle->n * sizeof(double)); for (i = 0; i < bundle->kkt_m; i++) { daxpy(bundle->n, bundle->kkt_mul[i], &bundle->a[bundle->kkt_i[i] * bundle->n], bundle->agg_subg); bundle->agg_b += bundle->kkt_mul[i] * bundle->b[bundle->kkt_i[i]]; bundle->agg_next_b += bundle->kkt_mul[i] * bundle->next_b[bundle->kkt_i[i]]; } // compute local x memcpy(bundle->kkt_x, bundle->agg_subg, bundle->n * sizeof(double)); dscal(bundle->n, 1.0 / bundle->scale, bundle->kkt_x); // compute global x memcpy(bundle->x, bundle->best_x, bundle->n * sizeof(double)); daxpy(bundle->n, 1.0, bundle->kkt_x, bundle->x); bundle->time_qp += getutime(1); // return guessed z return bundle->kkt_mul[bundle->kkt_m]; }
//------------------------------------------------------------------------ // rwhod - Periodically clean cache and (optionally) send rwho packets //------------------------------------------------------------------------ PROCESS rwhod(void) { int i, j; struct rwent *rwptr; struct rwent *myptr; struct rwhopac *rpacptr; struct rw_who *rwwptr; struct epacket *packet; IPaddr mynet; long now; int len; int ps; // Initialize rwho information Rwho.rwnent = 1; Rwho.rwsend = TRUE; getutime(&Rwho.rwbtime); myptr = &Rwho.rwcache[0]; getname(myptr->rwmach, RMACLEN); myptr->rwboot = myptr->rwlast = myptr->rwslast = Rwho.rwbtime; for (i = 0; i < 3; i++) myptr->rwload[i] = 0L; myptr->rwusers = 1; getnet(mynet); for (; TRUE; sleep(RWDELAY)) { getutime(&now); myptr->rwlast = myptr->rwslast = now; ps = disable(); for (i = 0; i < Rwho.rwnent; i++) { rwptr = &Rwho.rwcache[i]; if (now - rwptr->rwlast > RWMAXDT) { Rwho.rwnent--; for (j = i--; j < Rwho.rwnent; j++) Rwho.rwcache[j] = Rwho.rwcache[j + 1]; } } restore(ps); if (!Rwho.rwsend) continue; packet = (struct epacket *)getbuf(Net.netpool); rpacptr = (struct rwhopac *) ((struct udp *) (((struct ip *)packet->ep_data)->i_data))->u_data; rpacptr->rw_vers = RWVERSION; rpacptr->rw_type = RWSTATUS; rpacptr->rw_sndtim = hl2net(now); rpacptr->rw_rtim = 0L; getname(rpacptr->rw_host, sizeof(rpacptr->rw_host)); for (j = 0; j < RWNLOAD; j++) rpacptr->rw_load[j] = 0L; rpacptr->rw_btim = hl2net(Rwho.rwbtime); len = RWMINP; if (marked(Shl.shmark) && Shl.shused) { rwwptr = &rpacptr->rw_rww[0]; strlcpy(rwwptr->rw_tty, "Console", RWNLEN); strncpy(rwwptr->rw_nam, Shl.shuser, RWNLEN); rwwptr->rw_ton = hl2net(Shl.shlogon); rwwptr->rw_idle = hl2net(now - Shl.shlast); len += sizeof(struct rw_who); } udpsend(mynet, URWHO, URWHO, packet, len); } }