@@ -0,0 +1,1552 @@
+package water;%0A%0Aimport java.util.concurrent.atomic.AtomicInteger;%0A%0Apublic class ParallelizationTask%3CT extends H2O.H2OCountedCompleter%3CT%3E%3E extends H2O.H2OCountedCompleter %7B%0A    private final AtomicInteger _ctr; // Concurrency control%0A    private static int DEFAULT_MAX_PARALLEL_TASKS = -1;%0A    private final T%5B%5D _tasks; // Task holder%0A    private final Job _j; //Keep track of job progress%0A    transient private int _maxParallelTasks;%0A%0A    public ParallelizationTask(T%5B%5D tasks, Job j) %7B%0A        this(tasks, DEFAULT_MAX_PARALLEL_TASKS, j);%0A    %7D%0A%0A    public ParallelizationTask(T%5B%5D tasks, int maxParallelTasks, Job j) %7B%0A        _maxParallelTasks = maxParallelTasks %3E 0 ? maxParallelTasks : H2O.SELF._heartbeat._num_cpus;%0A        _ctr = new AtomicInteger(_maxParallelTasks - 1);%0A        _tasks = tasks;%0A        _j = j;%0A    %7D%0A%0A    @Override public void compute2() %7B%0A        final int nTasks = _tasks.length;%0A        addToPendingCount(nTasks-1);%0A        for (int i=0; i %3C Math.min(_maxParallelTasks, nTasks); ++i) asyncVecTask(i);%0A    %7D%0A%0A    private void asyncVecTask(final int task) %7B%0A        _tasks%5Btask%5D.setCompleter(new Callback());%0A        _tasks%5Btask%5D.fork();%0A    %7D%0A%0A    private class Callback extends H2O.H2OCallback%7B%0A        public Callback()%7Bsuper(ParallelizationTask.this);%7D%0A        @Override public void callback(H2O.H2OCountedCompleter cc) %7B%0A            if(_j != null) %7B%0A                _j.update(1);%0A            %7D%0A            int i = _ctr.incrementAndGet();%0A            if (i %3C _tasks.length)%0A                asyncVecTask(i);%0A        %7D%0A    %7D%0A%7D%0A

Add ParallelizationTask