Commit ac574e09 authored by Roger Ferrer's avatar Roger Ferrer
Browse files

Update for EPI-0.7

parent ef69ffb8
Loading
Loading
Loading
Loading
+3 −4
Changes for README.md: 3 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -27,16 +27,15 @@ low-level builtins.

## Documentation

These builtins targets the 0.8 version of the extension. The implementation
These builtins targets the 0.7 version of the extension. The implementation
is not complete and there are known limitations. See section _Known limitations_
below.

- [EPI builtins reference (Markdown)](https://repo.hca.bsc.es/gitlab/rferrer/epi-builtins-ref/blob/master/epi-builtins-ref.md). (May take a bit to render in the browser)
- [Examples](https://repo.hca.bsc.es/gitlab/rferrer/epi-builtins-ref/blob/master/examples.md)
- [EPI builtins reference (Markdown)](https://repo.hca.bsc.es/gitlab/rferrer/epi-builtins-ref/blob/EPI-0.7/epi-builtins-ref.md). (May take a bit to render in the browser)

We have implemented these builtins in a LLVM-based compiler.

 - The compiler can be used via the Compiler Explorer found at http://repo.hca.bsc.es/epic
 - The compiler can be used via the Compiler Explorer found at [http://repo.hca.bsc.es/epic](http://repo.hca.bsc.es/epic) Make sure you select the EPI-0.7 compiler.

## Some design decisions taken

+763 −408

File changed.

Preview size limit exceeded, changes collapsed.

epi-builtins-ref.pdf

0 → 100644
+607 KiB

File added.

No diff preview for this file type.

examples.md

deleted100644 → 0
+0 −162
Changes for examples.md: 0 added lines, 162 removed lines.
Original line number Diff line number Diff line
# Examples

This is a set of HPC kernels that we have vectorized using our low-level
intrinsics.

These examples are provided to show the programmability using our
implementation. We do not claim that these are the best possible vectorizations
of those algorithms.

## Vector addition

### Scalar

```cpp
void vec_add(int N, double *c, double *a, double *b)
{
  int N;
  for (i = 0; i < N; i++)
    c[i] = a[i] + b[i];
}
```

### Vector

```cpp
void vec_add(long N, double *c, double *a, double *b) {
  long i;
  for (i = 0; i < N;) {
    long gvl = __builtin_epi_vsetvl(N - i, __epi_e64, __epi_m1);
    __epi_1xf64 va = __builtin_epi_vload_1xf64(&a[i], gvl);
    __epi_1xf64 vb = __builtin_epi_vload_1xf64(&b[i], gvl);
    __epi_1xf64 vc = __builtin_epi_vfadd_1xf64(va, vb, gvl);
    __builtin_epi_vstore_1xf64(&c[i], vc, gvl);
    i += gvl;
  }
}
```

## Conditional vector subtraction

### Scalar

```cpp
void vec_conditional_sub(int N, double *c, double *a, double *b)
{
  int N;
  for (i = 0; i < N; i++)
  {
    c[i] = a[i];
    if (b[i] < a[i])
       c[i] = a[i] - b[i];
  }
}
```

### Vector

```cpp
void vec_conditional_sub(long N, double *c, double *a, double *b) {
  long i;
  for (i = 0; i < N;) {
    long gvl = __builtin_epi_vsetvl(N - i, __epi_e64, __epi_m1);
    __epi_1xf64 va = __builtin_epi_vload_1xf64(&a[i], gvl);
    __epi_1xf64 vb = __builtin_epi_vload_1xf64(&b[i], gvl);
    __epi_1xi1 vm = __builtin_epi_vmflt_1xf64(vb, va, gvl);
    __epi_1xf64 vc = __builtin_epi_vfsub_1xf64_mask(va, va, vb, vm, gvl);
    __builtin_epi_vstore_1xf64(&c[i], vc, gvl);
    i += gvl;
  }
}
```

## DAXPY

### Scalar

```cpp
void axpy_reference(double a, double *dx, double *dy, int n) {
   int i;
   for (i=0; i<n; i++) {
      dy[i] += a*dx[i];
   }
}
```


### Vector

```cpp
void axpy_intrinsics(double a, double *dx, double *dy, int n) {
  int i;

  long gvl = __builtin_epi_vsetvl(n, __epi_e64, __epi_m1);
  __epi_1xf64 v_a = __builtin_epi_vfmv_v_f_1xf64(a, gvl);

  for (i = 0; i < n;) {
    gvl = __builtin_epi_vsetvl(n - i, __epi_e64, __epi_m1);
    __epi_1xf64 v_dx = __builtin_epi_vload_1xf64(&dx[i], gvl);
    __epi_1xf64 v_dy = __builtin_epi_vload_1xf64(&dy[i], gvl);
    // v_res = v_a * v_dx + v_dy
    __epi_1xf64 v_res = __builtin_epi_vfmacc_1xf64(v_dy, v_a, v_dx, gvl);
    __builtin_epi_vstore_1xf64(&dy[i], v_res, gvl);

    i += gvl;
  }
}
```

## Sparse Matrix per Vector

Sparse matrices in CSR format.

### Scalar

```cpp
void SpMV_ref(double *a, long *ia, long *ja, double *x, double *y, int nrows) {
  int row, idx;
  for (row = 0; row < nrows; row++) {
    double sum = 0.0;
    for (idx = ia[row]; idx < ia[row + 1]; idx++) {
      sum += a[idx] * x[ja[idx]];
    }
    y[row] = sum;
  }
}
```

### Vector

```cpp
void SpMV_vec(double *a, long *ia, long *ja, double *x, double *y, int nrows) {
  for (int row = 0; row < nrows; row++) {
    // Number of nonzero elements in this row
    int nnz_row = ia[row + 1] - ia[row];
    int idx = ia[row];

    double acc = 0.0;
    for (int colid = 0; colid < nnz_row;) {
      // requested & granted vector lengths
      int rvl = nnz_row - colid;
      int gvl = __builtin_epi_vsetvl(rvl, __epi_e64, __epi_m1);

      __epi_1xf64 va = __builtin_epi_vload_1xf64(&a[idx + colid], gvl);
      __epi_1xi64 v_idx_row = __builtin_epi_vload_1xi64(&ja[idx + colid], gvl);

      // We need to scale the index to byte offsets
      __epi_1xi64 vthree = __builtin_epi_vmv_v_x_1xi64(3, gvl);
      v_idx_row = __builtin_epi_vsll_1xi64(v_idx_row, vthree, gvl);

      __epi_1xf64 vx = __builtin_epi_vload_indexed_1xf64(x, v_idx_row, gvl);

      __epi_1xf64 vprod = __builtin_epi_vfmul_1xf64(va, vx, gvl);
      __epi_1xf64 partial_res = __builtin_epi_vfmv_v_f_1xf64(0.0, gvl);
      partial_res = __builtin_epi_vfredsum_1xf64(vprod, partial_res, gvl);
      acc += __builtin_epi_vfmv_f_s_1xf64(partial_res);

      colid += gvl;
    }
    y[row] = acc;
  }
}
```