@@ -644,12 +644,13 @@ def provision_bq_remote_function(
644644
645645 # assumption is most bigframes functions are cpu bound, single-threaded and many won't release GIL
646646 # therefore, want to allocate a worker for each cpu, and allow a concurrent request per worker
647- expected_cpus = cloud_function_cpus or _infer_cpus_from_memory (
648- cloud_function_memory_mib
649- )
650- workers = expected_cpus
647+ expected_milli_cpus = (
648+ cloud_function_cpus * 1000
649+ ) or _infer_milli_cpus_from_memory ( cloud_function_memory_mib )
650+ workers = - ( expected_milli_cpus // - 1000 ) # ceil(cpus) without invoking floats
651651 threads = 4 # (per worker)
652- concurrency = workers * threads
652+ # max concurrency==1 for vcpus < 1 hard limit from cloud run
653+ concurrency = (workers * threads ) if (expected_milli_cpus >= 1000 ) else 1
653654
654655 # Create the cloud function if it does not exist
655656 if not cf_endpoint :
@@ -737,16 +738,23 @@ def get_remote_function_specs(self, remote_function_name):
737738 return (http_endpoint , bq_connection )
738739
739740
740- def _infer_cpus_from_memory (memory_mib : int ) -> int :
741+ def _infer_milli_cpus_from_memory (memory_mib : int ) -> int :
741742 # observed values, not formally documented by cloud run functions
742- if memory_mib <= 2048 :
743- # in actuality, will be 0.583 for 1024mb, 0.33 for 512mb, etc, but we round up to 1
744- return 1
743+ if memory_mib <= 128 :
744+ return 83
745+ elif memory_mib <= 256 :
746+ return 167
747+ elif memory_mib <= 512 :
748+ return 333
749+ elif memory_mib <= 1024 :
750+ return 583
751+ elif memory_mib <= 2048 :
752+ return 1000
745753 elif memory_mib <= 8192 :
746- return 2
754+ return 2000
747755 elif memory_mib <= 16384 :
748- return 4
756+ return 4000
749757 elif memory_mib <= 32768 :
750- return 8
758+ return 8000
751759 else :
752760 raise ValueError ("Cloud run supports at most 32768MiB per instance" )
0 commit comments