src/ftp.c
ftp_parameters_reuse* preform_ftp_reuse(network_parameters* net_para, ftp_parameters* ftp_para){
   int32_t i, j, l;
   uint32_t task;

   ftp_parameters_reuse* ftp_para_reuse = (ftp_parameters_reuse*)malloc(sizeof(ftp_parameters_reuse));
   ftp_para_reuse->partitions = ftp_para->partitions;
   ftp_para_reuse->partitions_h = ftp_para->partitions_h;
   ftp_para_reuse->partitions_w = ftp_para->partitions_w;
   ftp_para_reuse->fused_layers = ftp_para->fused_layers;
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         ftp_para_reuse->task_id[i][j] = ftp_para->task_id[i][j];
      }
   }
   reuse_aware_schedule(ftp_para_reuse);

   /*Copy the grid output from normal ftp*/
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         task = ftp_para_reuse->task_id[i][j];
         l = ftp_para_reuse->fused_layers-1;
         ftp_para_reuse->output_tiles[task][l] = ftp_para->output_tiles[task][l];
      }
   }

   /*Calculate the tile regions with no reuse data dependency*/
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         task = ftp_para_reuse->task_id[i][j];
         for(l = ftp_para_reuse->fused_layers-1; l >= 0; l--){
            if(ftp_para_reuse->schedule[task] == 0){
               /*If there is no dependency, just copy from normal ftp parameters*/
               ftp_para_reuse->input_tiles[task][l] = ftp_para->input_tiles[task][l];
               ftp_para_reuse->output_tiles[task][l] = ftp_para->output_tiles[task][l];
            }
         }
      }
   }

   /*Calculate the tile regions with reuse data dependency*/
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         task = ftp_para_reuse->task_id[i][j];
         for(l = ftp_para_reuse->fused_layers-1; l >= 0; l--){
            ftp_para_reuse->output_reuse_regions[task][l].down_size = 0;
            ftp_para_reuse->output_reuse_regions[task][l].right_size = 0;
            ftp_para_reuse->output_reuse_regions[task][l].up_size = 0;
            ftp_para_reuse->output_reuse_regions[task][l].left_size = 0;
            ftp_para_reuse->output_reuse_regions[task][l].right_region.h = 0;
            ftp_para_reuse->output_reuse_regions[task][l].right_region.w = 0;
            ftp_para_reuse->output_reuse_regions[task][l].down_region.h = 0;
            ftp_para_reuse->output_reuse_regions[task][l].down_region.w = 0;
            ftp_para_reuse->output_reuse_regions[task][l].left_region.h = 0;
            ftp_para_reuse->output_reuse_regions[task][l].left_region.w = 0;
            ftp_para_reuse->output_reuse_regions[task][l].up_region.h = 0;
            ftp_para_reuse->output_reuse_regions[task][l].up_region.w = 0;
         }
      }
   }
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
#if DEBUG_FTP
         printf("------------------(%3d,%3d)----------------\n", i, j);
#endif
         for(l = ftp_para_reuse->fused_layers-1; l >= 0; l--){
            task = ftp_para_reuse->task_id[i][j];
            if(ftp_para_reuse->schedule[task] == 1){
               ftp_para_reuse->input_tiles[ftp_para_reuse->task_id[i][j]][l] = 
                       traversal(net_para, ftp_para_reuse->output_tiles[ftp_para_reuse->task_id[i][j]][l], l);
               if(l>0) ftp_para_reuse->output_tiles[ftp_para_reuse->task_id[i][j]][l-1] 
                         = remove_and_record_overlapped_region_at_output(i, j, l-1,  ftp_para_reuse, 
                                                      ftp_para_reuse->input_tiles[ftp_para_reuse->task_id[i][j]][l]);
            }
#if DEBUG_FTP
            printf("---(layer %3d)---\n", l);
            print_tile_region(ftp_para_reuse->output_tiles[ftp_para->task_id[i][j]][l]);
            print_tile_region(ftp_para_reuse->input_tiles[ftp_para->task_id[i][j]][l]);
            printf("---(layer %3d)---\n", l);
#endif
         }
      }
   }

   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         task = ftp_para_reuse->task_id[i][j];
         calculate_reuse_data_size(ftp_para_reuse, net_para, task);/*Will be used in reuse_data serialization*/
      }
   }

   return ftp_para_reuse;
}
/*This function must be called after perform_ftp()*/
This function must be called after perform_ftp()
This function must be called after perform_ftp ()
ftp_parameters_reuse* preform_ftp_reuse(network_parameters* net_para, ftp_parameters* ftp_para){
   int32_t i, j, l;
   uint32_t task;
   ftp_parameters_reuse* ftp_para_reuse = (ftp_parameters_reuse*)malloc(sizeof(ftp_parameters_reuse));
   ftp_para_reuse->partitions = ftp_para->partitions;
   ftp_para_reuse->partitions_h = ftp_para->partitions_h;
   ftp_para_reuse->partitions_w = ftp_para->partitions_w;
   ftp_para_reuse->fused_layers = ftp_para->fused_layers;
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         ftp_para_reuse->task_id[i][j] = ftp_para->task_id[i][j];
      }
   }
   reuse_aware_schedule(ftp_para_reuse);
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         task = ftp_para_reuse->task_id[i][j];
         l = ftp_para_reuse->fused_layers-1;
         ftp_para_reuse->output_tiles[task][l] = ftp_para->output_tiles[task][l];
      }
   }
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         task = ftp_para_reuse->task_id[i][j];
         for(l = ftp_para_reuse->fused_layers-1; l >= 0; l--){
            if(ftp_para_reuse->schedule[task] == 0){
               ftp_para_reuse->input_tiles[task][l] = ftp_para->input_tiles[task][l];
               ftp_para_reuse->output_tiles[task][l] = ftp_para->output_tiles[task][l];
            }
         }
      }
   }
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         task = ftp_para_reuse->task_id[i][j];
         for(l = ftp_para_reuse->fused_layers-1; l >= 0; l--){
            ftp_para_reuse->output_reuse_regions[task][l].down_size = 0;
            ftp_para_reuse->output_reuse_regions[task][l].right_size = 0;
            ftp_para_reuse->output_reuse_regions[task][l].up_size = 0;
            ftp_para_reuse->output_reuse_regions[task][l].left_size = 0;
            ftp_para_reuse->output_reuse_regions[task][l].right_region.h = 0;
            ftp_para_reuse->output_reuse_regions[task][l].right_region.w = 0;
            ftp_para_reuse->output_reuse_regions[task][l].down_region.h = 0;
            ftp_para_reuse->output_reuse_regions[task][l].down_region.w = 0;
            ftp_para_reuse->output_reuse_regions[task][l].left_region.h = 0;
            ftp_para_reuse->output_reuse_regions[task][l].left_region.w = 0;
            ftp_para_reuse->output_reuse_regions[task][l].up_region.h = 0;
            ftp_para_reuse->output_reuse_regions[task][l].up_region.w = 0;
         }
      }
   }
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
#if DEBUG_FTP
         printf("------------------(%3d,%3d)----------------\n", i, j);
#endif
         for(l = ftp_para_reuse->fused_layers-1; l >= 0; l--){
            task = ftp_para_reuse->task_id[i][j];
            if(ftp_para_reuse->schedule[task] == 1){
               ftp_para_reuse->input_tiles[ftp_para_reuse->task_id[i][j]][l] = 
                       traversal(net_para, ftp_para_reuse->output_tiles[ftp_para_reuse->task_id[i][j]][l], l);
               if(l>0) ftp_para_reuse->output_tiles[ftp_para_reuse->task_id[i][j]][l-1] 
                         = remove_and_record_overlapped_region_at_output(i, j, l-1,  ftp_para_reuse, 
                                                      ftp_para_reuse->input_tiles[ftp_para_reuse->task_id[i][j]][l]);
            }
#if DEBUG_FTP
            printf("---(layer %3d)---\n", l);
            print_tile_region(ftp_para_reuse->output_tiles[ftp_para->task_id[i][j]][l]);
            print_tile_region(ftp_para_reuse->input_tiles[ftp_para->task_id[i][j]][l]);
            printf("---(layer %3d)---\n", l);
#endif
         }
      }
   }
   for(i = 0; i < ftp_para_reuse->partitions_h; i++){
      for(j = 0; j < ftp_para_reuse->partitions_w; j++){
         task = ftp_para_reuse->task_id[i][j];
         calculate_reuse_data_size(ftp_para_reuse, net_para, task);
      }
   }
   return ftp_para_reuse;
}
ftp_parameters_reuse * preform_ftp_reuse ( network_parameters * net_para , ftp_parameters * ftp_para ) { int32_t i , j , l ; uint32_t task ; ftp_parameters_reuse * ftp_para_reuse = ( ftp_parameters_reuse * ) malloc ( sizeof ( ftp_parameters_reuse ) ) ; ftp_para_reuse -> partitions = ftp_para -> partitions ; ftp_para_reuse -> partitions_h = ftp_para -> partitions_h ; ftp_para_reuse -> partitions_w = ftp_para -> partitions_w ; ftp_para_reuse -> fused_layers = ftp_para -> fused_layers ; for ( i = 0 ; i < ftp_para_reuse -> partitions_h ; i ++ ) { for ( j = 0 ; j < ftp_para_reuse -> partitions_w ; j ++ ) { ftp_para_reuse -> task_id [ i ] [ j ] = ftp_para -> task_id [ i ] [ j ] ; } } reuse_aware_schedule ( ftp_para_reuse ) ; for ( i = 0 ; i < ftp_para_reuse -> partitions_h ; i ++ ) { for ( j = 0 ; j < ftp_para_reuse -> partitions_w ; j ++ ) { task = ftp_para_reuse -> task_id [ i ] [ j ] ; l = ftp_para_reuse -> fused_layers - 1 ; ftp_para_reuse -> output_tiles [ task ] [ l ] = ftp_para -> output_tiles [ task ] [ l ] ; } } for ( i = 0 ; i < ftp_para_reuse -> partitions_h ; i ++ ) { for ( j = 0 ; j < ftp_para_reuse -> partitions_w ; j ++ ) { task = ftp_para_reuse -> task_id [ i ] [ j ] ; for ( l = ftp_para_reuse -> fused_layers - 1 ; l >= 0 ; l -- ) { if ( ftp_para_reuse -> schedule [ task ] == 0 ) { ftp_para_reuse -> input_tiles [ task ] [ l ] = ftp_para -> input_tiles [ task ] [ l ] ; ftp_para_reuse -> output_tiles [ task ] [ l ] = ftp_para -> output_tiles [ task ] [ l ] ; } } } } for ( i = 0 ; i < ftp_para_reuse -> partitions_h ; i ++ ) { for ( j = 0 ; j < ftp_para_reuse -> partitions_w ; j ++ ) { task = ftp_para_reuse -> task_id [ i ] [ j ] ; for ( l = ftp_para_reuse -> fused_layers - 1 ; l >= 0 ; l -- ) { ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . down_size = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . right_size = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . up_size = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . left_size = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . right_region . h = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . right_region . w = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . down_region . h = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . down_region . w = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . left_region . h = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . left_region . w = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . up_region . h = 0 ; ftp_para_reuse -> output_reuse_regions [ task ] [ l ] . up_region . w = 0 ; } } } for ( i = 0 ; i < ftp_para_reuse -> partitions_h ; i ++ ) { for ( j = 0 ; j < ftp_para_reuse -> partitions_w ; j ++ ) { #if DEBUG_FTP printf ( " \n " , i , j ) ; #endif for ( l = ftp_para_reuse -> fused_layers - 1 ; l >= 0 ; l -- ) { task = ftp_para_reuse -> task_id [ i ] [ j ] ; if ( ftp_para_reuse -> schedule [ task ] == 1 ) { ftp_para_reuse -> input_tiles [ ftp_para_reuse -> task_id [ i ] [ j ] ] [ l ] = traversal ( net_para , ftp_para_reuse -> output_tiles [ ftp_para_reuse -> task_id [ i ] [ j ] ] [ l ] , l ) ; if ( l > 0 ) ftp_para_reuse -> output_tiles [ ftp_para_reuse -> task_id [ i ] [ j ] ] [ l - 1 ] = remove_and_record_overlapped_region_at_output ( i , j , l - 1 , ftp_para_reuse , ftp_para_reuse -> input_tiles [ ftp_para_reuse -> task_id [ i ] [ j ] ] [ l ] ) ; } #if DEBUG_FTP printf ( " \n " , l ) ; print_tile_region ( ftp_para_reuse -> output_tiles [ ftp_para -> task_id [ i ] [ j ] ] [ l ] ) ; print_tile_region ( ftp_para_reuse -> input_tiles [ ftp_para -> task_id [ i ] [ j ] ] [ l ] ) ; printf ( " \n " , l ) ; #endif } } } for ( i = 0 ; i < ftp_para_reuse -> partitions_h ; i ++ ) { for ( j = 0 ; j < ftp_para_reuse -> partitions_w ; j ++ ) { task = ftp_para_reuse -> task_id [ i ] [ j ] ; calculate_reuse_data_size ( ftp_para_reuse , net_para , task ) ; } } return ftp_para_reuse ; }
This function must be called after perform_ftp()
This function must be called after perform_ftp ()
/*Copy the grid output from normal ftp*/ /*Calculate the tile regions with no reuse data dependency*/ /*If there is no dependency, just copy from normal ftp parameters*/ /*Calculate the tile regions with reuse data dependency*/ /*Will be used in reuse_data serialization*/