Faiss

- Main Page
- Namespaces
- Classes
- Files

- File List

All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
fp16_emu.cu
1 /**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 // from Nvidia cuDNN library samples; modified to compile within faiss
9
10 #include "fp16_emu.cuh"
11
12 namespace faiss { namespace gpu {
13
14 /*
15 * Copyright 1993-2014 NVIDIA Corporation. All rights reserved.
16 *
17 * NOTICE TO LICENSEE:
18 *
19 * This source code and/or documentation ("Licensed Deliverables") are
20 * subject to NVIDIA intellectual property rights under U.S. and
21 * international Copyright laws.
22 *
23 * These Licensed Deliverables contained herein is PROPRIETARY and
24 * CONFIDENTIAL to NVIDIA and is being provided under the terms and
25 * conditions of a form of NVIDIA software license agreement by and
26 * between NVIDIA and Licensee ("License Agreement") or electronically
27 * accepted by Licensee. Notwithstanding any terms or conditions to
28 * the contrary in the License Agreement, reproduction or disclosure
29 * of the Licensed Deliverables to any third party without the express
30 * written consent of NVIDIA is prohibited.
31 *
32 * NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
33 * LICENSE AGREEMENT, NVIDIA MAKES NO REPRESENTATION ABOUT THE
34 * SUITABILITY OF THESE LICENSED DELIVERABLES FOR ANY PURPOSE. IT IS
35 * PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.
36 * NVIDIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THESE LICENSED
37 * DELIVERABLES, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY,
38 * NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
39 * NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
40 * LICENSE AGREEMENT, IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY
41 * SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
42 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
44 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
45 * OF THESE LICENSED DELIVERABLES.
46 *
47 * U.S. Government End Users. These Licensed Deliverables are a
48 * "commercial item" as that term is defined at 48 C.F.R. 2.101 (OCT
49 * 1995), consisting of "commercial computer software" and "commercial
50 * computer software documentation" as such terms are used in 48
51 * C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Government
52 * only as a commercial end item. Consistent with 48 C.F.R.12.212 and
53 * 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), all
54 * U.S. Government End Users acquire the Licensed Deliverables with
55 * only those rights set forth herein.
56 *
57 * Any use of the Licensed Deliverables in individual and commercial
58 * software must include, in the user documentation and internal
59 * comments to the code, the above Disclaimer and U.S. Government End
60 * Users Notice.
61 */
62
63 // Host functions for converting between FP32 and FP16 formats
64 // Paulius Micikevicius (pauliusm@nvidia.com)
65
66 half1 cpu_float2half_rn(float f)
67 {
68 half1 ret;
69
70 union {
71 float f;
72 unsigned u;
73 } un;
74
75 un.f = f;
76
77 unsigned x = un.u;
78 unsigned u = (x & 0x7fffffff), remainder, shift, lsb, lsb_s1, lsb_m1;
79 unsigned sign, exponent, mantissa;
80
81 // Get rid of +NaN/-NaN case first.
82 if (u > 0x7f800000) {
83 ret.x = 0x7fffU;
84 return ret;
85 }
86
87 sign = ((x >> 16) & 0x8000);
88
89 // Get rid of +Inf/-Inf, +0/-0.
90 if (u > 0x477fefff) {
91 ret.x = sign | 0x7c00U;
92 return ret;
93 }
94 if (u < 0x33000001) {
95 ret.x = (sign | 0x0000);
96 return ret;
97 }
98
99 exponent = ((u >> 23) & 0xff);
100 mantissa = (u & 0x7fffff);
101
102 if (exponent > 0x70) {
103 shift = 13;
104 exponent -= 0x70;
105 } else {
106 shift = 0x7e - exponent;
107 exponent = 0;
108 mantissa |= 0x800000;
109 }
110 lsb = (1 << shift);
111 lsb_s1 = (lsb >> 1);
112 lsb_m1 = (lsb - 1);
113
114 // Round to nearest even.
115 remainder = (mantissa & lsb_m1);
116 mantissa >>= shift;
117 if (remainder > lsb_s1 || (remainder == lsb_s1 && (mantissa & 0x1))) {
118 ++mantissa;
119 if (!(mantissa & 0x3ff)) {
120 ++exponent;
121 mantissa = 0;
122 }
123 }
124
125 ret.x = (sign | (exponent << 10) | mantissa);
126
127 return ret;
128 }
129
130
131 float cpu_half2float(half1 h)
132 {
133 unsigned sign = ((h.x >> 15) & 1);
134 unsigned exponent = ((h.x >> 10) & 0x1f);
135 unsigned mantissa = ((h.x & 0x3ff) << 13);
136
137 if (exponent == 0x1f) { /* NaN or Inf */
138 mantissa = (mantissa ? (sign = 0, 0x7fffff) : 0);
139 exponent = 0xff;
140 } else if (!exponent) { /* Denorm or Zero */
141 if (mantissa) {
142 unsigned int msb;
143 exponent = 0x71;
144 do {
145 msb = (mantissa & 0x400000);
146 mantissa <<= 1; /* normalize */
147 --exponent;
148 } while (!msb);
149 mantissa &= 0x7fffff; /* 1.mantissa is implicit */
150 }
151 } else {
152 exponent += 0x70;
153 }
154
155 union {
156 int i;
157 float f;
158 } un;
159
160 un.i = ((sign << 31) | (exponent << 23) | mantissa);
161
162 return un.f;
163 }
164
165 } } // namespace