hanchenye-scalehls/samples/machsuite/backprop/support.h

136 lines
4.0 KiB
C

#include <stdlib.h>
#include <inttypes.h>
///// File and section functions
char *readfile(int fd);
char *find_section_start(char *s, int n);
///// Array read functions
#define SECTION_TERMINATED -1
int parse_string(char *s, char *arr, int n); // n==-1 : %%-terminated
int parse_uint8_t_array(char *s, uint8_t *arr, int n);
int parse_uint16_t_array(char *s, uint16_t *arr, int n);
int parse_uint32_t_array(char *s, uint32_t *arr, int n);
int parse_uint64_t_array(char *s, uint64_t *arr, int n);
int parse_int8_t_array(char *s, int8_t *arr, int n);
int parse_int16_t_array(char *s, int16_t *arr, int n);
int parse_int32_t_array(char *s, int32_t *arr, int n);
int parse_int64_t_array(char *s, int64_t *arr, int n);
int parse_float_array(char *s, float *arr, int n);
int parse_double_array(char *s, double *arr, int n);
///// Array write functions
int write_string(int fd, char *arr, int n);
int write_uint8_t_array(int fd, uint8_t *arr, int n);
int write_uint16_t_array(int fd, uint16_t *arr, int n);
int write_uint32_t_array(int fd, uint32_t *arr, int n);
int write_uint64_t_array(int fd, uint64_t *arr, int n);
int write_int8_t_array(int fd, int8_t *arr, int n);
int write_int16_t_array(int fd, int16_t *arr, int n);
int write_int32_t_array(int fd, int32_t *arr, int n);
int write_int64_t_array(int fd, int64_t *arr, int n);
int write_float_array(int fd, float *arr, int n);
int write_double_array(int fd, double *arr, int n);
int write_section_header(int fd);
///// Per-benchmark files
void run_benchmark( void *vargs );
void input_to_data(int fd, void *vdata);
void data_to_input(int fd, void *vdata);
void output_to_data(int fd, void *vdata);
void data_to_output(int fd, void *vdata);
int check_data(void *vdata, void *vref);
extern int INPUT_SIZE;
///// TYPE macros
// Macro trick to automatically expand TYPE into the appropriate function
// (S)et (T)ype (A)nd (C)oncatenate
#define __STAC_EXPANDED(f_pfx,t,f_sfx) f_pfx##t##f_sfx
#define STAC(f_pfx,t,f_sfx) __STAC_EXPANDED(f_pfx,t,f_sfx)
// Invoke like this:
// #define TYPE int32_t
// STAC(write_,TYPE,_array)(fd, array, n);
// where array is of type (TYPE *)
// This translates to:
// write_int32_t_array(fd, array, n);
/**** PRNG library. Available at https://github.com/rdadolf/prng. *****/
#ifndef __PRNG_H__
#define __PRNG_H__
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <stdint.h>
#define LAG1 (UINT16_C(24))
#define LAG2 (UINT16_C(55))
#define RAND_SSIZE ((UINT16_C(1))<<6)
#define RAND_SMASK (RAND_SSIZE-1)
#define RAND_EXHAUST_LIMIT LAG2
// 10x is a heuristic, it just needs to be large enough to remove correlation
#define RAND_REFILL_COUNT ((LAG2*10)-RAND_EXHAUST_LIMIT)
struct prng_rand_t {
uint64_t s[RAND_SSIZE]; // Lags
uint_fast16_t i; // Location of the current lag
uint_fast16_t c; // Exhaustion count
};
#define PRNG_RAND_MAX UINT64_MAX
static inline uint64_t prng_rand(struct prng_rand_t *state) {
uint_fast16_t i;
uint_fast16_t r, new_rands=0;
if( !state->c ) { // Randomness exhausted, run forward to refill
new_rands += RAND_REFILL_COUNT+1;
state->c = RAND_EXHAUST_LIMIT-1;
} else {
new_rands = 1;
state->c--;
}
for( r=0; r<new_rands; r++ ) {
i = state->i;
state->s[i&RAND_SMASK] = state->s[(i+RAND_SSIZE-LAG1)&RAND_SMASK]
+ state->s[(i+RAND_SSIZE-LAG2)&RAND_SMASK];
state->i++;
}
return state->s[i&RAND_SMASK];
}
static inline void prng_srand(uint64_t seed, struct prng_rand_t *state) {
uint_fast16_t i;
// Naive seed
state->c = RAND_EXHAUST_LIMIT;
state->i = 0;
state->s[0] = seed;
for(i=1; i<RAND_SSIZE; i++) {
// Arbitrary magic, mostly to eliminate the effect of low-value seeds.
// Probably could be better, but the run-up obviates any real need to.
state->s[i] = i*(UINT64_C(2147483647)) + seed;
}
// Run forward 10,000 numbers
for(i=0; i<10000; i++) {
prng_rand(state);
}
}
// Clean up our macros
#undef LAG1
#undef LAG2
#undef RAND_SSIZE
#undef RAND_SMASK
#undef RAND_EXHAUST_LIMIT
#undef RAND_REFILL_COUNT
// PRNG_RAND_MAX is exported
#endif