@ -1,4 +1,4 @@
#!/usr/bin/env python2.7
#!/usr/bin/env python3
# Copyright 2017 gRPC authors.
#
@ -14,6 +14,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import collections
import ctypes
import json
@ -34,10 +36,11 @@ def make_type(name, fields):
def c_str ( s , encoding = ' ascii ' ) :
if isinstance ( s , unicode ) :
if isinstance ( s , str ) :
s = s . encode ( encoding )
result = ' '
for c in s :
c = chr ( c ) if isinstance ( c , int ) else c
if not ( 32 < = ord ( c ) < 127 ) or c in ( ' \\ ' , ' " ' ) :
result + = ' \\ %03o ' % ord ( c )
else :
@ -81,7 +84,7 @@ def shift_works_until(mapped_bounds, shift_bits):
def find_ideal_shift ( mapped_bounds , max_size ) :
best = None
for shift_bits in reversed ( range ( 0 , 64 ) ) :
for shift_bits in reversed ( list ( range ( 0 , 64 ) ) ) :
n = shift_works_until ( mapped_bounds , shift_bits )
if n == 0 :
continue
@ -94,16 +97,16 @@ def find_ideal_shift(mapped_bounds, max_size):
best = ( shift_bits , n , table_size )
elif best [ 1 ] < n :
best = ( shift_bits , n , table_size )
print best
print ( best )
return best
def gen_map_table ( mapped_bounds , shift_data ) :
tbl = [ ]
cur = 0
print mapped_bounds
print ( mapped_bounds )
mapped_bounds = [ x >> shift_data [ 0 ] for x in mapped_bounds ]
print mapped_bounds
print ( mapped_bounds )
for i in range ( 0 , mapped_bounds [ shift_data [ 1 ] - 1 ] ) :
while i > mapped_bounds [ cur ] :
cur + = 1
@ -120,7 +123,7 @@ def decl_static_table(values, type):
for i , vp in enumerate ( static_tables ) :
if v == vp :
return i
print " ADD TABLE: %s %r " % ( type , values )
print ( " ADD TABLE: %s %r " % ( type , values ) )
r = len ( static_tables )
static_tables . append ( v )
return r
@ -205,11 +208,11 @@ def gen_bucket_code(histogram):
# utility: print a big comment block into a set of files
def put_banner ( files , banner ) :
for f in files :
print >> f , ' /* '
print ( ' /* ' , file = f )
for line in banner :
print >> f , ' * %s ' % line
print >> f , ' */ '
print >> f
print ( ' * %s ' % line , file = f )
print ( ' */ ' , file = f )
print ( file = f )
with open ( ' src/core/lib/debug/stats_data.h ' , ' w ' ) as H :
@ -233,77 +236,90 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H:
[ H ] ,
[ " Automatically generated by tools/codegen/core/gen_stats_data.py " ] )
print >> H , " #ifndef GRPC_CORE_LIB_DEBUG_STATS_DATA_H "
print >> H , " #define GRPC_CORE_LIB_DEBUG_STATS_DATA_H "
print >> H
print >> H , " #include <grpc/support/port_platform.h> "
print >> H
print >> H , " #include <inttypes.h> "
print >> H , " #include \" src/core/lib/iomgr/exec_ctx.h \" "
print >> H
print ( " #ifndef GRPC_CORE_LIB_DEBUG_STATS_DATA_H " , file = H )
print ( " #define GRPC_CORE_LIB_DEBUG_STATS_DATA_H " , file = H )
print ( file = H )
print ( " #include <grpc/support/port_platform.h> " , file = H )
print ( file = H )
print ( " #include <inttypes.h> " , file = H )
print ( " #include \" src/core/lib/iomgr/exec_ctx.h \" " , file = H )
print ( file = H )
for typename , instances in sorted ( inst_map . items ( ) ) :
print >> H , " typedef enum { "
print ( " typedef enum { " , file = H )
for inst in instances :
print >> H , " GRPC_STATS_ %s _ %s , " % ( typename . upper ( ) ,
inst . name . upper ( ) )
print >> H , " GRPC_STATS_ %s _COUNT " % ( typename . upper ( ) )
print >> H , " } grpc_stats_ %s s; " % ( typename . lower ( ) )
print >> H , " extern const char *grpc_stats_ %s _name[GRPC_STATS_ %s _COUNT]; " % (
typename . lower ( ) , typename . upper ( ) )
print >> H , " extern const char *grpc_stats_ %s _doc[GRPC_STATS_ %s _COUNT]; " % (
typename . lower ( ) , typename . upper ( ) )
print ( " GRPC_STATS_ %s _ %s , " % ( typename . upper ( ) , inst . name . upper ( ) ) ,
file = H )
print ( " GRPC_STATS_ %s _COUNT " % ( typename . upper ( ) ) , file = H )
print ( " } grpc_stats_ %s s; " % ( typename . lower ( ) ) , file = H )
print ( " extern const char *grpc_stats_ %s _name[GRPC_STATS_ %s _COUNT]; " %
( typename . lower ( ) , typename . upper ( ) ) ,
file = H )
print ( " extern const char *grpc_stats_ %s _doc[GRPC_STATS_ %s _COUNT]; " %
( typename . lower ( ) , typename . upper ( ) ) ,
file = H )
histo_start = [ ]
histo_buckets = [ ]
histo_bucket_boundaries = [ ]
print >> H , " typedef enum { "
print ( " typedef enum { " , file = H )
first_slot = 0
for histogram in inst_map [ ' Histogram ' ] :
histo_start . append ( first_slot )
histo_buckets . append ( histogram . buckets )
print >> H , " GRPC_STATS_HISTOGRAM_ %s _FIRST_SLOT = %d , " % (
histogram . name . upper ( ) , first_slot )
print >> H , " GRPC_STATS_HISTOGRAM_ %s _BUCKETS = %d , " % (
histogram . name . upper ( ) , histogram . buckets )
print ( " GRPC_STATS_HISTOGRAM_ %s _FIRST_SLOT = %d , " %
( histogram . name . upper ( ) , first_slot ) ,
file = H )
print ( " GRPC_STATS_HISTOGRAM_ %s _BUCKETS = %d , " %
( histogram . name . upper ( ) , histogram . buckets ) ,
file = H )
first_slot + = histogram . buckets
print >> H , " GRPC_STATS_HISTOGRAM_BUCKETS = %d " % first_slot
print >> H , " } grpc_stats_histogram_constants; "
print ( " GRPC_STATS_HISTOGRAM_BUCKETS = %d " % first_slot , file = H )
print ( " } grpc_stats_histogram_constants; " , file = H )
print >> H , " #if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) "
print ( " #if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) " , file = H )
for ctr in inst_map [ ' Counter ' ] :
print >> H , ( " #define GRPC_STATS_INC_ %s () " +
" GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_ %s ) " ) % (
ctr . name . upper ( ) , ctr . name . upper ( ) )
print ( ( " #define GRPC_STATS_INC_ %s () " +
" GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_ %s ) " ) %
( ctr . name . upper ( ) , ctr . name . upper ( ) ) ,
file = H )
for histogram in inst_map [ ' Histogram ' ] :
print >> H , " #define GRPC_STATS_INC_ %s (value) grpc_stats_inc_ %s ( (int)(value)) " % (
histogram . name . upper ( ) , histogram . name . lower ( ) )
print >> H , " void grpc_stats_inc_ %s (int x); " % histogram . name . lower ( )
print (
" #define GRPC_STATS_INC_ %s (value) grpc_stats_inc_ %s ( (int)(value)) "
% ( histogram . name . upper ( ) , histogram . name . lower ( ) ) ,
file = H )
print ( " void grpc_stats_inc_ %s (int x); " % histogram . name . lower ( ) , file = H )
print >> H , " #else "
print ( " #else " , file = H )
for ctr in inst_map [ ' Counter ' ] :
print >> H , ( " #define GRPC_STATS_INC_ %s () " ) % ( ctr . name . upper ( ) )
print ( ( " #define GRPC_STATS_INC_ %s () " ) % ( ctr . name . upper ( ) ) , file = H )
for histogram in inst_map [ ' Histogram ' ] :
print >> H , " #define GRPC_STATS_INC_ %s (value) " % (
histogram . name . upper ( ) )
print >> H , " #endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */ "
print ( " #define GRPC_STATS_INC_ %s (value) " % ( histogram . name . upper ( ) ) ,
file = H )
print ( " #endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */ " ,
file = H )
for i , tbl in enumerate ( static_tables ) :
print >> H , " extern const %s grpc_stats_table_ %d [ %d ]; " % ( tbl [ 0 ] , i ,
len ( tbl [ 1 ] ) )
print >> H , " extern const int grpc_stats_histo_buckets[ %d ]; " % len (
inst_map [ ' Histogram ' ] )
print >> H , " extern const int grpc_stats_histo_start[ %d ]; " % len (
inst_map [ ' Histogram ' ] )
print >> H , " extern const int *const grpc_stats_histo_bucket_boundaries[ %d ]; " % len (
inst_map [ ' Histogram ' ] )
print >> H , " extern void (*const grpc_stats_inc_histogram[ %d ])(int x); " % len (
inst_map [ ' Histogram ' ] )
print >> H
print >> H , " #endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */ "
print ( " extern const %s grpc_stats_table_ %d [ %d ]; " %
( tbl [ 0 ] , i , len ( tbl [ 1 ] ) ) ,
file = H )
print ( " extern const int grpc_stats_histo_buckets[ %d ]; " %
len ( inst_map [ ' Histogram ' ] ) ,
file = H )
print ( " extern const int grpc_stats_histo_start[ %d ]; " %
len ( inst_map [ ' Histogram ' ] ) ,
file = H )
print ( " extern const int *const grpc_stats_histo_bucket_boundaries[ %d ]; " %
len ( inst_map [ ' Histogram ' ] ) ,
file = H )
print ( " extern void (*const grpc_stats_inc_histogram[ %d ])(int x); " %
len ( inst_map [ ' Histogram ' ] ) ,
file = H )
print ( file = H )
print ( " #endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */ " , file = H )
with open ( ' src/core/lib/debug/stats_data.cc ' , ' w ' ) as C :
# copy-paste copyright notice from this file
@ -326,13 +342,13 @@ with open('src/core/lib/debug/stats_data.cc', 'w') as C:
[ C ] ,
[ " Automatically generated by tools/codegen/core/gen_stats_data.py " ] )
print >> C , " #include <grpc/support/port_platform.h> "
print >> C
print >> C , " #include \" src/core/lib/debug/stats.h \" "
print >> C , " #include \" src/core/lib/debug/stats_data.h \" "
print >> C , " #include \" src/core/lib/gpr/useful.h \" "
print >> C , " #include \" src/core/lib/iomgr/exec_ctx.h \" "
print >> C
print ( " #include <grpc/support/port_platform.h> " , file = C )
print ( file = C )
print ( " #include \" src/core/lib/debug/stats.h \" " , file = C )
print ( " #include \" src/core/lib/debug/stats_data.h \" " , file = C )
print ( " #include \" src/core/lib/gpr/useful.h \" " , file = C )
print ( " #include \" src/core/lib/iomgr/exec_ctx.h \" " , file = C )
print ( file = C )
histo_code = [ ]
for histogram in inst_map [ ' Histogram ' ] :
@ -341,36 +357,45 @@ with open('src/core/lib/debug/stats_data.cc', 'w') as C:
histo_code . append ( code )
for typename , instances in sorted ( inst_map . items ( ) ) :
print >> C , " const char *grpc_stats_ %s _name[GRPC_STATS_ %s _COUNT] = { " % (
typename . lower ( ) , typename . upper ( ) )
print ( " const char *grpc_stats_ %s _name[GRPC_STATS_ %s _COUNT] = { " %
( typename . lower ( ) , typename . upper ( ) ) ,
file = C )
for inst in instances :
print >> C , " %s , " % c_str ( inst . name )
print >> C , " }; "
print >> C , " const char *grpc_stats_ %s _doc[GRPC_STATS_ %s _COUNT] = { " % (
typename . lower ( ) , typename . upper ( ) )
print ( " %s , " % c_str ( inst . name ) , file = C )
print ( " }; " , file = C )
print ( " const char *grpc_stats_ %s _doc[GRPC_STATS_ %s _COUNT] = { " %
( typename . lower ( ) , typename . upper ( ) ) ,
file = C )
for inst in instances :
print >> C , " %s , " % c_str ( inst . doc )
print >> C , " }; "
print ( " %s , " % c_str ( inst . doc ) , file = C )
print ( " }; " , file = C )
for i , tbl in enumerate ( static_tables ) :
print >> C , " const %s grpc_stats_table_ %d [ %d ] = { %s }; " % (
tbl [ 0 ] , i , len ( tbl [ 1 ] ) , ' , ' . join ( ' %s ' % x for x in tbl [ 1 ] ) )
print ( " const %s grpc_stats_table_ %d [ %d ] = { %s }; " %
( tbl [ 0 ] , i , len ( tbl [ 1 ] ) , ' , ' . join ( ' %s ' % x for x in tbl [ 1 ] ) ) ,
file = C )
for histogram , code in zip ( inst_map [ ' Histogram ' ] , histo_code ) :
print >> C , ( " void grpc_stats_inc_ %s (int value) { %s } " ) % (
histogram . name . lower ( ) , code )
print >> C , " const int grpc_stats_histo_buckets[ %d ] = { %s }; " % ( len (
inst_map [ ' Histogram ' ] ) , ' , ' . join ( ' %s ' % x for x in histo_buckets ) )
print >> C , " const int grpc_stats_histo_start[ %d ] = { %s }; " % ( len (
inst_map [ ' Histogram ' ] ) , ' , ' . join ( ' %s ' % x for x in histo_start ) )
print >> C , " const int *const grpc_stats_histo_bucket_boundaries[ %d ] = { %s }; " % (
len ( inst_map [ ' Histogram ' ] ) , ' , ' . join (
' grpc_stats_table_ %d ' % x for x in histo_bucket_boundaries ) )
print >> C , " void (*const grpc_stats_inc_histogram[ %d ])(int x) = { %s }; " % (
len ( inst_map [ ' Histogram ' ] ) , ' , ' . join (
' grpc_stats_inc_ %s ' % histogram . name . lower ( )
for histogram in inst_map [ ' Histogram ' ] ) )
print ( ( " void grpc_stats_inc_ %s (int value) { %s } " ) %
( histogram . name . lower ( ) , code ) ,
file = C )
print (
" const int grpc_stats_histo_buckets[ %d ] = { %s }; " %
( len ( inst_map [ ' Histogram ' ] ) , ' , ' . join ( ' %s ' % x for x in histo_buckets ) ) ,
file = C )
print ( " const int grpc_stats_histo_start[ %d ] = { %s }; " %
( len ( inst_map [ ' Histogram ' ] ) , ' , ' . join ( ' %s ' % x for x in histo_start ) ) ,
file = C )
print ( " const int *const grpc_stats_histo_bucket_boundaries[ %d ] = { %s }; " %
( len ( inst_map [ ' Histogram ' ] ) , ' , ' . join (
' grpc_stats_table_ %d ' % x for x in histo_bucket_boundaries ) ) ,
file = C )
print ( " void (*const grpc_stats_inc_histogram[ %d ])(int x) = { %s }; " %
( len ( inst_map [ ' Histogram ' ] ) , ' , ' . join (
' grpc_stats_inc_ %s ' % histogram . name . lower ( )
for histogram in inst_map [ ' Histogram ' ] ) ) ,
file = C )
# patch qps_test bigquery schema
RECORD_EXPLICIT_PERCENTILES = [ 50 , 95 , 99 ]
@ -438,39 +463,56 @@ with open('tools/run_tests/performance/massage_qps_stats.py', 'w') as P:
break
for line in my_source :
if line [ 0 ] == ' # ' :
print >> P , line . rstrip ( )
print ( line . rstrip ( ) , file = P )
break
for line in my_source :
if line [ 0 ] != ' # ' :
break
print >> P , line . rstrip ( )
print >> P
print >> P , ' # Autogenerated by tools/codegen/core/gen_stats_data.py '
print >> P
print >> P , ' import massage_qps_stats_helpers '
print >> P , ' def massage_qps_stats(scenario_result): '
print >> P , ' for stats in scenario_result[ " serverStats " ] + scenario_result[ " clientStats " ]: '
print >> P , ' if " coreStats " in stats: '
print >> P , ' # Get rid of the " coreStats " element and replace it by statistics '
print >> P , ' # that correspond to columns in the bigquery schema. '
print >> P , ' core_stats = stats[ " coreStats " ] '
print >> P , ' del stats[ " coreStats " ] '
print ( line . rstrip ( ) , file = P )
print ( file = P )
print ( ' # Autogenerated by tools/codegen/core/gen_stats_data.py ' , file = P )
print ( file = P )
print ( ' import massage_qps_stats_helpers ' , file = P )
print ( ' def massage_qps_stats(scenario_result): ' , file = P )
print (
' for stats in scenario_result[ " serverStats " ] + scenario_result[ " clientStats " ]: ' ,
file = P )
print ( ' if " coreStats " in stats: ' , file = P )
print (
' # Get rid of the " coreStats " element and replace it by statistics ' ,
file = P )
print ( ' # that correspond to columns in the bigquery schema. ' , file = P )
print ( ' core_stats = stats[ " coreStats " ] ' , file = P )
print ( ' del stats[ " coreStats " ] ' , file = P )
for counter in inst_map [ ' Counter ' ] :
print >> P , ' stats[ " core_ %s " ] = massage_qps_stats_helpers.counter(core_stats, " %s " ) ' % (
counter . name , counter . name )
print (
' stats[ " core_ %s " ] = massage_qps_stats_helpers.counter(core_stats, " %s " ) '
% ( counter . name , counter . name ) ,
file = P )
for i , histogram in enumerate ( inst_map [ ' Histogram ' ] ) :
print >> P , ' h = massage_qps_stats_helpers.histogram(core_stats, " %s " ) ' % histogram . name
print >> P , ' stats[ " core_ %s " ] = " , " .join( " %% f " %% x for x in h.buckets) ' % histogram . name
print >> P , ' stats[ " core_ %s _bkts " ] = " , " .join( " %% f " %% x for x in h.boundaries) ' % histogram . name
print (
' h = massage_qps_stats_helpers.histogram(core_stats, " %s " ) ' %
histogram . name ,
file = P )
print (
' stats[ " core_ %s " ] = " , " .join( " %% f " %% x for x in h.buckets) ' %
histogram . name ,
file = P )
print (
' stats[ " core_ %s _bkts " ] = " , " .join( " %% f " %% x for x in h.boundaries) '
% histogram . name ,
file = P )
for pctl in RECORD_EXPLICIT_PERCENTILES :
print >> P , ' stats[ " core_ %s _ %d p " ] = massage_qps_stats_helpers.percentile(h.buckets, %d , h.boundaries) ' % (
histogram . name , pctl , pctl )
print (
' stats[ " core_ %s _ %d p " ] = massage_qps_stats_helpers.percentile(h.buckets, %d , h.boundaries) '
% ( histogram . name , pctl , pctl ) ,
file = P )
with open ( ' src/core/lib/debug/stats_data_bq_schema.sql ' , ' w ' ) as S :
columns = [ ]
for counter in inst_map [ ' Counter ' ] :
columns . append ( ( ' %s _per_iteration ' % counter . name , ' FLOAT ' ) )
print >> S , ' , \n ' . join ( ' %s : %s ' % x for x in columns )
print ( ' , \n ' . join ( ' %s : %s ' % x for x in columns ) , file = S )