void sc_allgather_alltoall (sc_MPI_Comm mpicomm, char *data, int datasize, int groupsize, int myoffset, int myrank) { int j, peer; int mpiret; sc_MPI_Request *request; SC_ASSERT (myoffset >= 0 && myoffset < groupsize); request = SC_ALLOC (sc_MPI_Request, 2 * groupsize); for (j = 0; j < groupsize; ++j) { if (j == myoffset) { request[j] = request[groupsize + j] = sc_MPI_REQUEST_NULL; continue; } peer = myrank - (myoffset - j); mpiret = sc_MPI_Irecv (data + j * datasize, datasize, sc_MPI_BYTE, peer, SC_TAG_AG_ALLTOALL, mpicomm, request + j); SC_CHECK_MPI (mpiret); mpiret = sc_MPI_Isend (data + myoffset * datasize, datasize, sc_MPI_BYTE, peer, SC_TAG_AG_ALLTOALL, mpicomm, request + groupsize + j); SC_CHECK_MPI (mpiret); } mpiret = sc_MPI_Waitall (2 * groupsize, request, sc_MPI_STATUSES_IGNORE); SC_CHECK_MPI (mpiret); SC_FREE (request); }
sc_keyvalue_t * sc_keyvalue_new () { sc_keyvalue_t *kv; kv = SC_ALLOC (sc_keyvalue_t, 1); kv->hash = sc_hash_new (sc_keyvalue_entry_hash, sc_keyvalue_entry_equal, NULL, NULL); kv->value_allocator = sc_mempool_new (sizeof (sc_keyvalue_entry_t)); return kv; }
int sc_vtk_write_compressed (FILE * vtkfile, char *numeric_data, size_t byte_length) { int retval, fseek1, fseek2; size_t iz; size_t blocksize, lastsize; size_t theblock, numregularblocks, numfullblocks; size_t header_entries; size_t code_length, base_length; long header_pos, final_pos; char *comp_data, *base_data; uint32_t *compression_header; uLongf comp_length; base64_encodestate encode_state; /* compute block sizes */ blocksize = (size_t) (1 << 15); /* 32768 */ lastsize = byte_length % blocksize; numregularblocks = byte_length / blocksize; numfullblocks = numregularblocks + (lastsize > 0 ? 1 : 0); /* allocate compression and base64 arrays */ code_length = 2 * blocksize; comp_data = SC_ALLOC (char, code_length); base_data = SC_ALLOC (char, code_length); /* figure out the size of the header and write a dummy */ header_entries = 3 + numfullblocks; compression_header = SC_ALLOC (uint32_t, header_entries); compression_header[0] = (uint32_t) numfullblocks; compression_header[1] = (uint32_t) blocksize; compression_header[2] = (uint32_t) (lastsize > 0 || byte_length == 0 ? lastsize : blocksize); for (iz = 3; iz < header_entries; ++iz) { compression_header[iz] = 0; } base64_init_encodestate (&encode_state); base_length = base64_encode_block ((char *) compression_header, sizeof (*compression_header) * header_entries, base_data, &encode_state); base_length += base64_encode_blockend (base_data + base_length, &encode_state); base_data[base_length] = '\0'; SC_ASSERT (base_length < code_length); header_pos = ftell (vtkfile); (void) fwrite (base_data, 1, base_length, vtkfile); /* write the regular data blocks */ base64_init_encodestate (&encode_state); for (theblock = 0; theblock < numregularblocks; ++theblock) { comp_length = code_length; retval = compress2 ((Bytef *) comp_data, &comp_length, (const Bytef *) (numeric_data + theblock * blocksize), (uLong) blocksize, Z_BEST_COMPRESSION); SC_ASSERT (retval == Z_OK); compression_header[3 + theblock] = comp_length; base_length = base64_encode_block (comp_data, comp_length, base_data, &encode_state); base_data[base_length] = '\0'; SC_ASSERT (base_length < code_length); (void) fwrite (base_data, 1, base_length, vtkfile); } /* write odd-sized last block if necessary */ if (lastsize > 0) { comp_length = code_length; retval = compress2 ((Bytef *) comp_data, &comp_length, (const Bytef *) (numeric_data + theblock * blocksize), (uLong) lastsize, Z_BEST_COMPRESSION); SC_ASSERT (retval == Z_OK); compression_header[3 + theblock] = comp_length; base_length = base64_encode_block (comp_data, comp_length, base_data, &encode_state); base_data[base_length] = '\0'; SC_ASSERT (base_length < code_length); (void) fwrite (base_data, 1, base_length, vtkfile); } /* write base64 end block */ base_length = base64_encode_blockend (base_data, &encode_state); (void) fwrite (base_data, 1, base_length, vtkfile); /* seek back, write header block, seek forward */ final_pos = ftell (vtkfile); base64_init_encodestate (&encode_state); base_length = base64_encode_block ((char *) compression_header, sizeof (*compression_header) * header_entries, base_data, &encode_state); base_length += base64_encode_blockend (base_data + base_length, &encode_state); base_data[base_length] = '\0'; SC_ASSERT (base_length < code_length); fseek1 = fseek (vtkfile, header_pos, SEEK_SET); (void) fwrite (base_data, 1, base_length, vtkfile); fseek2 = fseek (vtkfile, final_pos, SEEK_SET); /* clean up and return */ SC_FREE (compression_header); SC_FREE (comp_data); SC_FREE (base_data); if (fseek1 != 0 || fseek2 != 0 || ferror (vtkfile)) { return -1; } return 0; }
static void sc_reduce_alltoall (MPI_Comm mpicomm, void *data, int count, MPI_Datatype datatype, int groupsize, int target, int maxlevel, int level, int branch, sc_reduce_t reduce_fn) { int i, l; int mpiret; int doall, allcount; int myrank, peer, peer2; int shift; char *alldata; size_t datasize; MPI_Request *request, *rrequest, *srequest; doall = 0; if (target == -1) { doall = 1; target = 0; } SC_ASSERT (0 <= target && target < groupsize); myrank = sc_search_bias (maxlevel, level, branch, target); SC_ASSERT (0 <= myrank && myrank < groupsize); SC_ASSERT (reduce_fn != NULL); /* *INDENT-OFF* HORRIBLE indent bug */ datasize = (size_t) count * sc_mpi_sizeof (datatype); /* *INDENT-ON* */ if (doall || target == myrank) { allcount = 1 << level; alldata = SC_ALLOC (char, allcount * datasize); request = SC_ALLOC (MPI_Request, 2 * allcount); rrequest = request; srequest = request + allcount; for (i = 0; i < allcount; ++i) { peer = sc_search_bias (maxlevel, level, i, target); /* communicate with existing peers */ if (peer == myrank) { memcpy (alldata + i * datasize, data, datasize); rrequest[i] = srequest[i] = MPI_REQUEST_NULL; } else { if (peer < groupsize) { mpiret = MPI_Irecv (alldata + i * datasize, datasize, MPI_BYTE, peer, SC_TAG_REDUCE, mpicomm, rrequest + i); SC_CHECK_MPI (mpiret); if (doall) { mpiret = MPI_Isend (data, datasize, MPI_BYTE, peer, SC_TAG_REDUCE, mpicomm, srequest + i); SC_CHECK_MPI (mpiret); } else { srequest[i] = MPI_REQUEST_NULL; /* unused */ } } else { /* ignore non-existing ranks greater or equal mpisize */ rrequest[i] = srequest[i] = MPI_REQUEST_NULL; } } } /* complete receive operations */ mpiret = MPI_Waitall (allcount, rrequest, MPI_STATUSES_IGNORE); SC_CHECK_MPI (mpiret); /* process received data in the same order as sc_reduce_recursive */ for (shift = 0, l = level - 1; l >= 0; ++shift, --l) { for (i = 0; i < 1 << l; ++i) { #ifdef SC_DEBUG peer = sc_search_bias (maxlevel, l + 1, 2 * i, target); #endif peer2 = sc_search_bias (maxlevel, l + 1, 2 * i + 1, target); SC_ASSERT (peer < peer2); if (peer2 < groupsize) { reduce_fn (alldata + ((2 * i + 1) << shift) * datasize, alldata + ((2 * i) << shift) * datasize, count, datatype); } } } memcpy (data, alldata, datasize); SC_FREE (alldata); /* alldata is not used in send buffers */ /* wait for sends only after computation is done */ if (doall) { mpiret = MPI_Waitall (allcount, srequest, MPI_STATUSES_IGNORE); SC_CHECK_MPI (mpiret); } SC_FREE (request); }