function getFilteredNodesXToY(tape, xs, y) {
    // Forward pass to compute all the nodes and Tensors that are transitively a
    // function of x.
    const tensorsFromX = {};
    const nodesFromX = {};
    for(let i = 0; i < xs.length; i++)tensorsFromX[xs[i].id] = true;
    for(let i = 0; i < tape.length; i++){
        const node = tape[i];
        const nodeInputs = node.inputs;
        for(const inputName in nodeInputs){
            const input = nodeInputs[inputName];
            let anyInputFromX = false;
            for(let j = 0; j < xs.length; j++)if (tensorsFromX[input.id]) {
                node.outputs.forEach((output)=>tensorsFromX[output.id] = true);
                anyInputFromX = true;
                nodesFromX[node.id] = true;
                break;
            }
            if (anyInputFromX) break;
        }
    }
    // Backward pass to find all of the nodes and Tensors that lead to y.
    const tensorsLeadToY = {};
    tensorsLeadToY[y.id] = true;
    const nodesToY = {};
    for(let i = tape.length - 1; i >= 0; i--){
        const node = tape[i];
        const nodeInputs = node.inputs;
        // If any of the outputs lead to y, mark all of the inputs as leading to y.
        for(let j = 0; j < node.outputs.length; j++)if (tensorsLeadToY[node.outputs[j].id]) {
            for(const inputName in nodeInputs){
                tensorsLeadToY[nodeInputs[inputName].id] = true;
                nodesToY[node.id] = true;
            }
            break;
        }
    }
    // Return the paths that come from x and lead to y.
    const filteredTape = [];
    for(let i = 0; i < tape.length; i++){
        const node = tape[i];
        if (nodesFromX[node.id] && nodesToY[node.id]) {
            // Prune the inputs from the node that aren't a function of x.
            const prunedInputs = {};
            for(const inputName in node.inputs){
                const nodeInput = node.inputs[inputName];
                if (tensorsFromX[nodeInput.id]) prunedInputs[inputName] = nodeInput;
            }
            // Copy the node and overwrite inputsAndArgs to the pruned version.
            const prunedNode = Object.assign({}, node);
            prunedNode.inputs = prunedInputs;
            prunedNode.outputs = node.outputs;
            filteredTape.push(prunedNode);
        }
    }
    return filteredTape;
}
Backpropagate gradients through the filtered TapeNodes.

@param tensorAccumulatedGradientMap A map of Tensor to its gradient. This map
is mutated by this method.
@param filteredTape The filtered TapeNodes to backprop through.