1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * \author guonix
17 * \date Mar 2021
18 * \brief
19 */
20
21#include "transformer.h"
22
23namespace proxima {
24namespace be {
25
26bool Transformer::NeedTransform(DataTypes in_type, DataTypes out_type) {
27 return in_type != out_type;
28}
29
30int Transformer::SupportTransform(DataTypes in_type, DataTypes out_type) {
31 if ((in_type == out_type) || (in_type == DataTypes::VECTOR_FP32 &&
32 out_type == DataTypes::VECTOR_FP16)) {
33 return 0;
34 }
35 return PROXIMA_BE_ERROR_CODE(MismatchedDataType);
36}
37
38int Transformer::Transform(DataTypes in_type, const std::string &in,
39 DataTypes out_type, std::string *out) {
40 if (Transformer::NeedTransform(in_type, out_type)) {
41 if (in_type == DataTypes::VECTOR_FP32 &&
42 out_type == DataTypes::VECTOR_FP16) {
43 if (in.empty() || in.length() % sizeof(float) != 0) {
44 return PROXIMA_BE_ERROR_CODE(InvalidFeature);
45 }
46 // counts the elements of query
47 auto elements = in.length() / sizeof(float);
48 // resize fp32(4 bytes) -> fp16(2 bytes)
49 out->resize(elements << 1);
50
51 ailego::FloatHelper::ToFP16(
52 reinterpret_cast<const float *>(in.c_str()), elements,
53 reinterpret_cast<uint16_t *>(const_cast<char *>(out->c_str())));
54 return 0;
55 }
56 return PROXIMA_BE_ERROR_CODE(MismatchedDataType);
57 }
58 *out = in;
59 return 0;
60}
61
62//! Transform double of JsonValue to float
63template <>
64float Json2Primary::Primary<float>(const ailego::JsonValue &object) {
65 return float(object.as_float());
66}
67
68//! Transform double of JsonValue
69template <>
70double Json2Primary::Primary<double>(const ailego::JsonValue &object) {
71 return object.as_float();
72}
73
74
75template <>
76void Primary2Bytes::Bytes<int8_t, DataTypes::VECTOR_INT4>(
77 const std::vector<int8_t> &values, std::string *bytes) {
78 bytes->resize(values.size() >> 1);
79 uint8_t *out = reinterpret_cast<uint8_t *>(&(*bytes)[0]);
80 for (size_t i = 0; i < values.size(); i += 2) {
81 out[i >> 1] = (static_cast<uint8_t>(values[i + 1]) << 4) |
82 (static_cast<uint8_t>(values[i]) & 0xF);
83 }
84}
85
86template <>
87void Primary2Bytes::Bytes<float, DataTypes::VECTOR_FP16>(
88 const std::vector<float> &values, std::string *bytes) {
89 bytes->resize(values.size() * sizeof(float) >> 1);
90 ailego::FloatHelper::ToFP16(reinterpret_cast<const float *>(values.data()),
91 values.size(),
92 reinterpret_cast<uint16_t *>(&(*bytes)[0]));
93}
94
95} // namespace be
96} // namespace proxima
97