void *split( void *hnd, c4snet_data_t *A, int A_width, int A_height, int nodes) { int i, first, last, block; int *new_array; c4snet_data_t *new_data; int *array = C4SNetGetData(A); block = A_height / nodes; first = 0; last = first + block - 1; for (i = 0; i < nodes - 1; i++) { new_data = C4SNetAlloc(CTYPE_int, A_width * (last - first + 1), (void **) &new_array); memcpy(new_array, (array + A_width * first), sizeof(int) * A_width * (last - first + 1)); C4SNetOut( hnd, 1, new_data, A_width, A_height, i, first, last); first = last + 1; last += block; } last = A_height - 1; new_data = C4SNetAlloc(CTYPE_int, A_width * (last - first + 1), (void **) &new_array); memcpy(new_array, (array + A_width * first), sizeof(int) * A_width * (last - first + 1)); C4SNetOut(hnd, 1, new_data, A_width, A_height, i, first, last); C4SNetFree(A); return hnd; }
static c4snet_data_t *MPIUnpackFun(void *buf) { void *tmp; c4snet_data_t *result; int vtype, type, count; MPIUnpack(buf, &vtype, MPI_INT, 1); MPIUnpack(buf, &count, MPI_INT, 1); MPIUnpack(buf, &type, MPI_INT, 1); if (vtype == VTYPE_array) { result = C4SNetAlloc(type, count, &tmp); MPIUnpack(buf, tmp, TypeToMPIType(type), count); } else { result = C4SNetAlloc(type, 1, &tmp); MPIUnpack(buf, tmp, TypeToMPIType(type), 1); } return result; }
void *init( void *hnd) { int *int_x; c4snet_data_t *result; result = C4SNetAlloc(CTYPE_int, X*Y, &int_x); for (int i = 0; i < X*Y; i++) int_x[i] = i; C4SNetOut(hnd, 1, result); return hnd; }
void *init( void *hnd) { int *int_x; c4snet_data_t *result; result = C4SNetAlloc(CTYPE_int, X*Y, &int_x); for (int i = 0; i < X*Y; i++) int_x[i] = i; printf("\n\n\narray is created\n\n\n"); C4SNetOut(hnd, 1, result); return hnd; }
/* Do the InitialFactorization from input tile Fac to output tile Tri. */ void *facto(void *hnd, c4snet_data_t *Fac, int N, int B, int K) { int j; const int P = N / B; c4snet_data_t *Tri; if (verbose) { printf("%s: %p, N=%d, B=%d, (%d, , )\n", __func__, Fac, N, B, K); } if (compute) { tile_t A = (tile_t) C4SNetGetData(Fac); void *tile_ptr; c4snet_data_t *tile = C4SNetAlloc(CTYPE_double, B * B, &tile_ptr); tile_t L = (tile_t) tile_ptr; int k_b, j_b, j_bb, i_b; memset(L, 0, B * B * sizeof(double)); for (k_b = 0; k_b < B; ++k_b) { if (A[k_b + k_b * B] <= 0) { fprintf(stderr, "Not a symmetric positive definite (SPD) matrix\n"); fprintf(stderr, "K = %d, k_b = %d, B = %d, A[k_b + k_b * B] = %f\n", K, k_b, B, A[k_b + k_b * B]); exit(1); } L[k_b + k_b * B] = sqrt(A[k_b + k_b * B]); for (j_b = k_b + 1; j_b < B; ++j_b) { L[j_b + k_b * B] = A[j_b + k_b * B] / L[k_b + k_b * B]; } for (j_bb = k_b + 1; j_bb < B; ++j_bb) { for (i_b = j_bb; i_b < B; ++i_b) { A[i_b + j_bb * B] -= L[i_b + k_b * B] * L[j_bb + k_b * B]; } } } Tri = tile; C4SNetFree(Fac); } else { Tri = Fac; } for (j = K; j < P; ++j) { if (verbose) { printf("%s: -> Tri, N=%d, B=%d, (%d, %d, )\n", __func__, N, B, K, j); } C4SNetOut(hnd, 1, C4SNetShallowCopy(Tri), N, B, K, j); } /* printf("%s: -> Out, N=%d, B=%d, (%d, %d, %d)\n", __func__, N, B, K, K - 1, K - 1); */ C4SNetOut(hnd, 2, Tri, N, B, K, K - 1, K - 1); return hnd; }
void *split(void *hnd, c4snet_data_t *entries, int num_entries) { c4snet_data_t *hash_cdata; c4snet_data_t *salt_cdata; char *data, *hash, *salt, *first, *middle, *last; first = data = C4SNetGetData(entries) for (int i = 0; i < num_entries; i++) { last = strchr(first, '\n'); if (last == NULL) last = &data[strlen(data)]; for (int j = 0, middle = first; j < 3; j++) { middle = strchr(middle, '$') + 1; } hash_cdata = C4SNetAlloc(CTYPE_char, middle - first + 1, &hash); salt_cdata = C4SNetAlloc(CTYPE_char, last - first + 1, &salt); strncpy(salt, first, middle - first); salt[middle - first] = '\0'; strncpy(hash, first, last - first); hash[last - first] = '\0'; C4SNetOut(hnd, 1, hash_cdata, salt_cdata, i); first = last + 1; } C4SNetFree(entries); return hnd; }
static c4snet_data_t *MPIUnpackFun(void *buf) { void *tmp; c4snet_data_t *result; int vtype, type, count; SNetDistribUnpack(&vtype, buf, MPI_INT, 1); SNetDistribUnpack(&count, buf, MPI_INT, 1); SNetDistribUnpack(&type, buf, MPI_INT, 1); if (vtype == VTYPE_array) { result = C4SNetAlloc(type, count, &tmp); SNetDistribUnpack(tmp, buf, TypeToMPIType(type), count); } else { result = C4SNetCreate(type, 1, &tmp); SNetDistribUnpack(tmp, buf, TypeToMPIType(type), 1); } return result; }
/* Do the TriangularSolve from input tiles Tri and Tri2. */ void *trisol(void *hnd, c4snet_data_t *Tri, c4snet_data_t *Tri2, int N, int B, int K, int J) { c4snet_data_t *Out; c4snet_data_t *Sym; c4snet_data_t *Sym2; const int P = N / B; int i, j; if (verbose) { printf("%s: %p, %p, N=%d, B=%d, (%d, %d, )\n", __func__, Tri, Tri2, N, B, K, J); } if (compute) { tile_t A = C4SNetGetData(Tri2); tile_t Li = C4SNetGetData(Tri); void *tile_ptr; c4snet_data_t *tile = C4SNetAlloc(CTYPE_double, B * B, &tile_ptr); tile_t Lo = tile_ptr; int k_b, i_b, j_b; for (k_b = 0; k_b < B; ++k_b) { for (i_b = 0; i_b < B; ++i_b) { Lo[i_b + k_b * B] = A[i_b + k_b * B] / Li[k_b + k_b * B]; } for (j_b = k_b + 1; j_b < B; ++j_b) { for (i_b = 0; i_b < B; ++i_b) { A[i_b + j_b * B] -= Li[j_b + k_b * B] * Lo[i_b + k_b * B]; } } } Out = Sym = Sym2 = tile; C4SNetFree(Tri); C4SNetFree(Tri2); } else { Out = Sym = Sym2 = Tri; C4SNetFree(Tri2); } for (i = K + 1; i <= J; ++i) { if (verbose) { printf("%s: -> Sym(%d,%d)a, N=%d, B=%d, (%d, %d, %d)\n", __func__, K, J, N, B, K, J, i); } C4SNetOut(hnd, 1, C4SNetShallowCopy(Sym), N, B, K, J, i); if (i == J && i != K) { if (verbose) { printf("%s: -> Sym2(%d,%d)a, (%d, %d, %d)\n", __func__, K, J, K, J, i); } C4SNetOut(hnd, 2, C4SNetShallowCopy(Sym2), K, J, i); } } for (j = J; j < P; ++j) { if (j == J && j != K) { if (verbose) { printf("%s: -> Sym(%d,%d)b, N=%d, B=%d, (%d, %d, %d)\n", __func__, K, J, N, B, K, j, K); } C4SNetOut(hnd, 1, C4SNetShallowCopy(Sym2), N, B, K, j, K); } else { if (verbose) { printf("%s: -> Sym2(%d,%d)c, (%d, %d, %d)\n", __func__, K, J, K, j, J); } C4SNetOut(hnd, 2, C4SNetShallowCopy(Sym2), K, j, J); } if (j == K) { if (verbose) { printf("%s: -> Sym(%d,%d)d, N=%d, B=%d, (%d, %d, %d)\n", __func__, K, J, N, B, K, j, K); } C4SNetOut(hnd, 1, C4SNetShallowCopy(Sym), N, B, K, j, K); } } C4SNetOut(hnd, 3, Out, N, B, K, J, K - 1); return hnd; }
/* Setup the S-Net computation: read matrix data from file and distribute. */ void *start(void *hnd, c4snet_data_t *InFile, c4snet_data_t *OutFile, int N, int B) { int P, X; int j, i; void *result_data; char *infile; c4snet_data_t *result; double *array_data; get_options(); /* Matrix size N must be a multiple of the block size B. */ if (B < 1 || N < 1 || N % B) { fprintf(stderr, "%s: matrix size %d is not a multiple of the block size %d\n", __func__, N, B); exit(1); } /* P gives the number of tiles in either dimension. */ P = N / B; /* X gives the number of tiles needed to construct the output. */ X = (P * P + P) / 2; /* Get the input filename as a string. */ infile = chars_to_string(InFile); C4SNetFree(InFile); if (verbose) { printf("%s: N=%d, B=%d, P=%d, X=%d, I=%s\n", __func__, N, B, P, X, infile); } result = C4SNetAlloc(CTYPE_long, P * P, &result_data); memset(result_data, 0, sizeof(long) * P * P); array_data = SNetMemAlloc(N * N * sizeof(double)); if (compute) { read_matrix(N, array_data, infile); } free(infile); if (clock_gettime(CLOCK_REALTIME, &begin)) { pexit("clock_gettime"); } /* Loop over the rows as j. */ for (j = 0; j < P; ++j) { /* Loop over the columns up to the diagonal as i. */ for (i = 0; i <= j; ++i) { void *tile_ptr; c4snet_data_t *tile = C4SNetAlloc(CTYPE_double, B * B, &tile_ptr); if (compute) { tile_t tile_data = (tile_t) tile_ptr; int A_y, T_y, A_x, T_x; for (A_y = j * B, T_y = 0; T_y < B; ++A_y, ++T_y) { for (A_x = i * B, T_x = 0; T_x < B; ++A_x, ++T_x) { tile_data[T_y + T_x * B] = array_data[A_y * N + A_x]; } } } else { memset(tile_ptr, 0, B * B * sizeof(double)); } if (j == 0 && i == 0) { if (verbose) { printf("%s: -> Fac, N=%d, B=%d, (1, , )\n", __func__, N, B); } C4SNetOut(hnd, 2, tile, N, B, 1); } else if (i == 0) { if (verbose) { printf("%s: -> Tri2, (1, %d, )\n", __func__, j); } C4SNetOut(hnd, 3, tile, 1, j); } else { if (verbose) { printf("%s: -> Sym3, (1, %d, %d)\n", __func__, j, i); } C4SNetOut(hnd, 4, tile, 1, j, i); } } } C4SNetOut(hnd, 1, OutFile, result, X); free(array_data); return hnd; }