| 40 | |
| 41 | template<typename T, af_storage stype> |
| 42 | SparseArray<T> sparseConvertDenseToStorage(const Array<T> &in) { |
| 43 | if (stype == AF_STORAGE_CSR) { |
| 44 | uint nNZ = getScalar<uint>(reduce_all<af_notzero_t, T, uint>(in)); |
| 45 | |
| 46 | auto sparse = createEmptySparseArray<T>(in.dims(), nNZ, stype); |
| 47 | sparse.eval(); |
| 48 | |
| 49 | Array<T> values = sparse.getValues(); |
| 50 | Array<int> rowIdx = sparse.getRowIdx(); |
| 51 | Array<int> colIdx = sparse.getColIdx(); |
| 52 | |
| 53 | getQueue().enqueue(kernel::dense2csr<T>, values, rowIdx, colIdx, in); |
| 54 | |
| 55 | return sparse; |
| 56 | } else if (stype == AF_STORAGE_COO) { |
| 57 | auto nonZeroIdx = cast<int, uint>(where<T>(in)); |
| 58 | |
| 59 | dim_t nNZ = nonZeroIdx.elements(); |
| 60 | |
| 61 | auto cnst = createValueArray<int>(dim4(nNZ), in.dims()[0]); |
| 62 | |
| 63 | auto rowIdx = |
| 64 | arithOp<int, af_mod_t>(nonZeroIdx, cnst, nonZeroIdx.dims()); |
| 65 | auto colIdx = |
| 66 | arithOp<int, af_div_t>(nonZeroIdx, cnst, nonZeroIdx.dims()); |
| 67 | |
| 68 | Array<T> values = copyArray<T>(in); |
| 69 | values.modDims(dim4(values.elements())); |
| 70 | values = lookup<T, int>(values, nonZeroIdx, 0); |
| 71 | |
| 72 | return createArrayDataSparseArray<T>(in.dims(), values, rowIdx, colIdx, |
| 73 | stype); |
| 74 | } else { |
| 75 | AF_ERROR("CPU Backend only supports Dense to CSR or COO", |
| 76 | AF_ERR_NOT_SUPPORTED); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | template<typename T, af_storage stype> |
| 81 | Array<T> sparseConvertStorageToDense(const SparseArray<T> &in) { |