@@ -191,19 +191,38 @@ assert_square_matrix <- function(dims, operand, context, hoist, scope) {
191191# ---- BLAS emitters ----
192192
193193# Generated function results cannot currently represent zero-sized arrays.
194- # Reject a statically known zero output before emitting a BLAS call with an
195- # invalid leading dimension. A zero contracted dimension remains supported
196- # when every output extent is nonzero.
197- assert_nonempty_blas_output <- function (dims , context ) {
198- stopifnot(is.list(dims ), length(dims ) > 0L , is_string(context ))
199- has_zero_extent <- any(vapply(
200- dims ,
201- function (dim ) is_wholenumber(dim ) && as.integer(dim ) == 0L ,
202- logical (1 )
203- ))
204- if (has_zero_extent ) {
205- stop(context , " zero-sized outputs are not supported" , call. = FALSE )
194+ # Reject a known zero output during translation and guard unknown output
195+ # extents at runtime before emitting a BLAS call with an invalid leading
196+ # dimension. A zero contracted dimension remains supported when every output
197+ # extent is nonzero.
198+ assert_nonempty_blas_output <- function (
199+ dim ,
200+ operand ,
201+ axis ,
202+ context ,
203+ hoist ,
204+ scope
205+ ) {
206+ stopifnot(
207+ inherits(operand , Fortran ),
208+ is.numeric(axis ),
209+ length(axis ) == 1L ,
210+ is_string(context )
211+ )
212+ message <- paste0(context , " zero-sized outputs are not supported" )
213+ if (is_wholenumber(dim )) {
214+ if (as.integer(dim ) == 0L ) {
215+ stop(message , call. = FALSE )
216+ }
217+ return (invisible (TRUE ))
206218 }
219+
220+ emit_quickr_error_if(
221+ glue(" {guard_dim_f(dim, operand, axis)} == 0_c_ptrdiff_t" ),
222+ message ,
223+ hoist ,
224+ scope
225+ )
207226 invisible (TRUE )
208227}
209228
@@ -344,7 +363,22 @@ gemm <- function(
344363 context = " gemm"
345364) {
346365 assert_hoist_env(hoist )
347- assert_nonempty_blas_output(list (m , n ), context )
366+ assert_nonempty_blas_output(
367+ m ,
368+ left ,
369+ if (opA == " N" ) 1L else 2L ,
370+ context ,
371+ hoist ,
372+ scope
373+ )
374+ assert_nonempty_blas_output(
375+ n ,
376+ right ,
377+ if (opB == " N" ) 2L else 1L ,
378+ context ,
379+ hoist ,
380+ scope
381+ )
348382 A_name <- ensure_blas_operand_name(left , hoist )
349383 B_name <- ensure_blas_operand_name(right , hoist )
350384
@@ -391,7 +425,15 @@ gemv <- function(
391425 context = " gemv"
392426) {
393427 assert_hoist_env(hoist )
394- assert_nonempty_blas_output(out_dims , context )
428+ output_dim <- if (transA == " N" ) m else n
429+ assert_nonempty_blas_output(
430+ output_dim ,
431+ A ,
432+ if (transA == " N" ) 1L else 2L ,
433+ context ,
434+ hoist ,
435+ scope
436+ )
395437 A_name <- ensure_blas_operand_name(A , hoist )
396438 x_name <- ensure_blas_operand_name(x , hoist )
397439
@@ -495,7 +537,14 @@ syrk <- function(
495537 k <- x_dims $ cols
496538 }
497539 lda <- x_dims $ rows
498- assert_nonempty_blas_output(list (n , n ), context )
540+ assert_nonempty_blas_output(
541+ n ,
542+ X ,
543+ if (trans == " T" ) 2L else 1L ,
544+ context ,
545+ hoist ,
546+ scope
547+ )
499548 X_name <- ensure_blas_operand_name(X , hoist )
500549
501550 # Output is symmetric n x n matrix
0 commit comments