Copy sample code into samples/dynamic_shapes/README.md. (#19699)

Follow-up to https://github.com/iree-org/iree/pull/19658.
diff --git a/samples/dynamic_shapes/README.md b/samples/dynamic_shapes/README.md
index d3d66ee..710b948 100644
--- a/samples/dynamic_shapes/README.md
+++ b/samples/dynamic_shapes/README.md
@@ -13,10 +13,6 @@
 [`tensorflow_dynamic_shapes.ipynb`](./tensorflow_dynamic_shapes.ipynb)
 [Colab](https://colab.google/) notebooks:
 
-> [!WARNING]
-> The PyTorch sample code below is outdated, as the `@aot.jittable` API is
-> unstable.
-
 | Framework | Notebook |
 | --------- | -------- |
 PyTorch | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/iree-org/iree/blob/main/samples/dynamic_shapes/pytorch_dynamic_shapes.ipynb)
@@ -33,36 +29,65 @@
 import torch
 import iree.turbine.aot as aot
 
-class DynamicShapesModule(aot.CompiledModule, export_name="module"):
+class DynamicShapesModule(torch.nn.Module):
   # reduce_sum_1d (dynamic input size, static output size)
   #   tensor<?xi32> -> tensor<i32>
   #   e.g. [1, 2, 3] -> 6
-  def reduce_sum_1d(self, values=aot.AbstractTensor(None, dtype=torch.int32)):
-    return self.compute_reduce_sum_1d(values)
-
-  @aot.jittable
-  def compute_reduce_sum_1d(values):
-    return torch.sum(values, dtype=torch.int32)
+  def reduce_sum_1d(self, values):
+    return torch.sum(values)
 
   # reduce_sum_2d (partially dynamic input size, static output size)
   #   tensor<?x3xi32> -> tensor<3xi32>
   #   e.g. [[1, 2, 3], [10, 20, 30]] -> [11, 22, 33]
-  def reduce_sum_2d(self, values=aot.AbstractTensor(None, 3, dtype=torch.int32)):
-    return self.compute_reduce_sum_2d(values)
-
-  @aot.jittable
-  def compute_reduce_sum_2d(values):
-    return torch.sum(values, 0, dtype=torch.int32)
+  def reduce_sum_2d(self, values):
+    return torch.sum(values, 0)
 
   # add_one (dynamic input size, dynamic output size)
   #   tensor<?xi32>) -> tensor<?xi32>
   #   e.g. [1, 2, 3] -> [2, 3, 4]
-  def add_one(self, values=aot.AbstractTensor(None, dtype=torch.int32)):
-    return self.compute_add_one(values)
-
-  @aot.jittable
-  def compute_add_one(values):
+  def add_one(self, values):
     return values + 1
+
+    fxb = aot.FxProgramsBuilder(DynamicShapesModule())
+```
+
+Each function is exported using the `FxProgramsBuilder` class with explicit
+dynamic dimensions:
+
+```python
+fxb = aot.FxProgramsBuilder(DynamicShapesModule())
+
+# Create a single dynamic export dimension.
+dynamic_x = torch.export.Dim("x")
+# Example inputs with a mix of placeholder (dynamic) and static dimensions.
+example_1d = torch.empty(16, dtype=torch.int32)
+example_2d = torch.empty((16, 3), dtype=torch.int32)
+
+# Export reduce_sum_1d with a dynamic dimension.
+@fxb.export_program(
+    args=(example_1d,),
+    dynamic_shapes={"values": {0: dynamic_x}},
+)
+def reduce_sum_1d(module, values):
+    return module.reduce_sum_1d(values)
+
+# Export reduce_sum_2d with one dynamic dimension.
+@fxb.export_program(
+    args=(example_2d,),
+    dynamic_shapes={"values": {0: dynamic_x}},
+)
+def reduce_sum_2d(module, values):
+    return module.reduce_sum_2d(values)
+
+# Export add_one with a dynamic dimension.
+@fxb.export_program(
+    args=(example_1d,),
+    dynamic_shapes={"values": {0: dynamic_x}},
+)
+def add_one(module, values):
+    return module.add_one(values)
+
+export_output = aot.export(fxb)
 ```
 
 ## Background