Skip to content

Commit

Permalink
[pytorch#39] Initial build of libsleef (just dp and sp) with cmake. (p…
Browse files Browse the repository at this point in the history
…ytorch#40)

* [pytorch#39] Libsleef initial cmake build 
- Only builds scalar version, double and single precision.

* Add project versioning: MAJOR.MINOR format
* Add SONAME versioning on top on project versioning

* Build object file shared library libsleef
* Generate sleef header file 
(with symbols created by target executable mkrename)
* Build tests and create test-libm target to run them.
* Add sanity check for in-tree builds which we do not allow

* Configure travis-CI to build with cmake.
* Add MacOSX build and testing to Travis.

* Add basic documentation on how to build with cmake
  • Loading branch information
diaena committed Jul 26, 2017
1 parent 7311771 commit 07286c3
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 7 deletions.
26 changes: 19 additions & 7 deletions .travis.yml
@@ -1,14 +1,26 @@
language: c
sudo: required
dist: trusty
group: edge

matrix:
include:
- os: linux
sudo: required
dist: trusty
group: edge
- os: osx

before_install:
- sudo apt-get -qq update
- sudo apt-get install -y libmpfr-dev libgomp1 gcc

- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository -y ppa:adrozdoff/cmake ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y cmake libmpfr-dev libgomp1 gcc; fi

compiler:
- gcc

script: make test
before_script:
- mkdir sleef.build
- cd sleef.build
- cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../install -DSLEEF_SHOW_CONFIG=1 ..

script:
- make test-libm
- make install
78 changes: 78 additions & 0 deletions CMakeLists.txt
@@ -0,0 +1,78 @@
# See doc/build-with-cmake.md for instructions on how to build Sleef.
cmake_minimum_required(VERSION 3.4.3)

set(SLEEF_VERSION_MAJOR 3)
set(SLEEF_VERSION_MINOR 1)
set(SLEEF_SOVERSION ${SLEEF_VERSION_MAJOR})

project(SLEEF
VERSION ${SLEEF_VERSION_MAJOR}.${SLEEF_VERSION_MINOR}
LANGUAGES C)

message(STATUS "Configuring build for \
${PROJECT_NAME}-v${SLEEF_VERSION_MAJOR}.${SLEEF_VERSION_MINOR}")

# Sanity check for in-source builds which we do not want to happen
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "SLEEF does not allow in-source builds.
You can refer to doc/build-with-cmake.md for instructions on how provide a \
separate build directory. Note: Please remove autogenerated file \
`CMakeCache.txt` and directory `CMakeFiles` in the current directory.")
endif()

# Set output directories for the library files
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)

# PLATFORM DETECTION

# TODO.

# COMPILER DETECTION

# All variables storing compiler flags should be prefixed with FLAGS_
set(FLAGS_WALL "-Wall;-Wno-unused;-Wno-attributes")

set(FLAGS_FASTMATH "-ffast-math")
set(FLAGS_STRICTMATH "-ffp-contract=off")
set(FLAGS_OPENMP "-fopenmp")

# FEATURE DETECTION

include(CheckCSourceCompiles)
include(CheckTypeSize)

CHECK_C_SOURCE_COMPILES(
"int main(){ __float128 r = 1;}"
COMPILER_SUPPORTS_FLOAT128)

CHECK_TYPE_SIZE("long double" LD_SIZE)
if(LD_SIZE GREATER "9")
set(COMPILER_SUPPORTS_LONG_DOUBLE 1)
endif()

# sleef-config.h.in passes cmake settings to the source code
configure_file(
${PROJECT_SOURCE_DIR}/sleef-config.h.in
${PROJECT_BINARY_DIR}/include/sleef-config.h @ONLY)

# We like to have a documented index of all targets in the project. The
# variables listed below carry the names of the targets defined throughout
# the project.

# Generates object file (shared library) `libsleef`
# Defined in src/libm/CMakeLists.txt via command add_library
set(TARGET_LIBSLEEF "sleef")
# Generates executable files for running the test suite
# Defined in src/libm-tester/CMakeLists.txt via command add_executable
set(TARGET_IUT "iut")
set(TARGET_TESTER "tester")
# Runs the test suite
# Depends on targets: iut, tester
# Defined in src/libm-tester/CMakeLists.txt via command add_custom_target
set(TARGET_TEST "test-libm")
# Generates the helper executable file mkrename needed to write the sleef header
set(TARGET_MKRENAME "mkrename")

add_subdirectory("src")
98 changes: 98 additions & 0 deletions doc/build-with-cmake.md
@@ -0,0 +1,98 @@
# Introduction

[Cmake](http://www.cmake.org/) is an open-source and cross-platform building
tool for software packages that provides easy managing of multiple build systems
at a time. It works by allowing the developer to specify build parameters and
rules in a simple text file that cmake then processes to generate project files
for the actual native build tools (e.g. UNIX Makefiles, Microsoft Visual Studio,
Apple XCode, etc). That means you can easily maintain multiple separate builds
for one project and manage cross-platform hardware and software complexity.

If you are not already familiar with cmake, please refer to the [official
documentation](https://cmake.org/documentation/) or the
[Basic Introductions](https://cmake.org/Wiki/CMake#Basic_Introductions) in the
wiki (recommended).

Before using CMake you will need to install/build the binaries on your system.
Most systems have cmake already installed or provided by the standard package
manager. If that is not the case for you, please
[download](https://cmake.org/download/) and install now.
For building SLEEF, version 3.4.3 is the minimum required.

# Quick start

1. Make sure cmake is available on the command-line.
```
$ cmake --version
(should display a version number greater than or equal to 3.4.3)
```

2. Download the tar from the
[software repository](http://shibatch.sourceforge.net/)
or checkout out the source code from the
[github repository](https://github.com/shibatch/sleef):
```
$ git clone https://github.com/shibatch/sleef
```

3. Make a separate directory to create an out-of-source build. SLEEF does not
allow for in-tree builds.
```
$ cd sleef-project
$ mkdir my-sleef-build && cd my-sleef-build
```

4. Run cmake to configure your project and generate the system to build it:
```
$ cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX=../my-sleef-install \
..
```
This flag configures an optimised `libsleef` shared library build with basic
debug info.
By default, cmake will autodetect your system platform and configure the build
using the default parameters. You can control and modify these parameters by
setting variables when running cmake. See the list of
[options and variables](#build-customization) for customizing your build.

5. Now that you have the build files created by cmake, proceed from the top
of the build directory:
```
$ make sleef
```

6. Install the library under ../my-sleef/install by running:
```
$ make install
```

7. You can execute the tests by running:
```
$ make test-libm
```

# Build customization

Variables dictate how the build is generated; options are defined and undefined,
respectively, on the cmake command line like this:
```
cmake -DVARIABLE=<value> <cmake-build-dir>
cmake -UVARIABLE <cmake-build-dir>
```
Build configurations allow a project to be built in different ways for debug,
optimized, or any other special set of flags.


## CMake Variables

- `CMAKE_BUILD_TYPE`: By default, CMake supports the following configuration:
* `Debug`: basic debug flags turned on
* `Release`: basic optimizations turned on
* `MinSizeRel`: builds the smallest (but not fastest) object code
* `RelWithDebInfo`: builds optimized code with debug information as well

- `CMAKE_INSTALL_PREFIX`: The prefix the use when running `make install`.
Defaults to /usr/local on GNU/Linux and MacOS.
Defaults to C:/Program Files on Windows.

## SLEEF Variables
13 changes: 13 additions & 0 deletions sleef-config.h.in
@@ -0,0 +1,13 @@
// Configuration of @PROJECT_NAME@
// Generates header file: @PROJECT_NAME@Config.h

#ifndef CONFIG_H
#define CONFIG_H

#define SLEEF_VERSION_MAJOR @SLEEF_VERSION_MAJOR@
#define SLEEF_VERSION_MINOR @SLEEF_VERSION_MINOR@

#cmakedefine ENABLE_LONG_DOUBLE
#cmakedefine ENABLE_FLOAT128

#endif // CONFIG_H
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
@@ -0,0 +1,3 @@
include_directories("common")
add_subdirectory("libm")
add_subdirectory("libm-tester")
32 changes: 32 additions & 0 deletions src/libm-tester/CMakeLists.txt
@@ -0,0 +1,32 @@
link_directories(${CMAKE_BINARY_DIR}/lib)
include_directories(${CMAKE_BINARY_DIR}/include)

# This is why a conversation about headers is needed.
# TODO: Find way to avoid relative includes.
include_directories(../libm)

set(LIB_SLEEF sleef)
find_library(LIB_MPFR mpfr)
set(EXTRA_LIBS m
${LIB_MPFR})

# Compile executable 'iut'
add_executable(${TARGET_IUT} iut.c testerutil.c)
target_link_libraries(${TARGET_IUT} ${LIB_SLEEF} ${EXTRA_LIBS})
target_compile_options(${TARGET_IUT}
PRIVATE ${FLAGS_WALL} ${FLAGS_STRICTMATH})

# Compiler executable 'tester'
add_executable(${TARGET_TESTER} tester.c testerutil.c)
target_link_libraries(${TARGET_TESTER} ${EXTRA_LIBS})
target_compile_definitions(${TARGET_TESTER}
PRIVATE USEMPFR=1)
target_compile_options(${TARGET_TESTER}
PRIVATE ${FLAGS_WALL} ${FLAGS_STRICTMATH} -Wno-unused-result)

# Target 'test-libm' runs the libm tests
add_custom_target(${TARGET_TEST}
COMMAND ./tester ./iut
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
add_dependencies(${TARGET_TEST}
${TARGET_TESTER} ${TARGET_IUT} ${TARGET_LIBSLEEF})
59 changes: 59 additions & 0 deletions src/libm/CMakeLists.txt
@@ -0,0 +1,59 @@
# Helper executable: generates parts of the sleef header file
add_executable(${TARGET_MKRENAME} mkrename.c)
target_compile_options(${TARGET_MKRENAME}
PRIVATE ${FLAGS_WALL})
target_compile_features(${TARGET_MKRENAME}
PUBLIC c_variadic_macros)

# TODO: set the parameters for mkrename run for the SIMD implementation
set(MKRENAME_PARAMS "")

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/GenerateSleefHeader.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/GenerateSleefHeader.cmake @ONLY)

# Add custom command to generate the sleef header at build time
set(SLEEF_INCLUDE_HEADER ${CMAKE_BINARY_DIR}/include/sleef.h)
add_custom_command(
OUTPUT ${SLEEF_INCLUDE_HEADER}
COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/GenerateSleefHeader.cmake
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/sleeflibm.h.org
${CMAKE_CURRENT_BINARY_DIR}/GenerateSleefHeader.cmake
${TARGET_MKRENAME})

# Build main library
add_library(${TARGET_LIBSLEEF}
SHARED sleefdp.c sleefsp.c ${SLEEF_INCLUDE_HEADER})

if(COMPILER_SUPPORTS_LONG_DOUBLE)
target_sources(${TARGET_LIBSLEEF} PRIVATE sleefld.c)
endif(COMPILER_SUPPORTS_LONG_DOUBLE)

if(COMPILER_SUPPORTS_FLOAT128)
target_sources(${TARGET_LIBSLEEF} PRIVATE sleefqp.c)
target_compile_definitions(${TARGET_LIBSLEEF}
PRIVATE ENABLEFLOAT128=1)
endif(COMPILER_SUPPORTS_FLOAT128)

target_compile_definitions(${TARGET_LIBSLEEF}
PRIVATE DORENAME=1)
target_compile_options(${TARGET_LIBSLEEF}
PUBLIC ${FLAGS_WALL} ${FLAGS_STRICTMATH})
# Selects C99 with standard gnu99 (add -std=gnu99) for gcc
target_compile_features(${TARGET_LIBSLEEF}
PUBLIC c_variadic_macros)
set_target_properties(${TARGET_LIBSLEEF} PROPERTIES
VERSION ${SLEEF_VERSION_MAJOR}.${SLEEF_VERSION_MINOR}
SOVERSION ${SLEEF_SOVERSION})

# Always compile sleef with -ffp-contract and log at configuration time
if(SLEEF_SHOW_CONFIG)
message(STATUS "Using option `${FLAGS_STRICTMATH}` to compile libsleef")
endif(SLEEF_SHOW_CONFIG)

install(FILES ${SLEEF_INCLUDE_HEADER}
DESTINATION include)
install(TARGETS ${TARGET_LIBSLEEF}
DESTINATION lib)
22 changes: 22 additions & 0 deletions src/libm/GenerateSleefHeader.cmake.in
@@ -0,0 +1,22 @@
set(SRC_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
set(BIN_DIR "@CMAKE_BINARY_DIR@")

set(MKRENAME_PARAMS "@MKRENAME_PARAMS@")

# Do not run for empty parameters
if(MKRENAME_PARAMS)
execute_process(
COMMAND ./mkrename ${MKRENAME_PARAMS}
OUTPUT_VARIABLE MKRENAME_OUTPUT)
endif()

# Workaround: temporary copy of sleeflibm.h.org
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy
${SRC_DIR}/sleeflibm.h.org
${SRC_DIR}/sleeflibm.h.in)
file(APPEND ${SRC_DIR}/sleeflibm.h.in "\n@MKRENAME_OUTPUT@\n#undef IMPORT\n#endif")

configure_file(
${SRC_DIR}/sleeflibm.h.in
${BIN_DIR}/include/sleef.h @ONLY)

0 comments on commit 07286c3

Please sign in to comment.