@ -93,6 +93,29 @@ void DownpourWorker::Initialize(const TrainerDesc& desc) {
for ( int i = 0 ; i < desc . check_nan_var_names_size ( ) ; + + i ) {
check_nan_var_names_ . push_back ( desc . check_nan_var_names ( i ) ) ;
}
copy_table_config_ = desc . copy_table_config ( ) ;
for ( int i = 0 ; i < copy_table_config_ . src_sparse_tables_size ( ) ; + + i ) {
uint64_t src_table = copy_table_config_ . src_sparse_tables ( i ) ;
uint64_t dest_table = copy_table_config_ . dest_sparse_tables ( i ) ;
VLOG ( 3 ) < < " copy_sparse_tables_ push back " < < src_table < < " -> "
< < dest_table ;
copy_sparse_tables_ . push_back ( std : : make_pair ( src_table , dest_table ) ) ;
}
for ( int i = 0 ; i < copy_table_config_ . src_dense_tables_size ( ) ; + + i ) {
uint64_t src_table = copy_table_config_ . src_dense_tables ( i ) ;
uint64_t dest_table = copy_table_config_ . dest_dense_tables ( i ) ;
VLOG ( 3 ) < < " copy_dense_tables_ push back " < < src_table < < " -> "
< < dest_table ;
copy_dense_tables_ . push_back ( std : : make_pair ( src_table , dest_table ) ) ;
}
for ( auto & m : copy_table_config_ . table_denpendency_map ( ) ) {
if ( sparse_key_names_ . find ( m . key ( ) ) ! = sparse_key_names_ . end ( ) ) {
// currently only support one dependency
for ( auto & value : m . values ( ) ) {
table_dependency_ [ m . key ( ) ] = value ;
}
}
}
}
void DownpourWorker : : SetChannelWriter ( ChannelObject < std : : string > * queue ) {
@ -404,6 +427,102 @@ void DownpourWorker::AdjustInsWeight() {
# endif
}
void DownpourWorker : : CopySparseTable ( ) {
for ( size_t i = 0 ; i < copy_sparse_tables_ . size ( ) ; + + i ) {
int64_t src_table = copy_sparse_tables_ [ i ] . first ;
int64_t dest_table = copy_sparse_tables_ [ i ] . second ;
int32_t feanum = 0 ;
if ( src_table = = dest_table ) {
continue ;
} else if ( ! copy_table_config_ . sparse_copy_by_feasign ( ) ) {
if ( feasign_set_ . find ( src_table ) = = feasign_set_ . end ( ) ) {
continue ;
} else if ( feasign_set_ [ src_table ] . size ( ) = = 0 ) {
continue ;
}
feanum = fleet_ptr_ - > CopyTable ( src_table , dest_table ) ;
} else {
std : : vector < uint64_t > fea_vec ( feasign_set_ [ src_table ] . begin ( ) ,
feasign_set_ [ src_table ] . end ( ) ) ;
feanum = fleet_ptr_ - > CopyTableByFeasign ( src_table , dest_table , fea_vec ) ;
fea_vec . clear ( ) ;
std : : vector < uint64_t > ( ) . swap ( fea_vec ) ;
}
VLOG ( 3 ) < < " copy feasign from table " < < src_table < < " to table "
< < dest_table < < " , feasign num= " < < feanum ;
feasign_set_ [ src_table ] . clear ( ) ;
std : : unordered_set < uint64_t > ( ) . swap ( feasign_set_ [ src_table ] ) ;
}
feasign_set_ . clear ( ) ;
}
void DownpourWorker : : CopyDenseTable ( ) {
if ( thread_id_ ! = 0 ) {
return ;
}
thread_local std : : vector < std : : future < int32_t > > pull_dense_status ;
for ( size_t i = 0 ; i < copy_dense_tables_ . size ( ) ; + + i ) {
uint64_t src_table = copy_dense_tables_ [ i ] . first ;
uint64_t dest_table = copy_dense_tables_ [ i ] . second ;
if ( src_table = = dest_table ) {
continue ;
}
int32_t dim = fleet_ptr_ - > CopyTable ( src_table , dest_table ) ;
VLOG ( 3 ) < < " copy param from table " < < src_table < < " to table "
< < dest_table < < " , dim= " < < dim ;
if ( copy_table_config_ . dense_pull_after_copy ( ) ) {
VLOG ( 3 ) < < " dense pull after copy, table= " < < dest_table ;
pull_dense_status . resize ( 0 ) ;
fleet_ptr_ - > PullDenseVarsAsync ( * root_scope_ , dest_table ,
dense_value_names_ [ dest_table ] ,
& pull_dense_status ) ;
for ( auto & t : pull_dense_status ) {
t . wait ( ) ;
auto status = t . get ( ) ;
if ( status ! = 0 ) {
LOG ( WARNING ) < < " pull dense after copy table failed, "
< < " table= " < < dest_table ;
}
}
}
}
}
void DownpourWorker : : CopyDenseVars ( ) {
if ( thread_id_ ! = 0 ) {
return ;
}
for ( int i = 0 ; i < copy_table_config_ . src_var_list_size ( ) ; + + i ) {
auto & src_var_name = copy_table_config_ . src_var_list ( i ) ;
auto & dest_var_name = copy_table_config_ . dest_var_list ( i ) ;
if ( src_var_name = = dest_var_name ) {
continue ;
}
VLOG ( 3 ) < < " copy dense var from " < < src_var_name < < " to "
< < dest_var_name ;
Variable * src_var = thread_scope_ - > FindVar ( src_var_name ) ;
CHECK ( src_var ! = nullptr ) < < src_var_name < < " not found " ; // NOLINT
LoDTensor * src_tensor = src_var - > GetMutable < LoDTensor > ( ) ;
CHECK ( src_tensor ! = nullptr ) < < src_var_name
< < " tensor is null " ; // NOLINT
float * src_data = src_tensor - > data < float > ( ) ;
Variable * dest_var = thread_scope_ - > FindVar ( dest_var_name ) ;
CHECK ( dest_var ! = nullptr ) < < dest_var_name < < " not found " ; // NOLINT
LoDTensor * dest_tensor = dest_var - > GetMutable < LoDTensor > ( ) ;
CHECK ( dest_tensor ! = nullptr ) < < dest_var_name
< < " tensor is null " ; // NOLINT
float * dest_data = dest_tensor - > data < float > ( ) ;
CHECK ( src_tensor - > numel ( ) = = dest_tensor - > numel ( ) )
< < " tensor numel not equal, " < < src_tensor - > numel ( ) < < " vs "
< < dest_tensor - > numel ( ) ;
for ( int i = 0 ; i < src_tensor - > numel ( ) ; i + + ) {
dest_data [ i ] = src_data [ i ] ;
}
}
}
void DownpourWorker : : TrainFilesWithProfiler ( ) {
VLOG ( 3 ) < < " Begin to train files with profiler " ;
platform : : SetNumThreads ( 1 ) ;
@ -437,6 +556,7 @@ void DownpourWorker::TrainFilesWithProfiler() {
double fill_sparse_time = 0.0 ;
double push_sparse_time = 0.0 ;
double push_dense_time = 0.0 ;
double copy_table_time = 0.0 ;
int cur_batch ;
int batch_cnt = 0 ;
uint64_t total_inst = 0 ;
@ -445,6 +565,27 @@ void DownpourWorker::TrainFilesWithProfiler() {
timeline . Pause ( ) ;
read_time + = timeline . ElapsedSec ( ) ;
total_time + = timeline . ElapsedSec ( ) ;
timeline . Start ( ) ;
if ( copy_table_config_ . need_copy ( ) ) {
VLOG ( 3 ) < < " copy_sparse_tables_.size " < < copy_sparse_tables_ . size ( ) ;
if ( copy_table_config_ . sparse_copy_by_feasign ( ) ) {
for ( size_t i = 0 ; i < copy_sparse_tables_ . size ( ) ; + + i ) {
uint64_t tid = copy_sparse_tables_ [ i ] . first ;
feasign_set_ [ tid ] . insert ( sparse_push_keys_ [ tid ] . begin ( ) ,
sparse_push_keys_ [ tid ] . end ( ) ) ;
}
}
if ( batch_cnt % copy_table_config_ . batch_num ( ) = = 0 ) {
CopySparseTable ( ) ;
CopyDenseTable ( ) ;
CopyDenseVars ( ) ;
}
}
timeline . Pause ( ) ;
copy_table_time + = timeline . ElapsedSec ( ) ;
total_time + = timeline . ElapsedSec ( ) ;
VLOG ( 3 ) < < " program config size: " < < param_ . program_config_size ( ) ;
for ( int i = 0 ; i < param_ . program_config ( 0 ) . pull_sparse_table_id_size ( ) ;
+ + i ) {
@ -641,6 +782,7 @@ void DownpourWorker::TrainFilesWithProfiler() {
collect_label_time / batch_cnt ) ;
fprintf ( stderr , " adjust ins weight time: %fs \n " ,
adjust_ins_weight_time / batch_cnt ) ;
fprintf ( stderr , " copy table time: %fs \n " , copy_table_time / batch_cnt ) ;
fprintf ( stderr , " mean read time: %fs \n " , read_time / batch_cnt ) ;
fprintf ( stderr , " IO percent: %f \n " , read_time / total_time * 100 ) ;
fprintf ( stderr , " op run percent: %f \n " , op_sum_time / total_time * 100 ) ;
@ -648,6 +790,8 @@ void DownpourWorker::TrainFilesWithProfiler() {
pull_sparse_time / total_time * 100 ) ;
fprintf ( stderr , " adjust ins weight time percent: %f \n " ,
adjust_ins_weight_time / total_time * 100 ) ;
fprintf ( stderr , " copy table time percent: %f \n " ,
copy_table_time / total_time * 100 ) ;
fprintf ( stderr , " collect label time percent: %f \n " ,
collect_label_time / total_time * 100 ) ;
fprintf ( stderr , " fill sparse time percent: %f \n " ,
@ -661,6 +805,11 @@ void DownpourWorker::TrainFilesWithProfiler() {
}
timeline . Start ( ) ;
}
if ( copy_table_config_ . need_copy ( ) ) {
CopySparseTable ( ) ;
CopyDenseTable ( ) ;
CopyDenseVars ( ) ;
}
}
void DownpourWorker : : TrainFiles ( ) {
@ -670,6 +819,20 @@ void DownpourWorker::TrainFiles() {
int batch_cnt = 0 ;
int cur_batch ;
while ( ( cur_batch = device_reader_ - > Next ( ) ) > 0 ) {
if ( copy_table_config_ . need_copy ( ) ) {
if ( copy_table_config_ . sparse_copy_by_feasign ( ) ) {
for ( size_t i = 0 ; i < copy_sparse_tables_ . size ( ) ; + + i ) {
uint64_t tid = copy_sparse_tables_ [ i ] . first ;
feasign_set_ [ tid ] . insert ( sparse_push_keys_ [ tid ] . begin ( ) ,
sparse_push_keys_ [ tid ] . end ( ) ) ;
}
}
if ( batch_cnt % copy_table_config_ . batch_num ( ) = = 0 ) {
CopySparseTable ( ) ;
CopyDenseTable ( ) ;
CopyDenseVars ( ) ;
}
}
// pull sparse here
for ( int i = 0 ; i < param_ . program_config ( 0 ) . pull_sparse_table_id_size ( ) ;
+ + i ) {
@ -850,6 +1013,11 @@ void DownpourWorker::TrainFiles() {
if ( need_dump_field_ ) {
writer_ . Flush ( ) ;
}
if ( copy_table_config_ . need_copy ( ) ) {
CopySparseTable ( ) ;
CopyDenseTable ( ) ;
CopyDenseVars ( ) ;
}
}
} // end namespace framework