Faiss

- Main Page
- Namespaces
- Classes
- Files

- File List

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