| 251 | TEST(CAPI, RemoteExecuteAsync) { TestRemoteExecute(true); } |
| 252 | |
| 253 | void TestRemoteExecuteSilentCopies(bool async) { |
| 254 | tensorflow::ServerDef server_def = GetServerDef(3); |
| 255 | |
| 256 | // This server def has the task index set to 0. |
| 257 | string serialized = server_def.SerializeAsString(); |
| 258 | |
| 259 | server_def.set_task_index(1); |
| 260 | std::unique_ptr<tensorflow::GrpcServer> worker_server1; |
| 261 | ASSERT_TRUE(tensorflow::GrpcServer::Create( |
| 262 | server_def, tensorflow::Env::Default(), &worker_server1) |
| 263 | .ok()); |
| 264 | ASSERT_TRUE(worker_server1->Start().ok()); |
| 265 | |
| 266 | server_def.set_task_index(2); |
| 267 | std::unique_ptr<tensorflow::GrpcServer> worker_server2; |
| 268 | ASSERT_TRUE(tensorflow::GrpcServer::Create( |
| 269 | server_def, tensorflow::Env::Default(), &worker_server2) |
| 270 | .ok()); |
| 271 | ASSERT_TRUE(worker_server2->Start().ok()); |
| 272 | |
| 273 | TF_Status* status = TF_NewStatus(); |
| 274 | TFE_ContextOptions* opts = TFE_NewContextOptions(); |
| 275 | TFE_ContextOptionsSetAsync(opts, static_cast<unsigned char>(async)); |
| 276 | TFE_ContextOptionsSetDevicePlacementPolicy(opts, TFE_DEVICE_PLACEMENT_SILENT); |
| 277 | TFE_Context* ctx = TFE_NewContext(opts, status); |
| 278 | EXPECT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 279 | TFE_DeleteContextOptions(opts); |
| 280 | |
| 281 | TFE_ContextSetServerDef(ctx, 0, serialized.data(), serialized.size(), status); |
| 282 | EXPECT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 283 | |
| 284 | TFE_TensorHandle* h0_task0 = TestMatrixTensorHandle(); |
| 285 | TFE_TensorHandle* h1_task0 = TestMatrixTensorHandle(); |
| 286 | const char task1_name[] = "/job:localhost/replica:0/task:1/device:CPU:0"; |
| 287 | const char task2_name[] = "/job:localhost/replica:0/task:2/device:CPU:0"; |
| 288 | |
| 289 | auto* h1_task2 = |
| 290 | TFE_TensorHandleCopyToDevice(h1_task0, ctx, task2_name, status); |
| 291 | ASSERT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 292 | |
| 293 | // Handles are on task0 (local), and task2, but op is on task1. |
| 294 | TFE_Op* matmul = MatMulOp(ctx, h0_task0, h1_task2); |
| 295 | TFE_OpSetDevice(matmul, task1_name, status); |
| 296 | EXPECT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 297 | |
| 298 | TFE_TensorHandle* retvals[1]; |
| 299 | int num_retvals = 1; |
| 300 | TFE_Execute(matmul, &retvals[0], &num_retvals, status); |
| 301 | EXPECT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 302 | |
| 303 | auto* retval_task0 = TFE_TensorHandleCopyToDevice( |
| 304 | retvals[0], ctx, "/job:localhost/replica:0/task:0/device:CPU:0", status); |
| 305 | ASSERT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 306 | |
| 307 | TF_Tensor* t = TFE_TensorHandleResolve(retval_task0, status); |
| 308 | ASSERT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 309 | TFE_DeleteTensorHandle(retval_task0); |
| 310 | float product[4] = {0}; |
no test coverage detected