static void create_plot (const char *name, sc_bspline_t * bs) { int retval; int i, nevals; char filename[BUFSIZ]; double *result; const double *knotse; FILE *gf; SC_INFOF ("Creating plot %s\n", name); result = SC_ALLOC (double, SC_MAX (bs->d, 2)); knotse = bs->knots->e[0]; snprintf (filename, BUFSIZ, "%s.gnuplot", name); gf = fopen (filename, "wb"); SC_CHECK_ABORT (gf != NULL, "Plot file open"); fprintf (gf, "set key left\n" "set size ratio -1\n" "set output \"%s.eps\"\n" "set terminal postscript color solid\n", name); fprintf (gf, "plot '-' title \"points\" with linespoints, " "'-' title \"spline\" with lines, " "'-' title \"knot values\", " "'-' title \"uniform values\"\n"); /* plot control points */ for (i = 0; i <= bs->p; ++i) { fprintf (gf, "%g %g\n", bs->points->e[i][0], bs->points->e[i][1]); } fprintf (gf, "e\n"); /* plot spline curve */ nevals = 150; for (i = 0; i < nevals; ++i) { sc_bspline_evaluate (bs, i / (double) (nevals - 1), result); fprintf (gf, "%g %g\n", result[0], result[1]); } fprintf (gf, "e\n"); /* plot spline points at knot values */ for (i = 0; i <= bs->l; ++i) { sc_bspline_evaluate (bs, knotse[bs->n + i], result); fprintf (gf, "%g %g\n", result[0], result[1]); } fprintf (gf, "e\n"); /* plot spline points at equidistant values */ for (i = 0; i <= bs->l; ++i) { sc_bspline_evaluate (bs, i / (double) bs->l, result); fprintf (gf, "%g %g\n", result[0], result[1]); } fprintf (gf, "e\n"); retval = fclose (gf); SC_CHECK_ABORT (retval == 0, "Plot file close"); SC_FREE (result); }
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); }
void sc_keyvalue_destroy (sc_keyvalue_t * kv) { sc_hash_destroy (kv->hash); sc_mempool_destroy (kv->value_allocator); SC_FREE (kv); }
void sc_bspline_destroy (sc_bspline_t * bs) { if (bs->knots_owned) sc_dmatrix_destroy (bs->knots); if (bs->works_owned) sc_dmatrix_destroy (bs->works); SC_FREE (bs); }
int sc_vtk_write_binary (FILE * vtkfile, char *numeric_data, size_t byte_length) { size_t chunks, chunksize, remaining, writenow; size_t code_length, base_length; uint32_t int_header; char *base_data; base64_encodestate encode_state; /* VTK format used 32bit header info */ SC_ASSERT (byte_length <= (size_t) UINT32_MAX); chunksize = (size_t) 1 << 15; /* 32768 */ int_header = (uint32_t) byte_length; code_length = 2 * chunksize; base_data = SC_ALLOC (char, code_length); base64_init_encodestate (&encode_state); base_length = base64_encode_block ((char *) &int_header, sizeof (int_header), base_data, &encode_state); base_data[base_length] = '\0'; (void) fwrite (base_data, 1, base_length, vtkfile); chunks = 0; remaining = byte_length; while (remaining > 0) { writenow = SC_MIN (remaining, chunksize); base_length = base64_encode_block (numeric_data + chunks * chunksize, writenow, base_data, &encode_state); base_data[base_length] = '\0'; SC_ASSERT (base_length < code_length); (void) fwrite (base_data, 1, base_length, vtkfile); remaining -= writenow; ++chunks; } base_length = base64_encode_blockend (base_data, &encode_state); (void) fwrite (base_data, 1, base_length, vtkfile); SC_FREE (base_data); if (ferror (vtkfile)) { return -1; } return 0; }
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); }