-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fast exp algorithm implementation. (#1586)
A fast exp algorithm implementation following: Ref: 1. A Fast, Compact Approximation of the Exponential Function by Schraudolph 1999 (https://doi.org/10.1162/089976699300016467). 2. On a Fast Compact Approximation of the Exponential Function by Cawley 2000 (https://doi.org/10.1162/089976600300015033). 3. https://gist.github.com/jrade/293a73f89dfef51da6522428c857802d 4. https://github.com/ekmett/approximate/blob/master/cbits/fast.c There are two versions: jrade_exp: Its roughly 6-times faster than std::exp. It has reasonable accuracy across all range (roughly ~2% relative error), we follow Ref (3) ekmett_exp: It is about twice as slow as jrade_exp, but still ~ 3 times faster than std::exp, but it gives much better accuracy, ~0.1% relative error for most cases. The main driver is fast_exp, which also included a simple taylor approximation, 1+x, when x < 0.1, currently it is defaulted to use jrade_exp but one can just switch to ekmett_exp for better accuracy. We also use memcpy approach to avoid undefined behavior from type-punning when using union (pointed out by Eric), and this approach is demonstrated in Ref 3, which we adapt for ekmett_exp.
- Loading branch information
Showing
7 changed files
with
389 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
PRECISION = DOUBLE | ||
PROFILE = FALSE | ||
|
||
DEBUG = FALSE | ||
|
||
DIM = 3 | ||
|
||
COMP = gnu | ||
|
||
USE_MPI = FALSE | ||
USE_OMP = FALSE | ||
|
||
USE_REACT = TRUE | ||
|
||
EBASE = main | ||
|
||
# define the location of the Microphysics top directory | ||
MICROPHYSICS_HOME ?= ../../.. | ||
|
||
# This sets the EOS directory | ||
EOS_DIR := helmholtz | ||
|
||
# This sets the network directory | ||
NETWORK_DIR := aprox21 | ||
|
||
CONDUCTIVITY_DIR := stellar | ||
|
||
INTEGRATOR_DIR = VODE | ||
|
||
ifeq ($(USE_CUDA), TRUE) | ||
INTEGRATOR_DIR := VODE | ||
endif | ||
|
||
EXTERN_SEARCH += . | ||
|
||
Bpack := ../Make.package ./Make.package | ||
Blocs := ../ . | ||
|
||
include $(MICROPHYSICS_HOME)/unit_test/Make.unit_test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
CEXE_sources += main.cpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#include <test_fast_exp.H> | ||
|
||
int main() { | ||
|
||
// Accuracy tests | ||
|
||
// Test values including edge cases and some typical values | ||
|
||
test_fast_exp_accuracy(0.0_rt); | ||
test_fast_exp_accuracy(0.001_rt); | ||
test_fast_exp_accuracy(0.01_rt); | ||
test_fast_exp_accuracy(0.1_rt); | ||
test_fast_exp_accuracy(0.5_rt); | ||
test_fast_exp_accuracy(1.0_rt); | ||
test_fast_exp_accuracy(5.0_rt); | ||
test_fast_exp_accuracy(10.0_rt); | ||
test_fast_exp_accuracy(15.0_rt); | ||
test_fast_exp_accuracy(20.0_rt); | ||
test_fast_exp_accuracy(30.0_rt); | ||
test_fast_exp_accuracy(50.0_rt); | ||
test_fast_exp_accuracy(100.0_rt); | ||
test_fast_exp_accuracy(500.0_rt); | ||
|
||
test_fast_exp_accuracy(-0.001_rt); | ||
test_fast_exp_accuracy(-0.01_rt); | ||
test_fast_exp_accuracy(-0.1_rt); | ||
test_fast_exp_accuracy(-0.5_rt); | ||
test_fast_exp_accuracy(-1.0_rt); | ||
test_fast_exp_accuracy(-5.0_rt); | ||
test_fast_exp_accuracy(-10.0_rt); | ||
test_fast_exp_accuracy(-15.0_rt); | ||
test_fast_exp_accuracy(-20.0_rt); | ||
test_fast_exp_accuracy(-30.0_rt); | ||
test_fast_exp_accuracy(-50.0_rt); | ||
test_fast_exp_accuracy(-100.0_rt); | ||
test_fast_exp_accuracy(-500.0_rt); | ||
|
||
std::cout << "Accuracy tests passed!" << std::endl; | ||
|
||
// Now performance test | ||
|
||
int iters = 5; | ||
amrex::Real test_value = 160.0_rt; | ||
test_fast_exp_speed(100, iters, test_value); | ||
|
||
iters = 10; | ||
test_fast_exp_speed(100, iters, test_value); | ||
|
||
iters = 20; | ||
test_fast_exp_speed(100, iters, test_value); | ||
|
||
iters = 30; | ||
test_fast_exp_speed(100, iters, test_value); | ||
|
||
iters = 50; | ||
test_fast_exp_speed(100, iters, test_value); | ||
|
||
// iters = 70; | ||
// test_fast_exp_speed(100, iters, test_value); | ||
} |
Oops, something went wrong.