log_table_interleave.c
1 /* 2 * Copyright (C) 2018-2020, Advanced Micro Devices, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without modification, 5 * are permitted provided that the following conditions are met: 6 * 1. Redistributions of source code must retain the above copyright notice, 7 * this list of conditions and the following disclaimer. 8 * 2. Redistributions in binary form must reproduce the above copyright notice, 9 * this list of conditions and the following disclaimer in the documentation 10 * and/or other materials provided with the distribution. 11 * 3. Neither the name of the copyright holder nor the names of its contributors 12 * may be used to endorse or promote products derived from this software without 13 * specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 21 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 * POSSIBILITY OF SUCH DAMAGE. 25 * 26 */ 27 28 /* 29 30 Program to generate interleaved look-up tables for log function 31 32 The head and tail tables are calculated as follows: 33 34 Let table_size be the number of values required in the look-up tables 35 The values of log(1 + ( j / table_size)), where j ranges from 0 to table_size, 36 is stored as two tables - head and tail for maintaing precision 37 38 First, the log value is calculated in extra precision using libquadmath as 39 quadlog = logq (1 + ( j / table_size)) 40 Then, the least significant 32 bits (for vector log) / 28 bits (for scalar log) of the value quadlog are masked, which gives the head value 41 i.e, head = quadlog & BITS_MASK 42 43 Then, the tail value is calculated as, 44 tail = quadlog - head 45 46 The inverse values' table is used in Scalar log. It is generated as follows: 47 48 Let table_size be the number of values required in the table 49 Let step_size = 2 * table_size 50 51 Then, each value of the table = 2 * [ step_size / ( i + step_size) ], where i = 0,2,4,....,step_size 52 53 libquadmath is used for getting the required precision 54 55 This program can be used to interleave Head and tail tables alone, or Head, tail and inverse tables. 56 Set the value of inv_interleave according to whether inverse table is to be interleaved or not 57 58 59 */ 60 61 #include<stdio.h> 62 #include<quadmath.h> 63 #include<stdint.h> 64 65 #define BITS_MASK 0xFFFFFFFFF0000000 // 28 bits ; Use this for scalar log 66 67 // #define BITS_MASK 0xFFFFFFFF00000000 // 32 bits ; Use this for vector log 68 69 70 typedef union { 71 double doublex; 72 unsigned long long int hexvalue; 73 } doubleword; 74 75 int inv_interleave = 0; // Set this to 1 if you want to interleave the inverse table as well 76 77 void main() 78 { 79 80 int j=0; 81 double index; 82 __float128 quadlog; 83 doubleword temp,head,tail; 84 double table_size = 1024.0 ; // Set table-size as needed 85 86 // For inverse table 87 __float128 val,step = 2048.0; 88 doubleword vald; 89 90 91 for(j=0;j<=table_size;j++) 92 { 93 index = (double)(1.0 + (j/table_size)); 94 95 quadlog = logq(index); 96 97 temp.doublex = quadlog; 98 99 head.hexvalue = temp.hexvalue & BITS_MASK ; //HEAD 100 101 tail.doublex = quadlog - head.doublex; // Tail 102 103 if(inv_interleave) 104 { 105 val = step / ((j*2) + step); 106 val = 2.0 * val ; 107 vald.doublex = val; 108 109 printf(" .quad 0x%llx\n ", vald.hexvalue); 110 111 } 112 113 printf(" .quad 0x%llx\n ",head.hexvalue); 114 printf(" .quad 0x%llx\n ",tail.hexvalue); 115 116 117 } 118 119 120 }