in Tools/WinMLRunner/src/BindingUtilities.cpp [894:1013]
void PrintOrSaveEvaluationResults(const LearningModel& model, const CommandLineArgs& args,
const IMapView<hstring, winrt::Windows::Foundation::IInspectable>& results,
OutputHelper& output, int iterationNum)
{
for (auto&& desc : model.OutputFeatures())
{
if (desc.Kind() == LearningModelFeatureKind::Tensor)
{
std::wstring name(desc.Name());
if (args.IsSaveTensor() && args.SaveTensorMode() == L"First" && iterationNum > 0)
{
return;
}
if (args.IsSaveTensor())
{
output.SetDefaultCSVIterationResult(iterationNum, args, name);
}
void* tensor;
uint32_t uCapacity;
com_ptr<ITensorNative> itn = results.Lookup(desc.Name()).as<ITensorNative>();
HRESULT(itn->GetBuffer(reinterpret_cast<BYTE**>(&tensor), &uCapacity));
int size = 0;
unsigned int topK = args.TopK();
std::vector<std::pair<float, int>> maxKValues;
std::ofstream fout;
if (args.IsSaveTensor())
{
fout.open(output.GetCsvFileNamePerIterationResult(), std::ios_base::app);
fout << "Index"
<< ","
<< "Value" << std::endl;
}
TensorFeatureDescriptor tensorDescriptor = desc.as<TensorFeatureDescriptor>();
TensorKind tensorKind = tensorDescriptor.TensorKind();
switch (tensorKind)
{
case TensorKind::String:
{
if (!args.IsGarbageInput())
{
auto resultVector = results.Lookup(desc.Name()).as<TensorString>().GetAsVectorView();
auto output = resultVector.GetAt(0).data();
std::wcout << " Result: " << output << std::endl;
}
}
break;
case TensorKind::Float16:
{
output.ProcessTensorResult<HALF>(args, tensor, uCapacity, maxKValues, fout, topK);
}
break;
case TensorKind::Float:
{
output.ProcessTensorResult<float>(args, tensor, uCapacity, maxKValues, fout, topK);
}
break;
case TensorKind::Int64:
{
auto resultVector = results.Lookup(desc.Name()).as<TensorInt64Bit>().GetAsVectorView();
if (!args.IsGarbageInput())
{
auto output = resultVector.GetAt(0);
std::wcout << " Result: " << output << std::endl;
}
}
break;
default:
{
std::cout << "BindingUtilities: output type not implemented.";
}
break;
}
if (args.IsSaveTensor())
{
fout.close();
for (auto& pair : maxKValues)
{
auto maxValue = pair.first;
auto maxIndex = pair.second;
std::string iterationResult =
"Index: " + std::to_string(maxIndex) + "; Value: " + std::to_string(maxValue);
output.SaveResult(iterationNum, iterationResult,
static_cast<int>(hash_data(tensor, uCapacity)));
}
}
if (!args.IsGarbageInput() && iterationNum == 0)
{
std::wcout << L"Outputting top " << args.TopK() << L" values" << std::endl;
std::wcout << L"Feature Name: " << name << std::endl;
for (auto& pair : maxKValues)
{
auto maxValue = pair.first;
auto maxIndex = pair.second;
std::wcout << L" index: " << maxIndex << L", value: " << maxValue << std::endl;
}
}
}
else if (desc.Kind() == LearningModelFeatureKind::Sequence)
{
auto seqDescriptor = desc.as<SequenceFeatureDescriptor>();
auto mapDescriptor = seqDescriptor.ElementDescriptor().as<MapFeatureDescriptor>();
auto keyKind = mapDescriptor.KeyKind();
auto valueKind = mapDescriptor.ValueDescriptor();
auto tensorKind = valueKind.as<TensorFeatureDescriptor>().TensorKind();
switch (keyKind)
{
case TensorKind::Int64:
{
OutputSequenceBinding<int64_t, float>(results, desc.Name());
}
break;
case TensorKind::Float:
{
OutputSequenceBinding<float, float>(results, desc.Name());
}
break;
}
}
}
}