static void print_chip_power(const sensors_chip_name *name, const sensors_feature *feature, int label_size) { double val; const sensors_subfeature *sf; struct sensor_subfeature_data sensors[6]; struct sensor_subfeature_data alarms[3]; int sensor_count, alarm_count; char *label; const char *unit; int i; if (!(label = sensors_get_label(name, feature))) { fprintf(stderr, "ERROR: Can't get label of feature %s!\n", feature->name); return; } print_label(label, label_size); free(label); sensor_count = alarm_count = 0; /* Power sensors come in 2 flavors: instantaneous and averaged. To keep things simple, we assume that each sensor only implements one flavor. */ sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_POWER_INPUT); get_sensor_limit_data(name, feature, sf ? power_inst_sensors : power_avg_sensors, sensors, ARRAY_SIZE(sensors), &sensor_count, alarms, ARRAY_SIZE(alarms), &alarm_count); /* Add sensors common to both flavors. */ get_sensor_limit_data(name, feature, power_common_sensors, sensors, ARRAY_SIZE(sensors), &sensor_count, alarms, ARRAY_SIZE(alarms), &alarm_count); if (!sf) sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_POWER_AVERAGE); if (sf && get_input_value(name, sf, &val) == 0) { scale_value(&val, &unit); printf("%6.2f %sW ", val, unit); } else printf(" N/A "); for (i = 0; i < sensor_count; i++) scale_value(&sensors[i].value, &sensors[i].unit); print_limits(sensors, sensor_count, alarms, alarm_count, label_size, "%s = %6.2f %sW"); printf("\n"); }
static void print_chip_energy(const sensors_chip_name *name, const sensors_feature *feature, int label_size) { double val; const sensors_subfeature *sf; char *label; const char *unit; if (!(label = sensors_get_label(name, feature))) { fprintf(stderr, "ERROR: Can't get label of feature %s!\n", feature->name); return; } print_label(label, label_size); free(label); sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_ENERGY_INPUT); if (sf && get_input_value(name, sf, &val) == 0) { scale_value(&val, &unit); printf("%6.2f %sJ", val, unit); } else printf(" N/A"); printf("\n"); }
void read_socket() { char buf[5]; int r,g,b; int rval; msgsock = accept(sock, 0, 0); if (msgsock != -1) { while (1) { bzero(buf, sizeof(buf)); rval = read(msgsock, buf, 5); if (rval < 0) { perror("picolor: Error reading stream message"); break; } else if (rval == 0) { break; } else if (buf[0] != 0) { r = (int)buf[1]; g = (int)buf[2]; b = (int)buf[3]; delay_time = (int)buf[4]; // Scale the values between the min and max r = scale_value(r, RED_MIN, RED_MAX); g = scale_value(g, GREEN_MIN, GREEN_MAX); b = scale_value(b, BLUE_MIN, BLUE_MAX); if (buf[0] == '\x42') { set_target_color(r,g,b); } else if (buf[0] == '\x68') { buf[0] = (char)red; buf[1] = (char)green; buf[2] = (char)blue; buf[3] = 0; write(msgsock, buf, 4); } else { set_color(r,g,b); } } } } close(msgsock); }
static void print_chip_power(const sensors_chip_name *name, const sensors_feature *feature, int label_size) { double val; const sensors_subfeature *sf; struct sensor_subfeature_data sensors[NUM_POWER_SENSORS]; struct sensor_subfeature_data alarms[NUM_POWER_ALARMS]; int sensor_count, alarm_count; char *label; const char *unit; int i; if (!(label = sensors_get_label(name, feature))) { fprintf(stderr, "ERROR: Can't get label of feature %s!\n", feature->name); return; } print_label(label, label_size); free(label); sensor_count = alarm_count = 0; /* * Power sensors come in 2 flavors: instantaneous and averaged. * Most devices only support one flavor, so we try to display the * average power if the instantaneous power attribute does not exist. * If both instantaneous power and average power are supported, * average power is displayed as limit. */ sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_POWER_INPUT); get_sensor_limit_data(name, feature, sf ? power_inst_sensors : power_avg_sensors, sensors, &sensor_count, alarms, &alarm_count); /* Add sensors common to both flavors. */ get_sensor_limit_data(name, feature, power_common_sensors, sensors, &sensor_count, alarms, &alarm_count); if (!sf) sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_POWER_AVERAGE); if (sf && get_input_value(name, sf, &val) == 0) { scale_value(&val, &unit); printf("%6.2f %sW%*s", val, unit, 2 - (int)strlen(unit), ""); } else printf(" N/A "); for (i = 0; i < sensor_count; i++) { /* * Unit is W and needs to be scaled for all attributes except * interval, which does not need to be scaled and is reported in * seconds. */ if (strcmp(sensors[i].name, "interval")) { char *tmpstr; tmpstr = alloca(4); scale_value(&sensors[i].value, &unit); snprintf(tmpstr, 4, "%sW", unit); sensors[i].unit = tmpstr; } else { sensors[i].unit = "s"; } } print_limits(sensors, sensor_count, alarms, alarm_count, label_size, "%s = %6.2f %s"); printf("\n"); }
int uct_playout(struct uct *u, struct board *b, enum stone player_color, struct tree *t) { struct board b2; board_copy(&b2, b); struct playout_amafmap amaf; amaf.gamelen = amaf.game_baselen = 0; /* Walk the tree until we find a leaf, then expand it and do * a random playout. */ struct tree_node *n = t->root; enum stone node_color = stone_other(player_color); assert(node_color == t->root_color); /* Make sure the root node is expanded. */ if (tree_leaf_node(n) && !__sync_lock_test_and_set(&n->is_expanded, 1)) tree_expand_node(t, n, &b2, player_color, u, 1); /* Tree descent history. */ /* XXX: This is somewhat messy since @n and descent[dlen-1].node are * redundant. */ struct uct_descent descent[DESCENT_DLEN]; descent[0].node = n; descent[0].lnode = NULL; int dlen = 1; /* Total value of the sequence. */ struct move_stats seq_value = { .playouts = 0 }; /* The last "significant" node along the descent (i.e. node * with higher than configured number of playouts). For black * and white. */ struct tree_node *significant[2] = { NULL, NULL }; if (n->u.playouts >= u->significant_threshold) significant[node_color - 1] = n; int result; int pass_limit = (board_size(&b2) - 2) * (board_size(&b2) - 2) / 2; int passes = is_pass(b->last_move.coord) && b->moves > 0; /* debug */ static char spaces[] = "\0 "; /* /debug */ if (UDEBUGL(8)) fprintf(stderr, "--- UCT walk with color %d\n", player_color); while (!tree_leaf_node(n) && passes < 2) { spaces[dlen - 1] = ' '; spaces[dlen] = 0; /*** Choose a node to descend to: */ /* Parity is chosen already according to the child color, since * it is applied to children. */ node_color = stone_other(node_color); int parity = (node_color == player_color ? 1 : -1); assert(dlen < DESCENT_DLEN); descent[dlen] = descent[dlen - 1]; if (u->local_tree && (!descent[dlen].lnode || descent[dlen].node->d >= u->tenuki_d)) { /* Start new local sequence. */ /* Remember that node_color already holds color of the * to-be-found child. */ descent[dlen].lnode = node_color == S_BLACK ? t->ltree_black : t->ltree_white; } if (!u->random_policy_chance || fast_random(u->random_policy_chance)) u->policy->descend(u->policy, t, &descent[dlen], parity, b2.moves > pass_limit); else u->random_policy->descend(u->random_policy, t, &descent[dlen], parity, b2.moves > pass_limit); /*** Perform the descent: */ if (descent[dlen].node->u.playouts >= u->significant_threshold) { significant[node_color - 1] = descent[dlen].node; } seq_value.playouts += descent[dlen].value.playouts; seq_value.value += descent[dlen].value.value * descent[dlen].value.playouts; n = descent[dlen++].node; assert(n == t->root || n->parent); if (UDEBUGL(7)) fprintf(stderr, "%s+-- UCT sent us to [%s:%d] %d,%f\n", spaces, coord2sstr(node_coord(n), t->board), node_coord(n), n->u.playouts, tree_node_get_value(t, parity, n->u.value)); /* Add virtual loss if we need to; this is used to discourage * other threads from visiting this node in case of multiple * threads doing the tree search. */ if (u->virtual_loss) stats_add_result(&n->u, node_color == S_BLACK ? 0.0 : 1.0, u->virtual_loss); assert(node_coord(n) >= -1); record_amaf_move(&amaf, node_coord(n)); struct move m = { node_coord(n), node_color }; int res = board_play(&b2, &m); if (res < 0 || (!is_pass(m.coord) && !group_at(&b2, m.coord)) /* suicide */ || b2.superko_violation) { if (UDEBUGL(4)) { for (struct tree_node *ni = n; ni; ni = ni->parent) fprintf(stderr, "%s<%"PRIhash"> ", coord2sstr(node_coord(ni), t->board), ni->hash); fprintf(stderr, "marking invalid %s node %d,%d res %d group %d spk %d\n", stone2str(node_color), coord_x(node_coord(n),b), coord_y(node_coord(n),b), res, group_at(&b2, m.coord), b2.superko_violation); } n->hints |= TREE_HINT_INVALID; result = 0; goto end; } if (is_pass(node_coord(n))) passes++; else passes = 0; enum stone next_color = stone_other(node_color); /* We need to make sure only one thread expands the node. If * we are unlucky enough for two threads to meet in the same * node, the latter one will simply do another simulation from * the node itself, no big deal. t->nodes_size may exceed * the maximum in multi-threaded case but not by much so it's ok. * The size test must be before the test&set not after, to allow * expansion of the node later if enough nodes have been freed. */ if (tree_leaf_node(n) && n->u.playouts - u->virtual_loss >= u->expand_p && t->nodes_size < u->max_tree_size && !__sync_lock_test_and_set(&n->is_expanded, 1)) tree_expand_node(t, n, &b2, next_color, u, -parity); } amaf.game_baselen = amaf.gamelen; if (t->use_extra_komi && u->dynkomi->persim) { b2.komi += round(u->dynkomi->persim(u->dynkomi, &b2, t, n)); } if (passes >= 2) { /* XXX: No dead groups support. */ floating_t score = board_official_score(&b2, NULL); /* Result from black's perspective (no matter who * the player; black's perspective is always * what the tree stores. */ result = - (score * 2); if (UDEBUGL(5)) fprintf(stderr, "[%d..%d] %s p-p scoring playout result %d (W %f)\n", player_color, node_color, coord2sstr(node_coord(n), t->board), result, score); if (UDEBUGL(6)) board_print(&b2, stderr); board_ownermap_fill(&u->ownermap, &b2); } else { // assert(tree_leaf_node(n)); /* In case of parallel tree search, the assertion might * not hold if two threads chew on the same node. */ result = uct_leaf_node(u, &b2, player_color, &amaf, descent, &dlen, significant, t, n, node_color, spaces); } if (u->policy->wants_amaf && u->playout_amaf_cutoff) { unsigned int cutoff = amaf.game_baselen; cutoff += (amaf.gamelen - amaf.game_baselen) * u->playout_amaf_cutoff / 100; amaf.gamelen = cutoff; } /* Record the result. */ assert(n == t->root || n->parent); floating_t rval = scale_value(u, b, result); u->policy->update(u->policy, t, n, node_color, player_color, &amaf, &b2, rval); if (t->use_extra_komi) { stats_add_result(&u->dynkomi->score, result / 2, 1); stats_add_result(&u->dynkomi->value, rval, 1); } if (u->local_tree && n->parent && !is_pass(node_coord(n)) && dlen > 0) { /* Get the local sequences and record them in ltree. */ /* We will look for sequence starts in our descent * history, then run record_local_sequence() for each * found sequence start; record_local_sequence() may * pick longer sequences from descent history then, * which is expected as it will create new lnodes. */ enum stone seq_color = player_color; /* First move always starts a sequence. */ record_local_sequence(u, t, &b2, descent, dlen, 1, seq_color); seq_color = stone_other(seq_color); for (int dseqi = 2; dseqi < dlen; dseqi++, seq_color = stone_other(seq_color)) { if (u->local_tree_allseq) { /* We are configured to record all subsequences. */ record_local_sequence(u, t, &b2, descent, dlen, dseqi, seq_color); continue; } if (descent[dseqi].node->d >= u->tenuki_d) { /* Tenuki! Record the fresh sequence. */ record_local_sequence(u, t, &b2, descent, dlen, dseqi, seq_color); continue; } if (descent[dseqi].lnode && !descent[dseqi].lnode) { /* Record result for in-descent picked sequence. */ record_local_sequence(u, t, &b2, descent, dlen, dseqi, seq_color); continue; } } } end: /* We need to undo the virtual loss we added during descend. */ if (u->virtual_loss) { floating_t loss = node_color == S_BLACK ? 0.0 : 1.0; for (; n->parent; n = n->parent) { stats_rm_result(&n->u, loss, u->virtual_loss); loss = 1.0 - loss; } } board_done_noalloc(&b2); return result; } int uct_playouts(struct uct *u, struct board *b, enum stone color, struct tree *t, struct time_info *ti) { int i; if (ti && ti->dim == TD_GAMES) { for (i = 0; t->root->u.playouts <= ti->len.games && !uct_halt; i++) uct_playout(u, b, color, t); } else { for (i = 0; !uct_halt; i++) uct_playout(u, b, color, t); } return i; }