| 56 | } |
| 57 | |
| 58 | void Compute(OpKernelContext* ctx) override { |
| 59 | const Tensor* records; |
| 60 | OpInputList record_defaults; |
| 61 | |
| 62 | OP_REQUIRES_OK(ctx, ctx->input("records", &records)); |
| 63 | OP_REQUIRES_OK(ctx, ctx->input_list("record_defaults", &record_defaults)); |
| 64 | |
| 65 | for (int i = 0; i < record_defaults.size(); ++i) { |
| 66 | OP_REQUIRES(ctx, record_defaults[i].dims() <= 1, |
| 67 | errors::InvalidArgument( |
| 68 | "Each record default should be at most rank 1")); |
| 69 | OP_REQUIRES(ctx, record_defaults[i].NumElements() < 2, |
| 70 | errors::InvalidArgument( |
| 71 | "There should only be 1 default per field but field ", i, |
| 72 | " has ", record_defaults[i].NumElements())); |
| 73 | } |
| 74 | |
| 75 | auto records_t = records->flat<tstring>(); |
| 76 | int64 records_size = records_t.size(); |
| 77 | |
| 78 | OpOutputList output; |
| 79 | OP_REQUIRES_OK(ctx, ctx->output_list("output", &output)); |
| 80 | |
| 81 | for (int i = 0; i < static_cast<int>(out_type_.size()); ++i) { |
| 82 | Tensor* out = nullptr; |
| 83 | OP_REQUIRES_OK(ctx, output.allocate(i, records->shape(), &out)); |
| 84 | } |
| 85 | |
| 86 | auto RunTask = [&records_t, ctx, this, &output, |
| 87 | &record_defaults] (int64 start, int64 end) { |
| 88 | for (int64 i = start; i < end; ++i) { |
| 89 | const StringPiece record(records_t(i)); |
| 90 | std::vector<string> fields; |
| 91 | ExtractFields(ctx, record, &fields); |
| 92 | OP_REQUIRES(ctx, fields.size() == out_type_.size(), |
| 93 | errors::InvalidArgument("Expect ", out_type_.size(), |
| 94 | " fields but have ", fields.size(), |
| 95 | " in record ", i)); |
| 96 | |
| 97 | // Check each field in the record |
| 98 | for (int f = 0; f < static_cast<int>(out_type_.size()); ++f) { |
| 99 | const DataType& dtype = out_type_[f]; |
| 100 | switch (dtype) { |
| 101 | case DT_INT32: { |
| 102 | // If this field is empty or NA value, check if default is given: |
| 103 | // If yes, use default value; Otherwise report error. |
| 104 | if (fields[f].empty() || fields[f] == na_value_) { |
| 105 | OP_REQUIRES(ctx, record_defaults[f].NumElements() == 1, |
| 106 | errors::InvalidArgument( |
| 107 | "Field ", f, |
| 108 | " is required but missing in record ", i, "!")); |
| 109 | |
| 110 | output[f]->flat<int32>()(i) = record_defaults[f].flat<int32>()(0); |
| 111 | } else { |
| 112 | int32 value; |
| 113 | OP_REQUIRES(ctx, strings::safe_strto32(fields[f], &value), |
| 114 | errors::InvalidArgument( |
| 115 | "Field ", f, " in record ", i, |
nothing calls this directly
no test coverage detected