Caffe2 - C++ API
A deep learning, cross platform ML framework
byte_order.cpp
1 #include <torch/csrc/byte_order.h>
2 
3 #include <cstring>
4 
5 #if defined(_MSC_VER)
6 #include <stdlib.h>
7 #endif
8 
9 static inline void swapBytes16(void *ptr)
10 {
11  uint16_t output;
12  memcpy(&output, ptr, sizeof(uint16_t));
13 #if defined(_MSC_VER) && !defined(_DEBUG)
14  output = _byteswap_ushort(output);
15 #elif defined(__llvm__) || defined(__GNUC__) && !defined(__ICC)
16  output = __builtin_bswap16(output);
17 #else
18  uint16_t Hi = output >> 8;
19  uint16_t Lo = output << 8;
20  output = Hi | Lo;
21 #endif
22  memcpy(ptr, &output, sizeof(uint16_t));
23 }
24 
25 static inline void swapBytes32(void *ptr)
26 {
27  uint32_t output;
28  memcpy(&output, ptr, sizeof(uint32_t));
29 #if defined(_MSC_VER) && !defined(_DEBUG)
30  output = _byteswap_ulong(output);
31 #elif defined(__llvm__) || defined(__GNUC__) && !defined(__ICC)
32  output = __builtin_bswap32(output);
33 #else
34  uint32_t Byte0 = output & 0x000000FF;
35  uint32_t Byte1 = output & 0x0000FF00;
36  uint32_t Byte2 = output & 0x00FF0000;
37  uint32_t Byte3 = output & 0xFF000000;
38  output = (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
39 #endif
40  memcpy(ptr, &output, sizeof(uint32_t));
41 }
42 
43 static inline void swapBytes64(void *ptr)
44 {
45  uint64_t output;
46  memcpy(&output, ptr, sizeof(uint64_t));
47 #if defined(_MSC_VER)
48  output = _byteswap_uint64(output);
49 #elif defined(__llvm__) || defined(__GNUC__) && !defined(__ICC)
50  output = __builtin_bswap64(output);
51 #else
52  uint64_t Byte0 = output & 0x00000000000000FF;
53  uint64_t Byte1 = output & 0x000000000000FF00;
54  uint64_t Byte2 = output & 0x0000000000FF0000;
55  uint64_t Byte3 = output & 0x00000000FF000000;
56  uint64_t Byte4 = output & 0x000000FF00000000;
57  uint64_t Byte5 = output & 0x0000FF0000000000;
58  uint64_t Byte6 = output & 0x00FF000000000000;
59  uint64_t Byte7 = output & 0xFF00000000000000;
60  output = (Byte0 << (7*8)) | (Byte1 << (5*8)) | (Byte2 << (3*8)) | (Byte3 << (1*8)) |
61  (Byte7 >> (7*8)) | (Byte6 >> (5*8)) | (Byte5 >> (3*8)) | (Byte4 >> (1*8));
62 #endif
63  memcpy(ptr, &output, sizeof(uint64_t));
64 }
65 
66 static inline uint16_t decodeUInt16LE(const uint8_t *data) {
67  uint16_t output;
68  memcpy(&output, data, sizeof(uint16_t));
69  return output;
70 }
71 
72 static inline uint16_t decodeUInt16BE(const uint8_t *data) {
73  uint16_t output = decodeUInt16LE(data);
74  swapBytes16(&output);
75  return output;
76 }
77 
78 static inline uint32_t decodeUInt32LE(const uint8_t *data) {
79  uint32_t output;
80  memcpy(&output, data, sizeof(uint32_t));
81  return output;
82 }
83 
84 static inline uint32_t decodeUInt32BE(const uint8_t *data) {
85  uint32_t output = decodeUInt32LE(data);
86  swapBytes32(&output);
87  return output;
88 }
89 
90 static inline uint64_t decodeUInt64LE(const uint8_t *data) {
91  uint64_t output;
92  memcpy(&output, data, sizeof(uint64_t));
93  return output;
94 }
95 
96 static inline uint64_t decodeUInt64BE(const uint8_t *data) {
97  uint64_t output = decodeUInt64LE(data);
98  swapBytes64(&output);
99  return output;
100 }
101 
102 THPByteOrder THP_nativeByteOrder()
103 {
104  uint32_t x = 1;
105  return *(uint8_t*)&x ? THP_LITTLE_ENDIAN : THP_BIG_ENDIAN;
106 }
107 
108 void THP_decodeInt16Buffer(int16_t* dst, const uint8_t* src, THPByteOrder order, size_t len)
109 {
110  for (size_t i = 0; i < len; i++) {
111  dst[i] = (int16_t) (order == THP_BIG_ENDIAN ? decodeUInt16BE(src) : decodeUInt16LE(src));
112  src += sizeof(int16_t);
113  }
114 }
115 
116 void THP_decodeInt32Buffer(int32_t* dst, const uint8_t* src, THPByteOrder order, size_t len)
117 {
118  for (size_t i = 0; i < len; i++) {
119  dst[i] = (int32_t) (order == THP_BIG_ENDIAN ? decodeUInt32BE(src) : decodeUInt32LE(src));
120  src += sizeof(int32_t);
121  }
122 }
123 
124 void THP_decodeInt64Buffer(int64_t* dst, const uint8_t* src, THPByteOrder order, size_t len)
125 {
126  for (size_t i = 0; i < len; i++) {
127  dst[i] = (int64_t) (order == THP_BIG_ENDIAN ? decodeUInt64BE(src) : decodeUInt64LE(src));
128  src += sizeof(int64_t);
129  }
130 }
131 
132 void THP_decodeHalfBuffer(THHalf* dst, const uint8_t* src, THPByteOrder order, size_t len)
133 {
134  for (size_t i = 0; i < len; i++) {
135  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
136  union { uint16_t x; THHalf f; };
137  x = (order == THP_BIG_ENDIAN ? decodeUInt16BE(src) : decodeUInt16LE(src));
138  dst[i] = f;
139  src += sizeof(uint16_t);
140  }
141 }
142 
143 void THP_decodeBoolBuffer(bool* dst, const uint8_t* src, THPByteOrder order, size_t len)
144 {
145  for (size_t i = 0; i < len; i++) {
146  dst[i] = (int)src[i] != 0 ? true : false;
147  }
148 }
149 
150 void THP_decodeFloatBuffer(float* dst, const uint8_t* src, THPByteOrder order, size_t len)
151 {
152  for (size_t i = 0; i < len; i++) {
153  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
154  union { uint32_t x; float f; };
155  x = (order == THP_BIG_ENDIAN ? decodeUInt32BE(src) : decodeUInt32LE(src));
156  dst[i] = f;
157  src += sizeof(float);
158  }
159 }
160 
161 void THP_decodeDoubleBuffer(double* dst, const uint8_t* src, THPByteOrder order, size_t len)
162 {
163  for (size_t i = 0; i < len; i++) {
164  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
165  union { uint64_t x; double d; };
166  x = (order == THP_BIG_ENDIAN ? decodeUInt64BE(src) : decodeUInt64LE(src));
167  dst[i] = d;
168  src += sizeof(double);
169  }
170 }
171 
172 void THP_encodeInt16Buffer(uint8_t* dst, const int16_t* src, THPByteOrder order, size_t len)
173 {
174  memcpy(dst, src, sizeof(int16_t) * len);
175  if (order != THP_nativeByteOrder()) {
176  for (size_t i = 0; i < len; i++) {
177  swapBytes16(dst);
178  dst += sizeof(int16_t);
179  }
180  }
181 }
182 
183 void THP_encodeInt32Buffer(uint8_t* dst, const int32_t* src, THPByteOrder order, size_t len)
184 {
185  memcpy(dst, src, sizeof(int32_t) * len);
186  if (order != THP_nativeByteOrder()) {
187  for (size_t i = 0; i < len; i++) {
188  swapBytes32(dst);
189  dst += sizeof(int32_t);
190  }
191  }
192 }
193 
194 void THP_encodeInt64Buffer(uint8_t* dst, const int64_t* src, THPByteOrder order, size_t len)
195 {
196  memcpy(dst, src, sizeof(int64_t) * len);
197  if (order != THP_nativeByteOrder()) {
198  for (size_t i = 0; i < len; i++) {
199  swapBytes64(dst);
200  dst += sizeof(int64_t);
201  }
202  }
203 }
204 
205 void THP_encodeFloatBuffer(uint8_t* dst, const float* src, THPByteOrder order, size_t len)
206 {
207  memcpy(dst, src, sizeof(float) * len);
208  if (order != THP_nativeByteOrder()) {
209  for (size_t i = 0; i < len; i++) {
210  swapBytes32(dst);
211  dst += sizeof(float);
212  }
213  }
214 }
215 
216 void THP_encodeDoubleBuffer(uint8_t* dst, const double* src, THPByteOrder order, size_t len)
217 {
218  memcpy(dst, src, sizeof(double) * len);
219  if (order != THP_nativeByteOrder()) {
220  for (size_t i = 0; i < len; i++) {
221  swapBytes64(dst);
222  dst += sizeof(double);
223  }
224  }
225 }