Compare commits

...

17 Commits

Author SHA1 Message Date
BLUELOVETH
4b81a7af0e
Merge pull request #368 from PrimedErwin/determinism-math
add deterministic float test
2025-05-23 16:57:01 +08:00
PrimedErwin
3adf0509c0
Merge branch 'pocketpy:main' into determinism-math 2025-05-23 16:48:46 +08:00
blueloveTH
d528c4eb52 fix aarch64 2025-05-23 16:38:46 +08:00
PrimedErwin
0d40080d1f add random hard encoded test case 2025-05-23 16:24:30 +08:00
PrimedErwin
0f4acc1437
Merge branch 'pocketpy:main' into determinism-math 2025-05-23 15:20:33 +08:00
blueloveTH
6f4a5321a1 add pkpy.configmacros 2025-05-23 15:18:15 +08:00
PrimedErwin
205f11ebb1 add deterministic float test 2025-05-23 15:01:20 +08:00
blueloveTH
a0e721bd03 fix _DMATH_H 2025-05-23 13:46:31 +08:00
blueloveTH
b69b0787fa Update dmath 2025-05-23 13:41:02 +08:00
blueloveTH
0550f712f0 Update CMakeLists.txt 2025-05-23 13:39:35 +08:00
blueloveTH
1dabcd12db Update CMakeLists.txt 2025-05-23 13:37:56 +08:00
blueloveTH
1dc57b4c2d Update dmath 2025-05-23 13:34:55 +08:00
blueloveTH
cd08c4e022 Update CMakeLists.txt
Update CMakeLists.txt

Update CMakeLists.txt
2025-05-23 13:11:06 +08:00
blueloveTH
d28d86339d Revert "fix cmake"
This reverts commit 0a0d56770402b1e077c72c3fb76d0df52caf87d5.
2025-05-23 13:00:29 +08:00
blueloveTH
0a0d567704 fix cmake 2025-05-23 12:58:09 +08:00
blueloveTH
d424089e86 Update 70_math.py 2025-05-23 12:49:03 +08:00
blueloveTH
3c2d15abc2 add musl math library 2025-05-23 12:46:03 +08:00
12 changed files with 225 additions and 22 deletions

View File

@ -17,7 +17,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: true
submodules: recursive
- uses: ilammy/msvc-dev-cmd@v1
- name: Compile
shell: powershell
@ -30,7 +30,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: true
submodules: recursive
- uses: ilammy/msvc-dev-cmd@v1
- name: Compile
shell: bash
@ -52,7 +52,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: true
submodules: recursive
- name: Setup Clang
uses: egor-tensin/setup-clang@v1
with:
@ -87,7 +87,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: true
submodules: recursive
- name: Compile and Test
run: |
python cmake_build.py Release -DPK_BUILD_MODULE_LZ4=ON
@ -101,7 +101,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: true
submodules: recursive
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
@ -132,7 +132,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: true
submodules: recursive
- name: Compile Frameworks
run: |
git clone https://github.com/leetal/ios-cmake --depth 1 ~/ios-cmake
@ -151,7 +151,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: true
submodules: recursive
- name: Setup Alpine Linux for ${{ matrix.arch }}
uses: jirutka/setup-alpine@v1
with:

3
.gitmodules vendored
View File

@ -4,3 +4,6 @@
[submodule "3rd/lz4/lz4"]
path = 3rd/lz4/lz4
url = https://github.com/lz4/lz4
[submodule "3rd/dmath/dmath"]
path = 3rd/dmath/dmath
url = https://github.com/pocketpy/dmath

1
3rd/dmath/dmath Submodule

@ -0,0 +1 @@
Subproject commit beced4f4f906a117b559cf7de3d8b724c74f980d

View File

@ -20,10 +20,6 @@ if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Ox")
add_definitions(-DNDEBUG)
endif()
if(PK_ENABLE_DETERMINISM)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Oi-")
endif()
else()
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
@ -36,7 +32,7 @@ else()
endif()
if(PK_ENABLE_DETERMINISM)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexcess-precision=standard -ffp-contract=off")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffp-contract=off")
endif()
endif()
@ -48,6 +44,12 @@ if(PK_ENABLE_OS)
add_definitions(-DPK_ENABLE_OS=1)
endif()
if(PK_ENABLE_DETERMINISM)
add_subdirectory(3rd/dmath/dmath)
include_directories(BEFORE 3rd/dmath/dmath/include/public)
add_definitions(-DPK_ENABLE_DETERMINISM=1)
endif()
if(PK_ENABLE_WATCHDOG)
add_definitions(-DPK_ENABLE_WATCHDOG=1)
endif()
@ -82,6 +84,14 @@ else()
target_link_libraries(main ${PROJECT_NAME})
endif()
if(PK_ENABLE_DETERMINISM)
target_link_libraries(${PROJECT_NAME} dmath)
if(MSVC)
target_link_options(${PROJECT_NAME} PRIVATE /FORCE:MULTIPLE)
endif()
endif()
if(UNIX AND NOT APPLE)
if(NOT PK_ENABLE_DETERMINISM)
# use platform libm

View File

@ -7,7 +7,7 @@ endif()
# system features
option(PK_ENABLE_OS "" OFF)
option(PK_ENABLE_DETERMINISM "" FALSE)
option(PK_ENABLE_DETERMINISM "" OFF)
option(PK_ENABLE_WATCHDOG "" OFF)
# modules

View File

@ -20,7 +20,7 @@ assert config in ['Debug', 'Release', 'RelWithDebInfo']
os.chdir("build")
code = os.system(f"cmake .. -DPK_ENABLE_OS=ON -DCMAKE_BUILD_TYPE={config} {extra_flags}")
code = os.system(f"cmake .. -DPK_ENABLE_OS=ON -DPK_ENABLE_DETERMINISM=ON -DCMAKE_BUILD_TYPE={config} {extra_flags}")
assert code == 0
code = os.system(f"cmake --build . --config {config} -j 4")
assert code == 0

View File

@ -12,6 +12,10 @@
#define PK_ENABLE_OS 1
#endif
#ifndef PK_ENABLE_DETERMINISM // must be enabled from cmake
#define PK_ENABLE_DETERMINISM 0
#endif
#ifndef PK_ENABLE_WATCHDOG // can be overridden by cmake
#define PK_ENABLE_WATCHDOG 0
#endif

View File

@ -12,6 +12,8 @@ class TValue[T]:
# TValue_vec2i = TValue[vec2i]
# TValue_vec2 = TValue[vec2]
configmacros: dict[str, int]
def memory_usage() -> str:
"""Return a summary of the memory usage."""

View File

@ -7,6 +7,12 @@
#include <math.h>
#if PK_ENABLE_DETERMINISM
#ifndef _DMATH_H
#error "_DMATH_H not defined"
#endif
#endif
#define ONE_ARG_FUNC(name, func) \
static bool math_##name(int argc, py_Ref argv) { \
PY_CHECK_ARGC(1); \

View File

@ -454,6 +454,13 @@ static void pk_ComputeThread__register(py_Ref mod) {
py_bindmethod(type, "eval", ComputeThread_eval);
}
static void pkpy_configmacros_add(py_Ref dict, const char* key, int val){
assert(dict->type == tp_dict);
py_TValue tmp;
py_newint(&tmp, val);
py_dict_setitem_by_str(dict, key, &tmp);
}
void pk__add_module_pkpy() {
py_Ref mod = py_newmodule("pkpy");
@ -500,6 +507,14 @@ void pk__add_module_pkpy() {
#endif
pk_ComputeThread__register(mod);
py_Ref configmacros = py_emplacedict(mod, py_name("configmacros"));
py_newdict(configmacros);
pkpy_configmacros_add(configmacros, "PK_ENABLE_OS", PK_ENABLE_OS);
pkpy_configmacros_add(configmacros, "PK_ENABLE_DETERMINISM", PK_ENABLE_DETERMINISM);
pkpy_configmacros_add(configmacros, "PK_ENABLE_WATCHDOG", PK_ENABLE_WATCHDOG);
pkpy_configmacros_add(configmacros, "PK_GC_MIN_THRESHOLD", PK_GC_MIN_THRESHOLD);
pkpy_configmacros_add(configmacros, "PK_VM_STACK_SIZE", PK_VM_STACK_SIZE);
}
#undef DEF_TVALUE_METHODS

View File

@ -3,14 +3,14 @@ from math import log, log10, log2, sin, cos, tan, e, pi, isnan, isinf, fabs, flo
def isclose(a, b):
return abs(a-b) < 0.000001
assert isclose(e, 2.718281828459045)
assert isclose(pi, 3.141592653589793)
assert isclose(log(10), 2.302585092994046)
assert isclose(log10(10), 1.0)
assert isclose(log2(10), 3.321928094887362)
assert isclose(sin(0), 0.0)
assert isclose(cos(0), 1.0)
assert isclose(tan(0), 0.0)
assert isclose(e, 2.718281828459045), e
assert isclose(pi, 3.141592653589793), pi
assert isclose(log(10), 2.302585092994046), log(10)
assert isclose(log10(10), 1.0), log10(10)
assert isclose(log2(10), 3.321928094887362), log2(10)
assert isclose(sin(0), 0.0), sin(0)
assert isclose(cos(0), 1.0), cos(0)
assert isclose(tan(0), 0.0), tan(0)
a = -0.1
a = a**a

View File

@ -0,0 +1,162 @@
import math
import pkpy
config = pkpy.configmacros
if config["PK_ENABLE_DETERMINISM"] == 0:
exit(0)
def assertEqual(a, b):
if a == b:
return
print(f'{a} != {b}')
raise AssertionError
# test constants
assertEqual(math.pi, 3.14159265358979323846)
assertEqual(math.e, 2.7182818284590452354)
assert math.inf, math.inf
assert math.nan != math.nan
# test ceil
assertEqual(math.ceil(math.pi), 4.0)
assertEqual(math.ceil(-math.e), -2.0)
assertEqual(math.ceil(math.inf), math.inf)
# test floor
assertEqual(math.floor(math.pi), 3.0)
assertEqual(math.floor(-math.e), -3.0)
# test trunc
assertEqual(math.trunc(math.pi), 3.0)
# test fabs
assertEqual(math.fabs(math.pi), 3.14159265358979323846)
assertEqual(math.fabs(-math.pi), 3.14159265358979323846)
# test gcd
assertEqual(math.gcd(10, 5), 5)
assertEqual(math.gcd(10, 6), 2)
assertEqual(math.gcd(10, 7), 1)
assertEqual(math.gcd(10, 10), 10)
assertEqual(math.gcd(-10, 10), 10)
# test isfinite, isinf, isnan
assertEqual(math.isfinite(math.pi), 1)
assertEqual(math.isfinite(math.inf), 0)
assertEqual(math.isfinite(math.nan), 0)
assertEqual(math.isinf(math.pi), 0)
assertEqual(math.isinf(math.inf), 1)
assertEqual(math.isinf(math.nan), 0)
assertEqual(math.isnan(math.pi), 0)
assertEqual(math.isnan(math.inf), 0)
assertEqual(math.isnan(math.nan), 1)
# test exp
assertEqual(math.exp(0), 1.0)
assertEqual(math.exp(1), math.e)
assertEqual(math.exp(1.5), 4.481689070338065 - 8.881784197001252e-16)
assertEqual(math.exp(3), 20.08553692318767 - 3.552713678800501e-15)
assertEqual(math.exp(-3), 0.04978706836786394 + 6.938893903907228e-18)
assertEqual(math.exp(-2.253647), 0.1050155336754953 - 1.387778780781446e-17)
assertEqual(math.exp(4.729036), 113.1863980522005 - 4.263256414560601e-14)
# test log series
assertEqual(math.log(0), -math.inf)
assertEqual(math.log(1), 0.0)
assertEqual(math.log(2), 0.69314718055994530942)
assertEqual(math.log(math.e), 1.0)
assertEqual(math.log(10), 2.30258509299404568402)
assertEqual(math.log(28.897124), 3.363742074595449)
assertEqual(math.log2(math.e), 1.4426950408889634074)
assertEqual(math.log2(78.781291), 6.299781153677818)
assertEqual(math.log10(math.e), 0.43429448190325182765)
assertEqual(math.log10(56.907822), 1.755171964426069 + 4.440892098500626e-16)
# test pow
assertEqual(math.pow(2,2), 4.0)
assertEqual(math.pow(1.41421356237309504880, 2), 2.0 + 4.440892098500626e-16)
assertEqual(math.pow(0.70710678118654752440, 2), 0.5000000000000001)
assertEqual(math.pow(-1.255782,-3), -0.5049603042167915)
assertEqual(math.pow(6.127042, 4.071529), 1604.407546456745 + 2.273736754432321e-13)
# test sqrt
assertEqual(math.sqrt(2), 1.41421356237309504880)
assertEqual(math.sqrt(math.pi), 1.772453850905516 - 2.220446049250313e-16)
assertEqual(math.sqrt(125.872509), 11.21929182257062)
assertEqual(math.sqrt(1225.296280), 35.00423231553579)
# test cos, sin, tan
assertEqual(math.cos(0), 1.0)
assertEqual(math.cos(math.pi/2), 6.123233995736766e-17)
assertEqual(math.cos(math.pi), -1.0)
assertEqual(math.cos(-11.352808), 0.3496839289707818 - 5.551115123125783e-17)
assertEqual(math.cos(7.294708), 0.530570640518482)
assertEqual(math.sin(0), 0.0)
assertEqual(math.sin(math.pi/2), 1.0)
assertEqual(math.sin(math.pi), 1.224646799147353e-16 + 2.465190328815662e-32)
assertEqual(math.sin(-2.837592), -0.2993398018896187)
assertEqual(math.sin(9.294782), 0.1296301374714747)
assertEqual(math.tan(0), 0.0)
assertEqual(math.tan(math.pi/2), 1.633123935319537e+16)
assertEqual(math.tan(math.pi), -1.224646799147353e-16 - 2.465190328815662e-32)
assertEqual(math.tan(-4.812975), 9.908188146466314)
assertEqual(math.tan(1.875814), -3.176189742032396 - 4.440892098500626e-16)
# test acos, asin, atan
assertEqual(math.acos(0), 1.570796326794897 - 4.440892098500626e-16)
assertEqual(math.acos(1), 0.0)
assertEqual(math.acos(-0.758293), 2.431486995121896 + 4.440892098500626e-16)
assertEqual(math.acos(0.024758), 1.546035796825635)
assertEqual(math.asin(0), 0.0)
assertEqual(math.asin(1), 1.570796326794897 - 4.440892098500626e-16)
assertEqual(math.asin(-0.225895), -0.2278616865773913 + 2.775557561562891e-17)
assertEqual(math.asin(0.955658), 1.271886195819423 + 4.440892098500626e-16)
assertEqual(math.atan(0), 0.0)
assertEqual(math.atan(1), 0.7853981633974483)
assertEqual(math.atan(-3.758927), -1.310785284610617 - 4.440892098500626e-16)
assertEqual(math.atan(35.789293), 1.542862277280122)
# test atan2
assertEqual(math.atan2(math.pi/4, math.pi/4), 0.7853981633974483)
assertEqual(math.atan2(-math.pi/4, math.pi/4), -0.7853981633974483)
assertEqual(math.atan2(-math.pi/4, -math.pi/4), -2.356194490192345)
assertEqual(math.atan2(math.pi/4, -math.pi/4), 2.356194490192345)
assertEqual(math.atan2(1.573823, 0.685329), 1.160103682924653)
assertEqual(math.atan2(-0.899663, 0.668972), -0.9314162757114095)
assertEqual(math.atan2(-0.762894, -0.126497), -1.735113347173296 - 4.440892098500626e-16)
assertEqual(math.atan2(0.468463, -0.992734), 2.700683410692374 - 4.440892098500626e-16)
# test fsum, sum
fsum_sin = math.fsum([math.sin(i) for i in range(5000)])
fsum_cos = math.fsum([math.cos(i) for i in range(5000, 9999)])
assertEqual(fsum_sin, 1.267667771014267 + 2.220446049250313e-16)
assertEqual(fsum_cos, 1.949547793618193 - 4.440892098500626e-16)
assertEqual(fsum_sin + fsum_cos, 3.21721556463246)
sum_sin = sum([math.sin(i) for i in range(5000)])
sum_cos = sum([math.cos(i) for i in range(5000, 9999)])
assertEqual(sum_sin, 1.267667771014264 - 2.220446049250313e-16)
assertEqual(sum_cos, 1.949547793618197 - 4.440892098500626e-16)
assertEqual(sum_sin + sum_cos, 3.21721556463246 + 4.440892098500626e-16)
# test fmod
assertEqual(math.fmod(-2.0, 3.0), -2.0)
assertEqual(math.fmod(2.0, 3.0), 2.0)
assertEqual(math.fmod(4.0, 3.0), 1.0)
assertEqual(math.fmod(-4.0, 3.0), -1.0)
# test modf
x, y = math.modf(math.pi)
assertEqual(x, 0.14159265358979323846 - 1.110223024625157e-16)
assertEqual(y, 3.0)
x, y = math.modf(-math.e)
assertEqual(x, -0.7182818284590451)
assertEqual(y, -2.0)
# test factorial
assertEqual(math.factorial(0), 1)
assertEqual(math.factorial(1), 1)
assertEqual(math.factorial(2), 2)
assertEqual(math.factorial(3), 6)
assertEqual(math.factorial(4), 24)
assertEqual(math.factorial(5), 120)