From c0c26402c0f7aa80a5a5d48427821fbfccb7a82e Mon Sep 17 00:00:00 2001
From: vamshikrishna <vamshikrishna@in.ibm.com>
Date: Sat, 15 Apr 2023 21:08:37 -0500
Subject: [PATCH 1/7] merged changes to 1.14 release.

---
 onnxruntime/contrib_ops/cpu/murmur_hash3.cc   |  60 ++++++++--
 onnxruntime/core/framework/session_options.h  |   1 +
 .../core/framework/tensorprotoutils.cc        | 107 +++++++++++++++++-
 onnxruntime/core/framework/tensorprotoutils.h |   2 +
 onnxruntime/core/graph/graph.cc               |  14 +++
 onnxruntime/core/mlas/lib/mlasi.h             |   4 +
 onnxruntime/core/mlas/lib/platform.cpp        |  19 +++-
 onnxruntime/core/mlas/lib/qgemm.h             |   2 +-
 .../core/optimizer/attention_fusion.cc        |   6 +
 .../core/optimizer/attention_fusion_helper.h  |   2 +-
 .../core/optimizer/constant_folding.cc        |   3 +
 .../core/optimizer/embed_layer_norm_fusion.cc |   6 +
 onnxruntime/core/optimizer/reshape_fusion.cc  |   3 +
 .../transpose_optimizer/optimizer_api_impl.cc |   4 +-
 onnxruntime/core/platform/posix/env.cc        |   2 +
 onnxruntime/core/providers/shared/symbols.exp |   2 +
 onnxruntime/core/session/inference_session.cc |   4 +-
 onnxruntime/python/onnxruntime_validation.py  |  14 ++-
 onnxruntime/python/symbols.exp                |   1 +
 19 files changed, 233 insertions(+), 23 deletions(-)
 create mode 100644 onnxruntime/core/providers/shared/symbols.exp
 create mode 100644 onnxruntime/python/symbols.exp

diff --git a/onnxruntime/contrib_ops/cpu/murmur_hash3.cc b/onnxruntime/contrib_ops/cpu/murmur_hash3.cc
index 3eb519c68..f430396c8 100644
--- a/onnxruntime/contrib_ops/cpu/murmur_hash3.cc
+++ b/onnxruntime/contrib_ops/cpu/murmur_hash3.cc
@@ -60,11 +60,31 @@ inline uint64_t rotl64(uint64_t x, int8_t r) {
 // handle aligned reads, do the conversion here
 
 FORCE_INLINE uint32_t getblock(const uint32_t* p, int i) {
-  return p[i];
+  if constexpr (onnxruntime::endian::native == onnxruntime::endian::little) {
+    return p[i];
+  } else {
+    const uint8_t* c = (const uint8_t*)&p[i];
+    return (uint32_t)c[0] |
+           (uint32_t)c[1] << 8 |
+           (uint32_t)c[2] << 16 |
+           (uint32_t)c[3] << 24;
+  }
 }
 
 FORCE_INLINE uint64_t getblock(const uint64_t* p, int i) {
-  return p[i];
+  if constexpr (onnxruntime::endian::native == onnxruntime::endian::little) {
+    return p[i];
+  } else {
+    const uint8_t* c = (const uint8_t*)&p[i];
+    return (uint64_t)c[0] |
+           (uint64_t)c[1] << 8 |
+           (uint64_t)c[2] << 16 |
+           (uint64_t)c[3] << 24 |
+           (uint64_t)c[4] << 32 |
+           (uint64_t)c[5] << 40 |
+           (uint64_t)c[6] << 48 |
+           (uint64_t)c[7] << 56;
+  }
 }
 
 //-----------------------------------------------------------------------------
@@ -205,13 +225,35 @@ Status MurmurHash3::Compute(OpKernelContext* ctx) const {
     ORT_ENFORCE(input_num_bytes % 4 == 0);
     const auto input_end = input + input_count * input_num_bytes;
     while (input != input_end) {
-      MurmurHash3_x86_32(input,
-                         input_num_bytes,
-                         seed_,
-                         output);
-      input += input_num_bytes;
-      ++output;
-    }
+      if constexpr (onnxruntime::endian::native == onnxruntime::endian::little)  {
+         MurmurHash3_x86_32(input,
+                            input_num_bytes,
+                            seed_,
+                            output);
+      }
+      else {
+         std::cout<<"Doing Byte Swapping ..input_num_bytes is "<<input_num_bytes;   
+         char *input_cp = (char *)malloc(input_num_bytes); 
+         memcpy(input_cp, input, input_num_bytes);
+         char* start_byte = input_cp;
+         char* end_byte = start_byte + input_num_bytes - 1;
+         /* Keep swapping */
+         for (int count = 0; count < input_num_bytes/2; ++count) {
+           char temp = *start_byte;
+           *start_byte = *end_byte;
+           *end_byte = temp;
+           ++start_byte;
+           --end_byte;
+        }
+        MurmurHash3_x86_32(input_cp,
+                           input_num_bytes,
+                           seed_,
+                           output);
+        free(input_cp);
+     }
+     input += input_num_bytes;
+     ++output;
+   }
   }
   return Status::OK();
 }
diff --git a/onnxruntime/core/framework/session_options.h b/onnxruntime/core/framework/session_options.h
index 61b233766..2af47d890 100644
--- a/onnxruntime/core/framework/session_options.h
+++ b/onnxruntime/core/framework/session_options.h
@@ -5,6 +5,7 @@
 
 #include <string>
 #include <vector>
+#include "core/framework/ort_value.h"
 #include "core/common/gsl.h"
 #include "core/common/inlined_containers.h"
 #include "core/session/onnxruntime_c_api.h"
diff --git a/onnxruntime/core/framework/tensorprotoutils.cc b/onnxruntime/core/framework/tensorprotoutils.cc
index 22faa6737..9d032e6e0 100644
--- a/onnxruntime/core/framework/tensorprotoutils.cc
+++ b/onnxruntime/core/framework/tensorprotoutils.cc
@@ -188,6 +188,101 @@ static Status ReadExternalDataForTensor(const ONNX_NAMESPACE::TensorProto& tenso
 namespace onnxruntime {
 namespace utils {
 #if !defined(ORT_MINIMAL_BUILD)
+
+void ConvertRawDataInTensorProto(TensorProto* tensor)
+{
+            size_t element_size=1;
+            char* bytes = NULL;
+            size_t num_elements=0;
+            switch(tensor->data_type())
+            {
+             case TensorProto_DataType_FLOAT:
+             bytes = (char*)(tensor->mutable_float_data()->mutable_data());
+             num_elements = tensor->float_data_size();
+             element_size=4;
+             break;
+
+             case TensorProto_DataType_INT32:
+             bytes = (char*)(tensor->mutable_int32_data()->mutable_data());
+             num_elements = tensor->int32_data_size();
+             element_size=4;
+             break;
+
+             case TensorProto_DataType_UINT32:
+             bytes = (char*)(tensor->mutable_int32_data()->mutable_data());
+             num_elements = tensor->int32_data_size();
+             element_size=4;
+             break;
+
+             case TensorProto_DataType_UINT8:
+             case TensorProto_DataType_INT8:
+             element_size=1;
+             break;
+
+             case TensorProto_DataType_UINT16:
+             case TensorProto_DataType_INT16:
+             case TensorProto_DataType_FLOAT16:
+             case TensorProto_DataType_BFLOAT16:
+             element_size=2;
+             break;
+
+             case TensorProto_DataType_UINT64:
+             bytes = (char*)(tensor->mutable_uint64_data()->mutable_data());
+             num_elements = tensor->uint64_data_size();
+             element_size=8;
+             break;
+
+             case TensorProto_DataType_DOUBLE:
+             bytes = (char*)(tensor->mutable_double_data()->mutable_data());
+             num_elements = tensor->double_data_size();
+             element_size=8;
+             break;
+
+             case TensorProto_DataType_INT64:
+             bytes = (char*)(tensor->mutable_int64_data()->mutable_data());
+             num_elements = tensor->int64_data_size();
+             element_size=8;
+             break;
+
+             case TensorProto_DataType_COMPLEX64:
+             element_size=8;
+             break;
+            }
+            if (tensor->has_raw_data()) {
+              num_elements = (tensor->raw_data().size()) / element_size;
+              bytes = (char*)(tensor->mutable_raw_data()->c_str());
+            }
+/*
+            uint64_t *pbt = (uint64_t*)bytes;
+            std::cout << "Madhu graph.cc ConveTens tensor->name()=" << tensor->name()
+                      << " tensor->data_type()=" << tensor->data_type()
+                      << " element_size=" << element_size
+                      << " num_elements=" << num_elements << std::hex << " pbt[0]=" << pbt[0]
+                      << " pbt[1]=" << pbt[1] << std::dec << std::endl;
+*/
+
+
+           for (size_t i = 0; i < num_elements; ++i) {
+                char* start_byte = bytes + i * element_size;
+                char* end_byte = start_byte + element_size - 1;
+                /* keep swapping */
+                for (size_t count = 0; count < element_size / 2; ++count) {
+                    char temp = *start_byte;
+                    *start_byte = *end_byte;
+                    *end_byte = temp;
+                    ++start_byte;
+                    --end_byte;
+                }
+           }
+
+/*
+          std::cout << "Madhu1 graph.cc ConveTens pbt[0]=" << std::hex << pbt[0]
+                    << " pbt[1]=" << pbt[1] << std::dec << std::endl;
+*/
+
+  return;
+}
+
 static Status UnpackTensorWithExternalDataImpl(const ONNX_NAMESPACE::TensorProto& tensor,
                                                const ORTCHAR_T* tensor_proto_dir,
                                                size_t expected_num_elements, size_t element_size,
@@ -800,9 +895,9 @@ ONNXTensorElementDataType GetTensorElementType(const ONNX_NAMESPACE::TensorProto
 
 ONNX_NAMESPACE::TensorProto TensorToTensorProto(const Tensor& tensor, const std::string& tensor_proto_name) {
   // Given we are using the raw_data field in the protobuf, this will work only for little-endian format.
-  if constexpr (endian::native != endian::little) {
-    ORT_THROW("Big endian not supported");
-  }
+  //if constexpr (endian::native != endian::little) {
+  //  ORT_THROW("Big endian not supported");
+  //}
 
   // Set name, dimensions, type, and data of the TensorProto.
   ONNX_NAMESPACE::TensorProto tensor_proto;
@@ -823,6 +918,9 @@ ONNX_NAMESPACE::TensorProto TensorToTensorProto(const Tensor& tensor, const std:
     }
   } else {
     tensor_proto.set_raw_data(tensor.DataRaw(), tensor.SizeInBytes());
+    if constexpr (endian::native != endian::little) {
+       utils::ConvertRawDataInTensorProto((ONNX_NAMESPACE::TensorProto*)&tensor_proto);
+    }
   }
 
   return tensor_proto;
@@ -1207,6 +1305,9 @@ static void SparsifyGeneric(const void* dense_raw_data, size_t n_dense_elements,
     indices.set_data_type(ONNX_NAMESPACE::TensorProto_DataType_INT8);
     indices.set_raw_data(std::string());
   }
+  if constexpr (endian::native != endian::little) {
+       utils::ConvertRawDataInTensorProto((ONNX_NAMESPACE::TensorProto*)&indices);
+  }
   nnz = gathered_indices.size();
 }
 
diff --git a/onnxruntime/core/framework/tensorprotoutils.h b/onnxruntime/core/framework/tensorprotoutils.h
index 6f1b60dd2..25854fce7 100644
--- a/onnxruntime/core/framework/tensorprotoutils.h
+++ b/onnxruntime/core/framework/tensorprotoutils.h
@@ -456,5 +456,7 @@ common::Status UnpackInitializerData(const ONNX_NAMESPACE::TensorProto& initiali
  */
 common::Status UnpackInitializerData(const ONNX_NAMESPACE::TensorProto& initializer,
                                      std::vector<uint8_t>& unpacked_tensor);
+
+void ConvertRawDataInTensorProto(ONNX_NAMESPACE::TensorProto *initializer);
 }  // namespace utils
 }  // namespace onnxruntime
diff --git a/onnxruntime/core/graph/graph.cc b/onnxruntime/core/graph/graph.cc
index 81309ceb0..06daa7c33 100644
--- a/onnxruntime/core/graph/graph.cc
+++ b/onnxruntime/core/graph/graph.cc
@@ -1128,6 +1128,15 @@ Graph::Graph(const Model& owning_model,
 
     const gsl::not_null<TensorProto*> tensor{graph_proto_->add_initializer()};
     auto status = utils::ConstantNodeProtoToTensorProto(node, model_path, *tensor);
+    const AttributeProto& attrib = node.attribute(0);
+    if (attrib.type() == AttributeProto_AttributeType_SPARSE_TENSOR)
+    {
+        const TensorProto& sparse_values = node.attribute(0).sparse_tensor().values();
+        if ((!(sparse_values.has_raw_data())) && tensor->has_raw_data())
+        {
+            onnxruntime::utils::ConvertRawDataInTensorProto(tensor);
+        }
+    }
     ORT_ENFORCE(status.IsOK(), status.ToString());
     // Ensure initializers are also graph inputs.
     if (ir_version_ < 4) {
@@ -3049,6 +3058,11 @@ SaveInputsOutputsToOrtFormat(flatbuffers::FlatBufferBuilder& builder, const std:
 
 common::Status Graph::SaveToOrtFormat(flatbuffers::FlatBufferBuilder& builder,
                                       flatbuffers::Offset<fbs::Graph>& fbs_graph) const {
+  auto& tens = GetAllInitializedTensors();
+  for (auto& [name, tensor_p] : tens)
+  {
+     utils::ConvertRawDataInTensorProto((TensorProto*)tensor_p);
+  }
   auto inputs = SaveInputsOutputsToOrtFormat(builder, graph_inputs_including_initializers_);
   auto outputs = SaveInputsOutputsToOrtFormat(builder, graph_outputs_);
 
diff --git a/onnxruntime/core/mlas/lib/mlasi.h b/onnxruntime/core/mlas/lib/mlasi.h
index 31999f329..f6ad93f72 100644
--- a/onnxruntime/core/mlas/lib/mlasi.h
+++ b/onnxruntime/core/mlas/lib/mlasi.h
@@ -2072,7 +2072,11 @@ MlasReadTimeStampCounter(void)
 
 
 constexpr size_t ThreadedBufAlignment = 64;
+#if defined(_AIX)
+extern __thread size_t ThreadedBufSize;
+#else
 extern thread_local size_t ThreadedBufSize;
+#endif
 #ifdef _MSC_VER
 extern thread_local std::unique_ptr<uint8_t, decltype(&_aligned_free)> ThreadedBufHolder;
 #else
diff --git a/onnxruntime/core/mlas/lib/platform.cpp b/onnxruntime/core/mlas/lib/platform.cpp
index 7d8624a32..84846e2f8 100644
--- a/onnxruntime/core/mlas/lib/platform.cpp
+++ b/onnxruntime/core/mlas/lib/platform.cpp
@@ -20,8 +20,12 @@ Abstract:
 #include <thread>
 #include <mutex>
 
-#if defined(MLAS_TARGET_POWER) && defined(__linux__)
+#if defined(MLAS_TARGET_POWER) 
+#if defined(__linux__)
 #include <sys/auxv.h>
+#elif defined(_AIX)
+#include <sys/systemcfg.h>
+#endif
 #endif
 
 #if defined(MLAS_TARGET_ARM64)
@@ -462,6 +466,10 @@ Return Value:
     unsigned long hwcap2 = getauxval(AT_HWCAP2);
 
     bool HasP9Instructions = hwcap2 & PPC_FEATURE2_ARCH_3_00;
+#elif defined(_AIX)
+    bool HasP9Instructions = __power_9_andup();
+#endif // __linux__
+
     if (HasP9Instructions) {
         this->QuantizeLinearS8Kernel = MlasQuantizeLinearS8KernelVSX;
         this->QuantizeLinearU8Kernel = MlasQuantizeLinearU8KernelVSX;
@@ -470,7 +478,12 @@ Return Value:
 #if defined(POWER10)
 #if (defined(__GNUC__) && ((__GNUC__ > 10) || (__GNUC__== 10 && __GNUC_MINOR__ >= 2))) || \
     (defined(__clang__) && (__clang_major__ >= 12))
+#if defined(__linux__)
     bool HasP10Instructions = ((hwcap2 & PPC_FEATURE2_MMA) && (hwcap2 & PPC_FEATURE2_ARCH_3_1));
+#elif defined(_AIX)
+    bool HasP10Instructions = (__power_10_andup() && __power_mma_version() == MMA_V31);
+#endif // __linux__
+
     if (HasP10Instructions) {
         this->GemmFloatKernel = MlasSgemmKernelPOWER10;
         this->GemmDoubleKernel = MlasDgemmKernelPOWER10;
@@ -528,7 +541,11 @@ MlasPlatformU8S8Overflow(
 
 #endif
 
+#if defined(_AIX)
+__thread size_t ThreadedBufSize = 0;
+#else
 thread_local size_t ThreadedBufSize = 0;
+#endif
 #ifdef _MSC_VER
 thread_local std::unique_ptr<uint8_t, decltype(&_aligned_free)> ThreadedBufHolder(nullptr, &_aligned_free);
 #else
diff --git a/onnxruntime/core/mlas/lib/qgemm.h b/onnxruntime/core/mlas/lib/qgemm.h
index c34a91694..deca5e9e4 100644
--- a/onnxruntime/core/mlas/lib/qgemm.h
+++ b/onnxruntime/core/mlas/lib/qgemm.h
@@ -898,7 +898,7 @@ MlasGemmQuantGetDispatch(
     if (!AIsSigned) {
         GemmQuantDispatch = &MlasGemmU8X8DispatchWasmSimd;
     }
-#elif defined(MLAS_TARGET_POWER) && defined(__linux__)  && defined(POWER10) && \
+#elif defined(MLAS_TARGET_POWER) &&  (defined(__linux__) || defined(_AIX))  && defined(POWER10) && \
     ((defined(__GNUC__) && ((__GNUC__ > 10) || (__GNUC__== 10 && __GNUC_MINOR__ >= 2))) || \
     (defined(__clang__) && (__clang_major__ >= 12)))
     if (GetMlasPlatform().GemmU8X8Dispatch == &MlasGemm8X8DispatchPOWER10) {
diff --git a/onnxruntime/core/optimizer/attention_fusion.cc b/onnxruntime/core/optimizer/attention_fusion.cc
index d743a038c..ca31a7d76 100644
--- a/onnxruntime/core/optimizer/attention_fusion.cc
+++ b/onnxruntime/core/optimizer/attention_fusion.cc
@@ -127,6 +127,9 @@ static NodeArg& MergeQkvWeights(Graph& graph, int64_t hidden_size,
       MergeWeights<float>(q_weight, k_weight, v_weight, result, hidden_size);
     }
     initializer.set_raw_data(result.data(), gsl::narrow<size_t>(element_count) * sizeof(float));
+    if constexpr (endian::native != endian::little) {
+       utils::ConvertRawDataInTensorProto((TensorProto*)&initializer);
+    }
   } else {  // data_type == ONNX_NAMESPACE::TensorProto_DataType_FLOAT16
     const MLFloat16* q_weight = q_initializer.data<MLFloat16>();
     const MLFloat16* k_weight = k_initializer.data<MLFloat16>();
@@ -139,6 +142,9 @@ static NodeArg& MergeQkvWeights(Graph& graph, int64_t hidden_size,
       MergeWeights<MLFloat16>(q_weight, k_weight, v_weight, result, hidden_size);
     }
     initializer.set_raw_data(result.data(), gsl::narrow<size_t>(element_count) * sizeof(MLFloat16));
+    if constexpr (endian::native != endian::little) {
+       utils::ConvertRawDataInTensorProto((TensorProto*)&initializer);
+    }
   }
 
   return graph_utils::AddInitializer(graph, initializer);
diff --git a/onnxruntime/core/optimizer/attention_fusion_helper.h b/onnxruntime/core/optimizer/attention_fusion_helper.h
index e7f373708..d3c4f2bda 100644
--- a/onnxruntime/core/optimizer/attention_fusion_helper.h
+++ b/onnxruntime/core/optimizer/attention_fusion_helper.h
@@ -344,7 +344,7 @@ bool ValidateUnidirMask(const Graph& graph, const NodeArg& mask, bool& is_unidir
       return false;
     }
   } else if (tensor_proto->data_type() == ONNX_NAMESPACE::TensorProto_DataType_FLOAT) {
-    std::vector<float_t> float_data = ONNX_NAMESPACE::ParseData<float_t>(tensor_proto);
+    std::vector<float> float_data = ONNX_NAMESPACE::ParseData<float>(tensor_proto);
     if (!ValidateUnidirMask(float_data, shape->dim(2).dim_value(), is_unidirectional)) {
       DEBUG_LOG("Mask is neither unidirectional nor all ones");
       return false;
diff --git a/onnxruntime/core/optimizer/constant_folding.cc b/onnxruntime/core/optimizer/constant_folding.cc
index d32cb87fe..5bd816ffc 100644
--- a/onnxruntime/core/optimizer/constant_folding.cc
+++ b/onnxruntime/core/optimizer/constant_folding.cc
@@ -80,6 +80,9 @@ static bool ConstantFoldShapeNode(Graph& graph, Node& node) {
     shape_constant.add_dims(clamped_slice_length);
     shape_constant.set_raw_data(dim_values.data() + start,
                                 clamped_slice_length * sizeof(int64_t));
+    if constexpr (endian::native != endian::little) {
+       utils::ConvertRawDataInTensorProto((ONNX_NAMESPACE::TensorProto *)&shape_constant);
+    }
     ONNX_NAMESPACE::TensorShapeProto result_shape;
     result_shape.add_dim()->set_dim_value(clamped_slice_length);
     constant_arg_out->SetShape(result_shape);
diff --git a/onnxruntime/core/optimizer/embed_layer_norm_fusion.cc b/onnxruntime/core/optimizer/embed_layer_norm_fusion.cc
index 7b6f829b7..d4e130b8e 100644
--- a/onnxruntime/core/optimizer/embed_layer_norm_fusion.cc
+++ b/onnxruntime/core/optimizer/embed_layer_norm_fusion.cc
@@ -467,6 +467,9 @@ static NodeArg* ExtractEmbedding(Graph& graph,
     }
 
     initializer.set_raw_data(data, gsl::narrow<size_t>(element_count) * sizeof(float));
+    if constexpr (endian::native != endian::little) {
+       utils::ConvertRawDataInTensorProto((TensorProto*)&initializer);
+    }
   } else {  // data_type == ONNX_NAMESPACE::TensorProto_DataType_FLOAT16
     const MLFloat16* data = old_initializer.data<MLFloat16>();
     if (!CheckEmbeddingData(data, batch_size, element_count)) {
@@ -474,6 +477,9 @@ static NodeArg* ExtractEmbedding(Graph& graph,
     }
 
     initializer.set_raw_data(data, gsl::narrow<size_t>(element_count) * sizeof(MLFloat16));
+    if constexpr (endian::native != endian::little) {
+       utils::ConvertRawDataInTensorProto((TensorProto*)&initializer);
+    }
   }
 
   NodeArg& node_arg = graph_utils::AddInitializer(graph, initializer);
diff --git a/onnxruntime/core/optimizer/reshape_fusion.cc b/onnxruntime/core/optimizer/reshape_fusion.cc
index 9e31dcf08..ef7933212 100644
--- a/onnxruntime/core/optimizer/reshape_fusion.cc
+++ b/onnxruntime/core/optimizer/reshape_fusion.cc
@@ -434,6 +434,9 @@ bool ReshapeFusion::Fuse_Subgraph(Node& reshape, Graph& graph, const logging::Lo
   shape_initializer_proto.add_dims(static_cast<int64_t>(shape_value.size()));
   shape_initializer_proto.set_data_type(ONNX_NAMESPACE::TensorProto_DataType_INT64);
   shape_initializer_proto.set_raw_data(shape_value.data(), shape_value.size() * sizeof(int64_t));
+  if constexpr (endian::native != endian::little) {
+       utils::ConvertRawDataInTensorProto((ONNX_NAMESPACE::TensorProto *)&shape_initializer_proto);
+  }
   auto& new_node_arg = graph_utils::AddInitializer(graph, shape_initializer_proto);
 
   // Safely remove concat parent nodes which have only one output
diff --git a/onnxruntime/core/optimizer/transpose_optimizer/optimizer_api_impl.cc b/onnxruntime/core/optimizer/transpose_optimizer/optimizer_api_impl.cc
index 517fcf63d..3456beb3e 100644
--- a/onnxruntime/core/optimizer/transpose_optimizer/optimizer_api_impl.cc
+++ b/onnxruntime/core/optimizer/transpose_optimizer/optimizer_api_impl.cc
@@ -750,7 +750,9 @@ std::string_view ApiGraph::AddInitializer(api::DataType dtype, const std::vector
   for (int64_t dim : shape) {
     tensor_proto.add_dims(dim);
   }
-
+  if constexpr (endian::native != endian::little) {
+       utils::ConvertRawDataInTensorProto((TensorProto*)&tensor_proto);
+  }
   const auto& node_arg = graph_utils::AddInitializer(graph_, tensor_proto);
   return node_arg.Name();
 }
diff --git a/onnxruntime/core/platform/posix/env.cc b/onnxruntime/core/platform/posix/env.cc
index a5aa5773a..7b6968895 100644
--- a/onnxruntime/core/platform/posix/env.cc
+++ b/onnxruntime/core/platform/posix/env.cc
@@ -26,7 +26,9 @@ limitations under the License.
 #include <stdlib.h>
 #include <string.h>
 #include <sys/mman.h>
+#if !defined(_AIX)
 #include <sys/syscall.h>
+#endif
 #include <unistd.h>
 
 #include <iostream>
diff --git a/onnxruntime/core/providers/shared/symbols.exp b/onnxruntime/core/providers/shared/symbols.exp
new file mode 100644
index 000000000..80194a8ef
--- /dev/null
+++ b/onnxruntime/core/providers/shared/symbols.exp
@@ -0,0 +1,2 @@
+Provider_GetHost
+Provider_SetHost
diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc
index 79068a027..abe4e660d 100644
--- a/onnxruntime/core/session/inference_session.cc
+++ b/onnxruntime/core/session/inference_session.cc
@@ -575,7 +575,7 @@ common::Status InferenceSession::RegisterGraphTransformer(
 }
 
 common::Status InferenceSession::SaveToOrtFormat(const PathString& filepath) const {
-  ORT_RETURN_IF_NOT(FLATBUFFERS_LITTLEENDIAN, "ort format only supports little-endian machines");
+  //ORT_RETURN_IF_NOT(FLATBUFFERS_LITTLEENDIAN, "ort format only supports little-endian machines");
 
   // Get the byte size of the ModelProto and round it to the next MB and use it as flatbuffers' init_size
   // TODO: Investigate whether we should set a max size, and clarify the cost of having a buffer smaller than
@@ -976,7 +976,7 @@ Status InferenceSession::LoadOrtModel(const void* model_data, int model_data_len
 }
 
 Status InferenceSession::LoadOrtModelWithLoader(std::function<Status()> load_ort_format_model_bytes) {
-  static_assert(FLATBUFFERS_LITTLEENDIAN, "ORT format only supports little-endian machines");
+  //static_assert(FLATBUFFERS_LITTLEENDIAN, "ORT format only supports little-endian machines");
 
   std::lock_guard<onnxruntime::OrtMutex> l(session_mutex_);
 
diff --git a/onnxruntime/python/onnxruntime_validation.py b/onnxruntime/python/onnxruntime_validation.py
index 8b3136355..53c54d4b0 100644
--- a/onnxruntime/python/onnxruntime_validation.py
+++ b/onnxruntime/python/onnxruntime_validation.py
@@ -52,13 +52,17 @@ def check_distro_info():
         __my_distro__ = __my_system__
         __my_distro_ver__ = platform.release().lower()
 
-        if int(__my_distro_ver__.split(".")[0]) < 11:
-            warnings.warn(
-                "Unsupported macOS version (%s). ONNX Runtime supports macOS 11.0 or later." % (__my_distro_ver__)
-            )
+        if int(__my_distro_ver__.split('.')[0]) < 11:
+            warnings.warn('Unsupported macOS version (%s). ONNX Runtime supports macOS 11.0 or later.' %
+                          (__my_distro_ver__))
+    elif __my_system__ == "aix":
+        __my_distro__ = __my_system__
+        returned_output = subprocess.check_output("oslevel")
+        __my_distro_ver__str = returned_output.decode("utf-8")
+        __my_distro_ver = __my_distro_ver__str[:3]
     else:
         warnings.warn(
-            "Unsupported platform (%s). ONNX Runtime supports Linux, macOS and Windows platforms, only." % __my_system__
+            "Unsupported platform (%s). ONNX Runtime supports Linux, AIX, macOS and Windows platforms, only." % __my_system__
         )
 
 
diff --git a/onnxruntime/python/symbols.exp b/onnxruntime/python/symbols.exp
new file mode 100644
index 000000000..4b78ea7b1
--- /dev/null
+++ b/onnxruntime/python/symbols.exp
@@ -0,0 +1 @@
+PyInit_onnxruntime_pybind11_state
-- 
2.38.3

