| 884 | } |
| 885 | |
| 886 | void Model::OptimizeHillClimb(int64 cpu_budget, int64 ram_budget) { |
| 887 | std::shared_ptr<Node> snapshot; |
| 888 | { |
| 889 | tf_shared_lock lock(mu_); |
| 890 | snapshot = output_->Snapshot(nullptr); |
| 891 | } |
| 892 | VLOG(2) << "Starting optimization of tunable parameters with HillClimb"; |
| 893 | const double processing_time = TotalProcessingTime(snapshot); |
| 894 | auto parameters = CollectTunableParameters(snapshot); |
| 895 | // We add the number of model's buffered bytes because it is excluded from the |
| 896 | // memory budget, but it is included in the maximum number of buffered bytes. |
| 897 | ram_budget += TotalBufferedBytes(snapshot); |
| 898 | // Buffer size parameter will only be incremented if the output latency |
| 899 | // improvement is greater than this constant. |
| 900 | constexpr double kBufferSizeMinDelta = 1.0L; |
| 901 | |
| 902 | for (auto& pair : parameters) { |
| 903 | pair.second->value = pair.second->min; |
| 904 | } |
| 905 | while (true) { |
| 906 | const double output_time = OutputTime(snapshot, /*gradient=*/nullptr); |
| 907 | bool all_max = true; |
| 908 | for (auto& pair : parameters) { |
| 909 | if (pair.second->value < pair.second->max) { |
| 910 | all_max = false; |
| 911 | break; |
| 912 | } |
| 913 | } |
| 914 | if (output_time < processing_time / cpu_budget || all_max || |
| 915 | TotalMaximumBufferedBytes(snapshot) > ram_budget) { |
| 916 | break; |
| 917 | } |
| 918 | double best_delta = -1.0L; |
| 919 | Parameter* best_parameter = nullptr; |
| 920 | for (auto& pair : parameters) { |
| 921 | if (pair.second->value == pair.second->max) { |
| 922 | continue; |
| 923 | } |
| 924 | pair.second->value++; |
| 925 | double new_output_time = OutputTime(snapshot, /*gradient=*/nullptr); |
| 926 | double delta = output_time - new_output_time; |
| 927 | if (delta > best_delta && |
| 928 | (delta > kBufferSizeMinDelta || pair.second->name != kBufferSize)) { |
| 929 | best_delta = delta; |
| 930 | best_parameter = pair.second.get(); |
| 931 | } |
| 932 | pair.second->value--; |
| 933 | } |
| 934 | if (!best_parameter) { |
| 935 | VLOG(2) << "Failed to find a tunable parameter that would decrease the " |
| 936 | "output time. This means that the autotuning optimization got " |
| 937 | "stuck in a local maximum. The optimization attempt will be " |
| 938 | "aborted."; |
| 939 | return; |
| 940 | } |
| 941 | best_parameter->value++; |
| 942 | } |
| 943 | VLOG(2) << "Number of tunable parameters: " << parameters.size(); |
nothing calls this directly
no test coverage detected