Merge remote-tracking branch 'upstream/master' into user/jeffbloo/FreeDimOverrideByName

merge master
This commit is contained in:
Jeff 2020-04-15 16:27:43 -07:00
commit 47099a1700
44 changed files with 355 additions and 78 deletions

View file

@ -75,6 +75,12 @@ endif()
if (onnxruntime_USE_NUPHAR)
target_compile_definitions(onnxruntime4j_jni PRIVATE USE_NUPHAR=1)
endif()
if (onnxruntime_USE_ACL)
target_compile_definitions(onnxruntime4j_jni PRIVATE USE_ACL=1)
endif()
if (onnxruntime_USE_DML)
target_compile_definitions(onnxruntime4j_jni PRIVATE USE_DIRECTML=1)
endif()
# depend on java sources. if they change, the JNI should recompile
add_dependencies(onnxruntime4j_jni onnxruntime4j)

View file

@ -1836,4 +1836,44 @@ namespace Microsoft.ML.OnnxRuntime.Tests
}
}
// A Disposable list is a list of IDisposable objects. All elements will be disposed when the container is disposed.
internal class DisposableList<T> : List<T>, IDisposableReadOnlyCollection<T>
where T : IDisposable
{
public DisposableList() { }
public DisposableList(int count) : base(count) { }
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
for (int i = 0; i < this.Count; i++)
{
this[i]?.Dispose();
}
this.Clear();
}
disposedValue = true;
}
}
~DisposableList()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}

View file

@ -7,7 +7,7 @@
#include <string.h>
// This value is used in structures passed to ORT so that a newer version of ORT will still work with them
#define ORT_API_VERSION 2
#define ORT_API_VERSION 3
#ifdef __cplusplus
extern "C" {
@ -772,6 +772,16 @@ struct OrtApi {
ORT_CLASS_RELEASE(ThreadingOptions);
/**
* \param num_keys contains the number of keys in the custom metadata map
* \param keys is an array of null terminated strings (array count = num_keys) allocated using 'allocator'.
* The caller is responsible for freeing each string and the pointer array.
* 'keys' will be a nullptr if custom metadata map is empty.
*/
OrtStatus*(ORT_API_CALL* ModelMetadataGetCustomMetadataMapKeys)(_In_ const OrtModelMetadata* model_metadata,
_Inout_ OrtAllocator* allocator,
_Outptr_ char*** keys, _Out_ int64_t* num_keys)NO_EXCEPTION;
// Override symbolic dimensions (by specific name strings) with actual values if known at session initialization time to enable
// optimizations that can take advantage of fixed values (such as memory planning, etc)
OrtStatus*(ORT_API_CALL* AddFreeDimensionOverrideByName)(_Inout_ OrtSessionOptions* options,

View file

@ -199,6 +199,7 @@ struct ModelMetadata : Base<OrtModelMetadata> {
char* GetGraphName(OrtAllocator* allocator) const;
char* GetDomain(OrtAllocator* allocator) const;
char* GetDescription(OrtAllocator* allocator) const;
char** GetCustomMetadataMapKeys(OrtAllocator* allocator, _Out_ int64_t& num_keys) const;
char* LookupCustomMetadataMap(const char* key, OrtAllocator* allocator) const;
int64_t GetVersion() const;
};

View file

@ -324,6 +324,12 @@ inline char* ModelMetadata::LookupCustomMetadataMap(const char* key, OrtAllocato
return out;
}
inline char** ModelMetadata::GetCustomMetadataMapKeys(OrtAllocator* allocator, _Out_ int64_t& num_keys) const {
char** out;
ThrowOnError(Global<void>::api_.ModelMetadataGetCustomMetadataMapKeys(p_, allocator, &out, &num_keys));
return out;
}
inline int64_t ModelMetadata::GetVersion() const {
int64_t out;
ThrowOnError(Global<void>::api_.ModelMetadataGetVersion(p_, &out));

View file

@ -548,6 +548,26 @@ public class OrtSession implements AutoCloseable {
addNuphar(OnnxRuntime.ortApiHandle, nativeHandle, allowUnalignedBuffers ? 1 : 0, settings);
}
/**
* Adds DirectML as an execution backend.
*
* @param deviceId The id of the DirectML device.
* @throws OrtException If there was an error in native code.
*/
public void addDirectML(int deviceId) throws OrtException {
addDirectML(OnnxRuntime.ortApiHandle, nativeHandle, deviceId);
}
/**
* Adds the ARM Compute Library as an execution backend.
*
* @param useArena If true use the arena memory allocator.
* @throws OrtException If there was an error in native code.
*/
public void addACL(boolean useArena) throws OrtException {
addACL(OnnxRuntime.ortApiHandle, nativeHandle, useArena ? 1 : 0);
}
private native void setExecutionMode(long apiHandle, long nativeHandle, int mode)
throws OrtException;
@ -601,6 +621,11 @@ public class OrtSession implements AutoCloseable {
private native void addNuphar(
long apiHandle, long nativeHandle, int allowUnalignedBuffers, String settings)
throws OrtException;
private native void addDirectML(long apiHandle, long nativeHandle, int deviceId)
throws OrtException;
private native void addACL(long apiHandle, long nativeHandle, int useArena) throws OrtException;
}
/**

View file

@ -17,6 +17,10 @@
#include "onnxruntime/core/providers/nuphar/nuphar_provider_factory.h"
#include "onnxruntime/core/providers/openvino/openvino_provider_factory.h"
#include "onnxruntime/core/providers/tensorrt/tensorrt_provider_factory.h"
#include "onnxruntime/core/providers/acl/acl_provider_factory.h"
#ifdef USE_DIRECTML
#include "onnxruntime/core/providers/dml/dml_provider_factory.h"
#endif
/*
* Class: ai_onnxruntime_OrtSession_SessionOptions
@ -233,8 +237,7 @@ JNIEXPORT void JNICALL Java_ai_onnxruntime_OrtSession_00024SessionOptions_addNna
/*
* Class: ai_onnxruntime_OrtSession_SessionOptions
* Method: addNuphar
* Signature: (JILjava/lang/String {
})V
* Signature: (JILjava/lang/String)V
*/
JNIEXPORT void JNICALL Java_ai_onnxruntime_OrtSession_00024SessionOptions_addNuphar
(JNIEnv * jniEnv, jobject jobj, jlong apiHandle, jlong handle, jint allowUnalignedBuffers, jstring settingsString) {
@ -248,3 +251,35 @@ JNIEXPORT void JNICALL Java_ai_onnxruntime_OrtSession_00024SessionOptions_addNup
throwOrtException(jniEnv,convertErrorCode(ORT_INVALID_ARGUMENT),"This binary was not compiled with Nuphar support.");
#endif
}
/*
* Class: ai_onnxruntime_OrtSession_SessionOptions
* Method: addDirectML
* Signature: (JJI)V
*/
JNIEXPORT void JNICALL Java_ai_onnxruntime_OrtSession_00024SessionOptions_addDirectML
(JNIEnv * jniEnv, jobject jobj, jlong apiHandle, jlong handle, jint deviceID) {
(void)jobj;
#ifdef USE_DIRECTML
checkOrtStatus(jniEnv,(const OrtApi*)apiHandle,OrtSessionOptionsAppendExecutionProvider_DML((OrtSessionOptions*) handle, deviceID));
#else
(void)apiHandle;(void)handle;(void)deviceID; // Parameters used when DirectML is defined.
throwOrtException(jniEnv,convertErrorCode(ORT_INVALID_ARGUMENT),"This binary was not compiled with DirectML support.");
#endif
}
/*
* Class: ai_onnxruntime_OrtSession_SessionOptions
* Method: addACL
* Signature: (JJI)V
*/
JNIEXPORT void JNICALL Java_ai_onnxruntime_OrtSession_00024SessionOptions_addACL
(JNIEnv * jniEnv, jobject jobj, jlong apiHandle, jlong handle, jint useArena) {
(void)jobj;
#ifdef USE_ACL
checkOrtStatus(jniEnv,(const OrtApi*)apiHandle,OrtSessionOptionsAppendExecutionProvider_ACL((OrtSessionOptions*) handle,useArena));
#else
(void)apiHandle;(void)handle;(void)useArena; // Parameters used when ACL is defined.
throwOrtException(jniEnv,convertErrorCode(ORT_INVALID_ARGUMENT),"This binary was not compiled with ACL support.");
#endif
}

View file

@ -13,6 +13,7 @@
#include "core/common/logging/logging.h"
#include "core/common/status.h"
#include "core/common/safeint.h"
#include "core/graph/graph.h"
#include "core/framework/allocator.h"
#include "core/framework/tensor.h"
@ -755,6 +756,37 @@ ORT_API_STATUS_IMPL(OrtApis::ModelMetadataLookupCustomMetadataMap,
API_IMPL_END
}
ORT_API_STATUS_IMPL(OrtApis::ModelMetadataGetCustomMetadataMapKeys,
_In_ const OrtModelMetadata* model_metadata,
_Inout_ OrtAllocator* allocator, _Outptr_ char*** keys, _Out_ int64_t* num_keys) {
API_IMPL_BEGIN
const auto& custom_metadata_map =
reinterpret_cast<const ::onnxruntime::ModelMetadata*>(model_metadata)->custom_metadata_map;
auto count = custom_metadata_map.size();
if (count == 0) {
*keys = nullptr;
} else {
// To guard against overflow in the next step where we compute bytes to allocate
SafeInt<size_t> alloc_count(count);
// alloc_count * sizeof(...) will throw if there was an overflow which will be caught in API_IMPL_END
// and be returned to the user as a status
*keys = reinterpret_cast<char**>(allocator->Alloc(allocator, alloc_count * sizeof(char*)));
auto map_iter = custom_metadata_map.cbegin();
int64_t i = 0;
while (map_iter != custom_metadata_map.cend()) {
*keys[i++] = StrDup(map_iter->first, allocator);
++map_iter;
}
}
*num_keys = static_cast<int64_t>(count);
return nullptr;
API_IMPL_END
}
ORT_API_STATUS_IMPL(OrtApis::ModelMetadataGetVersion,
_In_ const OrtModelMetadata* model_metadata,
_Out_ int64_t* value) {
@ -1516,6 +1548,7 @@ static constexpr OrtApi ort_api_1_to_3 = {
&OrtApis::DisablePerSessionThreads,
&OrtApis::CreateThreadingOptions,
&OrtApis::ReleaseThreadingOptions,
&OrtApis::ModelMetadataGetCustomMetadataMapKeys,
&OrtApis::AddFreeDimensionOverrideByName};
// Assert to do a limited check to ensure Version 1 of OrtApi never changes (will detect an addition or deletion but not if they cancel out each other)

View file

@ -186,6 +186,10 @@ ORT_API_STATUS_IMPL(DisablePerSessionThreads, _In_ OrtSessionOptions* options);
ORT_API_STATUS_IMPL(CreateThreadingOptions, _Outptr_ OrtThreadingOptions** out);
ORT_API(void, ReleaseThreadingOptions, _Frees_ptr_opt_ OrtThreadingOptions*);
ORT_API_STATUS_IMPL(ModelMetadataGetCustomMetadataMapKeys, _In_ const OrtModelMetadata* model_metadata,
_Inout_ OrtAllocator* allocator, _Outptr_ char*** keys, _Out_ int64_t* num_keys);
ORT_API_STATUS_IMPL(AddFreeDimensionOverrideByName, _Inout_ OrtSessionOptions* options, _In_ const char* dim_name, _In_ int64_t dim_value);
} // namespace OrtApis

View file

@ -36,7 +36,7 @@ struct CatImputerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::CatImputerTransformer<T>(archive);
}());

View file

@ -19,7 +19,7 @@ void CountVectorizerTransformerImpl(OpKernelContext* ctx) {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::CountVectorizerTransformer(archive);
}());
@ -28,8 +28,10 @@ void CountVectorizerTransformerImpl(OpKernelContext* ctx) {
const std::string* input_data = input_tensor->template Data<std::string>();
// Prepare the callback that would output directly to output memory
std::function<void(NS::Featurizers::SparseVectorEncoding<uint32_t>)> callback;
callback = [ctx](NS::Featurizers::SparseVectorEncoding<uint32_t> result) {
bool callback_allow = true;
callback = [ctx, callback_allow](NS::Featurizers::SparseVectorEncoding<uint32_t> result) {
// Prepare output
ORT_ENFORCE(callback_allow, "callback function can only be called during execute() and special flush() when needed");
ORT_ENFORCE(result.NumElements < static_cast<uint64_t>(std::numeric_limits<int64_t>::max()),
"NumElements in SparseVectorEncoding is GE than max(int64)");
auto* output_tensor = ctx->Output(0, TensorShape{static_cast<int64_t>(result.NumElements)});
@ -40,6 +42,9 @@ void CountVectorizerTransformerImpl(OpKernelContext* ctx) {
}
};
transformer.execute(*input_data, callback);
// The flush() does nothing but shows Featurizers concept
callback_allow = false;
transformer.flush(callback);
};
class CountVectorizerTransformer final : public OpKernel {

View file

@ -24,7 +24,7 @@ class DateTimeTransformer final : public OpKernel {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::DateTimeTransformer(archive);
}());

View file

@ -24,7 +24,7 @@ struct ForecastingPivotTransformerImpl {
//Get the transformer
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
TransformerT transformer(archive);
// Get the Number of Rows
@ -59,9 +59,10 @@ struct ForecastingPivotTransformerImpl {
std::tuple<const T*,int64_t, int64_t> info_tuple(input_data, input_dim_1, input_dim_2);
dataPtrMap.insert(std::pair<int, std::tuple<const T*,int64_t, int64_t>>(index, info_tuple));
}
const T* input_data(std::get<0>(dataPtrMap.at(index)));
const int64_t input_dim_1(std::get<1>(dataPtrMap.at(index)));
const int64_t input_dim_2(std::get<2>(dataPtrMap.at(index)));
std::tuple<const T*,int64_t, int64_t> &inputTuple(dataPtrMap.at(index));
const T* input_data(std::get<0>(inputTuple));
const int64_t input_dim_1(std::get<1>(inputTuple));
const int64_t input_dim_2(std::get<2>(inputTuple));
input.push_back(typename InputType::value_type(input_data, input_dim_1, input_dim_2));
//Increment data pointer
input_data += input_dim_1 * input_dim_2;

View file

@ -21,7 +21,7 @@ struct FromStringTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::FromStringTransformer<T>(archive);
}());

View file

@ -21,7 +21,7 @@ struct HashOneHotVectorizerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::HashOneHotVectorizerTransformer<InputT>(archive);
}());

View file

@ -27,7 +27,7 @@ struct ImputationMarkerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::ImputationMarkerTransformer<InputT>(archive);
}());

View file

@ -21,7 +21,7 @@ struct LabelEncoderTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::LabelEncoderTransformer<InputT>(archive);
}());

View file

@ -28,7 +28,7 @@ struct LagLeadOperatorTransformerImpl {
//Get the transformer
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
typename EstimatorT::TransformerType transformer(archive);
// Get the Grains
@ -52,8 +52,8 @@ struct LagLeadOperatorTransformerImpl {
bool has_allocate_output_data = false;
std::function<void(OutputType)> callback_fn;
callback_fn = [ctx, &output_grains_data, &output_data, &has_allocate_output_data, output_dim_0](OutputType value) -> void {
GrainT & output_grains(std::get<GrainT>(value));
const OutputMatrixType & output_matrix(std::get<OutputMatrixType>(value));
GrainT & output_grains(std::get<0>(value));
const OutputMatrixType & output_matrix(std::get<1>(value));
//Allocate tensor memory after first output is generated
if (!has_allocate_output_data) {
TensorShape output_shape({output_dim_0, output_matrix.rows(), output_matrix.cols()});

View file

@ -44,7 +44,7 @@ struct MaxAbsScalerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::MaxAbsScalerTransformer<InputT, typename OutputTypeMapper<InputT>::type>(archive);
}());

View file

@ -36,7 +36,7 @@ struct MeanImputerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return MeanImputerTransformerT<InputT>(archive);
}());

View file

@ -50,7 +50,7 @@ struct MedianImputerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return MedianImputerTransformerT<InputT>(archive);
}());

View file

@ -45,7 +45,7 @@ struct MinMaxImputerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return MinMaxImputerTransformerT<T>(archive);
}());

View file

@ -21,7 +21,7 @@ struct MinMaxScalerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::MinMaxScalerTransformer<InputT>(archive);
}());

View file

@ -27,7 +27,7 @@ struct MissingDummiesTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::MissingDummiesTransformer<InputT>(archive);
}());

View file

@ -45,7 +45,7 @@ struct ModeImputerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return ModeImputerTransformerT<T>(archive);
}());

View file

@ -23,7 +23,7 @@ struct NormalizeTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Transformer(archive);
}());
@ -43,7 +43,9 @@ struct NormalizeTransformerImpl {
std::vector<double> result;
std::function<void(std::vector<double>)> callback;
callback = [&result](std::vector<double> val) mutable {
bool callback_allow = true;
callback = [&result, callback_allow](std::vector<double> val) {
ORT_ENFORCE(callback_allow, "callback function can only be called during execute() and special flush() when needed");
result = std::move(val);
};
@ -58,6 +60,9 @@ struct NormalizeTransformerImpl {
std::copy(result.cbegin(), result.cend(), output_data);
output_data += row_size;
}
// The flush() does nothing but shows Featurizers concept
callback_allow = false;
transformer.flush(callback);
}
};

View file

@ -21,7 +21,7 @@ struct NumericalizeTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::NumericalizeTransformer<InputT>(archive);
}());

View file

@ -21,7 +21,7 @@ struct OneHotEncoderTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::OneHotEncoderTransformer<InputT>(archive);
}());

View file

@ -25,7 +25,7 @@ struct PCATransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::PCATransformer<InputMatrixT>(archive);
}());
@ -47,10 +47,15 @@ struct PCATransformerImpl {
Eigen::Map<MatrixT> output_matrix(output_data, dim_0, dim_1);
std::function<void(MatrixT val)> callback;
callback = [&output_matrix](MatrixT val) {
bool callback_allow = true;
callback = [&output_matrix, callback_allow](MatrixT val) {
ORT_ENFORCE(callback_allow, "callback function can only be called during execute() and special flush() when needed");
output_matrix = val;
};
transformer.execute(input_matrix, callback);
// The flush() does nothing but shows Featurizers concept
callback_allow = false;
transformer.flush(callback);
}
};

View file

@ -44,7 +44,7 @@ struct RobustScalerTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::RobustScalerTransformer<InputT, typename OutputTypeMapper<InputT>::type>(archive);
}());

View file

@ -24,7 +24,7 @@ struct RollingWindowTransformerImpl {
//Get the transformer
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
typename EstimatorT::TransformerType transformer(archive);
// Get the Grains
@ -69,6 +69,7 @@ struct RollingWindowTransformerImpl {
target_data++;
grains_data += grains_num;
}
transformer.flush(callback_fn);
}
};

View file

@ -19,7 +19,7 @@ void ShortGrainDropperTransformerImpl(OpKernelContext* ctx) {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::ShortGrainDropperTransformer(archive);
}());

View file

@ -21,7 +21,7 @@ struct StandardScaleWrapperTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::StandardScalerTransformer<InputT, double>(archive);
}());

View file

@ -21,7 +21,7 @@ struct StringTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::StringTransformer<InputT>(archive);
}());

View file

@ -19,7 +19,7 @@ void TfidfVectorizerTransformerImpl(OpKernelContext* ctx) {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::TfidfVectorizerTransformer(archive);
}());
@ -29,8 +29,10 @@ void TfidfVectorizerTransformerImpl(OpKernelContext* ctx) {
// Prepare the callback that would output directly to output memory
std::function<void(NS::Featurizers::SparseVectorEncoding<float>)> callback;
callback = [ctx](NS::Featurizers::SparseVectorEncoding<float> result) {
bool callback_allow = true;
callback = [ctx, callback_allow](NS::Featurizers::SparseVectorEncoding<float> result) {
// Prepare output
ORT_ENFORCE(callback_allow, "callback function can only be called during execute() and special flush() when needed");
ORT_ENFORCE(result.NumElements < static_cast<uint64_t>(std::numeric_limits<int64_t>::max()),
"NumElements in SparseVectorEncoding is GE than max(int64)");
auto* output_tensor = ctx->Output(0, TensorShape{static_cast<int64_t>(result.NumElements)});
@ -41,6 +43,9 @@ void TfidfVectorizerTransformerImpl(OpKernelContext* ctx) {
}
};
transformer.execute(*input_data, callback);
// The flush() does nothing but shows Featurizers concept
callback_allow = false;
transformer.flush(callback);
}
class TfidfVectorizerTransformer final : public OpKernel {

View file

@ -25,7 +25,7 @@ struct TruncatedSVDTransformerImpl {
const auto* state_tensor(ctx->Input<Tensor>(0));
const uint8_t* const state_data(state_tensor->Data<uint8_t>());
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().GetDims()[0]);
Microsoft::Featurizer::Archive archive(state_data, state_tensor->Shape().Size());
return Microsoft::Featurizer::Featurizers::TruncatedSVDTransformer<InputMatrixT>(archive);
}());
@ -47,10 +47,15 @@ struct TruncatedSVDTransformerImpl {
Eigen::Map<MatrixT> output_matrix(output_data, dim_0, dim_1);
std::function<void(MatrixT val)> callback;
callback = [&output_matrix](MatrixT val) {
bool callback_allow = true;
callback = [&output_matrix, callback_allow](MatrixT val) {
ORT_ENFORCE(callback_allow, "callback function can only be called during execute() and special flush() when needed");
output_matrix = val;
};
transformer.execute(input_matrix, callback);
// The flush() does nothing but shows Featurizers concept
callback_allow = false;
transformer.flush(callback);
}
};

View file

@ -662,6 +662,18 @@ int real_main(int argc, char* argv[], Ort::Env& env) {
broken_tests.insert({"dynamic_slice_end_out_of_bounds", "This model uses contrib ops."});
broken_tests.insert({"dynamic_slice_neg", "This model uses contrib ops."});
broken_tests.insert({"mvn", "This model uses contrib ops.", {"onnx130"}});
broken_tests.insert({"cdist_float32_euclidean_1000_2000_1", "This model uses contrib ops."});
broken_tests.insert({"cdist_float32_euclidean_1000_2000_500", "This model uses contrib ops."});
broken_tests.insert({"cdist_float32_euclidean_1_1_1", "This model uses contrib ops."});
broken_tests.insert({"cdist_float32_sqeuclidean_1000_2000_1", "This model uses contrib ops."});
broken_tests.insert({"cdist_float32_sqeuclidean_1000_2000_500", "This model uses contrib ops."});
broken_tests.insert({"cdist_float32_sqeuclidean_1_1_1", "This model uses contrib ops."});
broken_tests.insert({"cdist_float64_euclidean_1000_2000_1", "This model uses contrib ops."});
broken_tests.insert({"cdist_float64_euclidean_1000_2000_500", "This model uses contrib ops."});
broken_tests.insert({"cdist_float64_euclidean_1_1_1", "This model uses contrib ops."});
broken_tests.insert({"cdist_float64_sqeuclidean_1000_2000_1", "This model uses contrib ops."});
broken_tests.insert({"cdist_float64_sqeuclidean_1000_2000_500", "This model uses contrib ops."});
broken_tests.insert({"cdist_float64_sqeuclidean_1_1_1", "This model uses contrib ops."});
#endif
int result = 0;

View file

@ -172,7 +172,8 @@ def create_backend_test(testname=None):
'^test_resize_downsample_scales_cubic_align_corners_cpu', # results mismatch with onnx tests
'^test_resize_downsample_scales_linear_align_corners_cpu' # results mismatch with onnx tests
]
if platform.architecture()[0] == '32bit':
current_failing_tests += ['^test_vgg19', '^test_zfnet512', '^test_bvlc_alexnet_cpu']
# Example of how to disable tests for a specific provider.
# if c2.supports_device('NGRAPH'):
# current_failing_tests.append('^test_operator_repeat_dim_overflow_cpu')

View file

@ -346,7 +346,7 @@ TEST(CApiTest, DISABLED_test_custom_op_library) {
#elif defined(__APPLE__)
lib_name = "libcustom_op_library.dylib";
#else
lib_name = "libcustom_op_library.so";
lib_name = "./libcustom_op_library.so";
#endif
TestInference<PATH_TYPE, int32_t>(*ort_env, CUSTOM_OP_LIBRARY_TEST_MODEL_URI, inputs, "output", expected_dims_y, expected_values_y, 0, nullptr, lib_name.c_str());
@ -509,37 +509,71 @@ TEST(CApiTest, end_profiling) {
}
TEST(CApiTest, model_metadata) {
Ort::MemoryInfo info("Cpu", OrtDeviceAllocator, 0, OrtMemTypeDefault);
auto allocator = onnxruntime::make_unique<MockedOrtAllocator>();
// Create session
Ort::SessionOptions session_options;
Ort::Session session(*ort_env, MODEL_WITH_CUSTOM_MODEL_METADATA, session_options);
// Fetch model metadata
// The following all tap into the c++ APIs which internally wrap over C APIs
auto model_metadata = session.GetModelMetadata();
char* producer_name = model_metadata.GetProducerName(allocator.get());
ASSERT_TRUE(strcmp("Hari", producer_name) == 0);
// The following section tests a model containing all metadata supported via the APIs
{
Ort::SessionOptions session_options;
Ort::Session session(*ort_env, MODEL_WITH_CUSTOM_MODEL_METADATA, session_options);
char* graph_name = model_metadata.GetGraphName(allocator.get());
ASSERT_TRUE(strcmp("matmul test", graph_name) == 0);
// Fetch model metadata
auto model_metadata = session.GetModelMetadata();
char* domain = model_metadata.GetDomain(allocator.get());
ASSERT_TRUE(strcmp("", domain) == 0);
char* producer_name = model_metadata.GetProducerName(allocator.get());
ASSERT_TRUE(strcmp("Hari", producer_name) == 0);
allocator.get()->Free(producer_name);
char* description = model_metadata.GetDescription(allocator.get());
ASSERT_TRUE(strcmp("This is a test model with a valid ORT config Json", description) == 0);
char* graph_name = model_metadata.GetGraphName(allocator.get());
ASSERT_TRUE(strcmp("matmul test", graph_name) == 0);
allocator.get()->Free(graph_name);
int64_t version = model_metadata.GetVersion();
ASSERT_TRUE(version == 1);
char* domain = model_metadata.GetDomain(allocator.get());
ASSERT_TRUE(strcmp("", domain) == 0);
allocator.get()->Free(domain);
char* lookup_value = model_metadata.LookupCustomMetadataMap("ort_config", allocator.get());
ASSERT_TRUE(strcmp(lookup_value,
"{\"session_options\": {\"inter_op_num_threads\": 5, \"intra_op_num_threads\": 2, \"graph_optimization_level\": 99, \"enable_profiling\": 1}}") == 0);
char* description = model_metadata.GetDescription(allocator.get());
ASSERT_TRUE(strcmp("This is a test model with a valid ORT config Json", description) == 0);
allocator.get()->Free(description);
// key doesn't exist in custom metadata map
lookup_value = model_metadata.LookupCustomMetadataMap("key_doesnt_exist", allocator.get());
ASSERT_TRUE(lookup_value == nullptr);
int64_t version = model_metadata.GetVersion();
ASSERT_TRUE(version == 1);
int64_t num_keys_in_custom_metadata_map;
char** custom_metadata_map_keys = model_metadata.GetCustomMetadataMapKeys(allocator.get(), num_keys_in_custom_metadata_map);
ASSERT_TRUE(num_keys_in_custom_metadata_map == 1);
ASSERT_TRUE(strcmp(custom_metadata_map_keys[0], "ort_config") == 0);
allocator.get()->Free(custom_metadata_map_keys[0]);
allocator.get()->Free(custom_metadata_map_keys);
char* lookup_value = model_metadata.LookupCustomMetadataMap("ort_config", allocator.get());
ASSERT_TRUE(strcmp(lookup_value,
"{\"session_options\": {\"inter_op_num_threads\": 5, \"intra_op_num_threads\": 2, \"graph_optimization_level\": 99, \"enable_profiling\": 1}}") == 0);
allocator.get()->Free(lookup_value);
// key doesn't exist in custom metadata map
lookup_value = model_metadata.LookupCustomMetadataMap("key_doesnt_exist", allocator.get());
ASSERT_TRUE(lookup_value == nullptr);
}
// The following section tests a model with some missing metadata info
// Adding this just to make sure the API implementation is able to handle empty/missing info
{
Ort::SessionOptions session_options;
Ort::Session session(*ort_env, MODEL_URI, session_options);
// Fetch model metadata
auto model_metadata = session.GetModelMetadata();
// Model description is empty
char* description = model_metadata.GetDescription(allocator.get());
ASSERT_TRUE(strcmp("", description) == 0);
allocator.get()->Free(description);
// Model does not contain custom metadata map
int64_t num_keys_in_custom_metadata_map;
char** custom_metadata_map_keys = model_metadata.GetCustomMetadataMapKeys(allocator.get(), num_keys_in_custom_metadata_map);
ASSERT_TRUE(num_keys_in_custom_metadata_map == 0);
ASSERT_TRUE(custom_metadata_map_keys == nullptr);
}
}

View file

@ -1,8 +1,11 @@
parameters:
- name: is_featurizers_build
displayName: "Is Featurizers Build"
type: boolean
default: false
# Note that any variable set in this file overrides a value set within the Azure pipeline UX.
# Therefore, do not set default values here, but instead do it within a template script.
#
# parameters:
# - name: is_featurizers_build
# displayName: "Is Featurizers Build"
# type: boolean
# default: false
jobs:
- job: Manylinux2010_py_Wheels
@ -36,7 +39,7 @@ jobs:
- template: templates/set-featurizer-build-flag-step.yml
parameters:
is_featurizers_build: ${{ parameters.is_featurizers_build }}
is_featurizers_build: $(is_featurizers_build)
- task: CmdLine@2
displayName: 'Download azcopy'
@ -111,7 +114,7 @@ jobs:
- template: templates/set-featurizer-build-flag-step.yml
parameters:
is_featurizers_build: ${{ parameters.is_featurizers_build }}
is_featurizers_build: $(is_featurizers_build)
- task: CmdLine@2
displayName: 'Download azcopy'
@ -193,7 +196,7 @@ jobs:
- template: templates/set-featurizer-build-flag-step.yml
parameters:
is_featurizers_build: ${{ parameters.is_featurizers_build }}
is_featurizers_build: $(is_featurizers_build)
- task: BatchScript@1
displayName: 'setup env'
@ -284,7 +287,7 @@ jobs:
- template: templates/set-featurizer-build-flag-step.yml
parameters:
is_featurizers_build: ${{ parameters.is_featurizers_build }}
is_featurizers_build: $(is_featurizers_build)
- task: PythonScript@0
displayName: 'Download test data'
@ -336,6 +339,10 @@ jobs:
clean: true
submodules: recursive
- template: templates/set-featurizer-build-flag-step.yml
parameters:
is_featurizers_build: $(is_featurizers_build)
- task: UsePythonVersion@0
displayName: 'Use Python'
inputs:
@ -344,7 +351,7 @@ jobs:
- script: |
sudo python -m pip install -r '$(Build.SourcesDirectory)/tools/ci_build/github/linux/docker/scripts/requirements.txt'
sudo xcode-select --switch /Applications/Xcode_10.app/Contents/Developer
./build.sh --config Release --skip_submodule_sync --parallel --build_wheel --use_openmp
./build.sh --config Release --skip_submodule_sync --parallel --build_wheel --use_openmp $(FeaturizerBuildFlag)
displayName: 'Command Line Script'
- task: CopyFiles@2

View file

@ -38,6 +38,15 @@ jobs:
workingDirectory: '$(Build.BinariesDirectory)'
displayName: 'Install python modules'
- powershell: |
$Env:USE_MSVC_STATIC_RUNTIME=1
$Env:ONNX_ML=1
$Env:CMAKE_ARGS="-DONNX_USE_PROTOBUF_SHARED_LIBS=OFF -DProtobuf_USE_STATIC_LIBS=ON -DONNX_USE_LITE_PROTO=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=$(buildArch)-windows-static"
python setup.py bdist_wheel
Get-ChildItem -Path dist/*.whl | foreach {pip install --upgrade $_.fullname}
workingDirectory: '$(Build.SourcesDirectory)\cmake\external\onnx'
displayName: 'Install ONNX'
- task: NuGetToolInstaller@0
displayName: Use Nuget 4.9
inputs:

View file

@ -37,7 +37,16 @@ jobs:
python -m pip install -q pyopenssl setuptools wheel numpy
workingDirectory: '$(Build.BinariesDirectory)'
displayName: 'Install python modules'
- powershell: |
$Env:USE_MSVC_STATIC_RUNTIME=1
$Env:ONNX_ML=1
$Env:CMAKE_ARGS="-DONNX_USE_PROTOBUF_SHARED_LIBS=OFF -DProtobuf_USE_STATIC_LIBS=ON -DONNX_USE_LITE_PROTO=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=$(buildArch)-windows-static"
python setup.py bdist_wheel
Get-ChildItem -Path dist/*.whl | foreach {pip install --upgrade $_.fullname}
workingDirectory: '$(Build.SourcesDirectory)\cmake\external\onnx'
displayName: 'Install ONNX'
- task: PythonScript@0
displayName: 'Generate cmake config'
inputs:

View file

@ -38,6 +38,15 @@ jobs:
workingDirectory: '$(Build.BinariesDirectory)'
displayName: 'Install python modules'
- powershell: |
$Env:USE_MSVC_STATIC_RUNTIME=1
$Env:ONNX_ML=1
$Env:CMAKE_ARGS="-DONNX_USE_PROTOBUF_SHARED_LIBS=OFF -DProtobuf_USE_STATIC_LIBS=ON -DONNX_USE_LITE_PROTO=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=$(buildArch)-windows-static"
python setup.py bdist_wheel
Get-ChildItem -Path dist/*.whl | foreach {pip install --upgrade $_.fullname}
workingDirectory: '$(Build.SourcesDirectory)\cmake\external\onnx'
displayName: 'Install ONNX'
- task: PythonScript@0
displayName: 'Generate cmake config'
inputs:

View file

@ -37,7 +37,16 @@ jobs:
python -m pip install -q pyopenssl setuptools wheel numpy
workingDirectory: '$(Build.BinariesDirectory)'
displayName: 'Install python modules'
- powershell: |
$Env:USE_MSVC_STATIC_RUNTIME=1
$Env:ONNX_ML=1
$Env:CMAKE_ARGS="-DONNX_USE_PROTOBUF_SHARED_LIBS=OFF -DProtobuf_USE_STATIC_LIBS=ON -DONNX_USE_LITE_PROTO=ON -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=$(buildArch)-windows-static"
python setup.py bdist_wheel
Get-ChildItem -Path dist/*.whl | foreach {pip install --upgrade $_.fullname}
workingDirectory: '$(Build.SourcesDirectory)\cmake\external\onnx'
displayName: 'Install ONNX'
- task: PythonScript@0
displayName: 'Generate cmake config'
inputs: