Index: linux-gl/lib/genetic-debug.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-gl/lib/genetic-debug.c 2006-07-14 16:45:44.000000000 -0500 @@ -0,0 +1,153 @@ +/* + * Genetic Algorithm Library Debugging Routines + * + * (C) Copyright 2006 IBM + * (C) Copyright 2006 Brandon Philips + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + */ + +#include +#include +#include + +struct dentry * genetic_tree_root = NULL; + +/** + * genetic_stat_show - generates /debug/genetic//stats + */ +static int genetic_stat_show(struct seq_file *s, void *unused) +{ + genetic_t * genetic = (genetic_t *)s->private; + + seq_printf(s, "name: %s\n", genetic->name); + seq_printf(s, "generation_number: %ld\n", genetic->generation_number); + seq_printf(s, "num_children: %ld\n", genetic->num_children); + seq_printf(s, "child_life_time: %ld\n", genetic->child_life_time); + seq_printf(s, "child_number: %ld\n", genetic->child_number); + + return 0; +} + +static int genetic_stat_open(struct inode *inode, struct file *file) +{ + return single_open(file, genetic_stat_show, inode->u.generic_ip); +} + +static struct file_operations genetic_stat_operations = { + .open = genetic_stat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/** + * genetic_phenotype_average_show - /debug/genetic//phenotype_average + */ +static int genetic_phenotype_average_show(struct seq_file *s, void *unused) +{ + genetic_t * genetic = (genetic_t *)s->private; + struct list_head * p; + phenotype_t * pt; + + list_for_each(p, &genetic->phenotype) { + pt = list_entry(p, phenotype_t, phenotype); + seq_printf(s, "%s: %lld\n", pt->name, pt->avg_fitness); + } + + return 0; +} + +static int genetic_phenotype_average_open(struct inode *inode, struct file *file) +{ + return single_open(file, genetic_phenotype_average_show, inode->u.generic_ip); +} + +static struct file_operations genetic_phenotype_average_operations = { + .open = genetic_phenotype_average_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +/** + * genetic_genes_show - /debug/genetic//gene + */ +int genetic_generic_gene_show(struct seq_file *s, void *unused) +{ + int i; + phenotype_t * pt = (phenotype_t *)s->private; + + genetic_child_t * child = list_entry(pt->run_queue->next, + genetic_child_t, list); + + unsigned long * genes = (unsigned long *)child->genes; + + for (i = 0; i < pt->num_genes; i++) + seq_printf(s, "%s: %lu\n", child->gene_param[i].name, genes[i]); + + return 0; +} + +static int genetic_generic_gene_open(struct inode *inode, struct file *file) +{ + phenotype_t * pt = (phenotype_t *)inode->u.generic_ip; + + return single_open(file, pt->ops->gene_show, inode->u.generic_ip); +} + +static struct file_operations genetic_gene_operations = { + .open = genetic_generic_gene_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +static struct dentry *genetic_create_tree(const char *name, struct dentry *parent) +{ + struct dentry *dir = NULL; + + if (!genetic_tree_root) { + genetic_tree_root = debugfs_create_dir("genetic", NULL); + if (!genetic_tree_root) + goto err; + } + + if (!parent) parent = genetic_tree_root; + + dir = debugfs_create_dir(name, parent); + +err: + return dir; +} + +#if GENETIC_DEBUG +/* Stores attributes into an array in the following format + * child_num fitness gene[0] gene[1] .... gene[num_genes-1] + * Add +1 to GENETIC_NUM_DEBUG_POINTS if add another dump_children + * call + */ +void dump_children(phenotype_t * pt) +{ + int i, j; + long * genes; + unsigned long debug_size = pt->debug_size; + + for (i = 0; i < pt->num_children; i++) { + pt->debug_history[pt->debug_index++ % debug_size] = pt->child_ranking[i]->id; + pt->debug_history[pt->debug_index++ % debug_size] = pt->child_ranking[i]->fitness; + + genes = (long *)pt->child_ranking[i]->genes; + + for (j = 0; j < pt->child_ranking[i]->num_genes; j++) { + pt->debug_history[pt->debug_index++ % debug_size] = genes[j]; + } + } +} +#else +void dump_children(phenotype_t * pt) {} +#endif /* GENETIC_DEBUG */ Index: linux-gl/lib/genetic.c =================================================================== --- linux-gl.orig/lib/genetic.c 2006-07-14 16:45:22.000000000 -0500 +++ linux-gl/lib/genetic.c 2006-07-14 16:45:44.000000000 -0500 @@ -38,6 +38,8 @@ #include #include +#include "genetic-debug.c" + char genetic_lib_version[] = "0.3.1"; int mutation_rate_change = GENETIC_DEFAULT_MUTATION_RATE_CHANGE; @@ -98,6 +100,20 @@ INIT_LIST_HEAD(&genetic->phenotype); + /* Setup debugfs */ + genetic->dir = genetic_create_tree(name, NULL); + genetic->phenotypes_dir = genetic_create_tree("phenotypes", genetic->dir); + + /* TODO add stack to the genetic track dentries for deallocation */ + debugfs_create_file("stats", S_IFREG|S_IRUGO, genetic->dir, + genetic, &genetic_stat_operations); + + debugfs_create_file("phenotype_average", S_IFREG|S_IRUGO, genetic->dir, + genetic, &genetic_phenotype_average_operations); + + debugfs_create_bool("defaults", S_IWUSR|S_IFREG|S_IRUGO, genetic->dir, + &genetic->defaults); + return 0; } @@ -170,6 +186,11 @@ list_add_tail(&pt->phenotype, &genetic->phenotype); + if (ops->gene_show) { + debugfs_create_file(name, S_IFREG|S_IRUGO, + genetic->phenotypes_dir, pt, &genetic_gene_operations); + } + return 0; } @@ -554,19 +575,27 @@ if (pt->ops->calc_post_fitness) pt->ops->calc_post_fitness(pt); + dump_children(pt); + /* figure out top performers */ genetic_split_performers(pt); /* calc stats */ genetic_calc_stats(pt); + dump_children(pt); + /* make some new children */ if (pt->num_genes) pt->natural_selection(pt); + dump_children(pt); + /* mutate a couple of the next generation */ genetic_mutate(pt); + dump_children(pt); + /* Move the new children still sitting in the finished queue to the run queue */ tmp = pt->run_queue;