@@ -661,11 +661,10 @@ struct ggml_backend_opencl_context {
661661 cl_kernel kernel_mul_mm_iq4_nl_f32_l4_lm;
662662
663663 std::vector<ProfilingInfo> profiling_info;
664+ std::vector<ProfilingInfo> profiling_results;
664665
665- void write_profiling_info() {
666- FILE * fperf = fopen("cl_profiling.csv", "w");
667- if (!fperf) {
668- GGML_LOG_ERROR("Failed to open cl_profiling.csv\n");
666+ void flush_profiling_batch() {
667+ if (profiling_info.empty()) {
669668 return;
670669 }
671670
@@ -689,6 +688,7 @@ struct ggml_backend_opencl_context {
689688 CL_CHECK(clGetEventProfilingInfo(
690689 info.evt, CL_PROFILING_COMMAND_COMPLETE, sizeof(cl_ulong), &cmd_complete, NULL));
691690 CL_CHECK(clReleaseEvent(info.evt));
691+ info.evt = nullptr;
692692
693693 char kernel_name[512];
694694 CL_CHECK(clGetKernelInfo(info.kernel, CL_KERNEL_FUNCTION_NAME,
@@ -706,10 +706,26 @@ struct ggml_backend_opencl_context {
706706 info.cmd_complete_duration_ns = cmd_complete - cmd_end;
707707 info.cmd_total_duration_ns = cmd_complete - cmd_queued;
708708 }
709+ profiling_results.insert(profiling_results.end(),
710+ std::make_move_iterator(profiling_info.begin()),
711+ std::make_move_iterator(profiling_info.end()));
712+ profiling_info.clear();
713+ }
714+
715+ void write_profiling_info() {
716+ if (profiling_results.empty()) {
717+ return;
718+ }
709719
710720 // Dump a csv
721+ FILE * fperf = fopen("cl_profiling.csv", "w");
722+ if (!fperf) {
723+ GGML_LOG_ERROR("Failed to open cl_profiling.csv\n");
724+ return;
725+ }
726+
711727 fprintf(fperf, "op name, kernel name, exec duration (ms), global size, local size, output size\n");
712- for (const ProfilingInfo & info : profiling_info ) {
728+ for (const ProfilingInfo & info : profiling_results ) {
713729 fprintf(fperf, "%s,%s,%f,%zux%zux%zu,%zux%zux%zu,%zux%zux%zux%zu\n",
714730 info.op_name.c_str(), info.kernel_name.c_str(),
715731 info.cmd_duration_ns/1.e6f,
@@ -720,14 +736,14 @@ struct ggml_backend_opencl_context {
720736 fclose(fperf);
721737
722738 // Dump a simple chrome trace
723- FILE* ftrace = fopen("cl_trace.json", "w");
739+ FILE * ftrace = fopen("cl_trace.json", "w");
724740 if (!ftrace) {
725741 GGML_LOG_ERROR("Failed to open cl_trace.json\n");
726742 return;
727743 }
728744
729745 fprintf(ftrace, "[\n");
730- for (const ProfilingInfo & info : profiling_info ) {
746+ for (const ProfilingInfo & info : profiling_results ) {
731747 fprintf(ftrace, "{\"name\": \"%s\", \"cat\": \"OpenCL\", \"ph\": \"B\", \"ts\": %" PRIu64 ", \"pid\": \"\", \"tid\": \"Host\"},\n",
732748 info.kernel_name.c_str(), info.cmd_queued/1000);
733749 fprintf(ftrace, "{\"name\": \"%s\", \"cat\": \"OpenCL\", \"ph\": \"E\", \"ts\": %" PRIu64 ", \"pid\": \"\", \"tid\": \"Host\"},\n",
@@ -738,6 +754,7 @@ struct ggml_backend_opencl_context {
738754 fprintf(ftrace, "{\"name\": \"%s\", \"cat\": \"OpenCL\", \"ph\": \"E\", \"ts\": %" PRIu64 ", \"pid\": \"\", \"tid\": \"Device\"},\n",
739755 info.kernel_name.c_str(), info.cmd_end/1000);
740756 }
757+ fprintf(ftrace, "]\n");
741758 fclose(ftrace);
742759 }
743760
@@ -758,6 +775,9 @@ struct ggml_backend_opencl_context {
758775
759776 profiling_info.emplace_back();
760777 populateProfilingInfo(profiling_info.back(), evt, kernel, work_dim, global_work_size, local_work_size, tensor);
778+ if (profiling_info.size() >= 2048) {
779+ flush_profiling_batch();
780+ }
761781#else
762782 GGML_UNUSED(tensor);
763783 CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, global_work_size, local_work_size, 0, NULL, NULL));
@@ -804,7 +824,7 @@ struct ggml_backend_opencl_context {
804824 if (ref_count == 0) {
805825#ifdef GGML_OPENCL_PROFILING
806826 write_profiling_info();
807- profiling_info .clear();
827+ profiling_results .clear();
808828#endif
809829 }
810830 }
0 commit comments