void insert_value_in_output()

in source/neuropod/backends/torchscript/torch_backend.cc [122:206]


void insert_value_in_output(NeuropodValueMap & output,
                            const std::string  name,
                            const c10::IValue &value,
                            const bool         has_type    = false,
                            const TensorType   tensor_type = FLOAT_TENSOR)
{
    if (value.isTensor())
    {
        // Torch tensor
        // Transfer it to CPU
        // .to(device) is a no-op if the tensor is already transferred
        // .contiguous() is a no-op if the tensor is already contiguous
        auto tensor = value.toTensor().to(torch::kCPU).contiguous();

        // Get the type and make a TorchNeuropodTensor
        auto neuropod_tensor_type = get_neuropod_type_from_torch_type(tensor.scalar_type());
        auto neuropod_tensor      = make_tensor<TorchNeuropodTensor>(neuropod_tensor_type, tensor);

        // Add it to our output
        auto &to_set = output[name];
        if (!to_set)
        {
            to_set = std::move(neuropod_tensor);
        }
        else
        {
            NEUROPOD_ERROR("An item with name `{}` was already returned by this model. Please ensure your model does "
                           "not have duplicate outputs",
                           name);
        }
    }
#if CAFFE2_NIGHTLY_VERSION >= 20200421
    else if (value.isList())
#else
    else if (value.isGenericList())
#endif
    {
        // A list of strings
        // This is used in place of string tensors because torch does not
        // have native support for string tensors
        auto &tensor = value;

#if CAFFE2_NIGHTLY_VERSION >= 20200421
        const auto &list = tensor.toListRef();
#else
        const auto &list = tensor.toGenericListRef();
#endif

        // if tensor_type string or no tensor_type and empty list or list containing actual string
        if ((has_type && tensor_type == TensorType::STRING_TENSOR) || (!has_type && list.empty()) ||
            (!has_type && list[0].isString()))
        {
            // Make a TorchNeuropodTensor
            auto neuropod_tensor = stdx::make_unique<TorchNeuropodTensor<std::string>>(tensor);

            // Add it to our output
            auto &to_set = output[name];
            if (!to_set)
            {
                to_set = std::move(neuropod_tensor);
            }
            else
            {
                NEUROPOD_ERROR("An item with name `{}` was already returned by this model. Please ensure your model "
                               "does not have duplicate outputs",
                               name);
            }
        }
        // it was bad spec or contained non-string type
        else
        {
            NEUROPOD_ERROR("Neuropod got a list of type '{}' for tensor '{}'."
                           "Only tensors or lists of strings are supported",
                           list[0].tagKind(),
                           name);
        }
    }
    else
    {
        NEUROPOD_ERROR("Neuropod returned an invalid type! All outputs must be tensors"
                       "or lists of strings. Got type '{}' for tensor '{}'",
                       value.tagKind(),
                       name);
    }
}