Skip to content

Commit

Permalink
Do not print giant Java models by default
Browse files Browse the repository at this point in the history
Big Tree models (e.g. 50 trees x 2 classes x 10000 leaves per tree) make
for Big Java - which we were printing to the browser with each
progress-bar update.
Move SB to its own file, so others can use it.
Peel out the Java generation from the API, into its own methods.
  • Loading branch information
cliffclick committed Nov 20, 2013
1 parent b713887 commit d879439
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 38 deletions.
2 changes: 1 addition & 1 deletion prj.el
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
'(jde-run-option-debug nil)
'(jde-run-option-vm-args nil)
'(jde-compile-option-directory "./target/classes")
'(jde-run-option-application-args (quote ("-beta" "-mainClass" "org.junit.runner.JUnitCore" "water.exec.Expr2Test" "hex.drf.DRFTestX")))
'(jde-run-option-application-args (quote ("-beta" "-mainClass" "org.junit.runner.JUnitCore" "hex.drf.DRFTest")))
'(jde-debugger (quote ("JDEbug")))
'(jde-compile-option-source (quote ("1.6")))
'(jde-compile-option-classpath (quote ("./target/classes" "./lib/javassist.jar" "./lib/hadoop/cdh4/hadoop-common.jar" "./lib/hadoop/cdh4/hadoop-auth.jar" "./lib/hadoop/cdh4/slf4j-api-1.6.1.jar" "./lib/hadoop/cdh4/slf4j-nop-1.6.1.jar" "./lib/hadoop/cdh4/hadoop-hdfs.jar" "./lib/hadoop/cdh4/protobuf-java-2.4.0a.jar" "./lib/apache/commons-codec-1.4.jar" "./lib/apache/commons-configuration-1.6.jar" "./lib/apache/commons-lang-2.4.jar" "./lib/apache/commons-logging-1.1.1.jar" "./lib/apache/httpclient-4.1.1.jar" "./lib/apache/httpcore-4.1.jar" "./lib/junit/junit-4.11.jar" "./lib/apache/guava-12.0.1.jar" "./lib/gson/gson-2.2.2.jar" "./lib/poi/poi-3.8-20120326.jar" "./lib/poi/poi-ooxml-3.8-20120326.jar" "./lib/poi/poi-ooxml-schemas-3.8-20120326.jar" "./lib/poi/dom4j-1.6.1.jar" "./lib/Jama/Jama.jar" "./lib/s3/aws-java-sdk-1.3.27.jar" "./lib/log4j/log4j-1.2.15.jar")))
Expand Down
23 changes: 13 additions & 10 deletions src/main/java/hex/gbm/DTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
import water.api.DocGen;
import water.api.Request.API;
import water.fvec.Chunk;
import water.util.Log;
import water.util.RString;
import water.util.*;

/**
A Decision Tree, laid over a Frame of Vecs, and built distributed.
Expand Down Expand Up @@ -548,17 +547,10 @@ public void score0(double data[], float preds[], int treeIdx) {
preds[c] += ts[c].score(data);
}

public void generateHTML(String title, StringBuilder sb, boolean includeModelCode) {
public void generateHTML(String title, StringBuilder sb) {
DocGen.HTML.title(sb,title);
DocGen.HTML.paragraph(sb,"Model Key: "+_selfKey);
DocGen.HTML.paragraph(sb,water.api.Predict.link(_selfKey,"Predict!"));
// include link to java code for all models
if (includeModelCode) {
sb.insert(sb.indexOf("</pre>") +"</pre></div>".length(),
"<br /><br /><div class=\"pull-right\"><a href=\"#\" onclick=\'$(\"#javaModel\").toggleClass(\"hide\");\'" +
"class=\'btn btn-inverse btn-mini\'>Java Model</a></div><br /><div class=\"hide\" id=\"javaModel\">" +
"<pre style=\"overflow-y:scroll;\"><code class=\"language-java\">"+DocGen.HTML.escape2(toJava())+"</code></pre></div>");
}
String[] domain = _domains[_domains.length-1]; // Domain of response col

// Top row of CM
Expand Down Expand Up @@ -822,6 +814,17 @@ StringBuilder toString(final String res, CompressedTree ct, final StringBuilder
return sb;
}

public void toJavaHtml( StringBuilder sb ) {
sb.append("<br /><br /><div class=\"pull-right\"><a href=\"#\" onclick=\'$(\"#javaModel\").toggleClass(\"hide\");\'" +
"class=\'btn btn-inverse btn-mini\'>Java Model</a></div><br /><div class=\"hide\" id=\"javaModel\">" +
"<pre style=\"overflow-y:scroll;\"><code class=\"language-java\">");
if( numTrees() * treeStats.meanLeaves > 10000 )
sb.append("/* Java code is too large to display, download it directly. */");
else
DocGen.HTML.escape(sb,toJava());
sb.append("</code></pre></div>");
}

// Convert Tree model to Java
@Override protected void toJavaPredictBody( final SB sb ) {
String[] cnames = classNames();
Expand Down
28 changes: 5 additions & 23 deletions src/main/java/water/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import water.fvec.*;
import water.util.Log.Tag.Sys;
import water.util.Log;
import water.util.Utils;
import water.util.*;

/**
* A Model models reality (hopefully).
Expand Down Expand Up @@ -318,8 +318,8 @@ protected float[] score0( Chunk chks[], int row_in_chunk, double[] tmp, float[]
* }
* </pre>
*/
public String toJava() {
SB sb = new SB();
public String toJava() { return toJava(new SB()).toString(); }
public SB toJava( SB sb ) {
sb.p("\n");
sb.p("class ").p(toJavaId(_selfKey.toString())).p(" {\n");
toJavaNAMES(sb);
Expand All @@ -331,7 +331,7 @@ public String toJava() {
sb.p(TOJAVA_PREDICT_MAP_ALLOC1);
sb.p(TOJAVA_PREDICT_MAP_ALLOC2);
sb.p("}\n");
return sb.toString();
return sb;
}
// Same thing as toJava, but as a Javassist CtClass
private CtClass makeCtClass() throws CannotCompileException {
Expand All @@ -349,7 +349,7 @@ private CtClass makeCtClass() throws CannotCompileException {


private SB toJavaNAMES( SB sb ) {
return sb.p(" public static final String[] NAMES = new String[] ").p(_names).p(";\n");
return sb.p(" public static final String[] NAMES = new String[] ").toJavaStringInit(_names).p(";\n");
}
private SB toJavaNCLASSES( SB sb ) {
return sb.p(" public static final int NCLASSES = ").p(nclasses()).p(";\n");
Expand Down Expand Up @@ -401,24 +401,6 @@ private SB toJavaPredict(SB sb) {
" return predict(map(row,new double[NAMES.length]),new float[NCLASSES+1]);\n"+
" }\n";

// Can't believe this wasn't done long long ago
protected static class SB {
public final StringBuilder _sb = new StringBuilder();
public SB p( String s ) { _sb.append(s); return this; }
public SB p( float s ) { _sb.append(s); return this; }
public SB p( char s ) { _sb.append(s); return this; }
public SB p( int s ) { _sb.append(s); return this; }
public SB indent( int d ) { for( int i=0; i<d; i++ ) p(" "); return this; }
// Convert a String[] into a valid Java String initializer
SB p( String[] ss ) {
p('{');
for( int i=0; i<ss.length-1; i++ ) p('"').p(ss[i]).p("\",");
if( ss.length > 0 ) p('"').p(ss[ss.length-1]).p('"');
return p('}');
}
@Override public String toString() { return _sb.toString(); }
}

// Convenience method for testing: build Java, convert it to a class &
// execute it: compare the results of the new class's (JIT'd) scoring with
// the built-in (interpreted) scoring on this dataset. Throws if there
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/water/api/DRFModelView.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static Response redirect(Request req, Key modelKey) {
}

@Override public boolean toHTML(StringBuilder sb){
drf_model.generateHTML("DRF Model", sb, true);
drf_model.generateHTML("DRF Model", sb);
return true;
}

Expand All @@ -28,4 +28,6 @@ public static Response redirect(Request req, Key modelKey) {
if (drf_model == null) return Response.error("Model '" + _modelKey + "' not found!");
else return Response.done(this);
}

@Override public void toJava(StringBuilder sb) { drf_model.toJavaHtml(sb); }
}
2 changes: 1 addition & 1 deletion src/main/java/water/api/DRFProgressPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static Response redirect(Request req, Key jobkey, Key dest) {
@Override public boolean toHTML( StringBuilder sb ) {
Job jjob = Job.findJob(job_key);
DRFModel m = UKV.get(jjob.dest());
if (m!=null) m.generateHTML("DRF Model", sb, false);
if (m!=null) m.generateHTML("DRF Model", sb);
else DocGen.HTML.paragraph(sb, "Pending...");

return true;
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/water/api/GBMModelView.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static Response redirect(Request req, Key modelKey) {
}

@Override public boolean toHTML(StringBuilder sb){
gbm_model.generateHTML("GBM Model", sb, true);
gbm_model.generateHTML("GBM Model", sb);
return true;
}

Expand All @@ -33,4 +33,6 @@ public static Response redirect(Request req, Key modelKey) {
if (gbm_model == null) return Response.error("Model '" + _modelKey + "' not found!");
else return Response.done(this);
}

@Override public void toJava(StringBuilder sb) { gbm_model.toJavaHtml(sb); }
}
2 changes: 1 addition & 1 deletion src/main/java/water/api/GBMProgressPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public static Response redirect(Request req, Key jobkey, Key dest) {
Job jjob = Job.findJob(job_key);
Value value = DKV.get(jjob.dest());
if( value == null ) DocGen.HTML.paragraph(sb, "Pending...");
else ((GBMModel)value.get()).generateHTML("GBM Model", sb, false);
else ((GBMModel)value.get()).generateHTML("GBM Model", sb);
return true;
}
@Override public API_VERSION[] supportedVersions() { return SUPPORTS_V1_V2; }
Expand Down
1 change: 1 addition & 0 deletions src/main/java/water/api/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ protected static Class mapTypeahead(Class c) {
public boolean toHTML(StringBuilder sb) {
return false;
}
public void toJava(StringBuilder sb) {}

public String toDocGET() {
return null;
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/water/api/RequestBuilders.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ protected String build(Response response) {
sb.append("<div class='row-fluid'>");
sb.append("<div class='span12'>");
sb.append(buildJSONResponseBox(response));
if( response._status == Response.Status.done ) response.toJava(sb);
sb.append(buildResponseHeader(response));
Builder builder = response.getBuilderFor(ROOT_OBJECT);
if (builder == null) {
Expand Down Expand Up @@ -532,6 +533,10 @@ public JsonObject toJson() {
return res;
}

public void toJava(StringBuilder sb) {
if( _req != null ) _req.toJava(sb);
}

/** Returns the error of the request object if any. Returns null if the
* response is not in error state.
*/
Expand Down
43 changes: 43 additions & 0 deletions src/main/java/water/util/SB.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package water.util;

// Tight/tiny StringBuilder wrapper.
// Short short names on purpose; so they don't obscure the printing.
// Can't believe this wasn't done long long ago.
public class SB {
public final StringBuilder _sb;
public SB( ) { _sb = new StringBuilder( ); }
public SB(String s) { _sb = new StringBuilder(s); }
public SB p( String s ) { _sb.append(s); return this; }
public SB p( float s ) { _sb.append(s); return this; }
public SB p( char s ) { _sb.append(s); return this; }
public SB p( int s ) { _sb.append(s); return this; }
public SB p( Object s ) { _sb.append(s.toString()); return this; }
public SB indent( int d ) { for( int i=0; i<d; i++ ) p(" "); return this; }
// Convert a String[] into a valid Java String initializer
public SB toJavaStringInit( String[] ss ) {
p('{');
for( int i=0; i<ss.length-1; i++ ) p('"').p(ss[i]).p("\",");
if( ss.length > 0 ) p('"').p(ss[ss.length-1]).p('"');
return p('}');
}
public SB toJSArray(float[] nums) {
p('[');
for (int i=0; i<nums.length; i++) {
if (i>0) p(',');
p(nums[i]);
}
return p(']');
}
public SB toJSArray(String[] ss) {
p('[');
for (int i=0; i<ss.length; i++) {
if (i>0) p(',');
p('"').p(ss[i]).p('"');
}
return p(']');
}

// Mostly a fail, since we should just dump into the same SB.
public SB p( SB sb ) { _sb.append(sb._sb); return this; }
@Override public String toString() { return _sb.toString(); }
}

0 comments on commit d879439

Please sign in to comment.