def backward(self, engine: EngineLM = None):
        """
        Backpropagate gradients through the computation graph starting from this variable.

        :param engine: The backward engine to use for gradient computation. If not provided, the global engine will be used.
        :type engine: EngineLM, optional

        :raises Exception: If no backward engine is provided and no global engine is set.
        :raises Exception: If both an engine is provided and the global engine is set.
        """
        if ((engine is None) and (SingletonBackwardEngine().get_engine() is None)):
            raise Exception("No backward engine provided. Either provide an engine as the argument to this call, or use `textgrad.set_backward_engine(engine)` to set the backward engine.")
        elif ((engine is not None) and (SingletonBackwardEngine().get_engine() is not None)):
            raise Exception("Both an engine is provided and the global engine is set. Be careful when doing this.")
        
        backward_engine = engine if engine else SingletonBackwardEngine().get_engine()
        """Taken from https://github.com/karpathy/micrograd/blob/master/micrograd/engine.py"""
        # topological order all the predecessors in the graph
        topo = []
        visited = set()

        def build_topo(v):
            if v not in visited:
                visited.add(v)
                for predecessor in v.predecessors:
                    build_topo(predecessor)
                topo.append(v)

        build_topo(self)

        # go one variable at a time and apply the chain rule to get its gradient
        # TODO: we should somehow ensure that we do not have cases such as the predecessors of a variable requiring a gradient, but the variable itself not requiring a gradient

        self.gradients = set()
        for v in reversed(topo):
            if v.requires_grad:
                v.gradients = _check_and_reduce_gradients(v, backward_engine)
                if v.get_grad_fn() is not None:
                    v.grad_fn(backward_engine=backward_engine)

        Backpropagate gradients through the computation graph starting from this variable.

        :param engine: The backward engine to use for gradient computation. If not provided, the global engine will be used.
        :type engine: EngineLM, optional

        :raises Exception: If no backward engine is provided and no global engine is set.
        :raises Exception: If both an engine is provided and the global engine is set.
        
textgrad/variable.py