Skip to content

Commit e22cfe6

Browse files
committed
sve - initial SVE backend framework
1 parent 39d18f8 commit e22cfe6

8 files changed

Lines changed: 485 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-ref.c := $(sort $(wildcard backends/cuda-ref/*.c))
@@ -285,6 +286,7 @@ info:
285286
$(info ------------------------------------)
286287
$(info MEMCHK_STATUS = $(MEMCHK_STATUS)$(call backend_status,$(MEMCHK_BACKENDS)))
287288
$(info AVX_STATUS = $(AVX_STATUS)$(call backend_status,$(AVX_BACKENDS)))
289+
$(info SVE_STATUS = $(SVE_STATUS)$(call backend_status,$(SVE_BACKENDS)))
288290
$(info XSMM_DIR = $(XSMM_DIR)$(call backend_status,$(XSMM_BACKENDS)))
289291
$(info OCCA_DIR = $(OCCA_DIR)$(call backend_status,$(OCCA_BACKENDS)))
290292
$(info MAGMA_DIR = $(MAGMA_DIR)$(call backend_status,$(MAGMA_BACKENDS)))
@@ -325,7 +327,7 @@ ifeq ($(MEMCHK),1)
325327
BACKENDS_MAKE += $(MEMCHK_BACKENDS)
326328
endif
327329

328-
# AVX Backed
330+
# AVX Backends
329331
AVX_STATUS = Disabled
330332
AVX_FLAG := $(if $(filter clang,$(CC_VENDOR)),+avx,-mavx)
331333
AVX := $(filter $(AVX_FLAG),$(shell $(CC) $(CFLAGS) -v -E -x c /dev/null 2>&1))
@@ -336,6 +338,17 @@ ifneq ($(AVX),)
336338
BACKENDS_MAKE += $(AVX_BACKENDS)
337339
endif
338340

341+
# SVE Backends
342+
SVE_STATUS = Disabled
343+
SVE_FLAG := $(if $(filter clang,$(CC_VENDOR)),+sve,-msve)
344+
SVE ?=
345+
SVE_BACKENDS = /cpu/self/sve/serial /cpu/self/sve/blocked
346+
ifneq ($(SVE),)
347+
SVE_STATUS = Enabled
348+
libceed.c += $(sve.c)
349+
BACKENDS_MAKE += $(SVE_BACKENDS)
350+
endif
351+
339352
# Collect list of libraries and paths for use in linking and pkg-config
340353
PKG_LIBS =
341354
# Stubs that will not be RPATH'd
@@ -415,7 +428,7 @@ ifneq ($(HIP_LIB_DIR),)
415428
BACKENDS_MAKE += $(HIP_BACKENDS)
416429
endif
417430

418-
# MAGMA Backend
431+
# MAGMA Backends
419432
ifneq ($(wildcard $(MAGMA_DIR)/lib/libmagma.*),)
420433
MAGMA_ARCH=$(shell nm -g $(MAGMA_DIR)/lib/libmagma.* | grep -c "hipblas")
421434
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: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC.
2+
// Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707.
3+
// All Rights reserved. See files LICENSE and NOTICE for details.
4+
//
5+
// This file is part of CEED, a collection of benchmarks, miniapps, software
6+
// libraries and APIs for efficient high-order finite element and spectral
7+
// element discretizations for exascale applications. For more information and
8+
// source code availability see http://github.com/ceed.
9+
//
10+
// The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11+
// a collaborative effort of two U.S. Department of Energy organizations (Office
12+
// of Science and the National Nuclear Security Administration) responsible for
13+
// the planning and preparation of a capable exascale ecosystem, including
14+
// software, applications, hardware, advanced system engineering and early
15+
// testbed platforms, in support of the nation's exascale computing imperative.
16+
17+
#include <ceed/ceed.h>
18+
#include <ceed/backend.h>
19+
#include <stdbool.h>
20+
#include <string.h>
21+
#include "ceed-sve.h"
22+
23+
//------------------------------------------------------------------------------
24+
// Backend Init
25+
//------------------------------------------------------------------------------
26+
static int CeedInit_Sve(const char *resource, Ceed ceed) {
27+
int ierr;
28+
if (strcmp(resource, "/cpu/self") && strcmp(resource, "/cpu/self/sve") &&
29+
strcmp(resource, "/cpu/self/sve/blocked"))
30+
// LCOV_EXCL_START
31+
return CeedError(ceed, CEED_ERROR_BACKEND,
32+
"SVE backend cannot use resource: %s", resource);
33+
// LCOV_EXCL_STOP
34+
ierr = CeedSetDeterministic(ceed, true); CeedChkBackend(ierr);
35+
36+
// Create reference CEED that implementation will be dispatched
37+
// through unless overridden
38+
Ceed ceed_ref;
39+
CeedInit("/cpu/self/opt/blocked", &ceed_ref);
40+
ierr = CeedSetDelegate(ceed, ceed_ref); CeedChkBackend(ierr);
41+
42+
if (CEED_SCALAR_TYPE == CEED_SCALAR_FP64) {
43+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "TensorContractCreate",
44+
CeedTensorContractCreate_f64_Sve);
45+
CeedChkBackend(ierr);
46+
} else {
47+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "TensorContractCreate",
48+
CeedTensorContractCreate_f32_Sve);
49+
CeedChkBackend(ierr);
50+
}
51+
52+
return CEED_ERROR_SUCCESS;
53+
}
54+
55+
//------------------------------------------------------------------------------
56+
// Backend Register
57+
//------------------------------------------------------------------------------
58+
CEED_INTERN int CeedRegister_Sve_Blocked(void) {
59+
return CeedRegister("/cpu/self/sve/blocked", CeedInit_Sve, 30);
60+
}
61+
//------------------------------------------------------------------------------

backends/sve/ceed-sve-serial.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC.
2+
// Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707.
3+
// All Rights reserved. See files LICENSE and NOTICE for details.
4+
//
5+
// This file is part of CEED, a collection of benchmarks, miniapps, software
6+
// libraries and APIs for efficient high-order finite element and spectral
7+
// element discretizations for exascale applications. For more information and
8+
// source code availability see http://github.com/ceed.
9+
//
10+
// The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11+
// a collaborative effort of two U.S. Department of Energy organizations (Office
12+
// of Science and the National Nuclear Security Administration) responsible for
13+
// the planning and preparation of a capable exascale ecosystem, including
14+
// software, applications, hardware, advanced system engineering and early
15+
// testbed platforms, in support of the nation's exascale computing imperative.
16+
17+
#include <ceed/ceed.h>
18+
#include <ceed/backend.h>
19+
#include <stdbool.h>
20+
#include <string.h>
21+
#include "ceed-sve.h"
22+
23+
//------------------------------------------------------------------------------
24+
// Backend Init
25+
//------------------------------------------------------------------------------
26+
static int CeedInit_Sve(const char *resource, Ceed ceed) {
27+
int ierr;
28+
if (strcmp(resource, "/cpu/self")
29+
&& strcmp(resource, "/cpu/self/sve/serial"))
30+
// LCOV_EXCL_START
31+
return CeedError(ceed, CEED_ERROR_BACKEND,
32+
"SVE backend cannot use resource: %s", resource);
33+
// LCOV_EXCL_STOP
34+
ierr = CeedSetDeterministic(ceed, true); CeedChkBackend(ierr);
35+
36+
// Create reference CEED that implementation will be dispatched
37+
// through unless overridden
38+
Ceed ceed_ref;
39+
CeedInit("/cpu/self/opt/serial", &ceed_ref);
40+
ierr = CeedSetDelegate(ceed, ceed_ref); CeedChkBackend(ierr);
41+
42+
if (CEED_SCALAR_TYPE == CEED_SCALAR_FP64) {
43+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "TensorContractCreate",
44+
CeedTensorContractCreate_f64_Sve);
45+
CeedChkBackend(ierr);
46+
} else {
47+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "TensorContractCreate",
48+
CeedTensorContractCreate_f32_Sve);
49+
CeedChkBackend(ierr);
50+
}
51+
52+
return CEED_ERROR_SUCCESS;
53+
}
54+
55+
//------------------------------------------------------------------------------
56+
// Backend Register
57+
//------------------------------------------------------------------------------
58+
CEED_INTERN int CeedRegister_Sve_Serial(void) {
59+
return CeedRegister("/cpu/self/sve/serial", CeedInit_Sve, 35);
60+
}
61+
//------------------------------------------------------------------------------

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

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
// Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC.
2+
// Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707.
3+
// All Rights reserved. See files LICENSE and NOTICE for details.
4+
//
5+
// This file is part of CEED, a collection of benchmarks, miniapps, software
6+
// libraries and APIs for efficient high-order finite element and spectral
7+
// element discretizations for exascale applications. For more information and
8+
// source code availability see http://github.com/ceed.
9+
//
10+
// The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11+
// a collaborative effort of two U.S. Department of Energy organizations (Office
12+
// of Science and the National Nuclear Security Administration) responsible for
13+
// the planning and preparation of a capable exascale ecosystem, including
14+
// software, applications, hardware, advanced system engineering and early
15+
// testbed platforms, in support of the nation's exascale computing imperative.
16+
17+
#include <ceed/ceed.h>
18+
#include <ceed/backend.h>
19+
#ifdef __ARM_FEATURE_SVE
20+
#include <arm_sve.h>
21+
#endif
22+
#include <stdbool.h>
23+
#include "ceed-sve.h"
24+
25+
//------------------------------------------------------------------------------
26+
// Blocked Tensor Contract
27+
//------------------------------------------------------------------------------
28+
static inline int CeedTensorContract_Sve_Blocked(CeedTensorContract contract,
29+
CeedInt A, CeedInt B, CeedInt C, CeedInt J, const float *restrict t,
30+
CeedTransposeMode t_mode, const CeedInt add, const float *restrict u,
31+
float *restrict v, const CeedInt JJ) {
32+
CeedInt t_stride_0 = B, t_stride_1 = 1;
33+
if (t_mode == CEED_TRANSPOSE) {
34+
t_stride_0 = 1; t_stride_1 = J;
35+
}
36+
37+
for (CeedInt a=0; a<A; a++)
38+
for (CeedInt b=0; b<B; b++)
39+
// Blocks of JJ rows
40+
for (CeedInt j=0; j<(J/JJ)*JJ; j+=JJ)
41+
for (CeedInt jj=0; jj<JJ; jj++) // unroll
42+
// C vectorization by compiler
43+
for (int32_t c=0; c<C; c+=svcntd()) {
44+
svbool_t pg = svwhilelt_b32(c, C);
45+
// Load u, v into vectors
46+
svfloat32_t u_vec = svld1(pg, &u[(a*B+b)*C+c]);
47+
svfloat32_t v_vec = svld1(pg, &v[(a*J+j+jj)*C+c]);
48+
// Basis matrix value
49+
float tq = t[(j+jj)*t_stride_0 + b*t_stride_1];
50+
// fmadd
51+
svst1(pg, &v[(a*J+j+jj)*C+c], svmla_x(pg, v_vec, u_vec, tq));
52+
}
53+
54+
// Remainder of rows
55+
CeedInt j=(J/JJ)*JJ;
56+
if (j < J)
57+
for (CeedInt a=0; a<A; a++)
58+
for (CeedInt b=0; b<B; b++)
59+
// Blocks of JJ rows
60+
for (CeedInt jj=0; jj<J-j; jj++) // not unrolled
61+
// C vectorization by compiler
62+
for (int32_t c=0; c<C; c+=svcntd()) {
63+
svbool_t pg = svwhilelt_b32(c, C);
64+
// Load u, v into vectors
65+
svfloat32_t u_vec = svld1(pg, &u[(a*B+b)*C+c]);
66+
svfloat32_t v_vec = svld1(pg, &v[(a*J+j+jj)*C+c]);
67+
// Basis matrix value
68+
float tq = t[(j+jj)*t_stride_0 + b*t_stride_1];
69+
// fmadd
70+
svst1(pg, &v[(a*J+j+jj)*C+c], svmla_x(pg, v_vec, u_vec, tq));
71+
}
72+
73+
return CEED_ERROR_SUCCESS;
74+
}
75+
76+
//------------------------------------------------------------------------------
77+
// Blocked Tensor Contract
78+
//------------------------------------------------------------------------------
79+
static inline int CeedTensorContract_Sve_Serial(CeedTensorContract contract,
80+
CeedInt A, CeedInt B, CeedInt C, CeedInt J, const float *restrict t,
81+
CeedTransposeMode t_mode, const CeedInt add, const float *restrict u,
82+
float *restrict v, const CeedInt JJ) {
83+
CeedInt t_stride_0 = B, t_stride_1 = 1;
84+
if (t_mode == CEED_TRANSPOSE) {
85+
t_stride_0 = 1; t_stride_1 = J;
86+
}
87+
88+
for (CeedInt a=0; a<A; a++)
89+
for (CeedInt b=0; b<B; b++)
90+
for (CeedInt j=0; j<(J/JJ)*JJ; j+=JJ)
91+
for (CeedInt jj=0; jj<JJ; jj++) // unroll
92+
v[a*J+(j+jj)] += t[(j+jj)*t_stride_0 + b*t_stride_1] * u[a*B+b];
93+
94+
CeedInt j=(J/JJ)*JJ;
95+
if (j < J)
96+
for (CeedInt a=0; a<A; a++)
97+
for (CeedInt b=0; b<B; b++)
98+
for (CeedInt jj=0; jj<J-j; jj++) // not unrolled
99+
v[a*J+(j+jj)] += t[(j+jj)*t_stride_0 + b*t_stride_1] * u[a*B+b];
100+
101+
return CEED_ERROR_SUCCESS;
102+
}
103+
104+
//------------------------------------------------------------------------------
105+
// Tensor Contract - Common Sizes
106+
//------------------------------------------------------------------------------
107+
static int CeedTensorContract_Sve_Blocked_8(CeedTensorContract contract,
108+
CeedInt A, CeedInt B, CeedInt C, CeedInt J, const float *restrict t,
109+
CeedTransposeMode t_mode, const CeedInt add, const float *restrict u,
110+
float *restrict v) {
111+
return CeedTensorContract_Sve_Blocked(contract, A, B, C, J, t, t_mode, add, u,
112+
v, 8);
113+
}
114+
static int CeedTensorContract_Sve_Serial_8(CeedTensorContract contract,
115+
CeedInt A, CeedInt B, CeedInt C, CeedInt J, const float *restrict t,
116+
CeedTransposeMode t_mode, const CeedInt add, const float *restrict u,
117+
float *restrict v) {
118+
return CeedTensorContract_Sve_Serial(contract, A, B, C, J, t, t_mode, add, u, v,
119+
8);
120+
}
121+
122+
//------------------------------------------------------------------------------
123+
// Tensor Contract Apply
124+
//------------------------------------------------------------------------------
125+
static int CeedTensorContractApply_Sve(CeedTensorContract contract, CeedInt A,
126+
CeedInt B, CeedInt C, CeedInt J,
127+
const float *restrict t,
128+
CeedTransposeMode t_mode,
129+
const CeedInt add,
130+
const float *restrict u,
131+
float *restrict v) {
132+
if (!add)
133+
for (CeedInt q=0; q<A*J*C; q++)
134+
v[q] = (float) 0.0;
135+
136+
if (C == 1)
137+
CeedTensorContract_Sve_Serial_8(contract, A, B, C, J, t, t_mode, true, u, v);
138+
else
139+
CeedTensorContract_Sve_Blocked_8(contract, A, B, C, J, t, t_mode, true, u, v);
140+
141+
return CEED_ERROR_SUCCESS;
142+
}
143+
144+
//------------------------------------------------------------------------------
145+
// Tensor Contract Create
146+
//------------------------------------------------------------------------------
147+
int CeedTensorContractCreate_f32_Sve(CeedBasis basis,
148+
CeedTensorContract contract) {
149+
int ierr;
150+
Ceed ceed;
151+
ierr = CeedTensorContractGetCeed(contract, &ceed); CeedChkBackend(ierr);
152+
153+
ierr = CeedSetBackendFunction(ceed, "TensorContract", contract, "Apply",
154+
CeedTensorContractApply_Sve); CeedChkBackend(ierr);
155+
156+
return CEED_ERROR_SUCCESS;
157+
}
158+
//------------------------------------------------------------------------------

0 commit comments

Comments
 (0)