/ scripts / log_table_generation / log_table_interleave.c
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  }