code: public void fit(GraphWalkIteratorProvider<V> iteratorProvider) {
          if (!initCalled)
              throw new UnsupportedOperationException("DeepWalk not initialized (call initialize before fit)");
          List<GraphWalkIterator<V>> iteratorList = iteratorProvider.getGraphWalkIterators(nThreads);
  
          PriorityScheduler scheduler = new PriorityScheduler(nThreads);
  
          List<Future<Void>> list = new ArrayList<>(iteratorList.size());
          //log.info("Fitting Graph with {} threads", Math.max(nThreads,iteratorList.size()));
          for (GraphWalkIterator<V> iter : iteratorList) {
              LearningCallable c = new LearningCallable(iter);
              list.add(scheduler.submit(c));
          }
  
          scheduler.shutdown();   // wont shutdown till complete
  
          try {
              FutureUtils.blockTillAllCompleteOrFirstError(list);
          } catch (InterruptedException e) {
              // should not be possible with blocking till scheduler terminates
              Thread.currentThread().interrupt();
              throw new RuntimeException(e);
          } catch (ExecutionException e) {
              throw new RuntimeException(e);
          }
      }
docs: Fit the model, in parallel, using a given GraphWalkIteratorProvider.<br>
  This object is used to generate multiple GraphWalkIterators, which can then be distributed to each thread
  to do in parallel<br>
  Note that {@link #fit(IGraph, int)} will be more convenient in many cases<br>
  Note that {@link #initialize(IGraph)} or {@link #initialize(int[])} <em>must</em> be called first.
  @param iteratorProvider GraphWalkIteratorProvider
  @see #fit(IGraph, int)