Skip to content

Commit

Permalink
Resolved strict aliasing violation resulted in invalid code generatio…
Browse files Browse the repository at this point in the history
…n by Intel compiler.
  • Loading branch information
IlyaGrebnov committed Feb 24, 2024
1 parent d5e74eb commit 381e3e5
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 153 deletions.
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Changes in 2.7.4 (February 23, 2024)
- Improved performance of suffix array and burrows wheeler transform construction on degenerate inputs.
- Resolved strict aliasing violation resulted in invalid code generation by Intel compiler.

Changes in 2.7.3 (April 21, 2023)
- CMake script for library build and integration with other projects.

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10)

project(libsais VERSION 2.7.3 LANGUAGES C DESCRIPTION "libsais is a library for linear time suffix array, longest common prefix array and burrows wheeler transform construction based on induced sorting algorithm.")
project(libsais VERSION 2.7.4 LANGUAGES C DESCRIPTION "libsais is a library for linear time suffix array, longest common prefix array and burrows wheeler transform construction based on induced sorting algorithm.")

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The libsais is a library for fast (see [Benchmarks](#benchmarks) below) linear t
* Nataliya Timoshevskaya, Wu-chun Feng *SAIS-OPT: On the characterization and optimization of the SA-IS algorithm for suffix array construction*, 2014
* Jing Yi Xie, Ge Nong, Bin Lao, Wentao Xu *Scalable Suffix Sorting on a Multicore Machine*, 2020

Copyright (c) 2021-2022 Ilya Grebnov <[email protected]>
Copyright (c) 2021-2024 Ilya Grebnov <[email protected]>

>The libsais is inspired by [libdivsufsort](https://github.com/y-256/libdivsufsort), [sais](https://sites.google.com/site/yuta256/sais) libraries by Yuta Mori and [msufsort](https://github.com/michaelmaniscalco/msufsort) by Michael Maniscalco.
Expand All @@ -23,6 +23,9 @@ The libsais provides simple C99 API to construct suffix array and Burrows-Wheele
The libsais is released under the [Apache License Version 2.0](LICENSE "Apache license")

## Changes
* February 23, 2024 (2.7.4)
* Improved performance of suffix array and burrows wheeler transform construction on degenerate inputs.
* Resolved strict aliasing violation resulted in invalid code generation by Intel compiler.
* April 21, 2023 (2.7.3)
* CMake script for library build and integration with other projects.
* April 18, 2023 (2.7.2)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.7.3
2.7.4
6 changes: 3 additions & 3 deletions include/libsais.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This file is a part of libsais, a library for linear time suffix array,
longest common prefix array and burrows wheeler transform construction.
Copyright (c) 2021-2022 Ilya Grebnov <[email protected]>
Copyright (c) 2021-2024 Ilya Grebnov <[email protected]>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -26,8 +26,8 @@ Please see the file LICENSE for full copyright information.

#define LIBSAIS_VERSION_MAJOR 2
#define LIBSAIS_VERSION_MINOR 7
#define LIBSAIS_VERSION_PATCH 3
#define LIBSAIS_VERSION_STRING "2.7.3"
#define LIBSAIS_VERSION_PATCH 4
#define LIBSAIS_VERSION_STRING "2.7.4"

#ifdef _WIN32
#ifdef LIBSAIS_SHARED
Expand Down
64 changes: 32 additions & 32 deletions include/libsais16.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This file is a part of libsais, a library for linear time suffix array,
longest common prefix array and burrows wheeler transform construction.
Copyright (c) 2021-2022 Ilya Grebnov <[email protected]>
Copyright (c) 2021-2024 Ilya Grebnov <[email protected]>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -26,21 +26,21 @@ Please see the file LICENSE for full copyright information.

#define LIBSAIS16_VERSION_MAJOR 2
#define LIBSAIS16_VERSION_MINOR 7
#define LIBSAIS16_VERSION_PATCH 3
#define LIBSAIS16_VERSION_STRING "2.7.3"
#define LIBSAIS16_VERSION_PATCH 4
#define LIBSAIS16_VERSION_STRING "2.7.4"

#ifdef _WIN32
#ifdef LIBSAIS_SHARED
#ifdef LIBSAIS_EXPORTS
#define LIBSAIS_API __declspec(dllexport)
#define LIBSAIS16_API __declspec(dllexport)
#else
#define LIBSAIS_API __declspec(dllimport)
#define LIBSAIS16_API __declspec(dllimport)
#endif
#else
#define LIBSAIS_API
#define LIBSAIS16_API
#endif
#else
#define LIBSAIS_API
#define LIBSAIS16_API
#endif

#ifdef __cplusplus
Expand All @@ -54,7 +54,7 @@ extern "C" {
* In multi-threaded environments, use one context per thread for parallel executions.
* @return the libsais16 context, NULL otherwise.
*/
LIBSAIS_API void * libsais16_create_ctx(void);
LIBSAIS16_API void * libsais16_create_ctx(void);

#if defined(LIBSAIS_OPENMP)
/**
Expand All @@ -63,14 +63,14 @@ extern "C" {
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return the libsais16 context, NULL otherwise.
*/
LIBSAIS_API void * libsais16_create_ctx_omp(int32_t threads);
LIBSAIS16_API void * libsais16_create_ctx_omp(int32_t threads);
#endif

/**
* Destroys the libsass context and free previusly allocated memory.
* @param ctx The libsais16 context (can be NULL).
*/
LIBSAIS_API void libsais16_free_ctx(void * ctx);
LIBSAIS16_API void libsais16_free_ctx(void * ctx);

/**
* Constructs the suffix array of a given 16-bit string.
Expand All @@ -81,7 +81,7 @@ extern "C" {
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16(const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
LIBSAIS16_API int32_t libsais16(const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);

/**
* Constructs the suffix array of a given 16-bit string using libsais16 context.
Expand All @@ -93,7 +93,7 @@ extern "C" {
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_ctx(const void * ctx, const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
LIBSAIS16_API int32_t libsais16_ctx(const void * ctx, const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);

#if defined(LIBSAIS_OPENMP)
/**
Expand All @@ -106,7 +106,7 @@ extern "C" {
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_omp(const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq, int32_t threads);
LIBSAIS16_API int32_t libsais16_omp(const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq, int32_t threads);
#endif

/**
Expand All @@ -119,7 +119,7 @@ extern "C" {
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_bwt(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq);
LIBSAIS16_API int32_t libsais16_bwt(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq);

/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string with auxiliary indexes.
Expand All @@ -133,7 +133,7 @@ extern "C" {
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_bwt_aux(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I);
LIBSAIS16_API int32_t libsais16_bwt_aux(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I);

/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string using libsais16 context.
Expand All @@ -146,7 +146,7 @@ extern "C" {
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_bwt_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq);
LIBSAIS16_API int32_t libsais16_bwt_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq);

/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string with auxiliary indexes using libsais16 context.
Expand All @@ -161,7 +161,7 @@ extern "C" {
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_bwt_aux_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I);
LIBSAIS16_API int32_t libsais16_bwt_aux_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I);

#if defined(LIBSAIS_OPENMP)
/**
Expand All @@ -175,7 +175,7 @@ extern "C" {
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_bwt_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t threads);
LIBSAIS16_API int32_t libsais16_bwt_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t threads);

/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string with auxiliary indexes in parallel using OpenMP.
Expand All @@ -190,15 +190,15 @@ extern "C" {
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_bwt_aux_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I, int32_t threads);
LIBSAIS16_API int32_t libsais16_bwt_aux_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I, int32_t threads);
#endif

/**
* Creates the libsais16 reverse BWT context that allows reusing allocated memory with each libsais16_unbwt_* operation.
* In multi-threaded environments, use one context per thread for parallel executions.
* @return the libsais16 context, NULL otherwise.
*/
LIBSAIS_API void * libsais16_unbwt_create_ctx(void);
LIBSAIS16_API void * libsais16_unbwt_create_ctx(void);

#if defined(LIBSAIS_OPENMP)
/**
Expand All @@ -207,14 +207,14 @@ extern "C" {
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return the libsais16 context, NULL otherwise.
*/
LIBSAIS_API void * libsais16_unbwt_create_ctx_omp(int32_t threads);
LIBSAIS16_API void * libsais16_unbwt_create_ctx_omp(int32_t threads);
#endif

/**
* Destroys the libsass reverse BWT context and free previusly allocated memory.
* @param ctx The libsais16 context (can be NULL).
*/
LIBSAIS_API void libsais16_unbwt_free_ctx(void * ctx);
LIBSAIS16_API void libsais16_unbwt_free_ctx(void * ctx);

/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with primary index.
Expand All @@ -226,7 +226,7 @@ extern "C" {
* @param i The primary index.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_unbwt(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i);
LIBSAIS16_API int32_t libsais16_unbwt(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i);

/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with primary index using libsais16 reverse BWT context.
Expand All @@ -239,7 +239,7 @@ extern "C" {
* @param i The primary index.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_unbwt_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i);
LIBSAIS16_API int32_t libsais16_unbwt_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i);

/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with auxiliary indexes.
Expand All @@ -252,7 +252,7 @@ extern "C" {
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_unbwt_aux(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I);
LIBSAIS16_API int32_t libsais16_unbwt_aux(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I);

/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with auxiliary indexes using libsais16 reverse BWT context.
Expand All @@ -266,7 +266,7 @@ extern "C" {
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_unbwt_aux_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I);
LIBSAIS16_API int32_t libsais16_unbwt_aux_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I);

#if defined(LIBSAIS_OPENMP)
/**
Expand All @@ -280,7 +280,7 @@ extern "C" {
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_unbwt_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i, int32_t threads);
LIBSAIS16_API int32_t libsais16_unbwt_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i, int32_t threads);

/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with auxiliary indexes in parallel using OpenMP.
Expand All @@ -294,7 +294,7 @@ extern "C" {
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais16_unbwt_aux_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I, int32_t threads);
LIBSAIS16_API int32_t libsais16_unbwt_aux_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I, int32_t threads);
#endif

/**
Expand All @@ -305,7 +305,7 @@ extern "C" {
* @param n The length of the 16-bit string and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais16_plcp(const uint16_t * T, const int32_t * SA, int32_t * PLCP, int32_t n);
LIBSAIS16_API int32_t libsais16_plcp(const uint16_t * T, const int32_t * SA, int32_t * PLCP, int32_t n);

/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array.
Expand All @@ -315,7 +315,7 @@ extern "C" {
* @param n The length of the permuted longest common prefix array and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais16_lcp(const int32_t * PLCP, const int32_t * SA, int32_t * LCP, int32_t n);
LIBSAIS16_API int32_t libsais16_lcp(const int32_t * PLCP, const int32_t * SA, int32_t * LCP, int32_t n);

#if defined(LIBSAIS_OPENMP)
/**
Expand All @@ -327,7 +327,7 @@ extern "C" {
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais16_plcp_omp(const uint16_t * T, const int32_t * SA, int32_t * PLCP, int32_t n, int32_t threads);
LIBSAIS16_API int32_t libsais16_plcp_omp(const uint16_t * T, const int32_t * SA, int32_t * PLCP, int32_t n, int32_t threads);

/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array in parallel using OpenMP.
Expand All @@ -338,7 +338,7 @@ extern "C" {
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais16_lcp_omp(const int32_t * PLCP, const int32_t * SA, int32_t * LCP, int32_t n, int32_t threads);
LIBSAIS16_API int32_t libsais16_lcp_omp(const int32_t * PLCP, const int32_t * SA, int32_t * LCP, int32_t n, int32_t threads);
#endif

#ifdef __cplusplus
Expand Down
Loading

0 comments on commit 381e3e5

Please sign in to comment.