code: def call_forward(self, vol_data, out=None):
          
          with self._mutex:
              assert vol_data in self.reco_space
              if out is not None:
                  assert out in self.proj_space
              else:
                  out = self.proj_space.element()
  
              # Copy data to GPU memory
              if self.geometry.ndim == 2:
                  astra.data2d.store(self.vol_id, vol_data.asarray())
              elif self.geometry.ndim == 3:
                  astra.data3d.store(self.vol_id, vol_data.asarray())
              else:
                  raise RuntimeError('unknown ndim')
  
              # Run algorithm
              astra.algorithm.run(self.algo_id)
  
              # Copy result to host
              if self.geometry.ndim == 2:
                  out[:] = self.out_array
              elif self.geometry.ndim == 3:
                  out[:] = np.swapaxes(self.out_array, 0, 1).reshape(
                      self.proj_space.shape)
  
              # Fix scaling to weight by pixel size
              if isinstance(self.geometry, Parallel2dGeometry):
                  # parallel2d scales with pixel stride
                  out *= 1 / float(self.geometry.det_partition.cell_volume)
  
              return out
docs: Run an ASTRA forward projection on the given data using the GPU.
  
          Parameters
          ----------
          vol_data : ``reco_space`` element
              Volume data to which the projector is applied.
          out : ``proj_space`` element, optional
              Element of the projection space to which the result is written. If
              ``None``, an element in `proj_space` is created.
  
          Returns
          -------
          out : ``proj_space`` element
              Projection data resulting from the application of the projector.
              If ``out`` was provided, the returned object is a reference to it.