docstr: data_in: input past data in same format of Ymat
  covariates: input past covariates
  ycovs: input past individual covariates
  future: number of time-points to predict
  bsize: batch size for processing (determine according to gopu memory limits)
  normalize: should be set according to the normalization used in the class initialization
  num_workers: number of workers to run prediction. if num_workers > 1, then prediction will
  run in distributed mode and there has to be an activate OrcaRayContext.
docstr_tok: ["data_in",":","input","past","data","in","same","format","of","Ymat","covariates",":","input","past","covariates","ycovs",":","input","past","individual","covariates","future",":","number","of","time-points","to","predict","bsize",":","batch","size","for","processing","(","determine","according","to","gopu","memory","limits",")","normalize",":","should","be","set","according","to","the","normalization","used","in","the","class","initialization","num_workers",":","number","of","workers","to","run","prediction",".","if","num_workers",">","1",",","then","prediction","will","run","in","distributed","mode","and","there","has","to","be","an","activate","OrcaRayContext","."]
code: def predict_future(
      self,
      data_in,
      covariates=None,
      ycovs=None,
      future=10,
      bsize=40,
      normalize=False,
      num_workers=1,
  ):
      """
      data_in: input past data in same format of Ymat
      covariates: input past covariates
      ycovs: input past individual covariates
      future: number of time-points to predict
      bsize: batch size for processing (determine according to gopu memory limits)
      normalize: should be set according to the normalization used in the class initialization
      num_workers: number of workers to run prediction. if num_workers > 1, then prediction will
      run in distributed mode and there has to be an activate OrcaRayContext.
      """
      with torch.no_grad():
          if normalize:
              data = (data_in - self.m[:, None]) / self.s[:, None]
              data += self.mini
  
          else:
              data = data_in
  
          n, T = data.shape
  
          I = list(np.arange(0, n, bsize))
          I.append(n)
  
          model = self.seq
          if num_workers > 1:
              import ray
              import math
  
              batch_num_per_worker = math.ceil(len(I) / num_workers)
              indexes = [
                  I[i : i + batch_num_per_worker + 1]
                  for i in range(0, len(I) - 1, batch_num_per_worker)
              ]
              logger.info(
                  f"actual number of workers used in prediction is {len(indexes)}"
              )
              data_id = ray.put(data)
              covariates_id = ray.put(covariates)
              ycovs_id = ray.put(ycovs)
              model_id = ray.put(model)
  
              @ray.remote
              def predict_future_worker(I):
                  data = ray.get(data_id)
                  covariates = ray.get(covariates_id)
                  ycovs = ray.get(ycovs_id)
                  model = ray.get(model_id)
                  out = LocalModel._predict_future(
                      data, ycovs, covariates, model, future, I
                  )
                  return out
  
              remote_out = ray.get(
                  [
                      predict_future_worker.remote(index)
                      for index in indexes
                  ]
              )
  
              out = np.concatenate(remote_out, axis=0)
  
          else:
              out = LocalModel._predict_future(
                  data, ycovs, covariates, model, future, I
              )
  
          if normalize:
              temp = (out - self.mini) * self.s[:, None] + self.m[
                  :, None
              ]
              out = temp
      return out
  
imports: import pickle
  import numpy
  import torch
  import torch.nn
  import torch.optim
  from torch.autograd import Variable
  from torch.nn.utils import weight_norm
  from bigdl.chronos.model.tcmf.data_loader import TCMFDataLoader
  from bigdl.chronos.model.tcmf.time import TimeCovariates
  import logging
label_desc: Use image node_id 11 for calling the LocalModel obj's underlying member method code with example usage: obj.predict_future(data_in, covariates, ycovs, future, bsize, normalize, num_workers) and returns: out, out