Skip to content

Commit d3cd77e

Browse files
committed
sve - initial SVE backend framework
1 parent dc64899 commit d3cd77e

8 files changed

Lines changed: 440 additions & 2 deletions

File tree

Makefile

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ blocked.c := $(sort $(wildcard backends/blocked/*.c))
222222
ceedmemcheck.c := $(sort $(wildcard backends/memcheck/*.c))
223223
opt.c := $(sort $(wildcard backends/opt/*.c))
224224
avx.c := $(sort $(wildcard backends/avx/*.c))
225+
sve.c := $(sort $(wildcard backends/sve/*.c))
225226
xsmm.c := $(sort $(wildcard backends/xsmm/*.c))
226227
cuda.c := $(sort $(wildcard backends/cuda/*.c))
227228
cuda.cpp := $(sort $(wildcard backends/cuda/*.cpp))
@@ -287,6 +288,7 @@ info:
287288
$(info ------------------------------------)
288289
$(info MEMCHK_STATUS = $(MEMCHK_STATUS)$(call backend_status,$(MEMCHK_BACKENDS)))
289290
$(info AVX_STATUS = $(AVX_STATUS)$(call backend_status,$(AVX_BACKENDS)))
291+
$(info SVE_STATUS = $(SVE_STATUS)$(call backend_status,$(SVE_BACKENDS)))
290292
$(info XSMM_DIR = $(XSMM_DIR)$(call backend_status,$(XSMM_BACKENDS)))
291293
$(info OCCA_DIR = $(OCCA_DIR)$(call backend_status,$(OCCA_BACKENDS)))
292294
$(info MAGMA_DIR = $(MAGMA_DIR)$(call backend_status,$(MAGMA_BACKENDS)))
@@ -327,7 +329,7 @@ ifeq ($(MEMCHK),1)
327329
BACKENDS_MAKE += $(MEMCHK_BACKENDS)
328330
endif
329331

330-
# AVX Backed
332+
# AVX Backends
331333
AVX_STATUS = Disabled
332334
AVX_FLAG := $(if $(filter clang,$(CC_VENDOR)),+avx,-mavx)
333335
AVX := $(filter $(AVX_FLAG),$(shell $(CC) $(CFLAGS) -v -E -x c /dev/null 2>&1))
@@ -338,6 +340,17 @@ ifneq ($(AVX),)
338340
BACKENDS_MAKE += $(AVX_BACKENDS)
339341
endif
340342

343+
# SVE Backends
344+
SVE_STATUS = Disabled
345+
SVE_FLAG := $(if $(filter clang,$(CC_VENDOR)),+sve,-msve)
346+
SVE ?=
347+
SVE_BACKENDS = /cpu/self/sve/serial /cpu/self/sve/blocked
348+
ifneq ($(SVE),)
349+
SVE_STATUS = Enabled
350+
libceed.c += $(sve.c)
351+
BACKENDS_MAKE += $(SVE_BACKENDS)
352+
endif
353+
341354
# Collect list of libraries and paths for use in linking and pkg-config
342355
PKG_LIBS =
343356
# Stubs that will not be RPATH'd
@@ -419,7 +432,7 @@ ifneq ($(HIP_LIB_DIR),)
419432
BACKENDS_MAKE += $(HIP_BACKENDS)
420433
endif
421434

422-
# MAGMA Backend
435+
# MAGMA Backends
423436
ifneq ($(wildcard $(MAGMA_DIR)/lib/libmagma.*),)
424437
MAGMA_ARCH=$(shell nm -g $(MAGMA_DIR)/lib/libmagma.* | grep -c "hipblas")
425438
ifeq ($(MAGMA_ARCH), 0) #CUDA MAGMA

backends/ceed-backend-list.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,7 @@ MACRO(CeedRegister_Opt_Blocked, 1, "/cpu/self/opt/blocked")
2929
MACRO(CeedRegister_Opt_Serial, 1, "/cpu/self/opt/serial")
3030
MACRO(CeedRegister_Ref, 1, "/cpu/self/ref/serial")
3131
MACRO(CeedRegister_Ref_Blocked, 1, "/cpu/self/ref/blocked")
32+
MACRO(CeedRegister_Sve_Serial, 1, "/cpu/self/sve/serial")
33+
MACRO(CeedRegister_Sve_Blocked, 1, "/cpu/self/sve/blocked")
3234
MACRO(CeedRegister_Xsmm_Blocked, 1, "/cpu/self/xsmm/blocked")
3335
MACRO(CeedRegister_Xsmm_Serial, 1, "/cpu/self/xsmm/serial")

backends/opt/ceed-opt-blocked.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ static int CeedInit_Opt_Blocked(const char *resource, Ceed ceed) {
4949

5050
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "Destroy",
5151
CeedDestroy_Opt); CeedChkBackend(ierr);
52+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "TensorContractCreate",
53+
CeedTensorContractCreate_Opt); CeedChkBackend(ierr);
5254
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "OperatorCreate",
5355
CeedOperatorCreate_Opt); CeedChkBackend(ierr);
5456

backends/sve/ceed-sve-blocked.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
2+
// All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3+
//
4+
// SPDX-License-Identifier: BSD-2-Clause
5+
//
6+
// This file is part of CEED: http://github.com/ceed
7+
8+
#include <ceed/ceed.h>
9+
#include <ceed/backend.h>
10+
#include <stdbool.h>
11+
#include <string.h>
12+
#include "ceed-sve.h"
13+
14+
//------------------------------------------------------------------------------
15+
// Backend Init
16+
//------------------------------------------------------------------------------
17+
static int CeedInit_Sve(const char *resource, Ceed ceed) {
18+
int ierr;
19+
if (strcmp(resource, "/cpu/self") && strcmp(resource, "/cpu/self/sve") &&
20+
strcmp(resource, "/cpu/self/sve/blocked"))
21+
// LCOV_EXCL_START
22+
return CeedError(ceed, CEED_ERROR_BACKEND,
23+
"SVE backend cannot use resource: %s", resource);
24+
// LCOV_EXCL_STOP
25+
ierr = CeedSetDeterministic(ceed, true); CeedChkBackend(ierr);
26+
27+
// Create reference CEED that implementation will be dispatched
28+
// through unless overridden
29+
Ceed ceed_ref;
30+
CeedInit("/cpu/self/opt/blocked", &ceed_ref);
31+
ierr = CeedSetDelegate(ceed, ceed_ref); CeedChkBackend(ierr);
32+
33+
if (CEED_SCALAR_TYPE == CEED_SCALAR_FP64) {
34+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "TensorContractCreate",
35+
CeedTensorContractCreate_f64_Sve);
36+
CeedChkBackend(ierr);
37+
} else {
38+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "TensorContractCreate",
39+
CeedTensorContractCreate_f32_Sve);
40+
CeedChkBackend(ierr);
41+
}
42+
43+
return CEED_ERROR_SUCCESS;
44+
}
45+
46+
//------------------------------------------------------------------------------
47+
// Backend Register
48+
//------------------------------------------------------------------------------
49+
CEED_INTERN int CeedRegister_Sve_Blocked(void) {
50+
return CeedRegister("/cpu/self/sve/blocked", CeedInit_Sve, 30);
51+
}
52+
//------------------------------------------------------------------------------

backends/sve/ceed-sve-serial.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
2+
// All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3+
//
4+
// SPDX-License-Identifier: BSD-2-Clause
5+
//
6+
// This file is part of CEED: http://github.com/ceed
7+
8+
#include <ceed/ceed.h>
9+
#include <ceed/backend.h>
10+
#include <stdbool.h>
11+
#include <string.h>
12+
#include "ceed-sve.h"
13+
14+
//------------------------------------------------------------------------------
15+
// Backend Init
16+
//------------------------------------------------------------------------------
17+
static int CeedInit_Sve(const char *resource, Ceed ceed) {
18+
int ierr;
19+
if (strcmp(resource, "/cpu/self")
20+
&& strcmp(resource, "/cpu/self/sve/serial"))
21+
// LCOV_EXCL_START
22+
return CeedError(ceed, CEED_ERROR_BACKEND,
23+
"SVE backend cannot use resource: %s", resource);
24+
// LCOV_EXCL_STOP
25+
ierr = CeedSetDeterministic(ceed, true); CeedChkBackend(ierr);
26+
27+
// Create reference CEED that implementation will be dispatched
28+
// through unless overridden
29+
Ceed ceed_ref;
30+
CeedInit("/cpu/self/opt/serial", &ceed_ref);
31+
ierr = CeedSetDelegate(ceed, ceed_ref); CeedChkBackend(ierr);
32+
33+
if (CEED_SCALAR_TYPE == CEED_SCALAR_FP64) {
34+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "TensorContractCreate",
35+
CeedTensorContractCreate_f64_Sve);
36+
CeedChkBackend(ierr);
37+
} else {
38+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "TensorContractCreate",
39+
CeedTensorContractCreate_f32_Sve);
40+
CeedChkBackend(ierr);
41+
}
42+
43+
return CEED_ERROR_SUCCESS;
44+
}
45+
46+
//------------------------------------------------------------------------------
47+
// Backend Register
48+
//------------------------------------------------------------------------------
49+
CEED_INTERN int CeedRegister_Sve_Serial(void) {
50+
return CeedRegister("/cpu/self/sve/serial", CeedInit_Sve, 35);
51+
}
52+
//------------------------------------------------------------------------------

backends/sve/ceed-sve-tensor-f32.c

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
2+
// All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3+
//
4+
// SPDX-License-Identifier: BSD-2-Clause
5+
//
6+
// This file is part of CEED: http://github.com/ceed
7+
8+
#include <ceed/ceed.h>
9+
#include <ceed/backend.h>
10+
#ifdef __ARM_FEATURE_SVE
11+
#include <arm_sve.h>
12+
#endif
13+
#include <stdbool.h>
14+
#include "ceed-sve.h"
15+
16+
//------------------------------------------------------------------------------
17+
// Blocked Tensor Contract
18+
//------------------------------------------------------------------------------
19+
static inline int CeedTensorContract_Sve_Blocked(CeedTensorContract contract,
20+
CeedInt A, CeedInt B, CeedInt C, CeedInt J, const float *restrict t,
21+
CeedTransposeMode t_mode, const CeedInt add, const float *restrict u,
22+
float *restrict v, const CeedInt JJ) {
23+
CeedInt t_stride_0 = B, t_stride_1 = 1;
24+
if (t_mode == CEED_TRANSPOSE) {
25+
t_stride_0 = 1; t_stride_1 = J;
26+
}
27+
28+
for (CeedInt a=0; a<A; a++)
29+
for (CeedInt b=0; b<B; b++)
30+
// Blocks of JJ rows
31+
for (CeedInt j=0; j<(J/JJ)*JJ; j+=JJ)
32+
for (CeedInt jj=0; jj<JJ; jj++) // unroll
33+
// C vectorization by compiler
34+
for (int32_t c=0; c<C; c+=svcntd()) {
35+
svbool_t pg = svwhilelt_b32(c, C);
36+
// Load u, v into vectors
37+
svfloat32_t u_vec = svld1(pg, &u[(a*B+b)*C+c]);
38+
svfloat32_t v_vec = svld1(pg, &v[(a*J+j+jj)*C+c]);
39+
// Basis matrix value
40+
float tq = t[(j+jj)*t_stride_0 + b*t_stride_1];
41+
// fmadd
42+
svst1(pg, &v[(a*J+j+jj)*C+c], svmla_x(pg, v_vec, u_vec, tq));
43+
}
44+
45+
// Remainder of rows
46+
CeedInt j=(J/JJ)*JJ;
47+
if (j < J)
48+
for (CeedInt a=0; a<A; a++)
49+
for (CeedInt b=0; b<B; b++)
50+
// Blocks of JJ rows
51+
for (CeedInt jj=0; jj<J-j; jj++) // not unrolled
52+
// C vectorization by compiler
53+
for (int32_t c=0; c<C; c+=svcntd()) {
54+
svbool_t pg = svwhilelt_b32(c, C);
55+
// Load u, v into vectors
56+
svfloat32_t u_vec = svld1(pg, &u[(a*B+b)*C+c]);
57+
svfloat32_t v_vec = svld1(pg, &v[(a*J+j+jj)*C+c]);
58+
// Basis matrix value
59+
float tq = t[(j+jj)*t_stride_0 + b*t_stride_1];
60+
// fmadd
61+
svst1(pg, &v[(a*J+j+jj)*C+c], svmla_x(pg, v_vec, u_vec, tq));
62+
}
63+
64+
return CEED_ERROR_SUCCESS;
65+
}
66+
67+
//------------------------------------------------------------------------------
68+
// Blocked Tensor Contract
69+
//------------------------------------------------------------------------------
70+
static inline int CeedTensorContract_Sve_Serial(CeedTensorContract contract,
71+
CeedInt A, CeedInt B, CeedInt C, CeedInt J, const float *restrict t,
72+
CeedTransposeMode t_mode, const CeedInt add, const float *restrict u,
73+
float *restrict v, const CeedInt JJ) {
74+
CeedInt t_stride_0 = B, t_stride_1 = 1;
75+
if (t_mode == CEED_TRANSPOSE) {
76+
t_stride_0 = 1; t_stride_1 = J;
77+
}
78+
79+
for (CeedInt a=0; a<A; a++)
80+
for (CeedInt b=0; b<B; b++)
81+
for (CeedInt j=0; j<(J/JJ)*JJ; j+=JJ)
82+
for (CeedInt jj=0; jj<JJ; jj++) // unroll
83+
v[a*J+(j+jj)] += t[(j+jj)*t_stride_0 + b*t_stride_1] * u[a*B+b];
84+
85+
CeedInt j=(J/JJ)*JJ;
86+
if (j < J)
87+
for (CeedInt a=0; a<A; a++)
88+
for (CeedInt b=0; b<B; b++)
89+
for (CeedInt jj=0; jj<J-j; jj++) // not unrolled
90+
v[a*J+(j+jj)] += t[(j+jj)*t_stride_0 + b*t_stride_1] * u[a*B+b];
91+
92+
return CEED_ERROR_SUCCESS;
93+
}
94+
95+
//------------------------------------------------------------------------------
96+
// Tensor Contract - Common Sizes
97+
//------------------------------------------------------------------------------
98+
static int CeedTensorContract_Sve_Blocked_8(CeedTensorContract contract,
99+
CeedInt A, CeedInt B, CeedInt C, CeedInt J, const float *restrict t,
100+
CeedTransposeMode t_mode, const CeedInt add, const float *restrict u,
101+
float *restrict v) {
102+
return CeedTensorContract_Sve_Blocked(contract, A, B, C, J, t, t_mode, add, u,
103+
v, 8);
104+
}
105+
static int CeedTensorContract_Sve_Serial_8(CeedTensorContract contract,
106+
CeedInt A, CeedInt B, CeedInt C, CeedInt J, const float *restrict t,
107+
CeedTransposeMode t_mode, const CeedInt add, const float *restrict u,
108+
float *restrict v) {
109+
return CeedTensorContract_Sve_Serial(contract, A, B, C, J, t, t_mode, add, u, v,
110+
8);
111+
}
112+
113+
//------------------------------------------------------------------------------
114+
// Tensor Contract Apply
115+
//------------------------------------------------------------------------------
116+
static int CeedTensorContractApply_Sve(CeedTensorContract contract, CeedInt A,
117+
CeedInt B, CeedInt C, CeedInt J,
118+
const float *restrict t,
119+
CeedTransposeMode t_mode,
120+
const CeedInt add,
121+
const float *restrict u,
122+
float *restrict v) {
123+
if (!add)
124+
for (CeedInt q=0; q<A*J*C; q++)
125+
v[q] = (float) 0.0;
126+
127+
if (C == 1)
128+
CeedTensorContract_Sve_Serial_8(contract, A, B, C, J, t, t_mode, true, u, v);
129+
else
130+
CeedTensorContract_Sve_Blocked_8(contract, A, B, C, J, t, t_mode, true, u, v);
131+
132+
return CEED_ERROR_SUCCESS;
133+
}
134+
135+
//------------------------------------------------------------------------------
136+
// Tensor Contract Create
137+
//------------------------------------------------------------------------------
138+
int CeedTensorContractCreate_f32_Sve(CeedBasis basis,
139+
CeedTensorContract contract) {
140+
int ierr;
141+
Ceed ceed;
142+
ierr = CeedTensorContractGetCeed(contract, &ceed); CeedChkBackend(ierr);
143+
144+
ierr = CeedSetBackendFunction(ceed, "TensorContract", contract, "Apply",
145+
CeedTensorContractApply_Sve); CeedChkBackend(ierr);
146+
147+
return CEED_ERROR_SUCCESS;
148+
}
149+
//------------------------------------------------------------------------------

0 commit comments

Comments
 (0)