| 964 | } |
| 965 | |
| 966 | static int dist_decode_activation_payload( |
| 967 | const void *wire, |
| 968 | uint32_t bits, |
| 969 | uint32_t wire_bytes, |
| 970 | float **out, |
| 971 | uint32_t *out_f32_bytes, |
| 972 | bool *out_uses_wire, |
| 973 | char *err, |
| 974 | size_t errlen) { |
| 975 | if (out) *out = NULL; |
| 976 | if (out_f32_bytes) *out_f32_bytes = 0; |
| 977 | if (out_uses_wire) *out_uses_wire = false; |
| 978 | bits = dist_activation_bits_or_default(bits); |
| 979 | if (!dist_activation_bits_valid(bits)) { |
| 980 | if (errlen) snprintf(err, errlen, "invalid distributed activation width: %u bits", bits); |
| 981 | return 1; |
| 982 | } |
| 983 | if (wire_bytes != 0 && !wire) { |
| 984 | if (errlen) snprintf(err, errlen, "missing distributed activation payload"); |
| 985 | return 1; |
| 986 | } |
| 987 | |
| 988 | uint64_t values = 0; |
| 989 | if (!dist_activation_values_from_wire_bytes(bits, wire_bytes, &values)) { |
| 990 | if (errlen) snprintf(err, errlen, "invalid distributed activation payload size"); |
| 991 | return 1; |
| 992 | } |
| 993 | const uint64_t f32_bytes64 = values * sizeof(float); |
| 994 | if (f32_bytes64 > UINT32_MAX) { |
| 995 | if (errlen) snprintf(err, errlen, "distributed activation payload is too large"); |
| 996 | return 1; |
| 997 | } |
| 998 | const uint32_t f32_bytes = (uint32_t)f32_bytes64; |
| 999 | if (bits == 32u) { |
| 1000 | if (out) *out = (float *)(void *)wire; |
| 1001 | if (out_f32_bytes) *out_f32_bytes = f32_bytes; |
| 1002 | if (out_uses_wire) *out_uses_wire = true; |
| 1003 | return 0; |
| 1004 | } |
| 1005 | |
| 1006 | float *dst = f32_bytes ? malloc(f32_bytes) : NULL; |
| 1007 | if (f32_bytes && !dst) { |
| 1008 | if (errlen) snprintf(err, errlen, "out of memory decoding distributed activations"); |
| 1009 | return 1; |
| 1010 | } |
| 1011 | if (bits == 16u) { |
| 1012 | const uint16_t *src = wire; |
| 1013 | for (uint64_t i = 0; i < values; i++) dst[i] = dist_f16_to_f32(src[i]); |
| 1014 | } else { |
| 1015 | const uint8_t *src = wire; |
| 1016 | for (uint64_t i = 0; i < values; i++) dst[i] = dist_f8_e4m3_to_f32(src[i]); |
| 1017 | } |
| 1018 | if (out) *out = dst; |
| 1019 | if (out_f32_bytes) *out_f32_bytes = f32_bytes; |
| 1020 | return 0; |
| 1021 | } |
| 1022 | |
| 1023 | /* ========================================================================= |
no test coverage detected