/* Implementation of the MATMUL intrinsic
- Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ Copyright (C) 2002-2021 Free Software Foundation, Inc.
Contributed by Paul Brook <paul@nowt.org>
This file is part of the GNU Fortran runtime library (libgfortran).
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else if (GFC_DESCRIPTOR_RANK (b) == 1)
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 1:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,1);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 2:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 2 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
}
if (count != GFC_DESCRIPTOR_EXTENT(b,0))
{
if (count > 0 || GFC_DESCRIPTOR_EXTENT(b,0) > 0)
- runtime_error ("dimension of array B incorrect in MATMUL intrinsic");
+ runtime_error ("Incorrect extent in argument B in MATMUL intrinsic "
+ "in dimension 1: is %ld, should be %ld",
+ (long int) GFC_DESCRIPTOR_EXTENT(b,0), (long int) count);
}
if (GFC_DESCRIPTOR_RANK (b) == 1)
if (lda > 0 && ldb > 0 && ldc > 0 && m > 1 && n > 1 && k > 1)
{
assert (gemm != NULL);
- gemm (axstride == 1 ? "N" : "T", bxstride == 1 ? "N" : "T", &m,
+ const char *transa, *transb;
+ if (try_blas & 2)
+ transa = "C";
+ else
+ transa = axstride == 1 ? "N" : "T";
+
+ if (try_blas & 4)
+ transb = "C";
+ else
+ transb = bxstride == 1 ? "N" : "T";
+
+ gemm (transa, transb , &m,
&n, &k, &one, abase, &lda, bbase, &ldb, &zero, dest,
&ldc, 1, 1);
return;
return;
/* Adjust size of t1 to what is needed. */
- index_type t1_dim;
- t1_dim = (a_dim1 - (ycount > 1)) * 256 + b_dim1;
+ index_type t1_dim, a_sz;
+ if (aystride == 1)
+ a_sz = rystride;
+ else
+ a_sz = a_dim1;
+
+ t1_dim = a_sz * 256 + b_dim1;
if (t1_dim > 65536)
t1_dim = 65536;
}
}
}
- else if (axstride < aystride)
- {
- for (y = 0; y < ycount; y++)
- for (x = 0; x < xcount; x++)
- dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
-
- for (y = 0; y < ycount; y++)
- for (n = 0; n < count; n++)
- for (x = 0; x < xcount; x++)
- /* dest[x,y] += a[x,n] * b[n,y] */
- dest[x*rxstride + y*rystride] +=
- abase[x*axstride + n*aystride] *
- bbase[n*bxstride + y*bystride];
- }
else if (GFC_DESCRIPTOR_RANK (a) == 1)
{
const GFC_COMPLEX_8 *restrict bbase_y;
dest[y*rxstride] = s;
}
}
+ else if (axstride < aystride)
+ {
+ for (y = 0; y < ycount; y++)
+ for (x = 0; x < xcount; x++)
+ dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
+
+ for (y = 0; y < ycount; y++)
+ for (n = 0; n < count; n++)
+ for (x = 0; x < xcount; x++)
+ /* dest[x,y] += a[x,n] * b[n,y] */
+ dest[x*rxstride + y*rystride] +=
+ abase[x*axstride + n*aystride] *
+ bbase[n*bxstride + y*bystride];
+ }
else
{
const GFC_COMPLEX_8 *restrict abase_x;
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else if (GFC_DESCRIPTOR_RANK (b) == 1)
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 1:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,1);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 2:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 2 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
}
if (count != GFC_DESCRIPTOR_EXTENT(b,0))
{
if (count > 0 || GFC_DESCRIPTOR_EXTENT(b,0) > 0)
- runtime_error ("dimension of array B incorrect in MATMUL intrinsic");
+ runtime_error ("Incorrect extent in argument B in MATMUL intrinsic "
+ "in dimension 1: is %ld, should be %ld",
+ (long int) GFC_DESCRIPTOR_EXTENT(b,0), (long int) count);
}
if (GFC_DESCRIPTOR_RANK (b) == 1)
if (lda > 0 && ldb > 0 && ldc > 0 && m > 1 && n > 1 && k > 1)
{
assert (gemm != NULL);
- gemm (axstride == 1 ? "N" : "T", bxstride == 1 ? "N" : "T", &m,
+ const char *transa, *transb;
+ if (try_blas & 2)
+ transa = "C";
+ else
+ transa = axstride == 1 ? "N" : "T";
+
+ if (try_blas & 4)
+ transb = "C";
+ else
+ transb = bxstride == 1 ? "N" : "T";
+
+ gemm (transa, transb , &m,
&n, &k, &one, abase, &lda, bbase, &ldb, &zero, dest,
&ldc, 1, 1);
return;
return;
/* Adjust size of t1 to what is needed. */
- index_type t1_dim;
- t1_dim = (a_dim1 - (ycount > 1)) * 256 + b_dim1;
+ index_type t1_dim, a_sz;
+ if (aystride == 1)
+ a_sz = rystride;
+ else
+ a_sz = a_dim1;
+
+ t1_dim = a_sz * 256 + b_dim1;
if (t1_dim > 65536)
t1_dim = 65536;
}
}
}
- else if (axstride < aystride)
- {
- for (y = 0; y < ycount; y++)
- for (x = 0; x < xcount; x++)
- dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
-
- for (y = 0; y < ycount; y++)
- for (n = 0; n < count; n++)
- for (x = 0; x < xcount; x++)
- /* dest[x,y] += a[x,n] * b[n,y] */
- dest[x*rxstride + y*rystride] +=
- abase[x*axstride + n*aystride] *
- bbase[n*bxstride + y*bystride];
- }
else if (GFC_DESCRIPTOR_RANK (a) == 1)
{
const GFC_COMPLEX_8 *restrict bbase_y;
dest[y*rxstride] = s;
}
}
+ else if (axstride < aystride)
+ {
+ for (y = 0; y < ycount; y++)
+ for (x = 0; x < xcount; x++)
+ dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
+
+ for (y = 0; y < ycount; y++)
+ for (n = 0; n < count; n++)
+ for (x = 0; x < xcount; x++)
+ /* dest[x,y] += a[x,n] * b[n,y] */
+ dest[x*rxstride + y*rystride] +=
+ abase[x*axstride + n*aystride] *
+ bbase[n*bxstride + y*bystride];
+ }
else
{
const GFC_COMPLEX_8 *restrict abase_x;
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else if (GFC_DESCRIPTOR_RANK (b) == 1)
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 1:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,1);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 2:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 2 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
}
if (count != GFC_DESCRIPTOR_EXTENT(b,0))
{
if (count > 0 || GFC_DESCRIPTOR_EXTENT(b,0) > 0)
- runtime_error ("dimension of array B incorrect in MATMUL intrinsic");
+ runtime_error ("Incorrect extent in argument B in MATMUL intrinsic "
+ "in dimension 1: is %ld, should be %ld",
+ (long int) GFC_DESCRIPTOR_EXTENT(b,0), (long int) count);
}
if (GFC_DESCRIPTOR_RANK (b) == 1)
if (lda > 0 && ldb > 0 && ldc > 0 && m > 1 && n > 1 && k > 1)
{
assert (gemm != NULL);
- gemm (axstride == 1 ? "N" : "T", bxstride == 1 ? "N" : "T", &m,
+ const char *transa, *transb;
+ if (try_blas & 2)
+ transa = "C";
+ else
+ transa = axstride == 1 ? "N" : "T";
+
+ if (try_blas & 4)
+ transb = "C";
+ else
+ transb = bxstride == 1 ? "N" : "T";
+
+ gemm (transa, transb , &m,
&n, &k, &one, abase, &lda, bbase, &ldb, &zero, dest,
&ldc, 1, 1);
return;
return;
/* Adjust size of t1 to what is needed. */
- index_type t1_dim;
- t1_dim = (a_dim1 - (ycount > 1)) * 256 + b_dim1;
+ index_type t1_dim, a_sz;
+ if (aystride == 1)
+ a_sz = rystride;
+ else
+ a_sz = a_dim1;
+
+ t1_dim = a_sz * 256 + b_dim1;
if (t1_dim > 65536)
t1_dim = 65536;
}
}
}
- else if (axstride < aystride)
- {
- for (y = 0; y < ycount; y++)
- for (x = 0; x < xcount; x++)
- dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
-
- for (y = 0; y < ycount; y++)
- for (n = 0; n < count; n++)
- for (x = 0; x < xcount; x++)
- /* dest[x,y] += a[x,n] * b[n,y] */
- dest[x*rxstride + y*rystride] +=
- abase[x*axstride + n*aystride] *
- bbase[n*bxstride + y*bystride];
- }
else if (GFC_DESCRIPTOR_RANK (a) == 1)
{
const GFC_COMPLEX_8 *restrict bbase_y;
dest[y*rxstride] = s;
}
}
+ else if (axstride < aystride)
+ {
+ for (y = 0; y < ycount; y++)
+ for (x = 0; x < xcount; x++)
+ dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
+
+ for (y = 0; y < ycount; y++)
+ for (n = 0; n < count; n++)
+ for (x = 0; x < xcount; x++)
+ /* dest[x,y] += a[x,n] * b[n,y] */
+ dest[x*rxstride + y*rystride] +=
+ abase[x*axstride + n*aystride] *
+ bbase[n*bxstride + y*bystride];
+ }
else
{
const GFC_COMPLEX_8 *restrict abase_x;
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else if (GFC_DESCRIPTOR_RANK (b) == 1)
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 1:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,1);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 2:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 2 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
}
if (count != GFC_DESCRIPTOR_EXTENT(b,0))
{
if (count > 0 || GFC_DESCRIPTOR_EXTENT(b,0) > 0)
- runtime_error ("dimension of array B incorrect in MATMUL intrinsic");
+ runtime_error ("Incorrect extent in argument B in MATMUL intrinsic "
+ "in dimension 1: is %ld, should be %ld",
+ (long int) GFC_DESCRIPTOR_EXTENT(b,0), (long int) count);
}
if (GFC_DESCRIPTOR_RANK (b) == 1)
if (lda > 0 && ldb > 0 && ldc > 0 && m > 1 && n > 1 && k > 1)
{
assert (gemm != NULL);
- gemm (axstride == 1 ? "N" : "T", bxstride == 1 ? "N" : "T", &m,
+ const char *transa, *transb;
+ if (try_blas & 2)
+ transa = "C";
+ else
+ transa = axstride == 1 ? "N" : "T";
+
+ if (try_blas & 4)
+ transb = "C";
+ else
+ transb = bxstride == 1 ? "N" : "T";
+
+ gemm (transa, transb , &m,
&n, &k, &one, abase, &lda, bbase, &ldb, &zero, dest,
&ldc, 1, 1);
return;
return;
/* Adjust size of t1 to what is needed. */
- index_type t1_dim;
- t1_dim = (a_dim1 - (ycount > 1)) * 256 + b_dim1;
+ index_type t1_dim, a_sz;
+ if (aystride == 1)
+ a_sz = rystride;
+ else
+ a_sz = a_dim1;
+
+ t1_dim = a_sz * 256 + b_dim1;
if (t1_dim > 65536)
t1_dim = 65536;
}
}
}
- else if (axstride < aystride)
- {
- for (y = 0; y < ycount; y++)
- for (x = 0; x < xcount; x++)
- dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
-
- for (y = 0; y < ycount; y++)
- for (n = 0; n < count; n++)
- for (x = 0; x < xcount; x++)
- /* dest[x,y] += a[x,n] * b[n,y] */
- dest[x*rxstride + y*rystride] +=
- abase[x*axstride + n*aystride] *
- bbase[n*bxstride + y*bystride];
- }
else if (GFC_DESCRIPTOR_RANK (a) == 1)
{
const GFC_COMPLEX_8 *restrict bbase_y;
dest[y*rxstride] = s;
}
}
+ else if (axstride < aystride)
+ {
+ for (y = 0; y < ycount; y++)
+ for (x = 0; x < xcount; x++)
+ dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
+
+ for (y = 0; y < ycount; y++)
+ for (n = 0; n < count; n++)
+ for (x = 0; x < xcount; x++)
+ /* dest[x,y] += a[x,n] * b[n,y] */
+ dest[x*rxstride + y*rystride] +=
+ abase[x*axstride + n*aystride] *
+ bbase[n*bxstride + y*bystride];
+ }
else
{
const GFC_COMPLEX_8 *restrict abase_x;
/* Currently, this is i386 only. Adjust for other architectures. */
-#include <config/i386/cpuinfo.h>
void matmul_c8 (gfc_array_c8 * const restrict retarray,
gfc_array_c8 * const restrict a, gfc_array_c8 * const restrict b, int try_blas,
int blas_limit, blas_call gemm)
if (matmul_fn == NULL)
{
matmul_fn = matmul_c8_vanilla;
- if (__cpu_model.__cpu_vendor == VENDOR_INTEL)
+ if (__builtin_cpu_is ("intel"))
{
/* Run down the available processors in order of preference. */
#ifdef HAVE_AVX512F
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX512F))
+ if (__builtin_cpu_supports ("avx512f"))
{
matmul_fn = matmul_c8_avx512f;
goto store;
#endif /* HAVE_AVX512F */
#ifdef HAVE_AVX2
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX2))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c8_avx2;
goto store;
#endif
#ifdef HAVE_AVX
- if (__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
+ if (__builtin_cpu_supports ("avx"))
{
matmul_fn = matmul_c8_avx;
goto store;
}
#endif /* HAVE_AVX */
}
- else if (__cpu_model.__cpu_vendor == VENDOR_AMD)
+ else if (__builtin_cpu_is ("amd"))
{
#if defined(HAVE_AVX) && defined(HAVE_FMA3) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma"))
{
matmul_fn = matmul_c8_avx128_fma3;
goto store;
}
#endif
#if defined(HAVE_AVX) && defined(HAVE_FMA4) && defined(HAVE_AVX128)
- if ((__cpu_model.__cpu_features[0] & (1 << FEATURE_AVX))
- && (__cpu_model.__cpu_features[0] & (1 << FEATURE_FMA4)))
+ if (__builtin_cpu_supports ("avx")
+ && __builtin_cpu_supports ("fma4"))
{
matmul_fn = matmul_c8_avx128_fma4;
goto store;
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else if (GFC_DESCRIPTOR_RANK (b) == 1)
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic: is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
else
arg_extent = GFC_DESCRIPTOR_EXTENT(a,0);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 1:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 1 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
arg_extent = GFC_DESCRIPTOR_EXTENT(b,1);
ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,1);
if (arg_extent != ret_extent)
- runtime_error ("Incorrect extent in return array in"
- " MATMUL intrinsic for dimension 2:"
- " is %ld, should be %ld",
+ runtime_error ("Array bound mismatch for dimension 2 of "
+ "array (%ld/%ld) ",
(long int) ret_extent, (long int) arg_extent);
}
}
if (count != GFC_DESCRIPTOR_EXTENT(b,0))
{
if (count > 0 || GFC_DESCRIPTOR_EXTENT(b,0) > 0)
- runtime_error ("dimension of array B incorrect in MATMUL intrinsic");
+ runtime_error ("Incorrect extent in argument B in MATMUL intrinsic "
+ "in dimension 1: is %ld, should be %ld",
+ (long int) GFC_DESCRIPTOR_EXTENT(b,0), (long int) count);
}
if (GFC_DESCRIPTOR_RANK (b) == 1)
if (lda > 0 && ldb > 0 && ldc > 0 && m > 1 && n > 1 && k > 1)
{
assert (gemm != NULL);
- gemm (axstride == 1 ? "N" : "T", bxstride == 1 ? "N" : "T", &m,
+ const char *transa, *transb;
+ if (try_blas & 2)
+ transa = "C";
+ else
+ transa = axstride == 1 ? "N" : "T";
+
+ if (try_blas & 4)
+ transb = "C";
+ else
+ transb = bxstride == 1 ? "N" : "T";
+
+ gemm (transa, transb , &m,
&n, &k, &one, abase, &lda, bbase, &ldb, &zero, dest,
&ldc, 1, 1);
return;
return;
/* Adjust size of t1 to what is needed. */
- index_type t1_dim;
- t1_dim = (a_dim1 - (ycount > 1)) * 256 + b_dim1;
+ index_type t1_dim, a_sz;
+ if (aystride == 1)
+ a_sz = rystride;
+ else
+ a_sz = a_dim1;
+
+ t1_dim = a_sz * 256 + b_dim1;
if (t1_dim > 65536)
t1_dim = 65536;
}
}
}
- else if (axstride < aystride)
- {
- for (y = 0; y < ycount; y++)
- for (x = 0; x < xcount; x++)
- dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
-
- for (y = 0; y < ycount; y++)
- for (n = 0; n < count; n++)
- for (x = 0; x < xcount; x++)
- /* dest[x,y] += a[x,n] * b[n,y] */
- dest[x*rxstride + y*rystride] +=
- abase[x*axstride + n*aystride] *
- bbase[n*bxstride + y*bystride];
- }
else if (GFC_DESCRIPTOR_RANK (a) == 1)
{
const GFC_COMPLEX_8 *restrict bbase_y;
dest[y*rxstride] = s;
}
}
+ else if (axstride < aystride)
+ {
+ for (y = 0; y < ycount; y++)
+ for (x = 0; x < xcount; x++)
+ dest[x*rxstride + y*rystride] = (GFC_COMPLEX_8)0;
+
+ for (y = 0; y < ycount; y++)
+ for (n = 0; n < count; n++)
+ for (x = 0; x < xcount; x++)
+ /* dest[x,y] += a[x,n] * b[n,y] */
+ dest[x*rxstride + y*rystride] +=
+ abase[x*axstride + n*aystride] *
+ bbase[n*bxstride + y*bystride];
+ }
else
{
const GFC_COMPLEX_8 *restrict abase_x;