package hex.deeplearning;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import water.*;
import water.fvec.Frame;
import water.fvec.NFSFileVec;
import water.parser.ParseDataset;
import water.util.Log;

import java.io.File;

import static hex.deeplearning.DeepLearningModel.DeepLearningParameters;

/**
 * Simple Deep Neural Network on MNIST with ~12M parameters
 * ~50MB model size, won't fit in L3 cache -> main memory bandwidth (fprop) and latency (bprop) limited
 * Note: requires './gradlew syncBigDataLaptop'
 */
public class DeepLearningMNIST extends TestUtil {
    @BeforeClass() public static void setup() { stall_till_cloudsize(1); }

    @Test public void run() {

        try {
            Scope.enter();
            File file = find_test_file("bigdata/laptop/mnist/train.csv.gz");
            if (file != null) {
                NFSFileVec trainfv = NFSFileVec.make(file);
                Frame frame = ParseDataset.parse(Key.make(), trainfv._key);
                DeepLearningParameters p = new DeepLearningParameters();

                // populate model parameters
                p._destination_key = Key.make("dl_mnist_model");
                p._train = frame._key;
                p._response_column = "C785"; //last column is the response
                p._convert_to_enum = true; //response is categorical (digits 1 to 10)
                p._activation = DeepLearningParameters.Activation.Tanh;
                p._hidden = new int[]{2500, 2000, 1500, 1000, 500};
                p._train_samples_per_iteration = 1500 * H2O.getCloudSize(); //process 1500 rows per node per map-reduce step
                p._epochs = 1.8 * (float) p._train_samples_per_iteration / frame.numRows(); //train long enough to do 2 map-reduce passes (with scoring each time)

                // speed up training
                p._adaptive_rate = false; //disable adaptive per-weight learning rate, but requires more tuning as learning rate and momentum default values might not be ideal (most likely slower convergence, too).
                p._replicate_training_data = false; //avoid extra communication cost upfront
                p._shuffle_training_data = false;

                // reduce time spent on scoring (we don't need to know the training set accuracy of the model)
                p._score_interval = 20; //score and print progress report every 20 seconds
                p._score_training_samples = 10; //only score on a very small sample of the training set -> don't want to spend too much time scoring

                DeepLearning dl = new DeepLearning(p);
                DeepLearningModel model = null;
                try {
                    model = dl.trainModel().get();
                } catch (Throwable t) {
                    t.printStackTrace();
                    throw new RuntimeException(t);
                } finally {
                    dl.remove();
                    if (model != null) {
                        Assert.assertTrue(1000. * model.model_info().get_processed_total() / model.run_time > 50); //we expect at least a training speed of 50 samples / second (MacBook Pro laptop does ~90 samples / second)
                        model.delete_xval_models();
                        model.delete_best_model();
                        model.delete();
                    }
                    Scope.exit();
                }
            } else {
                Log.info("Please run ./gradlew syncBigDataLaptop in the top-level directory of h2o-dev.");
            }
        } catch (Throwable t) {
            t.printStackTrace();
            throw new RuntimeException(t);
        }
    }
}

Add (currently ignored) BigDataLaptop Test Case for MNIST Deep Learning.