#!/usr/bin/env python USAGE = """fx-run: Runs a program for use with FASTexec data collection. Example: fx-run timing ./main --count=1,2,5 --foo=2, "other{1,2,3}" --timing=true This tries running ./main for all combinations of --count=1 --count=2 --count=3 with other1, other2, other3, and the other parameters set accordingly. These runs are given a tag or label of "timing", which is useful if you want to run different flavors of experiments. For each trial, a directory will be created within the current directory's ./fx, automatically named based on parameters. For this example: ./fx/timing/main/count_1__foo_2__other1/... ./fx/timing/main/count_1__foo_2__other2/... and so on... Before running a particular trial, fx-run checks if a file called "status.txt" exists in the automatically naed directory. If this status file exists, the trial will be skipped. As a result: - If a trial has run already, it won't be re-run. This is useful if you want to add just a couple new parameter choices but don't want to re-run everything. - If have multiple machines with NFS, this gives you a really cheap form of load distribution. If you use the same fx-run command on multiple machines, the machines will compete for work items. - If you want to re-run something, you need to use fx-cleanup. Syntax Examples: label ./executable The first two arguments specify a "label" for the type of experiment, and the executable being run. --key=a,b,c Trying multiple FASTexec style parameters. This will try each of: --key=a --key=b --key=c. "foo_{a,b,c...}_x" Syntax for non-standard parameters. The quotes are required by the shell because of the {} symbols. This will try each of: foo_a_x foo_b_x foo_c_x --key=value Single choice parameters. These will not appear in foo_a_bar the automatically generated filenames. Note that if you might want to try different parameters later, you will need it to appear in the filename. --key=onlyvalue, Single choice parameter, but it will appear in the "foo_{a}_x" generated filenames. Caveats: Each run occurs with the automatically named directory as the current working directory. If you want to access a file in the "current" directory, you need to use ../../../../ (four levels of ..). See the next example. Here is an example usage with fx-csv and fx-latex: cd $FASTLIBPATH/u/example && fl-build main # Let's try varying KNN's "k" and see the results. fx-run knn_k ./main --knn/k=1,2,3,4,5 --data=../../../../fake.arff fx-csv knn_k ./main /params/knn/k /kfold/results/p_correct fx-latex knn_k ./main /params/knn/k /kfold/results/p_correct NOTE: If this doesn't fit on your screen, type: fx-run | less and use the letter "q" to quit """ import pm import util import fxsys import sys import os if len(sys.argv) < 3: print USAGE sys.exit(1) label = sys.argv[1] exename = os.path.abspath(sys.argv[2]) arguments = sys.argv[3:] paramset = pm.paramset_from_args(arguments) paramset = pm.Combine( paramset, pm.Bind(pm.Binfile(), exename), pm.Bind(pm.Output("fx/output"), fxsys.OUTPUT_FNAME)) print "*** List of runs that will be performed" paramset.print_all() print print "*** Executing (results go in ./fx)" fxsys.execute_paramset_here(exename, label, paramset) print print "*** Finished (results in ./fx)"