Prevent errors during initialization of `EngineConfig`s from getting clobbered.

Otherwise they're clobbered by a less-useful `NOT_INITIALIZED` error.

PiperOrigin-RevId: 402606298
Change-Id: I9264eaf5fe2343d72730251ba5f1ffc611adcfa3
diff --git a/tensorflow/stream_executor/cuda/cuda_dnn.cc b/tensorflow/stream_executor/cuda/cuda_dnn.cc
index 30e01c3..d933fcb 100644
--- a/tensorflow/stream_executor/cuda/cuda_dnn.cc
+++ b/tensorflow/stream_executor/cuda/cuda_dnn.cc
@@ -3882,10 +3882,18 @@
         "Got legacy cuDNN algorithm enum in RebuildExecutionPlan.");
   }
 
-  auto engine = cudnn_frontend::EngineBuilder()
-                    .setOperationGraph(op_graph)
-                    .setGlobalEngineIdx(desc.algo_id())
-                    .build();
+  // Errors encountered when building a cuDNN operation graph are surfaced in an
+  // unprecedented and innovative way: they're written into a field of the
+  // contained engine object, but then clobbered by the object's move
+  // constructor which makes more cuDNN API calls and encounters further errors.
+  // The only way to get the actual errors is to peek at them via the returned
+  // rvalue reference before actually moving the object to finish its
+  // initialization.
+  cudnn_frontend::EngineBuilder engine_builder;
+  engine_builder.setOperationGraph(op_graph).setGlobalEngineIdx(desc.algo_id());
+  auto&& unmoved = engine_builder.build();
+  RETURN_MSG_IF_CUDNN_ERROR(unmoved);
+  cudnn_frontend::Engine engine = std::move(unmoved);
   RETURN_MSG_IF_CUDNN_ERROR(engine);
 
   for (auto& knob : engine.getSupportedKnobs()) {