void mapper_slot_upgrade_extrema_memory(mapper_slot slot) { int len; mapper_table_record_t *rec; rec = mapper_table_record(slot->props, AT_MIN, NULL); if (rec && rec->value && *rec->value) { void *old_mem = *rec->value; void *new_mem = calloc(1, slot->signal->length * mapper_type_size(slot->signal->type)); len = (rec->length < slot->signal->length ? rec->length : slot->signal->length); set_coerced_value(new_mem, old_mem, len, slot->signal->type, rec->type); mapper_table_set_record(slot->props, AT_MIN, NULL, slot->signal->length, slot->signal->type, new_mem, REMOTE_MODIFY); if (new_mem) free(new_mem); } rec = mapper_table_record(slot->props, AT_MAX, NULL); if (rec && rec->value && *rec->value) { void *old_mem = *rec->value; void *new_mem = calloc(1, slot->signal->length * mapper_type_size(slot->signal->type)); len = (rec->length < slot->signal->length ? rec->length : slot->signal->length); set_coerced_value(new_mem, old_mem, len, slot->signal->type, rec->type); mapper_table_set_record(slot->props, AT_MAX, NULL, slot->signal->length, slot->signal->type, new_mem, REMOTE_MODIFY); if (new_mem) free(new_mem); } }
static void reallocate_slot_instances(mapper_slot slot, int size) { int i; if (slot->num_instances < size) { slot->local->history = realloc(slot->local->history, sizeof(struct _mapper_history) * size); for (i = slot->num_instances; i < size; i++) { slot->local->history[i].type = slot->signal->type; slot->local->history[i].length = slot->signal->length; slot->local->history[i].size = slot->local->history_size; slot->local->history[i].value = calloc(1, mapper_type_size(slot->signal->type) * slot->local->history_size); slot->local->history[i].timetag = calloc(1, sizeof(mapper_timetag_t) * slot->local->history_size); slot->local->history[i].position = -1; } slot->num_instances = size; } }
void mapper_router_process_signal(mapper_router rtr, mapper_signal sig, int instance, const void *value, int count, mapper_timetag_t tt) { mapper_id_map id_map = sig->local->id_maps[instance].map; lo_message msg; // find the router signal mapper_router_signal rs = rtr->signals; while (rs) { if (rs->signal == sig) break; rs = rs->next; } if (!rs) return; int i, j, k, idx = sig->local->id_maps[instance].instance->index; mapper_map map; mapper_local_map lmap; if (!value) { mapper_local_slot lslot; mapper_slot slot; for (i = 0; i < rs->num_slots; i++) { if (!rs->slots[i]) continue; slot = rs->slots[i]; map = slot->map; lmap = map->local; if (map->status < STATUS_ACTIVE) continue; // need to reset user variable memory for this instance for (j = 0; j < lmap->num_expr_vars; j++) { memset(lmap->expr_vars[idx][j].value, 0, sizeof(double) * lmap->expr_vars[idx][j].length * lmap->expr_vars[idx][j].size); memset(lmap->expr_vars[idx][j].timetag, 0, sizeof(mapper_timetag_t) * lmap->expr_vars[idx][j].size); lmap->expr_vars[idx][j].position = -1; } mapper_slot dst_slot = &map->destination; mapper_local_slot dst_lslot = dst_slot->local; // also need to reset associated output memory dst_lslot->history[idx].position= -1; memset(dst_lslot->history[idx].value, 0, dst_lslot->history_size * dst_slot->signal->length * mapper_type_size(dst_slot->signal->type)); memset(dst_lslot->history[idx].timetag, 0, dst_lslot->history_size * sizeof(mapper_timetag_t)); dst_lslot->history[idx].position = -1; if (slot->direction == MAPPER_DIR_OUTGOING && !(sig->local->id_maps[instance].status & RELEASED_REMOTELY)) { msg = 0; if (!slot->use_instances) msg = mapper_map_build_message(map, slot, 0, 1, 0, 0); else if (map_in_scope(map, id_map->global)) msg = mapper_map_build_message(map, slot, 0, 1, 0, id_map); if (msg) send_or_bundle_message(dst_slot->link, dst_slot->signal->path, msg, tt); } for (j = 0; j < map->num_sources; j++) { slot = map->sources[j]; lslot = slot->local; // also need to reset associated input memory memset(lslot->history[idx].value, 0, lslot->history_size * slot->signal->length * mapper_type_size(slot->signal->type)); memset(lslot->history[idx].timetag, 0, lslot->history_size * sizeof(mapper_timetag_t)); lslot->history[idx].position = -1; if (!map->sources[j]->use_instances) continue; if (!map_in_scope(map, id_map->global)) continue; if (sig->local->id_maps[instance].status & RELEASED_REMOTELY) continue; if (slot->direction == MAPPER_DIR_INCOMING) { // send release to upstream msg = mapper_map_build_message(map, slot, 0, 1, 0, id_map); if (msg) send_or_bundle_message(slot->link, slot->signal->path, msg, tt); } } } return; } // if count > 1, we need to allocate sufficient memory for largest output // vector so that we can store calculated values before sending // TODO: calculate max_output_size, cache in link_signal void *out_value_p = count == 1 ? 0 : alloca(count * sig->length * sizeof(double)); for (i = 0; i < rs->num_slots; i++) { if (!rs->slots[i]) continue; mapper_slot slot = rs->slots[i]; map = slot->map; if (map->status < STATUS_ACTIVE) continue; int in_scope = map_in_scope(map, id_map->global); // TODO: should we continue for out-of-scope local destination updates? if (slot->use_instances && !in_scope) { continue; } mapper_local_slot lslot = slot->local; mapper_slot dst_slot = &map->destination; mapper_slot to = (map->process_location == MAPPER_LOC_SOURCE ? dst_slot : slot); int to_size = mapper_type_size(to->signal->type) * to->signal->length; char src_types[slot->signal->length * count]; memset(src_types, slot->signal->type, slot->signal->length * count); char dst_types[to->signal->length * count]; memset(dst_types, to->signal->type, to->signal->length * count); k = 0; for (j = 0; j < count; j++) { // copy input history size_t n = mapper_signal_vector_bytes(sig); lslot->history[idx].position = ((lslot->history[idx].position + 1) % lslot->history[idx].size); memcpy(mapper_history_value_ptr(lslot->history[idx]), value + n * j, n); memcpy(mapper_history_tt_ptr(lslot->history[idx]), &tt, sizeof(mapper_timetag_t)); // process source boundary behaviour if ((mapper_boundary_perform(&lslot->history[idx], slot, src_types + slot->signal->length * k))) { // back up position index --lslot->history[idx].position; if (lslot->history[idx].position < 0) lslot->history[idx].position = lslot->history[idx].size - 1; continue; } if (slot->direction == MAPPER_DIR_INCOMING) { continue; } if (map->process_location == MAPPER_LOC_SOURCE && !slot->causes_update) continue; if (!(mapper_map_perform(map, slot, idx, dst_types + to->signal->length * k))) continue; if (map->process_location == MAPPER_LOC_SOURCE) { // also process destination boundary behaviour if ((mapper_boundary_perform(&map->destination.local->history[idx], dst_slot, dst_types + to->signal->length * k))) { // back up position index --map->destination.local->history[idx].position; if (map->destination.local->history[idx].position < 0) map->destination.local->history[idx].position = map->destination.local->history[idx].size - 1; continue; } } void *result = mapper_history_value_ptr(map->destination.local->history[idx]); if (count > 1) { memcpy((char*)out_value_p + to_size * j, result, to_size); } else { msg = mapper_map_build_message(map, slot, result, 1, dst_types, slot->use_instances ? id_map : 0); if (msg) send_or_bundle_message(map->destination.link, dst_slot->signal->path, msg, tt); } ++k; } if (count > 1 && slot->direction == MAPPER_DIR_OUTGOING && (!slot->use_instances || in_scope)) { msg = mapper_map_build_message(map, slot, out_value_p, k, dst_types, slot->use_instances ? id_map : 0); if (msg) send_or_bundle_message(map->destination.link, dst_slot->signal->path, msg, tt); } } }
int mapper_connection_perform(mapper_connection connection, mapper_signal_history_t *from, mapper_signal_history_t **expr_vars, mapper_signal_history_t *to, char *typestring) { int changed = 0, i; int vector_length = from->length < to->length ? from->length : to->length; if (connection->props.muted) return 0; /* If the destination type is unknown, we can't do anything * intelligent here -- even bypass mode might screw up if we * assume the types work out. */ if (connection->props.dest_type != 'f' && connection->props.dest_type != 'i' && connection->props.dest_type != 'd') { return 0; } if (!connection->props.mode || connection->props.mode == MO_BYPASS) { /* Increment index position of output data structure. */ to->position = (to->position + 1) % to->size; if (connection->props.src_type == connection->props.dest_type) { memcpy(msig_history_value_pointer(*to), msig_history_value_pointer(*from), mapper_type_size(to->type) * vector_length); memset(msig_history_value_pointer(*to) + mapper_type_size(to->type) * vector_length, 0, (to->length - vector_length) * mapper_type_size(to->type)); } else if (connection->props.src_type == 'f') { float *vfrom = msig_history_value_pointer(*from); if (connection->props.dest_type == 'i') { int *vto = msig_history_value_pointer(*to); for (i = 0; i < vector_length; i++) { vto[i] = (int)vfrom[i]; } for (; i < to->length; i++) { vto[i] = 0; } } else if (connection->props.dest_type == 'd') { double *vto = msig_history_value_pointer(*to); for (i = 0; i < vector_length; i++) { vto[i] = (double)vfrom[i]; } for (; i < to->length; i++) { vto[i] = 0; } } } else if (connection->props.src_type == 'i') { int *vfrom = msig_history_value_pointer(*from); if (connection->props.dest_type == 'f') { float *vto = msig_history_value_pointer(*to); for (i = 0; i < vector_length; i++) { vto[i] = (float)vfrom[i]; } for (; i < to->length; i++) { vto[i] = 0; } } else if (connection->props.dest_type == 'd') { double *vto = msig_history_value_pointer(*to); for (i = 0; i < vector_length; i++) { vto[i] = (double)vfrom[i]; } for (; i < to->length; i++) { vto[i] = 0; } } } else if (connection->props.src_type == 'd') { double *vfrom = msig_history_value_pointer(*from); if (connection->props.dest_type == 'i') { int *vto = msig_history_value_pointer(*to); for (i = 0; i < vector_length; i++) { vto[i] = (int)vfrom[i]; } for (; i < to->length; i++) { vto[i] = 0; } } else if (connection->props.dest_type == 'f') { float *vto = msig_history_value_pointer(*to); for (i = 0; i < vector_length; i++) { vto[i] = (float)vfrom[i]; } for (; i < to->length; i++) { vto[i] = 0; } } } for (i = 0; i < vector_length; i++) { typestring[i] = to->type; } return 1; } else if (connection->props.mode == MO_EXPRESSION || connection->props.mode == MO_LINEAR) { die_unless(connection->expr!=0, "Missing expression.\n"); return (mapper_expr_evaluate(connection->expr, from, expr_vars, to, typestring)); } else if (connection->props.mode == MO_CALIBRATE) { /* Increment index position of output data structure. */ to->position = (to->position + 1) % to->size; if (!connection->props.src_min) { connection->props.src_min = malloc(connection->props.src_length * mapper_type_size(connection->props.src_type)); } if (!connection->props.src_max) { connection->props.src_max = malloc(connection->props.src_length * mapper_type_size(connection->props.src_type)); } /* If calibration mode has just taken effect, first data * sample sets source min and max */ if (connection->props.src_type == 'f') { float *v = msig_history_value_pointer(*from); float *src_min = (float*)connection->props.src_min; float *src_max = (float*)connection->props.src_max; if (!connection->calibrating) { for (i = 0; i < from->length; i++) { src_min[i] = v[i]; src_max[i] = v[i]; } connection->calibrating = 1; changed = 1; } else { for (i = 0; i < from->length; i++) { if (v[i] < src_min[i]) { src_min[i] = v[i]; changed = 1; } if (v[i] > src_max[i]) { src_max[i] = v[i]; changed = 1; } } } } else if (connection->props.src_type == 'i') { int *v = msig_history_value_pointer(*from); int *src_min = (int*)connection->props.src_min; int *src_max = (int*)connection->props.src_max; if (!connection->calibrating) { for (i = 0; i < from->length; i++) { src_min[i] = v[i]; src_max[i] = v[i]; } connection->calibrating = 1; changed = 1; } else { for (i = 0; i < from->length; i++) { if (v[i] < src_min[i]) { src_min[i] = v[i]; changed = 1; } if (v[i] > src_max[i]) { src_max[i] = v[i]; changed = 1; } } } } else if (connection->props.src_type == 'd') { double *v = msig_history_value_pointer(*from); double *src_min = (double*)connection->props.src_min; double *src_max = (double*)connection->props.src_max; if (!connection->calibrating) { for (i = 0; i < from->length; i++) { src_min[i] = v[i]; src_max[i] = v[i]; } connection->calibrating = 1; changed = 1; } else { for (i = 0; i < from->length; i++) { if (v[i] < src_min[i]) { src_min[i] = v[i]; changed = 1; } if (v[i] > src_max[i]) { src_max[i] = v[i]; changed = 1; } } } } if (changed) { mapper_connection_set_mode_linear(connection); /* Stay in calibrate mode. */ connection->props.mode = MO_CALIBRATE; } if (connection->expr) return (mapper_expr_evaluate(connection->expr, from, expr_vars, to, typestring)); else return 0; } return 1; }
void reallocate_connection_histories(mapper_connection c, int input_history_size, int output_history_size) { mapper_signal sig = c->parent->signal; int i, j; // At least for now, exit if this is an input signal if (!sig->props.is_output) { return; } // If there is no expression, then no memory needs to be // reallocated. if (!c->expr) return; if (input_history_size < 1) input_history_size = 1; // Reallocate input histories if (input_history_size > c->parent->history_size) { size_t sample_size = msig_vector_bytes(sig); for (i=0; i<sig->props.num_instances; i++) { mhist_realloc(&c->parent->history[i], input_history_size, sample_size, 1); } c->parent->history_size = input_history_size; } else if (input_history_size < c->parent->history_size) { // Do nothing for now... // Find maximum input length needed for connections /*mapper_connection temp = c->parent->connections; while (c) { if (c->props.mode == MO_EXPRESSION) { if (c->expr->input_history_size > input_history_size) { input_history_size = c->expr->input_history_size; } } c = c->next; }*/ } // reallocate output histories if (output_history_size > c->props.dest_history_size) { int sample_size = mapper_type_size(c->props.dest_type) * c->props.dest_length; for (i=0; i<sig->props.num_instances; i++) { mhist_realloc(&c->history[i], output_history_size, sample_size, 0); } c->props.dest_history_size = output_history_size; } else if (output_history_size < mapper_expr_output_history_size(c->expr)) { // Do nothing for now... } // reallocate user variable histories int new_num_vars = mapper_expr_num_variables(c->expr); if (new_num_vars > c->num_expr_vars) { for (i=0; i<sig->props.num_instances; i++) { c->expr_vars[i] = realloc(c->expr_vars[i], new_num_vars * sizeof(struct _mapper_signal_history)); // initialize new variables... for (j=c->num_expr_vars; j<new_num_vars; j++) { c->expr_vars[i][j].type = 'd'; c->expr_vars[i][j].length = 0; c->expr_vars[i][j].size = 0; c->expr_vars[i][j].value = 0; c->expr_vars[i][j].timetag = 0; c->expr_vars[i][j].position = -1; } } c->num_expr_vars = new_num_vars; } else if (new_num_vars < c->num_expr_vars) { // Do nothing for now... } for (i=0; i<sig->props.num_instances; i++) { for (j=0; j<new_num_vars; j++) { int history_size = mapper_expr_variable_history_size(c->expr, j); int vector_length = mapper_expr_variable_vector_length(c->expr, j); mhist_realloc(c->expr_vars[i]+j, history_size, vector_length * sizeof(double), 0); (c->expr_vars[i]+j)->length = vector_length; (c->expr_vars[i]+j)->size = history_size; (c->expr_vars[i]+j)->position = -1; } } }