@@ -81,13 +81,84 @@ class TrainingLogger final {
81
81
void print (raw_fd_ostream &OutFile);
82
82
83
83
private:
84
+ // / Write the values of one tensor as a list.
84
85
template <typename T>
85
- void writeTensor (raw_fd_ostream &OutFile, StringRef TensorName,
86
- const std::vector<T> &Tensor);
86
+ void writeTensorValues (raw_fd_ostream &OutFile, const char *TensorData,
87
+ size_t ElemCount) const {
88
+ OutFile << " [" ;
89
+ const T *TypedData = reinterpret_cast <const T *>(TensorData);
90
+ for (size_t I = 0 ; I < ElemCount; ++I) {
91
+ if (I > 0 )
92
+ OutFile << " , " ;
93
+ OutFile << TypedData[I];
94
+ }
95
+ OutFile << " ]" ;
96
+ }
97
+
98
+ // / Write a list of tensors as a sequence of TensorFlow FeatureList protobufs.
99
+ // / The tensors are assumed to be stored contiguously, in row-major format,
100
+ // / in the TensorData buffer. Each tensor has the shape given by Spec. The
101
+ // / feature name in the output is either the provided LoggingName, if
102
+ // / specified, otherwise it's the name of the tensor (as given by Spec).
103
+ template <typename T>
104
+ void
105
+ writeTensorsAsFeatureLists (raw_fd_ostream &OutFile, const TensorSpec &Spec,
106
+ const T *TensorData, size_t TensorCount,
107
+ Optional<StringRef> LoggingName = None) const {
108
+ writeRawTensorsAsFeatureLists (OutFile, Spec,
109
+ reinterpret_cast <const char *>(TensorData),
110
+ TensorCount, LoggingName);
111
+ }
112
+
113
+ // / Untyped implementation of the API above.
114
+ void
115
+ writeRawTensorsAsFeatureLists (raw_fd_ostream &OutFile, const TensorSpec &Spec,
116
+ const char *TensorData, size_t TensorCount,
117
+ Optional<StringRef> LoggingName = None) const {
118
+ const char *FieldName = " <invalid>" ;
119
+ std::function<void (const char *)> ValueWriter;
120
+ // The 'Feature' protobuf only has 3 possible fields: float_list,
121
+ // int64_list, or bytes_list, so we capture int32 values as int64. We don't
122
+ // support any other types.
123
+ if (Spec.isElementType <int64_t >()) {
124
+ FieldName = " int64_list" ;
125
+ ValueWriter = [&](const char *Data) {
126
+ writeTensorValues<int64_t >(OutFile, Data, Spec.getElementCount ());
127
+ };
128
+ } else if (Spec.isElementType <int32_t >()) {
129
+ FieldName = " int64_list" ;
130
+ ValueWriter = [&](const char *Data) {
131
+ writeTensorValues<int32_t >(OutFile, Data, Spec.getElementCount ());
132
+ };
133
+
134
+ } else if (Spec.isElementType <float >()) {
135
+ FieldName = " float_list" ;
136
+ ValueWriter = [&](const char *Data) {
137
+ writeTensorValues<float >(OutFile, Data, Spec.getElementCount ());
138
+ };
139
+
140
+ } else
141
+ llvm_unreachable (" Unsupported tensor type." );
142
+
143
+ OutFile << " feature_list: {\n " ;
144
+ OutFile << " key: "
145
+ << " \" " << (LoggingName ? *LoggingName : Spec.name ()) << " \" " ;
146
+ OutFile << " value: {\n " ;
147
+ size_t TensorByteSize = Spec.getElementCount () * Spec.getElementByteSize ();
148
+ for (const char *P = TensorData,
149
+ *E = TensorData + TensorByteSize * TensorCount;
150
+ P < E; P += TensorByteSize) {
151
+ OutFile << " feature: { " << FieldName << " : { value: " ;
152
+ ValueWriter (P);
153
+ OutFile << " } }\n " ;
154
+ }
155
+ OutFile << " }\n " ;
156
+ OutFile << " }\n " ;
157
+ }
87
158
88
159
std::vector<InlineFeatures> Features;
89
- std::vector<bool > DefaultDecisions;
90
- std::vector<bool > Decisions;
160
+ std::vector<int64_t > DefaultDecisions;
161
+ std::vector<int64_t > Decisions;
91
162
std::vector<bool > Effects;
92
163
std::vector<int64_t > Rewards;
93
164
};
@@ -294,35 +365,30 @@ void TrainingLogger::logInlineEvent(const InlineEvent &Event,
294
365
}
295
366
296
367
void TrainingLogger::print (raw_fd_ostream &OutFile) {
297
- if (DefaultDecisions.empty ())
368
+ size_t NumberOfRecords = Decisions.size ();
369
+ if (NumberOfRecords == 0 )
298
370
return ;
299
- OutFile << " feature_lists: {\n " ;
300
371
301
- for (size_t I = 0 ; I < Features.size (); I++) {
302
- writeTensor (OutFile, FeatureNameMap.at (I), Features[I]);
303
- }
304
- writeTensor (OutFile, DefaultDecisionName, DefaultDecisions);
305
- writeTensor (OutFile, DecisionName, Decisions);
306
- writeTensor (OutFile, RewardName, Rewards);
372
+ OutFile << " feature_lists: {\n " ;
373
+ for (size_t I = 0 ; I < Features.size (); ++I)
374
+ writeTensorsAsFeatureLists (
375
+ OutFile, TensorSpec::createSpec<int64_t >(FeatureNameMap.at (I), {1 }),
376
+ Features[I].data (), NumberOfRecords);
377
+
378
+ writeTensorsAsFeatureLists (
379
+ OutFile, TensorSpec::createSpec<int64_t >(DefaultDecisionName, {1 }),
380
+ DefaultDecisions.data (), NumberOfRecords);
381
+
382
+ writeTensorsAsFeatureLists (OutFile,
383
+ TensorSpec::createSpec<int64_t >(DecisionName, {1 }),
384
+ Decisions.data (), NumberOfRecords);
385
+ writeTensorsAsFeatureLists (OutFile,
386
+ TensorSpec::createSpec<int64_t >(RewardName, {1 }),
387
+ Rewards.data (), NumberOfRecords);
307
388
308
389
OutFile << " }\n " ;
309
390
}
310
391
311
- template <typename T>
312
- void TrainingLogger::writeTensor (raw_fd_ostream &OutFile, StringRef TensorName,
313
- const std::vector<T> &Tensor) {
314
- OutFile << " feature_list: {\n " ;
315
- OutFile << " key: "
316
- << " \" " << TensorName << " \" " ;
317
- OutFile << " value: {\n " ;
318
- for (const auto &Feature : Tensor) {
319
- OutFile << " feature: { int64_list: { value: [" << Feature
320
- << " ] } }\n " ;
321
- }
322
- OutFile << " }\n " ;
323
- OutFile << " }\n " ;
324
- }
325
-
326
392
DevelopmentModeMLInlineAdvisor::DevelopmentModeMLInlineAdvisor (
327
393
Module &M, ModuleAnalysisManager &MAM,
328
394
std::unique_ptr<MLModelRunner> ModelRunner,
0 commit comments