Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 47 additions & 6 deletions tmva/sofie_parsers/src/RModelParser_ONNX.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <stdexcept>
#include <string>
#include <cstring>
#include <memory>
#include <cassert>
#include <iostream>
Expand Down Expand Up @@ -155,6 +156,45 @@ struct ExtractDataFromTP<int64_t> {
}
};

#ifndef R__BYTESWAP
namespace {

// Copy nbytes from source to dest, byte-swapping each N-byte element. The
// temporary avoids misaligned loads from the protobuf string buffer and makes
// in-place swapping (dest == source) valid.
template <std::size_t N>
void CopyBswap(void *dest, const void *source, std::size_t nbytes)
{
using value_type = typename RByteSwap<N>::value_type;
auto dst = static_cast<unsigned char *>(dest);
auto src = static_cast<const unsigned char *>(source);
for (std::size_t k = 0; k < nbytes; k += N) {
value_type v;
std::memcpy(&v, src + k, N);
v = RByteSwap<N>::bswap(v);
std::memcpy(dst + k, &v, N);
}
}

// Copy a buffer of little-endian tensor elements to host (big-endian) byte order
void CopyLEToHost(void *dest, const void *source, std::size_t nbytes, ETensorType tensor_type)
{
switch (GetTypeSize(tensor_type)) {
case 1:
if (dest != source)
std::memcpy(dest, source, nbytes);
break;
case 2: CopyBswap<2>(dest, source, nbytes); break;
case 4: CopyBswap<4>(dest, source, nbytes); break;
case 8: CopyBswap<8>(dest, source, nbytes); break;
default:
throw std::runtime_error("Data type " + ConvertTypeToString(tensor_type) + " in tensor is not supported!\n");
}
}

} // anonymous namespace
#endif

std::shared_ptr<void> RModelParser_ONNX::GetInitializedTensorData(onnx::TensorProto *tensorproto, size_t tensor_size, ETensorType tensor_type)
{

Expand All @@ -172,13 +212,10 @@ std::shared_ptr<void> RModelParser_ONNX::GetInitializedTensorData(onnx::TensorPr
std::memcpy(data.get(), tensorproto->raw_data().c_str(), tensor_size);
#else
// big-endian architectures - need to swap bytes
for (std::size_t k = 0; k < tensor_size; ++k)
(reinterpret_cast<typename RByteSwap<sizeof(uint8_t)>::value_type *>(data.get()))[k] =
RByteSwap<sizeof(T)>::bswap((reinterpret_cast<const typename RByteSwap<sizeof(uint8_t)>::value_type *>(
tensorproto->raw_data().c_str()))[k]);
CopyLEToHost(data.get(), tensorproto->raw_data().c_str(), tensor_size, tensor_type);
#endif
} else {
// case tensor data are stored as specific types and now in raw_data
// case tensor data are stored as specific types and not in raw_data
switch (tensor_type) {
case ETensorType::FLOAT: {
ExtractDataFromTP<float>::Copy(tensorproto, data.get(), tensor_size/ 4);
Expand All @@ -200,7 +237,7 @@ std::shared_ptr<void> RModelParser_ONNX::GetInitializedTensorData(onnx::TensorPr
throw std::runtime_error("TMVA::SOFIE - ExtractData from TP in BOOL not supported");
break;
}
case ETensorType::UINT8: {
case ETensorType::UINT8: {
throw std::runtime_error("TMVA::SOFIE - ExtractData from TP in UINT8 not supported");
break;
}
Expand Down Expand Up @@ -238,6 +275,10 @@ std::shared_ptr<void> RModelParser_ONNX::GetInitializedTensorData(onnx::TensorPr

fDataFile.seekg(offset);
fDataFile.read(reinterpret_cast<char *>(data.get()), buffer_size);
#ifndef R__BYTESWAP
// external data is stored little-endian like raw_data - swap in place
CopyLEToHost(data.get(), data.get(), buffer_size, tensor_type);
#endif
}

return data;
Expand Down
Loading