| 29 | public: |
| 30 | using OpKernel::OpKernel; |
| 31 | void Compute(OpKernelContext* context) override { |
| 32 | const Tensor* patterns_t; |
| 33 | // NOTE(ringwalt): Changing the input name "pattern" to "patterns" would |
| 34 | // break existing graphs. |
| 35 | OP_REQUIRES_OK(context, context->input("pattern", &patterns_t)); |
| 36 | OP_REQUIRES( |
| 37 | context, |
| 38 | TensorShapeUtils::IsScalar(patterns_t->shape()) || |
| 39 | TensorShapeUtils::IsVector(patterns_t->shape()), |
| 40 | errors::InvalidArgument( |
| 41 | "Input patterns tensor must be scalar or vector, but had shape: ", |
| 42 | patterns_t->shape().DebugString())); |
| 43 | const auto patterns = patterns_t->flat<tstring>(); |
| 44 | int num_patterns = patterns.size(); |
| 45 | int num_files = 0; |
| 46 | std::vector<std::vector<string>> all_fnames(num_patterns); |
| 47 | for (int i = 0; i < num_patterns; i++) { |
| 48 | OP_REQUIRES_OK(context, context->env()->GetMatchingPaths(patterns(i), |
| 49 | &all_fnames[i])); |
| 50 | num_files += all_fnames[i].size(); |
| 51 | } |
| 52 | Tensor* output_t = nullptr; |
| 53 | OP_REQUIRES_OK( |
| 54 | context, context->allocate_output("filenames", TensorShape({num_files}), |
| 55 | &output_t)); |
| 56 | auto output = output_t->vec<tstring>(); |
| 57 | int index = 0; |
| 58 | for (int i = 0; i < num_patterns; ++i) { |
| 59 | for (int j = 0; j < all_fnames[i].size(); j++) { |
| 60 | output(index++) = all_fnames[i][j]; |
| 61 | } |
| 62 | } |
| 63 | std::sort(&output(0), &output(0) + num_files); |
| 64 | } |
| 65 | }; |
| 66 | |
| 67 | REGISTER_KERNEL_BUILDER(Name("MatchingFiles").Device(DEVICE_CPU), |
nothing calls this directly
no test coverage detected