Taken from Note 10 5G & S10 [Exynos 9825/9820] and fully merged with KAIR feature as they quote "AI based Resource Control"
419 lines
No EOL
13 KiB
C
419 lines
No EOL
13 KiB
C
/**
|
|
* Classfication and realization of KAIR concept using ECAVE - Elastic Capability
|
|
* Vessel - dynamic resource control abstraction theory
|
|
**/
|
|
#include <linux/sched.h>
|
|
#include <linux/bug.h>
|
|
#include <linux/list.h>
|
|
#include <linux/tfifo.h>
|
|
#include <linux/kobject.h>
|
|
#include <linux/sysfs.h>
|
|
|
|
/**
|
|
*
|
|
**/
|
|
#define KAIR_QUANT_STEP (17)
|
|
#define KAIR_QUANT_SHIFT (4)
|
|
#define KAIR_VARIANCE_SPAN (64)
|
|
#define KAIR_VARIANCE_SPAN_SHIFT (6)
|
|
#define KAIR_UNDETERMINED (0xFFFFFFFF)
|
|
#define KAIR_DIVERGING (-1)
|
|
#define KAIR_CONVERGING (0)
|
|
#define KAIR_TPDF_CUMSUM (512)
|
|
#define KAIR_TPDF_MINVAL (1)
|
|
#define KAIR_TPDF_CASCADE_LEVEL (1)
|
|
#define KAIR_ALIAS_LEN (8)
|
|
|
|
#define KAIR_INF_TPDF_WEIGHT (1)
|
|
#define KAIR_FIN_TPDF_WEIGHT (2)
|
|
#if KAIR_TPDF_CASCADE_LEVEL > 1
|
|
#define KAIR_INST_TPDF_WEIGHT (4)
|
|
#else
|
|
#define KAIR_INST_TPDF_WEIGHT (8)
|
|
#endif
|
|
|
|
/**
|
|
* Calculating Energy-Performance(EP) weight ratio, which is described
|
|
* in theory as beta / alpha * upscaler.
|
|
* where, beta is energy consuming panelty weight, alpha is bottleneck
|
|
* panelty weight, and upscaler is 1024.
|
|
**/
|
|
#define KAIR_BALANCED_EP_RATIO (1024)
|
|
|
|
/**
|
|
*
|
|
**/
|
|
#define KAIR_WINDOW_INF (0x8000000000000000UL)
|
|
#define KAIR_WINDOW_INF_MASK (0x8000000000000000UL)
|
|
#define KAIR_WINDOW_NEED_RESCALE (0x4000000000000000UL)
|
|
#define KAIR_WINDOW_SIZE_MASK (0x0FFFFFFF00000000UL)
|
|
#define KAIR_WINDOW_SIZE_SHIFT (32)
|
|
#define KAIR_WINDOW_CNT_MASK (0x000000000FFFFFFFUL)
|
|
|
|
/**
|
|
*
|
|
**/
|
|
#define KAIR_DEF_RAND_NEUTRAL (2)
|
|
#define KAIR_TRIGGER_THROTTLE (3)
|
|
#define KAIR_FASTEN_THROTTLE (-100)
|
|
|
|
/**
|
|
* 1-dimensional discrete indexing degree of randomness which correspondingly
|
|
* spans upto 64 skewness * 64 flatness long.
|
|
* randomness bitfield : | <-- skewness --> | <-- flatness(variance) --> |
|
|
**/
|
|
#define RAND_SKEW_SHIFT (8)
|
|
|
|
typedef int randomness;
|
|
|
|
/**
|
|
* Random integer variable for stochastic process
|
|
**/
|
|
struct rand_var {
|
|
int nval;
|
|
unsigned int ubound;
|
|
unsigned int lbound;
|
|
};
|
|
|
|
/**
|
|
* Random integer variable coordinators
|
|
**/
|
|
#define __RV_INITIALIZER() \
|
|
{ \
|
|
.nval = 0, \
|
|
.ubound = 0, \
|
|
.lbound = 0 \
|
|
}
|
|
|
|
#define RV_DECLARE(name) struct rand_var name = __RV_INITIALIZER()
|
|
|
|
/**
|
|
* @rv : random variable structure
|
|
* @num : signed number
|
|
* @ulimit : positive upper bound
|
|
* @llimit : positive lower bound
|
|
**/
|
|
#define RV_SET(rv, num, ulimit, llimit) \
|
|
({ \
|
|
rv.nval = (int)(num); \
|
|
rv.ubound = (unsigned int)(ulimit); \
|
|
rv.lbound = (unsigned int)(llimit); \
|
|
})
|
|
|
|
/* Stretching nval to fit given tpdf->qlvl and returning the proper index
|
|
* within >= 0 and < tpdf->qlvl.
|
|
*/
|
|
#define RV_TAILORED(pdf, rv) \
|
|
({ \
|
|
typeof((pdf) + 1) __pdf = (pdf); \
|
|
typeof((rv) + 1) __rv = (rv); \
|
|
int __nval; \
|
|
int __hscale = (int)__pdf->qlvl >> 1; \
|
|
int __ubound = (int)__rv->ubound; \
|
|
int __lbound = (int)__rv->lbound; \
|
|
__nval = (__rv->nval >= 0) ? \
|
|
(__ubound ? \
|
|
((__rv->nval * __hscale / __ubound) + __hscale) : \
|
|
__hscale) : \
|
|
(__lbound ? \
|
|
((__rv->nval * __hscale / __lbound) + __hscale) : \
|
|
__hscale); \
|
|
__nval; \
|
|
})
|
|
|
|
#define RV_SPAN(rv) \
|
|
({ \
|
|
typeof((rv) + 1) __rv = (rv); \
|
|
unsigned int __span = __rv->ubound + __rv->lbound; \
|
|
__span; \
|
|
})
|
|
|
|
/**
|
|
* TPDF(Temporal Probability Density Function) container class
|
|
**/
|
|
struct tpdf {
|
|
struct list_head pos;
|
|
unsigned int qlvl;
|
|
u64 win_size;
|
|
struct __tfifo cache;
|
|
unsigned int *qtbl;
|
|
unsigned int pc_cnt;
|
|
|
|
/**
|
|
* """ TPDF container methods list """
|
|
* @tabling : preparing qtbl
|
|
* @untabling : removing qtbl
|
|
* @rv_register : registration of corresponding rv
|
|
* @rv_unregister : moving rv
|
|
* @interpolator : calculating moderate value
|
|
* @equilibrator : rebalancing qtbl to maintain total PDF integral
|
|
* @rescaler : rescaling the whole PDF to have
|
|
**/
|
|
int (*tabling)(struct tpdf *self);
|
|
void (*untabling)(struct tpdf *self);
|
|
void (*rv_register)(struct tpdf *self, struct rand_var *rv);
|
|
void (*rv_unregister)(struct tpdf *self);
|
|
unsigned int (*interpolator)(struct tpdf *self, unsigned int tpos,
|
|
unsigned int rpos);
|
|
void (*equilibrator)(struct tpdf *self);
|
|
void (*rescaler)(struct tpdf *self);
|
|
|
|
randomness irand;
|
|
char alias[KAIR_ALIAS_LEN];
|
|
struct rand_var *rv;
|
|
unsigned int weight;
|
|
};
|
|
|
|
/**
|
|
* """ KAIR statistics """
|
|
* @choke_cnt : counting how much the event so-called bottleneck or
|
|
* momentary sluggish in ECAVE theory happened.
|
|
* @save_total : accumulating amount how much redundant capacity is saved.
|
|
* @rand_neutral : an argument used for running betting algorithm.
|
|
* @throttling : +- accumulation of continuous choke/relief events.
|
|
* 0 is neutral.
|
|
**/
|
|
struct kair_stats {
|
|
unsigned int choke_cnt;
|
|
long long save_total;
|
|
unsigned int rand_neutral;
|
|
int throttling;
|
|
};
|
|
|
|
/**
|
|
* KAIR instance kobject created per each kair_obj_creator() call by
|
|
* any client and will be used to register to sysfs.
|
|
**/
|
|
struct krinst_obj {
|
|
struct kobject obj;
|
|
struct kair_class *inst;
|
|
};
|
|
#define to_krinst_obj(x) container_of(x, struct krinst_obj, obj)
|
|
|
|
/**
|
|
* KAIR attribute customized for krinst_obj.
|
|
**/
|
|
struct krinst_attribute {
|
|
struct attribute attr;
|
|
ssize_t (*show)(struct krinst_obj *inst, struct krinst_attribute *attr, char *buf);
|
|
ssize_t (*store)(struct krinst_obj *inst, struct krinst_attribute *attr, const char *buf, size_t count);
|
|
};
|
|
#define to_krinst_attr(x) container_of(x, struct krinst_attribute, attr)
|
|
|
|
#define KRINST_ATTR_RO(__name) \
|
|
static struct krinst_attribute __name##_attr = __ATTR_RO(__name)
|
|
#define KRINST_ATTR_RW(__name) \
|
|
static struct krinst_attribute __name##_attr = __ATTR_RW(__name)
|
|
|
|
/**
|
|
* TODO: more studies may be required to apply an external training.
|
|
* Kairistics is experimentally determined, which describes the pair of integer
|
|
* ratios in consideration of the fixed scaling factor heuristically used in each
|
|
* client's legacy mechanism.
|
|
**/
|
|
struct kairistics {
|
|
unsigned int gamma_numer:8;
|
|
unsigned int gamma_denom:8;
|
|
unsigned int theta_numer:8;
|
|
unsigned int theta_denom:8;
|
|
};
|
|
|
|
#define DECLARE_KAIRISTICS(alias, gnumer, gdenum, tnumer, tdenum) \
|
|
static struct kairistics kairistic_##alias = { \
|
|
.gamma_numer = gnumer, \
|
|
.gamma_denom = gdenum, \
|
|
.theta_numer = tnumer, \
|
|
.theta_denom = tdenum, \
|
|
}
|
|
|
|
/**
|
|
* "" KAIR class description """
|
|
* Which is virtually integrating Elastic Capacity Vessel abstraction model
|
|
* applicable on arbitrary dynamic self resource control systems.
|
|
* All real numbered properties must be handled with integers through adequate
|
|
* conversion and quantization processes.
|
|
**/
|
|
struct kair_class {
|
|
struct list_head tpdf_cascade;
|
|
/**
|
|
* bit-shift representation of KAIR capacity denominator
|
|
* which is considered as the summation of each level's TPDF weight
|
|
* multiplied by maximum randomness.
|
|
**/
|
|
unsigned int capa_denom;
|
|
|
|
/**
|
|
* """ KAIR methods list """:
|
|
* @initializer : self-initializer
|
|
* @stopper : stopping to learn tpdf, cleaning up.
|
|
* @finalizer : returning all resources.
|
|
* @job_learner : learner of capacity-probability-density which is
|
|
* actually conducting exclusive on-device learning
|
|
* algorithm on the given capacity-random variable.
|
|
* @job_inferer : returns randomness index of the TPDF which is most
|
|
* resembling given TPDF.
|
|
* @cap_bettor : returns betting capacity estimated.
|
|
**/
|
|
int (*initializer)(struct kair_class *self);
|
|
void (*stopper)(struct kair_class *self);
|
|
void (*finalizer)(struct kair_class *self);
|
|
void (*job_learner)(struct kair_class *self, struct rand_var *v);
|
|
int (*job_inferer)(struct kair_class *self);
|
|
unsigned int (*cap_bettor)(struct kair_class *self, struct rand_var *v,
|
|
unsigned int cap_legecy);
|
|
|
|
struct kair_stats stats;
|
|
unsigned int df_velocity;
|
|
unsigned int resilience;
|
|
unsigned int ep_ratio;
|
|
unsigned int max_capa;
|
|
unsigned int min_capa;
|
|
unsigned int epsilon;
|
|
struct kairistics kairistic;
|
|
char alias[KAIR_ALIAS_LEN];
|
|
struct krinst_obj *extif;
|
|
};
|
|
|
|
/**
|
|
*
|
|
*
|
|
**/
|
|
extern int kair_tpdf_tabling(struct tpdf *self);
|
|
extern void kair_tpdf_untabling(struct tpdf *self);
|
|
extern void kair_tpdf_rv_register(struct tpdf *self, struct rand_var *rv);
|
|
extern void kair_tpdf_rv_unregister(struct tpdf *self);
|
|
extern unsigned int linear_interpolator(struct tpdf *self, unsigned int top_pos,
|
|
unsigned int raw_pos);
|
|
extern void kair_tpdf_equilibrator(struct tpdf *self);
|
|
extern void kair_tpdf_rescaler(struct tpdf *self);
|
|
|
|
#define tpdf_infinite_init(pdf, __tlevel) \
|
|
({ \
|
|
int __err = 0; \
|
|
typeof((pdf) + 1) __pdf = (pdf); \
|
|
sprintf(__pdf->alias, "%s_tpdf", #__tlevel); \
|
|
*__pdf = (struct tpdf) { \
|
|
.pos = LIST_HEAD_INIT(__pdf->pos), \
|
|
.qlvl = KAIR_QUANT_STEP, \
|
|
.win_size = KAIR_WINDOW_INF, \
|
|
.pc_cnt = 0, \
|
|
.irand = KAIR_DIVERGING, \
|
|
.weight = KAIR_INF_TPDF_WEIGHT, \
|
|
.cache = tfifo_init(&__pdf->cache), \
|
|
.tabling = kair_tpdf_tabling, \
|
|
.untabling = kair_tpdf_untabling, \
|
|
.rv_register = kair_tpdf_rv_register, \
|
|
.rv_unregister = kair_tpdf_rv_unregister, \
|
|
.interpolator = linear_interpolator, \
|
|
.equilibrator = kair_tpdf_equilibrator, \
|
|
.rescaler = kair_tpdf_rescaler, \
|
|
}; \
|
|
__err = __pdf->tabling(__pdf); \
|
|
__err; \
|
|
})
|
|
|
|
#define tpdf_finite_init(pdf, __tlevel, period) \
|
|
({ \
|
|
int __err = 0; \
|
|
typeof((pdf) + 1) __pdf = (pdf); \
|
|
sprintf(__pdf->alias, "%s_tpdf", #__tlevel); \
|
|
*__pdf = (struct tpdf) { \
|
|
.pos = LIST_HEAD_INIT(__pdf->pos), \
|
|
.qlvl = KAIR_QUANT_STEP, \
|
|
.win_size = ((u64)period << KAIR_WINDOW_SIZE_SHIFT) | \
|
|
KAIR_WINDOW_NEED_RESCALE, \
|
|
.pc_cnt = 0, \
|
|
.irand = KAIR_DIVERGING, \
|
|
.weight = KAIR_FIN_TPDF_WEIGHT, \
|
|
.cache = tfifo_init(&__pdf->cache), \
|
|
.tabling = kair_tpdf_tabling, \
|
|
.untabling = kair_tpdf_untabling, \
|
|
.rv_register = kair_tpdf_rv_register, \
|
|
.rv_unregister = kair_tpdf_rv_unregister, \
|
|
.interpolator = linear_interpolator, \
|
|
.equilibrator = kair_tpdf_equilibrator, \
|
|
.rescaler = kair_tpdf_rescaler, \
|
|
}; \
|
|
__err = __pdf->tabling(__pdf); \
|
|
__err; \
|
|
})
|
|
|
|
#define tpdf_instant_init(pdf, __tlevel, period) \
|
|
({ \
|
|
int __err = 0; \
|
|
typeof((pdf) + 1) __pdf = (pdf); \
|
|
sprintf(__pdf->alias, "%s_tpdf", #__tlevel); \
|
|
*__pdf = (struct tpdf) { \
|
|
.pos = LIST_HEAD_INIT(__pdf->pos), \
|
|
.qlvl = KAIR_QUANT_STEP, \
|
|
.win_size = ((u64)period << KAIR_WINDOW_SIZE_SHIFT), \
|
|
.pc_cnt = 0, \
|
|
.irand = KAIR_DIVERGING, \
|
|
.weight = KAIR_INST_TPDF_WEIGHT, \
|
|
.cache = tfifo_init(&__pdf->cache), \
|
|
.tabling = kair_tpdf_tabling, \
|
|
.untabling = kair_tpdf_untabling, \
|
|
.rv_register = kair_tpdf_rv_register, \
|
|
.rv_unregister = kair_tpdf_rv_unregister, \
|
|
.interpolator = linear_interpolator, \
|
|
.equilibrator = kair_tpdf_equilibrator, \
|
|
.rescaler = kair_tpdf_rescaler, \
|
|
}; \
|
|
__err = __pdf->tabling(__pdf); \
|
|
__err; \
|
|
})
|
|
|
|
/**
|
|
* @kair_l1_pdf_init() : instant generative TPDF covering only about past 1 second.
|
|
* @kair_l2_pdf_init() : generative TPDF convering only about past 1 minute.
|
|
* @kair_l3_pdf_init() : ever lasting generative TPDF
|
|
**/
|
|
#define kair_l1_pdf_init(pdf) tpdf_instant_init((pdf), l1, KAIR_TPDF_CUMSUM)
|
|
#define kair_l2_pdf_init(pdf) tpdf_finite_init((pdf), l2, KAIR_TPDF_CUMSUM << 1)
|
|
#define kair_l3_pdf_init(pdf) tpdf_infinite_init((pdf), l3)
|
|
|
|
/**
|
|
* KAIR window information extractors
|
|
**/
|
|
#define is_kair_window_infty(pdf) \
|
|
({ \
|
|
typeof((pdf) + 1) __pdf = (pdf); \
|
|
(__pdf->win_size & KAIR_WINDOW_INF_MASK); \
|
|
})
|
|
|
|
#define kair_window_size(pdf) \
|
|
({ \
|
|
typeof((pdf) + 1) __pdf = (pdf); \
|
|
((__pdf->win_size & KAIR_WINDOW_SIZE_MASK) >> KAIR_WINDOW_SIZE_SHIFT); \
|
|
})
|
|
|
|
#define kair_windowing_cnt(pdf) \
|
|
({ \
|
|
typeof((pdf) + 1) __pdf = (pdf); \
|
|
(__pdf->win_size & KAIR_WINDOW_CNT_MASK); \
|
|
})
|
|
|
|
#define kair_window_need_rescale(pdf) \
|
|
({ \
|
|
typeof((pdf) + 1) __pdf = (pdf); \
|
|
(__pdf->win_size & KAIR_WINDOW_NEED_RESCALE); \
|
|
})
|
|
|
|
#define kair_window_rescale_done(pdf) \
|
|
({ \
|
|
typeof((pdf) + 1) __pdf = (pdf); \
|
|
__pdf->win_size &= ~KAIR_WINDOW_NEED_RESCALE; \
|
|
})
|
|
|
|
/*.............................................................................
|
|
*.............................................................................
|
|
*................ """ KAIR Major External interfaces """ ....................
|
|
*.............................................................................
|
|
*...........................................................................*/
|
|
|
|
struct kair_class *kair_obj_creator(const char *alias,
|
|
unsigned int resilience,
|
|
unsigned int max_capa,
|
|
unsigned int min_capa,
|
|
struct kairistics *kairistic);
|
|
void kair_obj_destructor(struct kair_class *self); |