Commit 2d31ce70 authored by Federico Rossi's avatar Federico Rossi

tmp: addded cppPosit

parent af280344
*/posit8_tbl.cpp
*/posit10_tbl.cpp
*/posit12_tbl.cpp
*/posit16_tbl.cpp
*/float12_tbl.cpp
*/float16_tbl.cpp
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# build folders
build/
# build folder
doc/build/
# file for developers
my_*.*
language: cpp
script: cmake
compiler: g++
dist: xenial
before_script:
- sudo apt udpate && sudo apt install libeigen3-dev
- gcc --version
- sudo unlink /usr/bin/gcc && sudo ln -s /usr/bin/gcc-5 /usr/bin/gcc
- gcc --version
# create a build folder for the out-of-source build
- mkdir build
# switch to build directory
- cd build
# run cmake; here we assume that the project's
# top-level CMakeLists.txt is located at '..'
- cmake -DSOFTFLOAT=OFF ..
script:
# once CMake has done its job we just build using make as usual
- make
# if the project uses ctest we can run the tests like this
#- make test
cmake_minimum_required(VERSION 3.0)
project(cppposit)
#Issues with clang. Build soft float manually
#add_subdirectory(extern/softfloat)
#link_directories(extern/lib)
#set(SYSPROC arm)
if(SYSPROC MATCHES "arm")
add_definitions (-D__arm__ )
ENDIF()
if(MSVC)
# Force to always compile with W4
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" /WX "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX")
endif()
else()
# Update if necessary
#-Wno-int-in-bool-context
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wno-long-long -Wno-int-in-bool-context -pedantic")
endif()
option(USE_CXX14 "C++14" )
if(USE_CXX14)
add_definitions(--std=c++14)
else()
add_definitions(--std=c++11)
endif()
option(SOFTFLOAT "softfloat" TRUE)
if(SOFTFLOAT)
add_definitions(-DWITH_SOFTFLOAT)
endif()
add_definitions(-march=native)
include_directories(include)
find_package(Eigen3 )
include_directories(${EIGEN3_INCLUDE_DIRS})
add_executable(main src/main.cpp)
#add_executable(maineigen src/maineigen.cpp)
add_executable(testunpacked tests/testunpacked.cpp)
add_executable(testposit tests/testposit.cpp)
# TABULATED posits
# TODO Generalize to any arbitrary configuration of posit: given a posit configuration then
# automatically make the generator, the table file and the cmake
option(POSIT14 "posit14 tabulated" FALSE)
option(POSIT12 "posit12 tabulated" FALSE)
option(POSIT10 "posit10 tabulated" FALSE)
option(POSIT8 "posit8 tabulated" FALSE)
option(BINARY8 "binary8_5 tabulated" FALSE)
option(POSIT8LOG "posit8_2 tabulated" FALSE)
if(POSIT14)
add_executable(posit14_gen src/posit14_gen.cpp)
set(POSIT14_SRC src/posit14.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/posit14_tbl.cpp)
if(NOT CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/posit14_tbl.cpp COMMAND $<TARGET_FILE:posit14_gen> ${CMAKE_CURRENT_SOURCE_DIR}/src/posit14_tbl.cpp DEPENDS posit14_gen )
endif()
endif()
if(POSIT8LOG)
add_executable(posit8_logtab_gen src/posit8_logtab_gen.cpp)
set(POSIT8LOG_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/posit8_logtab_tbl.cpp)
if(NOT CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/posit8_logtab_tbl.cpp COMMAND $<TARGET_FILE:posit8_logtab_gen ${CMAKE_CURRENT_SOURCE_DIR}/src/posit8_logtab_tbl.cpp DEPENDS posit8_logtab_gen )
endif()
endif()
if(POSIT12)
add_executable(posit12_gen src/posit12_gen.cpp)
set(POSIT12_SRC src/posit12.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/posit12_tbl.cpp)
if(NOT CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/posit12_tbl.cpp COMMAND $<TARGET_FILE:posit12_gen> ${CMAKE_CURRENT_SOURCE_DIR}/src/posit12_tbl.cpp DEPENDS posit12_gen )
endif()
endif()
if(POSIT10)
add_executable(posit10_gen src/posit10_gen.cpp)
set(POSIT10_SRC src/posit10.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/posit10_tbl.cpp)
if(NOT CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/posit10_tbl.cpp COMMAND $<TARGET_FILE:posit10_gen> ${CMAKE_CURRENT_SOURCE_DIR}/src/posit10_tbl.cpp DEPENDS posit10_gen )
endif()
endif()
if(POSIT8)
add_executable(posit8_gen src/posit8_gen.cpp)
set(POSIT8_SRC src/posit8.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/posit8_tbl.cpp)
if(NOT CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/posit8_tbl.cpp COMMAND $<TARGET_FILE:posit8_gen> ${CMAKE_CURRENT_SOURCE_DIR}/src/posit8_tbl.cpp DEPENDS posit8_gen )
endif()
endif()
if(BINARY8)
add_executable(binary8_gen src/binary8_gen.cpp)
set(BINARY8_SRC src/binary8.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/binary8_tbl.cpp)
if(NOT CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/binary8_tbl.cpp COMMAND $<TARGET_FILE:binary8_gen> ${CMAKE_CURRENT_SOURCE_DIR}/src/binary8_tbl.cpp DEPENDS binary8_gen )
endif()
endif()
if(BINARY8 OR POSIT8 OR POSIT10 OR POSIT12 OR POSIT8LOG)
set(POSITTABTARGET posittab)
add_library(posittab STATIC ${POSIT8_SRC} ${BINARY8_SRC} ${POSIT10_SRC} ${POSIT12_SRC} ${POSIT8LOG_SRC})
set_property(TARGET posittab PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/include)
endif()
#if(BINARY8)
#add_executable(testbinary8 tests/testbinary8.cpp)
#target_link_libraries(testbinary8 posittab)
#endif()
if(POSIT8)
add_executable(testposit8 tests/testposit8.cpp)
target_link_libraries(testposit8 posittab)
endif()
if(POSIT10)
add_executable(testposit10 tests/testposit10.cpp)
target_link_libraries(testposit10 posittab)
endif()
if(POSIT12)
add_executable(testposit12 tests/testposit12.cpp)
target_link_libraries(testposit12 posittab)
endif()
#if(SYSPROC MATCHES "arm")
#else()
#include_directories(include/simd)
#add_executable(testsimdposit8 tests/testsimdposit8.cpp src/simdposit8.cpp)
#target_link_libraries(testsimdposit8 ${POSITTABTARGET})
#endif()
add_library(posit INTERFACE)
set_property(TARGET posit PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/include)
if(${POSITTABTARGET})
add_executable(listposits src/listposits.cpp)
target_link_libraries(listposits posittab)
endif()
if(SOFTFLOAT)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/extern)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/extern)
add_library(p::softfloat INTERFACE IMPORTED)
set_property(TARGET p::softfloat PROPERTY INTERFACE_LINK_LIBRARIES softfloat.a)
set_property(TARGET p::softfloat PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/extern)
add_executable(softfloat_gen src/softfloat_gen.cpp)
target_link_libraries(softfloat_gen p::softfloat)
if(NOT CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/float16_tbl.cpp COMMAND DYLD_LIBRARY_PATH=${CMAKE_CURRENT_SOURCE_DIR}/extern LD_LIBRARY_PATH=${CMAKE_CURRENT_SOURCE_DIR}/extern $<TARGET_FILE:softfloat_gen> ${CMAKE_CURRENT_SOURCE_DIR}/src/float16_tbl.cpp DEPENDS softfloat_gen)
endif()
add_library(softfloat16 STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/float16_tbl.cpp)
set_property(TARGET softfloat16 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/extern)
target_link_libraries(softfloat16 p::softfloat)
add_executable(testsoftfloat tests/testsoftfloat.cpp)
target_link_libraries(testsoftfloat softfloat16)
#set_property(TARGET softfloat16 PROPERTY INTERFACE_LINK_LIBRARIES ${CMAKE_CURRENT_SOURCE_DIR}/extern/softfloat)
install (TARGETS softfloat16 DESTINATION lib)
endif()
#export(EXPORT cppPosit FILE cppPosit.cmake)
export(TARGETS ${POSITTABTARGET} posit FILE cppPosit.cmake)
include_directories(extern)
install (TARGETS ${POSITTABTARGET} DESTINATION lib) #INTERFACE_INCLUDE_DIRECTORIES include )
install(DIRECTORY include/ DESTINATION include/cppPosit)
#install(EXPORT cppPosit DESTINATION lib/cppPosit )
add_subdirectory(doc EXCLUDE_FROM_ALL)
add_subdirectory(examples)
if(POSIT8)
add_executable(test_posit8_0tab tests/test_posit8_0tab.cpp)
target_link_libraries(test_posit8_0tab posittab posit)
endif()
\ No newline at end of file
COPYRIGHT
All contributions by Emanuele Ruffaldi
Copyright (c) 2016-2019, E
All rights reserved.
All other contributions:
Copyright (c) 2019, the respective contributors.
All rights reserved.
Each contributor holds copyright over their respective contributions.
The project versioning (Git) records all such contribution source information.
LICENSE
The BSD 3-Clause License
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of tiny-dnn nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = cppPosit
SOURCEDIR = doc
BUILDDIR = builddocsp
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help MakefileD
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: MakefileD
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
# C++ Posit implementation
Implementation of Gustafoson Unum Type III aka Posits using C++ Templates.
Initial inspiration was the existing C++ https://github.com/libcg/bfp but then we diverged a lot with several features as detailed below.
Testing on Travis (GCC) and Appveyor (MSVC): [![Build Status](https://travis-ci.com/eruffaldi/cppPosit.svg?branch=master)](https://travis-ci.com/eruffaldi/cppPosit)
# Comparison with other Posit in C++
* https://github.com/libcg/bfp posit sizes specified dynamically by Clement Guerin
* https://github.com/stillwater-sc/universal template based using bitset
* https://github.com/Etaphase/FastSigmoids.jla starting from Julia and emitting C++. Based on float ops
# Features
Overall:
- Posit's total bits from 4 to 64
- storage in larger holfing typre (always signed in) e.g 12bit in 16bits
- any valid exponent bits size
- support of variant with NaN and signed Infinity (see below)
- tabulated 8bit posit operations
- implementation of operations expressed over 4 possible levels (see below)
- x86-64 Intel optimizations
- constexpr whenever possible
- integration with Eigen
- Unit Testing
- MATLAB MEX conversion and basic ops
The library supports many variants of the Posits as controlled by the template parameters:
template <class T,int totalbits, int esbits, class FT, bool withnan>
- this is a Posit with totalbits size and it is stored in an storage type of class T whose sie is smaller than totalbits.
- totalbits can go from 2 to 63
- esbits is the maximum exponent size in bits. Values from 0 to totalbits-1 are support
- FT is the data type that holds the fractional part during operations
- withnan is a boolean flags that activates the Posit With NaN extension (see below)
# Development Machines
* macOS with i7 4th gen
* Linux with i7 6th gen
* NVidia Tegra TX2 with ARMv8
# Posit with NaN
In some scenarios it is needed to have a treatment of NaN and signed infinity compatible with IEEE floats. For this reason I have introduced a Posit modality with these features. The implementation is straightforward and compatible with the properties of Posit:
* NaN is opposite position to 0 that is 1(0)+ (e.g. 100000000 in 8bit), usually represented by Infinity
* Positive and Negative infinities are on the right and left of the NaN, each negation of the other: 0(1)+ and 1(0)+1
* it respect ordering of values
* unfortunately we need to give away for the maximum value
<img src="doc/posit_with_nan.png" style="height: 200px;" alt="Posit with NaN" />
# Tools
Listposits allows to print the stats about any supported Posit type or list all the values and some operations. Due to the fact that we specify it using compile time types it is better to use the cling interpreter. Listposits allows for printing many different stats based on a printf like interface.
H: head only
N: no header
I: inverse
2: twice
A: half
U: unsigned order instead of signed order
B: binary output emitting all doubles without header
i: signed integer
b: binary form
v: float valu
u: unpacked form
p: posit object print
k: k factor
e: exponent
The script in scripts/listpositany eases the use. The following is similar to the lookup result for posit 4 and exp 1.
listpositany.sh int16_t,4,1,uint16_t,false -DLISTFORMAT=Uibkerv
# Operation Implementation Level
We define 4 level of operations for working with Posits, then in the next section we show the level of implementation of every level:
* Level 1: binary manipulation of the posit in the storage type
* Level 2: decoding of the fields (S R E F) in storage type without building the exponent
* Level 3: using a fully unpacked version (S EXP F) with the full exponent and extended fraction
* Level 4: native IEEE float
| op | level | notes |
|---|---|---|
| classify(x) | 1 | |
| -x | 1 | |
| x <=> y | 1 | |
| inv(x) | 2 (if F=0) 3 otherwise | |
| x/2 | 2 | |
| 2x | 2 | |
| x+y | 3 | |
| x*y | 3 | |
| x/y | 3 | |
| exp2(x) | 4 | |
| -> float | 3 | |
| <- float | 3 | |
## Valids
| op | level | notes |
|---|---|---|
| classify(x) | 1 | |
| -x | 1 | |
| x <=> y | 1 | |
| inv(x) | 1 (exact) | |
| x/2 | 2 | |
| 2x | 2 | |
| x+y | 4 | |
| x*y | 4 | |
| x/y | 4 | |
| exp2(x) | 4 | |
| -> float | 4 | |
| <- float | 4 | |
# Value Classes and Posit Encoding
A Posit is encoded as a signed integer with complement 2 sign representation. The first MSB is the sign and operations on negative posit are executed typically after absolute value. The second MSB is the inversion bit that is used to mark values above one and the ones below.
Important numbers:
* Infinity 1(0)+ for Posit without NaN, otherwise NaN 1(0)+
* +Infinity 0(1)+ for Posits with NaN
* one is 001(0)+
* two is 010(E=1)0+ where E is over e bits, that is 010(0){-1}0?
* 1/2 is 001(Emax)0+ where E is ove e bits, that is 001(1){e}0?
* fractionary numbers have inversion bit 0
Above we used the EBNF like notation for expressing the bit patterns.
# Approach
Everything is template based (while bfp was not) and we define three key types: UnpackedLow, Unpacked and Posit.
Unpacked is parametrized to the type of the fraction (mantissa) and it can handle the conversion to/from any type of IEEE floating point number (expressed via trait) and posit.
The UnpackedLow is:
- type: Infinity, Zero, Nan, Regular
- regime
- exponent
- fraction MSB aligned
The Unpacked is:
- type: Infinity, Zero, Nan, Regular
- any integer type will be good as fraction type (in theory this could be adapted to Boost multiprecision big integerr)
- integer exponent
Posit is parametrized as follows:
- storage type (signed integer, e.g. 16,32,64 bit)
- number of bits of the posit (<= of the storage type)
- number of bits of the exponent (fixed as in bfp)
- type for expression the fraction
Each Posit type is linked to a corresponding Unpacked type via the fraction type
For Posit with 8-bits we provide a distinct Posit8 type that uses tables for resolution
# Install
## Prepare softfloat
Under Linux softfloat can be fully embedded
## Build using Docker
Dockerfile
FROM alpine:3.7
RUN apk update
RUN apk add --no-cache gcc musl-dev g++ cmake python3 make bash cling
Run
docker run --rm -i -v $(pwd):/tmp alpinegxx bash
# Usage
Interface with Eigen is possible with possible optimizations
Eventually it is possible to use cling
cling -D "POSIT_TYPE=Posit<int8_t,8,2,uint8_t>" ".x listposits.cpp"
For loading lbraries:
#pragma cling add_library_path("path")
#pragma cling load("softfloat")
#pragma cling add_include_path("inc_directory")
# Constexpr
C++14 allows many operations but it is not possible to efficiently convert constant float to our unpacked (no union availale or reinterpret cast). As shown in fptemplate it is possible to convert to float.
# Testing Posit12
scripts/listpositany.sh ignore -DPOSIT_TYPEID=posit12 > a
scripts/listpositany.sh int16_t,12,2,uint16_t,false > b
# Related
Fixed Point Library
https://github.com/johnmcfarlane/cnl
fixed_point<int, -1>
make_fixed<30, 1>
Special: elastic_fixed_point based on elastic_intger
MPFR
Boost Multiprecision: big integer could replace the fractional part, big float could replace unpacked at all
fptemplate (from here https://www.edwardrosten.com/code/fp_template.html and githubbed here https://github.com/eruffaldi/fptemplate)
constexpr C++14 (not used yet)
https://github.com/elbeno/constexpr
FP16<->Integer or <-> Float
https://github.com/Maratyszcza/FP16
https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/
https://gist.github.com/rygorous/2156668
# References
FP Guide
https://floating-point-gui.de/
Blinn Tricks
https://ieeexplore.ieee.org/document/595279
also on p123 of https://files.cnblogs.com/files/mavaL/blinn.pdf
Blog
https://randomascii.wordpress.com/2012/01/11/tricks-with-the-floating-point-format/
https://randomascii.wordpress.com/2012/01/23/stupid-float-tricks-2/
What everybody shohuld know about FP
http://www.physics.mcgill.ca/~patscott/teaching/numeric/Goldberg.pdf
Slides
http://www.it.uu.se/edu/course/homepage/dark/ht11/floating-point-details.pdf
Handbook of FP Arithmetics, Muller & co (Book, 579pp)
http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html
Fixed Point sg14: https://github.com/johnmcfarlane/fixed_point/blob/develop/doc/p0037.md
Fixed Point Compositional (after sg14): http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0554r0.html
\ No newline at end of file
# This is a sample build configuration for C++ Make.
# Check our guides at https://confluence.atlassian.com/x/5Q4SMw for more examples.