| 1035 | TEST(CAPI, Execute_MatMul_CPUAsync) { Execute_MatMul_CPU(true); } |
| 1036 | |
| 1037 | void Execute_MatMul_CPU_Runtime_Error(bool async) { |
| 1038 | TF_Status* status = TF_NewStatus(); |
| 1039 | TFE_ContextOptions* opts = TFE_NewContextOptions(); |
| 1040 | TFE_ContextOptionsSetAsync(opts, static_cast<unsigned char>(async)); |
| 1041 | TFE_Context* ctx = TFE_NewContext(opts, status); |
| 1042 | CHECK_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 1043 | TFE_DeleteContextOptions(opts); |
| 1044 | |
| 1045 | TFE_TensorHandle* m1 = TestMatrixTensorHandle(); |
| 1046 | TFE_TensorHandle* m2 = DoubleTestMatrixTensorHandle3X2(); |
| 1047 | TFE_Op* matmul = MatMulOp(ctx, m1, m2); |
| 1048 | TFE_OpSetDevice(matmul, "/job:localhost/replica:0/task:0/device:CPU:0", |
| 1049 | status); |
| 1050 | ASSERT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 1051 | TFE_Op* matmul2 = MatMulOp(ctx, m1, m1); |
| 1052 | TFE_OpSetDevice(matmul2, "/job:localhost/replica:0/task:0/device:CPU:0", |
| 1053 | status); |
| 1054 | ASSERT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 1055 | TFE_TensorHandle* retvals[1] = {nullptr}; |
| 1056 | int num_retvals = 1; |
| 1057 | TFE_Execute(matmul, &retvals[0], &num_retvals, status); |
| 1058 | TFE_DeleteOp(matmul); |
| 1059 | if (!async) { |
| 1060 | EXPECT_NE(TF_OK, TF_GetCode(status)); |
| 1061 | } else { |
| 1062 | TF_Tensor* t = TFE_TensorHandleResolve(retvals[0], status); |
| 1063 | EXPECT_NE(TF_OK, TF_GetCode(status)); |
| 1064 | EXPECT_EQ(nullptr, t); |
| 1065 | const char* msg = "In[0] mismatch In[1] shape: 2 vs. 3: [2,2] [3,2]"; |
| 1066 | EXPECT_TRUE(strstr(TF_Message(status), msg) != nullptr) |
| 1067 | << TF_Message(status); |
| 1068 | // Since error is not cleared, the following copy with correct device will |
| 1069 | // still fail. |
| 1070 | TF_SetStatus(status, TF_OK, ""); |
| 1071 | TFE_DeleteTensorHandle(retvals[0]); |
| 1072 | retvals[0] = nullptr; |
| 1073 | TFE_Execute(matmul2, &retvals[0], &num_retvals, status); |
| 1074 | EXPECT_NE(TF_OK, TF_GetCode(status)); |
| 1075 | TFE_Executor* executor = TFE_ContextGetExecutorForThread(ctx); |
| 1076 | TFE_ExecutorClearError(executor); |
| 1077 | TFE_ExecutorWaitForAllPendingNodes(executor, status); |
| 1078 | ASSERT_EQ(TF_OK, TF_GetCode(status)) << TF_Message(status); |
| 1079 | TFE_DeleteExecutor(executor); |
| 1080 | } |
| 1081 | // Following works in async mode since TFE_ContextAsyncClearError was called. |
| 1082 | TF_SetStatus(status, TF_OK, ""); |
| 1083 | if (retvals[0] != nullptr) { |
| 1084 | TFE_DeleteTensorHandle(retvals[0]); |
| 1085 | } |
| 1086 | retvals[0] = nullptr; |
| 1087 | TFE_Execute(matmul2, &retvals[0], &num_retvals, status); |
| 1088 | EXPECT_EQ(TF_OK, TF_GetCode(status)); |
| 1089 | TF_Tensor* t = TFE_TensorHandleResolve(retvals[0], status); |
| 1090 | EXPECT_EQ(TF_OK, TF_GetCode(status)); |
| 1091 | TF_DeleteTensor(t); |
| 1092 | TFE_DeleteOp(matmul2); |
| 1093 | TFE_DeleteTensorHandle(m1); |
| 1094 | TFE_DeleteTensorHandle(m2); |
no test coverage detected