| 843 | } |
| 844 | |
| 845 | OptimizationResult AttemptBackendAssignment(BackendSettings& backendSettings, |
| 846 | Graph& graph, |
| 847 | Layer* layer, |
| 848 | BackendId backend, |
| 849 | DataType dataTypeIn, |
| 850 | DataType dataTypeOut, |
| 851 | const std::vector<BackendId>& availablePreferredBackends, |
| 852 | std::string& reasonIfUnsupported, |
| 853 | Optional<std::vector<std::string>&> messages) |
| 854 | { |
| 855 | OptimizationResult result; |
| 856 | |
| 857 | // Helper lambda to compose meaningful error message before returning with error |
| 858 | auto ReturnError = [&](const Layer* layer) |
| 859 | { |
| 860 | return ReturnWithError(result, layer, backendSettings, messages); |
| 861 | }; |
| 862 | |
| 863 | // need to set the compute device on the layer |
| 864 | // before we can check if it is supported |
| 865 | layer->SetBackendId(backend); |
| 866 | std::string currentReasonIfUnsupported; |
| 867 | |
| 868 | // To run FP16 operations on CpuAcc we need at least v8.2 architecture. If the available architecture |
| 869 | // is older than v8.2, we can check if the operator is supported by changing operator inputs & outputs |
| 870 | // to be FP32 and inserting convert layers around the FP32 operator. |
| 871 | bool isLayerSupported = IWorkloadFactory::IsLayerSupported(*layer, EmptyOptional(), currentReasonIfUnsupported); |
| 872 | reasonIfUnsupported += currentReasonIfUnsupported; |
| 873 | if (!isLayerSupported && HasCapability("AllOrNothing", backend)) |
| 874 | { |
| 875 | // It has the capability but is it set to true? |
| 876 | if (GetCapability("AllOrNothing", backend).value().GetValue().AsBool()) |
| 877 | { |
| 878 | // This is when a backend says it must execute all layers in a model. We'll report a message to say the |
| 879 | // backend will be ignored for the rest of this subgraph. |
| 880 | std::stringstream fullWarningMessage; |
| 881 | fullWarningMessage << "Backend: " << backend |
| 882 | << " has \"AllOrNothing\" enabled. A layer of type " |
| 883 | << GetLayerTypeAsCString(layer->GetType()) << " reports that it is not supported. " |
| 884 | << "This backend will not be considered to execute this subgraph."; |
| 885 | reasonIfUnsupported.append(fullWarningMessage.str()); |
| 886 | // Also add it to the messages if they exist. |
| 887 | ReportWarning(fullWarningMessage.str(), messages); |
| 888 | result.m_Warning = true; |
| 889 | return result; |
| 890 | } |
| 891 | } |
| 892 | // This string matches the error message that is produced by acl when attempting to run FP16 kernels on |
| 893 | // a cpu or build that does not have fp16 support. We use this to check if we should add |
| 894 | // conversion layers or not. |
| 895 | std::string checkStr = "This CPU architecture does not support F16 data type, you need v8.2 or above"; |
| 896 | if (!isLayerSupported || currentReasonIfUnsupported.find(checkStr) != std::string::npos) |
| 897 | { |
| 898 | if (dataTypeIn == DataType::Float16 || dataTypeOut == DataType::Float16) |
| 899 | { |
| 900 | if (IWorkloadFactory::IsLayerSupported(*layer, DataType::Float32, reasonIfUnsupported) |
| 901 | && layer->GetType() != LayerType::ConvertFp32ToFp16 |
| 902 | && layer->GetType() != LayerType::ConvertFp16ToFp32) |
no test coverage detected