void cncEnvIn(int argc, char **argv, Context *context) { CNC_REQUIRE(argc == 5, "Usage: %s fileName1 fileName2 tileWidth tileHeight\n", argv[0]); // Open sequence input files FILE *file1 = open_file(argv[1]); FILE *file2 = open_file(argv[2]); size_t filesize1 = file_length(file1); size_t filesize2 = file_length(file2); // Allocate tile data item and read sequence data SeqData *data; size_t dataSize = sizeof(SeqData) + filesize1 + filesize2 + 2; cncHandle_t dataHandle = cncCreateItemSized_data(&data, dataSize); data->seq2offset = filesize1 + 1; size_t length1 = read_sequence(file1, 1, SEQ1(data), filesize1); size_t length2 = read_sequence(file2, 2, SEQ2(data), filesize2); // Tile width and height int tw = atoi(argv[3]); int th = atoi(argv[4]); PRINTF("Tile width: %d\n", tw); PRINTF("Tile height: %d\n", th); CNC_REQUIRE(tw <= length1 && th <= length2, "Tile size too large for given input.\n"); // Number of tiles wide and high int ntw = length1 / tw; int nth = length2 / th; PRINTF("Imported %d x %d tiles.\n", ntw, nth); // Initialize tile dimension data and put data->tw = tw; data->th = th; data->ntw = ntw; data->nth = nth; memcpy(data->score_matrix, ALIGNMENT_SCORES, sizeof(ALIGNMENT_SCORES)); cncPut_data(dataHandle, 0, context); // Record starting time struct timeval *startTime; cncHandle_t startTime_handle = cncCreateItem_startTime(&startTime, 1); gettimeofday(startTime, 0); cncPut_startTime(startTime_handle, 0, context); // Seed edges cncPrescribe_initAboveStep(tw, ntw, context); cncPrescribe_initLeftStep(th, nth, context); int i, j; for(i = 0; i < nth; i++){ for(j = 0; j < ntw; j++){ cncPrescribe_swStep(i, j, context); } } cncPrescribe_cncEnvOut(ntw, nth, tw, context); }
void s1ComputeStep(int k, tileSizeItem tileSize, LkjiItem Lkji1D, Context *context){ int t = tileSize.item; double (*Lkji)[t] = (double(*)[t])Lkji1D.item; // Allocate new tile double *lBlock1D; cncHandle_t lBlock_handle = cncCreateItem_Lkji(&lBlock1D, t*t); double (*lBlock)[t] = (double(*)[t])lBlock1D; // Calculate tile values int kB, jB, jBB, iB; for (kB = 0 ; kB < t ; kB++) { CNC_REQUIRE(Lkji[ kB ][ kB ] > 0.0, "[%d][%d] Error: Not a symmetric positive definite (SPD) matrix\n", k, kB); lBlock[ kB ][ kB ] = sqrt( Lkji[ kB ][ kB ] ); for (jB = kB + 1; jB < t ; jB++) lBlock[ jB ][ kB ] = Lkji[ jB ][ kB ] / lBlock[ kB ][ kB ]; for (jBB= kB + 1; jBB < t ; jBB++) for (iB = jBB ; iB < t ; iB++) Lkji[ iB ][ jBB ] = Lkji[ iB ][ jBB ] - ( lBlock[ iB ][ kB ] * lBlock[ jBB ][ kB ] ); } cncPut_Lkji(lBlock_handle, k, k, k+1, context); int tagResult = (k)*(k+1)/2 + k; cncPut_results(lBlock_handle, tagResult, context); }
void Cholesky_cncInitialize(CholeskyArgs *args, CholeskyCtx *ctx) { int i, j; int nt = ctx->numTiles; int t = ctx->tileSize; int n = nt * t; // Read input matrix from file // Make sure the matrix side lengths are square numbers int root = sqrt(n); CNC_REQUIRE(root * root == n, "Generated matrices must have square dimensions\n"); // Create tiles from source matrix for (i = 0; i < nt; i++){ for (j = 0 ; j <= i ; j++ ) { int A_i, A_j, T_i, T_j; double *temp1D = cncItemAlloc(sizeof(*temp1D) * t*t); // The 1D array of tile entries maps to a // 2D array corresponding to a t-by-t matrix tile double (*temp)[t] = (double(*)[t])temp1D; // Copy this tile's data from the input matrix for (A_i = i * t, T_i = 0 ; T_i < t ; A_i++, T_i++) { for (A_j = j * t, T_j = 0 ; T_j < t ; A_j++, T_j++) { double *cell = &temp[T_i][T_j]; if (A_i == A_j) { *cell = 4; } else if (A_i == A_j + root) { *cell = -1; } else if (A_i == A_j + 1 && (A_j + 1) % n != 0) { *cell = -1; } else { *cell = 0; } } } // Put the initialized tile cncPut_data(temp1D, i, j, 0, ctx); } } // Record starting time #if CNCOCR_TG struct timeval *startTime = NULL; #else struct timeval *startTime = cncItemAlloc(sizeof(*startTime)); gettimeofday(startTime, 0); #endif cncPut_startTime(startTime, ctx); // Prescribe "kComputeStep" steps cncPrescribe_kComputeStep(ctx); // Set finalizer function's tag int tileCount = ctx->numTiles * (ctx->numTiles + 1) / 2; Cholesky_await(tileCount, ctx); }
int cncMain(int argc, char *argv[]) { #if CHOLESKY_USE_FILE CNC_REQUIRE(argc==4, "Usage: ./Cholesky matrixSize tileSize fileName (found %d args)\n", argc-1); #else CNC_REQUIRE(argc==3, "Usage: ./Cholesky matrixSize tileSize (found %d args)\n", argc-1); #endif // Create a new graph context CholeskyCtx *context = Cholesky_create(); // Parse matrix dim info int matrixCols = atoi(argv[1]); int tileSize = atoi(argv[2]); int numTiles = matrixCols / tileSize; CNC_REQUIRE(matrixCols % tileSize == 0, "Incompatible tile size %d for the matrix of size %d\n", tileSize, matrixCols); #if CHOLESKY_USE_FILE CholeskyArgs *args = cncItemAlloc(sizeof(*args)); // Matrix read from input file char *lastChar = args->inFile + sizeof(args->inFile) - 1; *lastChar = '\0'; strncpy(args->inFile, argv[3], sizeof(args->inFile)); CNC_REQUIRE(*lastChar == '\0', "Input path is longer than %lu characters.\n", sizeof(args->inFile)); #else CholeskyArgs *args = NULL; #endif // Set graph parameters context->numTiles = numTiles; context->tileSize = tileSize; // Launch the graph for execution Cholesky_launch(args, context); // Exit when the graph execution completes CNC_SHUTDOWN_ON_FINISH(context); return 0; }
/** * Step function defintion for "findTargetBatchStep" */ void Primes_findTargetBatchStep(cncTag_t n, ReducedResult *reducedPrimes, PrimesCtx *ctx) { s64 N = n; N -= FACTOR_BATCH_COUNT+2; // offset N by the seeded prime count assert(N < reducedPrimes->count && "Didn't find enough primes"); N -= reducedPrimes->offset; // offset by all the summarized prime results for (u32 i=0; i<reducedPrimes->batchCount; i++) { BatchRef batch = reducedPrimes->batches[i]; N -= batch.count; if (N <= 0) { N += batch.count; // schedule EDT to put nth prime with the found batch's guid cncPrescribe_findNthPrimeStep(N, batch.index, ctx); return; } } CNC_REQUIRE(0, "Couldn't find Nth prime.\n"); }
void cncEnvIn(int argc, char **argv, Context *context) { CNC_REQUIRE(argc==4, "Usage: ./Cholesky matrixSize tileSize fileName (found %d args)\n", argc); // Parse matrix dim info int n, t, nt; n = atoi(argv[1]); t = atoi(argv[2]); nt = n/t; CNC_REQUIRE(n % t == 0, "Incompatible tile size %d for the matrix of size %d\n", t, n); // Read source matrix FILE *f = fopen(argv[3], "r"); CNC_REQUIRE(f != NULL, "Cannot find file: %s\n", argv[3]); int i, j; int matrixElementCount = n * n; double *A1D = MALLOC(matrixElementCount * sizeof(double)) ; for (i=0; i<matrixElementCount; i++) { fscanf(f, "%lf", &A1D[i]); } // The 1D array of matrix entries maps to a // 2D array corresponding to an n-by-n matrix double (*A)[n] = (double(*)[n])A1D; // Create tiles from source matrix for (i = 0; i < nt; i++){ for (j = 0 ; j <= i ; j++ ) { int A_i, A_j, T_i, T_j; double *temp1D; cncHandle_t tile_handle = cncCreateItem_Lkji(&temp1D, t*t); // The 1D array of tile entries maps to a // 2D array corresponding to a t-by-t matrix tile double (*temp)[t] = (double(*)[t])temp1D; // Copy this tile's data from the input matrix for (A_i = i * t, T_i = 0 ; T_i < t ; A_i++, T_i++) { for (A_j = j * t, T_j = 0 ; T_j < t ; A_j++, T_j++) { temp[ T_i ][ T_j ] = A[ A_i ][ A_j ]; } } // Put the initialized tile cncPut_Lkji(tile_handle, i, j, 0, context); } } // Clean up source matrix (no longer needed) FREE(A1D); // Put matrix and tile dimension info int *ntPtr, *tPtr; cncHandle_t nt_handle = cncCreateItem_tileSize(&ntPtr); *ntPtr = nt; cncPut_numTiles(nt_handle, 0, context); cncHandle_t t_handle = cncCreateItem_numTiles(&tPtr); *tPtr = t; cncPut_tileSize(t_handle, 0, context); // Record the starting time of the computation struct timeval *startTime; cncHandle_t time_handle = cncCreateItem_startTime(&startTime, 1); gettimeofday(startTime, 0); cncPut_startTime(time_handle, 0, context); // Start the computation cncPrescribe_kComputeStep(0, context); // Set tag for the output step int totalTileCount = nt * (nt + 1) / 2; cncPrescribe_cncEnvOut(totalTileCount, context); }
static FILE *open_file(const char *fileName) { FILE *f = fopen(fileName, "r"); CNC_REQUIRE(f, "Could not open file: %s\n", fileName); }