code: def predict(self, data, output_margin=False, ntree_limit=0, pred_leaf=False):
          
          option_mask = 0x00
          if output_margin:
              option_mask |= 0x01
          if pred_leaf:
              option_mask |= 0x02
  
          self._validate_features(data)
  
          length = ctypes.c_ulong()
          preds = ctypes.POINTER(ctypes.c_float)()
          _check_call(_LIB.XGBoosterPredict(self.handle, data.handle,
                                            option_mask, ntree_limit,
                                            ctypes.byref(length),
                                            ctypes.byref(preds)))
          preds = ctypes2numpy(preds, length.value, np.float32)
          if pred_leaf:
              preds = preds.astype(np.int32)
          nrow = data.num_row()
          if preds.size != nrow and preds.size % nrow == 0:
              preds = preds.reshape(nrow, preds.size / nrow)
          return preds
docs: Predict with data.
  
          NOTE: This function is not thread safe.
                For each booster object, predict can only be called from one thread.
                If you want to run prediction using multiple thread, call bst.copy() to make copies
                of model object and then call predict
  
          Parameters
          ----------
          data : DMatrix
              The dmatrix storing the input.
  
          output_margin : bool
              Whether to output the raw untransformed margin value.
  
          ntree_limit : int
              Limit number of trees in the prediction; defaults to 0 (use all trees).
  
          pred_leaf : bool
              When this option is on, the output will be a matrix of (nsample, ntrees)
              with each record indicating the predicted leaf index of each sample in each tree.
              Note that the leaf index of a tree is unique per tree, so you may find leaf 1
              in both tree 1 and tree 0.
  
          Returns
          -------
          prediction : numpy array