Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0f2adc5

Browse files
committedApr 24, 2024
ci(performance): Add SuperPi like test
1 parent c5989a9 commit 0f2adc5

File tree

8 files changed

+4767
-8
lines changed

8 files changed

+4767
-8
lines changed
 

‎tests/performance/fibonacci/fibonacci.ino

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <Arduino.h>
22

3-
#define N_RUNS 3 // Number of runs to average
3+
// Number of runs to average
4+
#define N_RUNS 3
45

56
// Fibonacci number to calculate. Keep between 35 and 45.
67
#define FIB_N 40
@@ -36,7 +37,7 @@ void setup(){
3637
sum += times[i];
3738
}
3839
uint32_t avg = sum / N_RUNS;
39-
Serial.printf("Average time: %lu.%03lu s\n", avg/1000, avg%1000);
40+
Serial.printf("Average time: %lu.%03lu s\n", avg / 1000, avg % 1000);
4041
}
4142

4243
void loop(){

‎tests/performance/fibonacci/test_fibonacci.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
import logging
33
import os
44

5-
LOGGER = logging.getLogger(__name__)
5+
def test_fibonacci(dut, request):
6+
LOGGER = logging.getLogger(__name__)
67

7-
# Fibonacci results starting from fib(35) to fib(45)
8-
fib_results = [9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733]
8+
# Fibonacci results starting from fib(35) to fib(45)
9+
fib_results = [9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733]
910

10-
def test_fibonacci(dut, request):
1111
# Match "Runs: %d"
1212
res = dut.expect(r"Runs: (\d+)", timeout=60)
1313
runs = int(res.group(0).decode("utf-8").split(" ")[1])
@@ -32,7 +32,7 @@ def test_fibonacci(dut, request):
3232
LOGGER.info("Average time on {} runs: {} s".format(runs, avg_time))
3333

3434
# Create JSON with results and write it to file
35-
# Always create a JSON with the format (so it can be merged later on):
35+
# Always create a JSON with this format (so it can be merged later on):
3636
# { TEST_NAME_STR: TEST_RESULTS_DICT }
3737
results = {
3838
"fibonacci": {
@@ -44,7 +44,8 @@ def test_fibonacci(dut, request):
4444
}
4545

4646
current_folder = os.path.dirname(request.path)
47-
with open(current_folder + "/result_fibonacci.json", "w") as f:
47+
report_file = os.path.join(current_folder, "result_fibonacci.json")
48+
with open(report_file, "w") as f:
4849
try:
4950
f.write(json.dumps(results))
5051
except Exception as e:

‎tests/performance/superpi/fftsg_h.cpp

Lines changed: 2329 additions & 0 deletions
Large diffs are not rendered by default.

‎tests/performance/superpi/fftsg_h.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
Based on "Calculation of PI(= 3.14159...) using FFT and AGM" by T.Ooura, Nov. 1999.
3+
https://github.com/Fibonacci43/SuperPI
4+
Modified for Arduino by Lucas Saavedra Vaz, 2024.
5+
*/
6+
7+
#pragma once
8+
9+
#include <math.h>
10+
11+
#ifndef M_PI_2
12+
#define M_PI_2 1.570796326794896619231321691639751442098584699687
13+
#endif
14+
#ifndef WR5000 /* cos(M_PI_2*0.5000) */
15+
#define WR5000 0.707106781186547524400844362104849039284835937688
16+
#endif
17+
#ifndef WR2500 /* cos(M_PI_2*0.2500) */
18+
#define WR2500 0.923879532511286756128183189396788286822416625863
19+
#endif
20+
#ifndef WI2500 /* sin(M_PI_2*0.2500) */
21+
#define WI2500 0.382683432365089771728459984030398866761344562485
22+
#endif
23+
#ifndef WR1250 /* cos(M_PI_2*0.1250) */
24+
#define WR1250 0.980785280403230449126182236134239036973933730893
25+
#endif
26+
#ifndef WI1250 /* sin(M_PI_2*0.1250) */
27+
#define WI1250 0.195090322016128267848284868477022240927691617751
28+
#endif
29+
#ifndef WR3750 /* cos(M_PI_2*0.3750) */
30+
#define WR3750 0.831469612302545237078788377617905756738560811987
31+
#endif
32+
#ifndef WI3750 /* sin(M_PI_2*0.3750) */
33+
#define WI3750 0.555570233019602224742830813948532874374937190754
34+
#endif
35+
36+
#ifndef CDFT_RECURSIVE_N /* length of the recursive FFT mode */
37+
#define CDFT_RECURSIVE_N 512 /* <= (L1 cache size) / 16 */
38+
#endif
39+
40+
#ifndef CDFT_LOOP_DIV /* control of the CDFT's speed & tolerance */
41+
#define CDFT_LOOP_DIV 32
42+
#endif
43+
44+
#ifndef RDFT_LOOP_DIV /* control of the RDFT's speed & tolerance */
45+
#define RDFT_LOOP_DIV 64
46+
#endif
47+
48+
#ifndef DCST_LOOP_DIV /* control of the DCT,DST's speed & tolerance */
49+
#define DCST_LOOP_DIV 64
50+
#endif
51+
52+
void bitrv1(int n, double *a);
53+
void bitrv2(int n, double *a);
54+
void bitrv208(double *a);
55+
void bitrv208neg(double *a);
56+
void bitrv216(double *a);
57+
void bitrv216neg(double *a);
58+
void bitrv2conj(int n, double *a);
59+
void cdft(int n, int isgn, double *a);
60+
void cftb040(double *a);
61+
void cftb1st(int n, double *a);
62+
void cftbsub(int n, double *a);
63+
void cftexp1(int n, double *a);
64+
void cftexp2(int n, double *a);
65+
void cftf040(double *a);
66+
void cftf081(double *a);
67+
void cftf082(double *a);
68+
void cftf161(double *a);
69+
void cftf162(double *a);
70+
void cftfsub(int n, double *a);
71+
void cftfx41(int n, double *a);
72+
void cftfx42(int n, double *a);
73+
void cftmdl1(int n, double *a);
74+
void cftmdl2(int n, double *a);
75+
void cftrec1(int n, double *a);
76+
void cftrec2(int n, double *a);
77+
void cftx020(double *a);
78+
void dctsub(int n, double *a);
79+
void dctsub4(int n, double *a);
80+
void ddct(int n, int isgn, double *a);
81+
void ddst(int n, int isgn, double *a);
82+
void dfct(int n, double *a);
83+
void dfst(int n, double *a);
84+
void dstsub(int n, double *a);
85+
void dstsub4(int n, double *a);
86+
void rdft(int n, int isgn, double *a);
87+
void rftbsub(int n, double *a);
88+
void rftfsub(int n, double *a);

‎tests/performance/superpi/pi_fftcs.cpp

Lines changed: 2214 additions & 0 deletions
Large diffs are not rendered by default.

‎tests/performance/superpi/pi_fftcs.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
Based on "Calculation of PI(= 3.14159...) using FFT and AGM" by T.Ooura, Nov. 1999.
3+
https://github.com/Fibonacci43/SuperPI
4+
Modified for Arduino by Lucas Saavedra Vaz, 2024.
5+
*/
6+
7+
#pragma once
8+
9+
#include <ctype.h>
10+
11+
#define PI_FFTC_VER "ver. LG1.1.2-MP1.5.2a.memsave"
12+
13+
/* Please check the following macros before compiling */
14+
#ifndef DBL_ERROR_MARGIN
15+
#define DBL_ERROR_MARGIN 0.4 /* must be < 0.5 */
16+
#endif
17+
18+
#define DGTINT short int /* sizeof(DGTINT) == 2 */
19+
#define DGTINT_MAX SHRT_MAX
20+
21+
#define DGT_PACK 10
22+
#define DGT_PACK_LINE 5
23+
#define DGT_LINE_BLOCK 20
24+
25+
void pi_calc(int nfft);
26+
void mp_load_0(int n, int radix, int out[]);
27+
void mp_load_1(int n, int radix, int out[]);
28+
void mp_round(int n, int radix, int m, int inout[]);
29+
int mp_cmp(int n, int radix, int in1[], int in2[]);
30+
void mp_add(int n, int radix, int in1[], int in2[], int out[]);
31+
void mp_sub(int n, int radix, int in1[], int in2[], int out[]);
32+
void mp_imul(int n, int radix, int in1[], int in2, int out[]);
33+
int mp_idiv(int n, int radix, int in1[], int in2, int out[]);
34+
void mp_idiv_2(int n, int radix, int in[], int out[]);
35+
double mp_mul_radix_test(int n, int radix, int nfft, double tmpfft[]);
36+
void mp_mul(int n, int radix, int in1[], int in2[], int out[], int tmp[], int nfft, double tmp1fft[], double tmp2fft[], double tmp3fft[]);
37+
void mp_squ(int n, int radix, int in[], int out[], int tmp[], int nfft, double tmp1fft[], double tmp2fft[]);
38+
void mp_mulhf(int n, int radix, int in1[], int in2[], int out[], int tmp[], int nfft, double in1fft[], double tmpfft[]);
39+
void mp_mulhf_use_in1fft(int n, int radix, double in1fft[], int in2[], int out[], int tmp[], int nfft, double tmpfft[]);
40+
void mp_squhf_use_infft(int n, int radix, double infft[], int in[], int out[], int tmp[], int nfft, double tmpfft[]);
41+
void mp_mulh(int n, int radix, int in1[], int in2[], int out[], int nfft, double in1fft[], double outfft[]);
42+
void mp_squh(int n, int radix, int in[], int out[], int nfft, double outfft[]);
43+
int mp_inv(int n, int radix, int in[], int out[], int tmp1[], int tmp2[], int nfft, double tmp1fft[], double tmp2fft[]);
44+
int mp_sqrt(int n, int radix, int in[], int out[], int tmp1[], int tmp2[], int nfft, double tmp1fft[], double tmp2fft[]);
45+
int mp_invisqrt(int n, int radix, int in, int out[], int tmp1[], int tmp2[], int nfft, double tmp1fft[], double tmp2fft[]);
46+
void mp_sprintf(int n, int log10_radix, int in[], char out[]);
47+
void mp_sscanf(int n, int log10_radix, char in[], int out[]);

‎tests/performance/superpi/superpi.ino

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <Arduino.h>
2+
3+
#include "pi_fftcs.h"
4+
5+
// Number of runs to average
6+
#define N_RUNS 3
7+
8+
// Number of decimal digits to calculate
9+
#define DIGITS (1 << 14)
10+
11+
uint32_t times[N_RUNS];
12+
13+
void setup(){
14+
Serial.begin(115200);
15+
while (!Serial) delay(10);
16+
17+
log_d("Starting PI calculation");
18+
Serial.printf("Runs: %d\n", N_RUNS);
19+
Serial.printf("Digits: %d\n", DIGITS);
20+
for (int i = 0; i < N_RUNS; i++) {
21+
log_d("Run %d", i);
22+
unsigned long start = millis();
23+
pi_calc(DIGITS);
24+
unsigned long end = millis();
25+
times[i] = end - start;
26+
log_d("Run %d: %lu.%03lu s\n", i, times[i]/1000, times[i]%1000);
27+
}
28+
29+
uint32_t sum = 0;
30+
for (int i = 0; i < N_RUNS; i++) {
31+
sum += times[i];
32+
}
33+
uint32_t avg = sum / N_RUNS;
34+
Serial.printf("Average time: %lu.%03lu s\n", avg / 1000, avg % 1000);
35+
}
36+
37+
void loop(){
38+
vTaskDelete(NULL);
39+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import json
2+
import logging
3+
import os
4+
5+
def test_superpi(dut, request):
6+
LOGGER = logging.getLogger(__name__)
7+
8+
# Match "Runs: %d"
9+
res = dut.expect(r"Runs: (\d+)", timeout=60)
10+
runs = int(res.group(0).decode("utf-8").split(" ")[1])
11+
LOGGER.info("Number of runs: {}".format(runs))
12+
13+
# Match "Digits: %d"
14+
res = dut.expect(r"Digits: (\d+)", timeout=60)
15+
digits = int(res.group(0).decode("utf-8").split(" ")[1])
16+
LOGGER.info("Number of decimal digits: {}".format(digits))
17+
18+
# Match "Average time: %lu.%03lu s"
19+
res = dut.expect(r"Average time: (\d+)\.(\d+) s", timeout=300)
20+
avg_time = float(res.group(0).decode("utf-8").split(" ")[2])
21+
LOGGER.info("Average time on {} runs: {} s".format(runs, avg_time))
22+
23+
# Create JSON with results and write it to file
24+
# Always create a JSON with this format (so it can be merged later on):
25+
# { TEST_NAME_STR: TEST_RESULTS_DICT }
26+
results = {
27+
"superpi": {
28+
"runs": runs,
29+
"digits": digits,
30+
"avg_time": avg_time
31+
}
32+
}
33+
34+
current_folder = os.path.dirname(request.path)
35+
report_file = os.path.join(current_folder, "result_superpi.json")
36+
with open(report_file, "w") as f:
37+
try:
38+
f.write(json.dumps(results))
39+
except Exception as e:
40+
LOGGER.warning("Failed to write results to file: {}".format(e))

0 commit comments

Comments
 (0)
Please sign in to comment.