/* * method that returns both cut and uncut indices vector of the partitioned matrix * input: logical vector (1 cut, 0 uncut). Usage: * * long *cut_vec, *uncut_vec; * int len, len2; * cut_and_uncut(&matrix,&cut_vec,&len,&uncut_vec,&len2); */ void cut_and_uncut(struct sparsematrix *A, long** cut_part, int* cut_length, long** uncut_part, int* uncut_length){ struct twomatrices two = split_matrix(A,1.0,2.0); long* split = cut_vector(&two.Ar,&two.Ac); int length = A->m+A->n; int i, n_cut=0; for(i=0;i<length;i++) n_cut+=split[i]; *cut_part = vecallocl(n_cut); *uncut_part = vecallocl(length-n_cut); *cut_length = n_cut; *uncut_length = length-n_cut; long* cut = *cut_part; long* uncut = *uncut_part; int index_cut = 0, index_uncut=0; for(i=0;i<length;i++){ if(split[i]==1) cut[index_cut++] = i; else uncut[index_uncut++] = i; } vecfreel(split); MMDeleteSparseMatrix(&two.Ar); MMDeleteSparseMatrix(&two.Ac); }
/** * Get the maximum capacity of the cover with the given parameters. * * @param data Pointer to a svg_data_t structure containing the cover data. * @param capacity The maximum capacity, in bits. * @param param The parameters for this algorithm. * * @return LSTG_OK on success, LSTG_ERROR if there was an error. */ uint32_t svg_check_capacity( const svg_data_t *data, uint32_t *capacity, const svg_parameter_t *param){ uint32_t i = 0, dec_len = 0; uint8_t *start = 0, *end = 0; svg_llist_head_t head; svg_llist_t *current; *capacity = 0; for (i = 0; i < data->num_attribs; ++i) { // we only embed in transform matrices if (strncmp("matrix(", data->attributes[i].data, 7) == 0) { if (split_matrix(data->attributes[i].data, &head) != LSTG_OK) { // error code already set return LSTG_ERROR; } for (current = head; current != NULL; current = current->next) { // get decimal part of number (between '.' and the exponent (if any) // find decimal point start = strchr(current->str, '.'); if (start == NULL) { // there was no '.' in this number, skip it continue; } // find exponent (if any) end = strchr(current->str, 'e'); if (end == NULL) { // there was no exponent, set end to end of string end = current->str + strlen(current->str); } // calculate length of decimal part dec_len = end - start - 1; // check if there are enough digits to embed anything if (dec_len > param->first_embed_digit) { *capacity += dec_len - param->first_embed_digit; } } free_list(head); } } if (*capacity > 32) *capacity -= 32; else *capacity = 0; return LSTG_OK; }
/* * Vérification visuelle de la fonction d'affichage. * Affichage d'une matrice complète, puis d'un sous-bloc. * Vérification du scatter/gather */ int main(){ double* global_mat; double* global_verif; MPI_Init(NULL, NULL); int size, rank, i; MPI_Comm_size(MPI_COMM_WORLD,&size); MPI_Comm_rank(MPI_COMM_WORLD,&rank); if (rank == 0){ double* mat = matrix_rand(4,6); printf("Matrice entière de taille (4,6) : \n"); affiche(4, 6, mat, 4, stdout); printf("Sous-bloc [3,2] de taille (2,3) : \n"); affiche(2, 3, mat+2+4, 4, stdout); free(mat); printf("Test scatter/gather...\t"); global_verif = matrix_rand(100, 100); global_mat = matrix_rand(100, 100); memcpy(global_verif, global_mat, 100*100*sizeof(double)); } int bsize = 3; int nb_cols = nb_col(size, bsize, 100, rank); double* local_mat = matrix_rand(100, nb_cols*bsize); split_matrix(100, 100, global_mat, local_mat, bsize, SCATTER); split_matrix(100, 100, global_mat, local_mat, bsize, GATHER); if (rank == 0){ for(i=0;i<100*100;++i) ASSERT_EQ(global_mat[i],global_verif[i]); printf("ok\n"); free(global_verif); free(global_mat); } free(local_mat); MPI_Finalize(); return 0; }
int main(){ /* srand(time(NULL)); */ /* reading the matrix from file */ FILE* File; struct sparsematrix matrix; File = fopen("../../matrices/test_matrix.mtx", "r"); if (!MMReadSparseMatrix(File, &matrix)) printf("Unable to read input matrix!\n"); fclose(File); struct twomatrices two = split_matrix(&matrix,1.0,2.0); print_matrix(two.Ar); printf("------------\n"); print_matrix(two.Ac); MMDeleteSparseMatrix(&matrix); MMDeleteSparseMatrix(&two.Ar); MMDeleteSparseMatrix(&two.Ac); return 0; }
/** * Wrapper function for using LSB with SVG data. Depending on the wrap_mode * parameter, this function is equivalent to a call to lsb_embed, lsb_extract or * lsb_get_message_length. * * @param data The SVG data which should be used for embedding or extracting. * @param message Pointer to the message, which will be embedded or extracted. * @param msglen Pointer to the message length. * @parem param Pointer to a set of parameters for the SVG algorithm. * @param wrap_mode The function this function should wrap, one of * SVG_WRAP_EMBED, SVG_WRAP_EXTRACT or SVG_WRAP_MSGLEN. * * @return LSTG_OK on success, LSTG_ERROR if there was an error. */ uint32_t svg_wrap_lsb( const svg_data_t *data, uint8_t **message, uint32_t *msglen, const svg_parameter_t *param, enum svg_wrap_mode wrap_mode) { uint32_t capacity = 0; uint32_t bytes_selected = 0; uint32_t bit_length = 0, data_len = 0; uint32_t i = 0, dec_len = 0, k = 0; uint8_t *start = 0, *end = 0; uint8_t return_code = LSTG_OK; svg_llist_head_t *matrices; svg_llist_t *current; lsb_parameter_t lsb_param; uint8_t **bytes = 0; // length may not be bigger than one eighth of the maximum of uint32_t, else // we risk a buffer overflow and resulting madnesses when we multiply it // with eight later on if (*msglen > (0xFFFFFFFF - 32) / 8) { FAIL(LSTG_E_INSUFFCAP); } bit_length = *msglen * 8 + 32; // we need a password if (param->pwlen == 0) { FAIL(LSTG_E_INVALIDPARAM); } svg_check_capacity(data, &capacity, param); // check_capacity compensates for the 32 bit message length -- we have to correct for that capacity += 32; if (wrap_mode == SVG_WRAP_EMBED) { // check for capacity if (capacity < bit_length) { FAIL(LSTG_E_INSUFFCAP); } } // create a buffer to hold split matrices matrices = (svg_llist_head_t*)malloc(sizeof(svg_llist_head_t) * data->num_attribs); if (matrices == NULL) { lstg_errno = LSTG_E_MALLOC; return_code = LSTG_ERROR; goto svg_wrap_cleanup; } // create array of pointers, will point to bytes which can be embedded into bytes = (uint8_t**)malloc(sizeof(uint8_t*) * capacity); if (bytes == NULL) { lstg_errno = LSTG_E_MALLOC; return_code = LSTG_ERROR; goto svg_wrap_cleanup; } for (i = 0; i < data->num_attribs; ++i) { // initialize pointer to zero matrices[i] = 0; // we only embed in transform matrices if (strncmp("matrix(", data->attributes[i].data, 7) == 0) { if (split_matrix(data->attributes[i].data, &matrices[i]) != LSTG_OK) { // error code alredy set return_code = LSTG_ERROR; goto svg_wrap_cleanup; } for (current = matrices[i]; current != NULL; current = current->next) { // get decimal part of number (between '.' and the exponent (if any) // find decimal point start = strchr(current->str, '.'); if (start == NULL) { // there was no '.' in this number, skip it continue; } // find exponent (if any) end = strchr(current->str, 'e'); if (end == NULL) { // there was no exponent, set end to end of string end = current->str + strlen(current->str); } // calculate length of decimal part dec_len = end - start - 1; // set pointers to usable bytes for (k = param->first_embed_digit; k < dec_len; ++k) { bytes[bytes_selected++] = &start[k]; } } } } // prepare lsb_parameter_t lsb_param.password = (uint8_t*)malloc(sizeof(uint8_t) * (param->pwlen + 1)); if (lsb_param.password == NULL) { lstg_errno = LSTG_E_MALLOC; return_code = LSTG_ERROR; goto svg_wrap_cleanup; } memcpy(lsb_param.password, param->password, sizeof(uint8_t) * (param->pwlen + 1)); lsb_param.pwlen = param->pwlen; lsb_param.select_mode = LSB_SELECT_RANDOM; lsb_param.use_msb = 0; switch (wrap_mode) { case SVG_WRAP_EMBED: // embed using LSB if (lsb_embed_indirect(bytes, bytes_selected, *message, *msglen, &lsb_param) != LSTG_OK) { // error code alredy set return_code = LSTG_ERROR; goto svg_wrap_cleanup; } // re-assemble the changed matrices for (i = 0; i < data->num_attribs; ++i ) { if (matrices[i]) { // free space, will be replaced by new matrix SAFE_DELETE(data->attributes[i].data); join_matrix(&data->attributes[i].data, matrices[i]); } } break; case SVG_WRAP_EXTRACT: // extract using LSB if (lsb_extract_indirect(bytes, bytes_selected, message, msglen, &lsb_param) != LSTG_OK) { // error code alredy set return_code = LSTG_ERROR; goto svg_wrap_cleanup; } break; case SVG_WRAP_MSGLEN: // get message length using LSB if (lsb_get_message_length_indirect(bytes, bytes_selected, msglen, &lsb_param) != LSTG_OK) { // error code alredy set return_code = LSTG_ERROR; goto svg_wrap_cleanup; } break; }; svg_wrap_cleanup: for (i = 0; i < data->num_attribs; ++i) { if (matrices[i]) { free_list(matrices[i]); } } SAFE_DELETE(lsb_param.password); SAFE_DELETE(matrices); SAFE_DELETE(bytes); return return_code; }
/* * function that assigns the nonzeros of matrix either to Ar or Ac */ struct twomatrices localview(struct sparsematrix* matrix){ /* dividing between A1 and A2 */ struct twomatrices A = split_matrix(matrix,1.0,2.0); struct sparsematrix* A1 = &(A.Ar); struct sparsematrix* A2 = &(A.Ac); /* explicit saving of m,n for brevity */ int m = matrix->m; int n = matrix->n; /* * building the bookkeeping vectors * nzXr = nonzeros in the rows of AX * nzXc = nonzeros in the columns of AX * nzr,nzc = nonzeros in row/col of matrix */ long* nz1r = nnz(A1->i, A1->NrNzElts, m); long* nz2r = nnz(A2->i, A2->NrNzElts, m); long* nzr = nnz(matrix->i, matrix->NrNzElts, m); long* nz1c = nnz(A1->j, A1->NrNzElts, n); long* nz2c = nnz(A2->j, A2->NrNzElts, n); long* nzc = nnz(matrix->j, matrix->NrNzElts, n); /* storing the number of nonzeros that have to be assigned */ int len = matrix->NrNzElts; /* * initialization of the new vectors to be populated * assuming everything is assigned to one and the other stays empty * the max size is matrix.NrNzElts (len) */ long* ir = vecallocl(len); long* jr = vecallocl(len); long* ic = vecallocl(len); long* jc = vecallocl(len); /* counters for filling of ir,jr and ic,jc */ int index_r = 0; int index_c = 0; int i,j,k; k = 0; while(len>0){ /* TODO k randomly chosen between 0 and len */ /* k = randi(len); */ /* computing explicitly row and column of the k-th element of the matrix */ i = matrix->i[k]; j = matrix->j[k]; /* computing whether i,j are split */ int rowsplit = (nz1r[i] && nz2r[i]); int colsplit = (nz1c[j] && nz2c[j]); /* actual assignment of the nonzero */ if (!xor(rowsplit,colsplit)){ if (nzr[i]<nzc[j]){ ir[index_r] = i; jr[index_r] = j; index_r++; } else { ic[index_c] = i; jc[index_c] = j; index_c++; } } else { if (rowsplit) { ic[index_c] = i; jc[index_c] = j; index_c++; } else { ir[index_r] = i; jr[index_r] = j; index_r++; } } /* * putting the last element that could be chosen instead of the * k-th one, and we reduce the interval for randi by 1 */ /* matrix.i[k] = matrix.i[len-1]; matrix.j[k] = matrix.j[len-1]; */ k++; len--; } /* creation of vectors of the right size */ long* ir_n = vecallocl(index_r); long* jr_n = vecallocl(index_r); long* ic_n = vecallocl(index_c); long* jc_n = vecallocl(index_c); /* copying only the filled part */ memcpy(ir_n,ir,index_r*SZLONG); memcpy(jr_n,jr,index_r*SZLONG); memcpy(ic_n,ic,index_c*SZLONG); memcpy(jc_n,jc,index_c*SZLONG); /* creating the (dummy) values for the nonzeros */ double* val_r = vecallocd(index_r); double* valc_r = vecallocd(index_r); double* val_c = vecallocd(index_c); double* valc_c = vecallocd(index_c); for(k=0;k<index_r;k++){ val_r[k] = 1.0; valc_r[k] = 0.0; } for(k=0;k<index_c;k++){ val_c[k] = 1.0; valc_c[k] = 0.0; } /* explicit creation of the final matrices */ struct sparsematrix Ar; MMSparseMatrixInit(&Ar); Ar.NrNzElts = index_r; Ar.m = m; Ar.n = n; Ar.i = ir_n; Ar.j = jr_n; Ar.ReValue = val_r; Ar.ImValue = valc_r; struct sparsematrix Ac; MMSparseMatrixInit(&Ac); Ac.NrNzElts = index_c; Ac.i = ic_n; Ac.j = jc_n; Ac.m = m; Ac.n = n; Ac.ReValue = val_c; Ac.ImValue = valc_c; /* freeing memory from unnecessary arrays */ vecfreel(ir); vecfreel(jr); vecfreel(ic); vecfreel(jc); vecfreel(nz1c); vecfreel(nz2c); vecfreel(nzc); vecfreel(nz1r); vecfreel(nz2r); vecfreel(nzr); MMDeleteSparseMatrix(A1); MMDeleteSparseMatrix(A2); /* explicit construction of the output */ struct twomatrices output; output.Ar = Ar; output.Ac = Ac; return output; }