mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-04 15:21:11 +00:00
Merged
This commit is contained in:
commit
5b8a97d170
69 changed files with 13326 additions and 310 deletions
|
@ -15,9 +15,10 @@ private:
|
|||
int _num_files;
|
||||
SimuData *gadget_header;
|
||||
string snapshot_name;
|
||||
SimulationPreprocessor *preproc;
|
||||
public:
|
||||
FlashLoader(const string& basename, SimuData *header, int flags, bool singleFile, int _num)
|
||||
: snapshot_name(basename), load_flags(flags), onefile(singleFile), _num_files(_num), gadget_header(header)
|
||||
FlashLoader(const string& basename, SimuData *header, int flags, bool singleFile, int _num, SimulationPreprocessor *p)
|
||||
: snapshot_name(basename), load_flags(flags), onefile(singleFile), _num_files(_num), gadget_header(header), preproc(p)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -58,6 +59,7 @@ public:
|
|||
}
|
||||
|
||||
applyTransformations(d);
|
||||
basicPreprocessing(d, preproc);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
@ -107,5 +109,5 @@ SimulationLoader *flashLoader(const std::string& snapshot, int flags, Simulation
|
|||
}
|
||||
}
|
||||
|
||||
return new FlashLoader(snapshot, header, flags, singleFile, num_files);
|
||||
return new FlashLoader(snapshot, header, flags, singleFile, num_files, p);
|
||||
}
|
||||
|
|
|
@ -71,33 +71,7 @@ public:
|
|||
d->BoxSize *= unitMpc;
|
||||
|
||||
applyTransformations(d);
|
||||
|
||||
long numAccepted = 0;
|
||||
bool *accepted = new bool[d->NumPart];
|
||||
for (long i = 0; i < d->NumPart; i++)
|
||||
{
|
||||
SingleParticle p;
|
||||
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
p.Pos[k] = (d->Pos[k]) ? 0 : d->Pos[k][i];
|
||||
p.Vel[k] = (d->Vel[k]) ? 0 : d->Vel[k][i];
|
||||
}
|
||||
p.ID = (d->Id) ? 0 : d->Id[i];
|
||||
|
||||
accepted[i] = preproc->accept(p);
|
||||
numAccepted += accepted[i];
|
||||
}
|
||||
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
filteredCopy(d->Pos[k], accepted, d->NumPart);
|
||||
filteredCopy(d->Vel[k], accepted, d->NumPart);
|
||||
}
|
||||
filteredCopy(d->Id, accepted, d->NumPart);
|
||||
filteredCopy(d->type, accepted, d->NumPart);
|
||||
delete[] accepted;
|
||||
d->NumPart = numAccepted;
|
||||
basicPreprocessing(d, preproc);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
|
|
@ -16,10 +16,11 @@ private:
|
|||
bool double_precision;
|
||||
SimuData *ramses_header;
|
||||
string snapshot_name;
|
||||
SimulationPreprocessor *preproc;
|
||||
public:
|
||||
RamsesLoader(const string& basename, int baseid, bool dp, SimuData *header, int flags, int _num)
|
||||
RamsesLoader(const string& basename, int baseid, bool dp, SimuData *header, int flags, int _num, SimulationPreprocessor *p)
|
||||
: snapshot_name(basename), load_flags(flags), _num_files(_num), double_precision(dp),
|
||||
ramses_header(header)
|
||||
ramses_header(header), preproc(p)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -56,6 +57,7 @@ public:
|
|||
}
|
||||
|
||||
applyTransformations(d);
|
||||
basicPreprocessing(d, preproc);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
@ -76,6 +78,6 @@ SimulationLoader *ramsesLoader(const std::string& snapshot, int baseid, bool dou
|
|||
delete d;
|
||||
}
|
||||
|
||||
return new RamsesLoader(snapshot, baseid, double_precision, header, flags, num_files);
|
||||
return new RamsesLoader(snapshot, baseid, double_precision, header, flags, num_files, p);
|
||||
}
|
||||
|
||||
|
|
232
c_tools/mock/loaders/sdf_loader.cpp
Normal file
232
c_tools/mock/loaders/sdf_loader.cpp
Normal file
|
@ -0,0 +1,232 @@
|
|||
#include <iostream>
|
||||
#include <boost/format.hpp>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include "sdfloader_internal.hpp"
|
||||
#include "simulation_loader.hpp"
|
||||
#include <libsdf/mpmy.h>
|
||||
#include <libsdf/SDF.h>
|
||||
#include <libsdf/error.h>
|
||||
#include <libsdf/cosmo.h>
|
||||
|
||||
using boost::format;
|
||||
|
||||
using namespace std;
|
||||
using namespace CosmoTool;
|
||||
|
||||
class SDFLoader: public SimulationLoader
|
||||
{
|
||||
private:
|
||||
int load_flags;
|
||||
bool onefile;
|
||||
int _num_files;
|
||||
double unitMpc;
|
||||
SimuData *sdf_header;
|
||||
SDF *sdfp;
|
||||
SimulationPreprocessor *preproc;
|
||||
int num_splitting;
|
||||
public:
|
||||
SDFLoader(SDF *sdf_file, SimuData *header, int flags, int num_splitting,
|
||||
SimulationPreprocessor *p)
|
||||
: sdfp(sdf_file), load_flags(flags),
|
||||
sdf_header(header), preproc(p)
|
||||
{
|
||||
this->num_splitting = num_splitting;
|
||||
}
|
||||
|
||||
~SDFLoader()
|
||||
{
|
||||
delete sdf_header;
|
||||
}
|
||||
|
||||
SimuData *getHeader() {
|
||||
return sdf_header;
|
||||
}
|
||||
|
||||
int num_files() {
|
||||
return num_splitting;
|
||||
}
|
||||
|
||||
|
||||
int64_t getStart(int id)
|
||||
{
|
||||
return sdf_header->TotalNumPart * int64_t(id) / num_splitting;
|
||||
}
|
||||
|
||||
int64_t getNumberInSplit(int id)
|
||||
{
|
||||
return getStart(id+1)-getStart(id);
|
||||
}
|
||||
|
||||
void rescaleParticles(SimuData *d,
|
||||
double rescale_position,
|
||||
double rescale_velocity)
|
||||
{
|
||||
float shift = 0.5*d->BoxSize;
|
||||
rescale_position /= d->time;
|
||||
|
||||
if (d->Pos[0] != 0)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
for (int64_t i = 0; i < d->NumPart; i++)
|
||||
{
|
||||
d->Pos[k][i] = (d->Pos[k][i]*rescale_position + shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d->Vel[0] != 0)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
for (int64_t i = 0; i < d->NumPart; i++)
|
||||
{
|
||||
d->Vel[k][i] *= rescale_velocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SimuData *loadFile(int id) {
|
||||
SimuData *d;
|
||||
int64_t starts[7];
|
||||
int nobjs[7];
|
||||
int strides[7];
|
||||
void *addrs[7];
|
||||
const char *names[7];
|
||||
int ret;
|
||||
|
||||
if (id >= num_splitting)
|
||||
return 0;
|
||||
|
||||
d = new SimuData;
|
||||
*d = *sdf_header;
|
||||
d->NumPart = getNumberInSplit(id);
|
||||
|
||||
int64_t numPartToLoad = getNumberInSplit(id);
|
||||
int64_t start = getStart(id);
|
||||
int k = 0;
|
||||
#define SETUP_READ(name, vec) \
|
||||
names[k] = name, starts[k] = start, nobjs[k] = numPartToLoad, strides[k] = sizeof(vec[0]), addrs[k] = vec, k++;
|
||||
|
||||
if (load_flags & NEED_POSITION)
|
||||
{
|
||||
const char *name_template[3] = { "x", "y", "z" };
|
||||
for (int q = 0; q < 3; q++)
|
||||
{
|
||||
d->Pos[q] = new float[numPartToLoad];
|
||||
SETUP_READ(name_template[q], d->Pos[q]);
|
||||
}
|
||||
}
|
||||
if (load_flags & NEED_VELOCITY)
|
||||
{
|
||||
const char *name_template[3] = { "x", "y", "z" };
|
||||
for (int q = 0; q < 3; q++)
|
||||
{
|
||||
d->Vel[q] = new float[numPartToLoad];
|
||||
SETUP_READ(name_template[q], d->Vel[q]);
|
||||
}
|
||||
}
|
||||
if (load_flags & NEED_GADGET_ID)
|
||||
{
|
||||
d->Id = new long[numPartToLoad];
|
||||
SETUP_READ("ident", d->Id);
|
||||
}
|
||||
#undef SETUP_READ
|
||||
|
||||
ret = SDFseekrdvecsarr(sdfp, k, (char**)names, starts, nobjs, addrs, strides);
|
||||
if (ret != 0)
|
||||
{
|
||||
cerr << format("Splitting %d/%d, SDF read failure: %s") % id % num_splitting % SDFerrstring << endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
if (load_flags & (NEED_POSITION | NEED_VELOCITY))
|
||||
rescaleParticles(d, 0.001*d->Hubble, one_kpc/one_Gyr);
|
||||
|
||||
applyTransformations(d);
|
||||
basicPreprocessing(d, preproc);
|
||||
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
SimulationLoader *sdfLoader(const std::string& snapshot, int flags,
|
||||
int num_splitting,
|
||||
SimulationPreprocessor *p)
|
||||
{
|
||||
SDF *sdfp;
|
||||
int fileversion;
|
||||
SimuData *hdr;
|
||||
int64_t gnobj;
|
||||
|
||||
sdfp = SDFopen(0, snapshot.c_str());
|
||||
if (sdfp == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDFgetintOrDefault(sdfp, "version", &fileversion, 1);
|
||||
if (fileversion == 1)
|
||||
{
|
||||
SDFgetfloatOrDie(sdfp, "Omega0", &hdr->Omega_M);
|
||||
SDFgetfloatOrDie(sdfp, "Lambda_prime", &hdr->Omega_Lambda);
|
||||
SDFgetfloatOrDie(sdfp, "H0", &hdr->Hubble);
|
||||
}
|
||||
else
|
||||
{
|
||||
float Or, Of;
|
||||
SDFgetfloatOrDie(sdfp, "Omega0_m", &hdr->Omega_M);
|
||||
SDFgetfloatOrDie(sdfp, "Omega0_lambda", &hdr->Omega_Lambda);
|
||||
SDFgetfloatOrDie(sdfp, "Omega0_r", &Or);
|
||||
SDFgetfloatOrDie(sdfp, "Omega0_fld", &Of);
|
||||
|
||||
hdr->Omega_M += Or;
|
||||
hdr->Omega_Lambda += Of;
|
||||
SDFgetfloatOrDie(sdfp, "H0", &hdr->Hubble);
|
||||
|
||||
}
|
||||
double h0;
|
||||
h0 = hdr->Hubble*10.0*(one_kpc/one_Gyr);
|
||||
|
||||
if (SDFhasname("R0", sdfp))
|
||||
{
|
||||
double R0;
|
||||
|
||||
SDFgetdoubleOrDie(sdfp, "R0", &R0);
|
||||
hdr->BoxSize = 2.0*0.001*R0*h0;
|
||||
}
|
||||
|
||||
if (SDFhasname("Rx", sdfp))
|
||||
{
|
||||
double R0;
|
||||
|
||||
SDFgetdoubleOrDie(sdfp, "Rx", &R0);
|
||||
hdr->BoxSize = 2.0*0.001*R0*h0;
|
||||
}
|
||||
|
||||
if (SDFhasname("redshift", sdfp))
|
||||
{
|
||||
double redshift;
|
||||
|
||||
SDFgetdoubleOrDie(sdfp, "redshift", &redshift);
|
||||
hdr->time = 1/(1+redshift);
|
||||
}
|
||||
|
||||
if (SDFgetint64(sdfp, "npart", &gnobj))
|
||||
{
|
||||
gnobj = SDFnrecs("x", sdfp);
|
||||
cerr << format("[Warning] No 'npart' found in SDF file '%s', guessing npart=%ld from SDFnrecs") % snapshot % gnobj << endl;
|
||||
}
|
||||
hdr->NumPart = hdr->TotalNumPart = gnobj;
|
||||
|
||||
return new SDFLoader(sdfp, hdr, flags, num_splitting, p);
|
||||
}
|
||||
|
||||
|
||||
void sdfLoaderInit(int& argc, char **& argv)
|
||||
{
|
||||
MPMY_Init(&argc, &argv);
|
||||
}
|
6
c_tools/mock/loaders/sdfloader_internal.hpp
Normal file
6
c_tools/mock/loaders/sdfloader_internal.hpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __VOID_SDF_LOADER_INTERNAL_HPP
|
||||
#define __VOID_SDF_LOADER_INTERNAL_HPP
|
||||
|
||||
void sdfLoaderInit(int& argc, char **&argv);
|
||||
|
||||
#endif
|
|
@ -1,6 +1,9 @@
|
|||
#include <cmath>
|
||||
#include <CosmoTool/loadSimu.hpp>
|
||||
#include "simulation_loader.hpp"
|
||||
#ifdef SDF_SUPPORT
|
||||
#include "sdfloader_internal.hpp"
|
||||
#endif
|
||||
|
||||
using std::min;
|
||||
using namespace CosmoTool;
|
||||
|
@ -39,3 +42,45 @@ void SimulationLoader::applyTransformations(SimuData *s)
|
|||
redshift_gravity*s->Vel[redshift_axis][i]/100.;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SimulationLoader::basicPreprocessing(SimuData *d,
|
||||
SimulationPreprocessor *preproc)
|
||||
{
|
||||
if (preproc == 0)
|
||||
return;
|
||||
|
||||
long numAccepted = 0;
|
||||
bool *accepted = new bool[d->NumPart];
|
||||
for (long i = 0; i < d->NumPart; i++)
|
||||
{
|
||||
SingleParticle p;
|
||||
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
p.Pos[k] = (d->Pos[k]) ? 0 : d->Pos[k][i];
|
||||
p.Vel[k] = (d->Vel[k]) ? 0 : d->Vel[k][i];
|
||||
}
|
||||
p.ID = (d->Id) ? 0 : d->Id[i];
|
||||
|
||||
accepted[i] = preproc->accept(p);
|
||||
numAccepted += accepted[i];
|
||||
}
|
||||
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
filteredCopy(d->Pos[k], accepted, d->NumPart);
|
||||
filteredCopy(d->Vel[k], accepted, d->NumPart);
|
||||
}
|
||||
filteredCopy(d->Id, accepted, d->NumPart);
|
||||
filteredCopy(d->type, accepted, d->NumPart);
|
||||
d->NumPart = accepted;
|
||||
delete[] accepted;
|
||||
}
|
||||
|
||||
void simulationLoadersInit(int& argc, char **& argv)
|
||||
{
|
||||
#ifdef SDF_SUPPORT
|
||||
sdfLoaderInit(argc, argv);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,6 +13,17 @@ struct SingleParticle
|
|||
long ID;
|
||||
};
|
||||
|
||||
class SimulationPreprocessor
|
||||
{
|
||||
public:
|
||||
SimulationPreprocessor() {}
|
||||
virtual ~SimulationPreprocessor() {}
|
||||
|
||||
virtual long getEstimatedPostprocessed(long numParticles) { return numParticles; };
|
||||
virtual bool accept(const SingleParticle& p) { return true; }
|
||||
virtual void reset() {}
|
||||
};
|
||||
|
||||
class SimulationLoader
|
||||
{
|
||||
protected:
|
||||
|
@ -40,6 +51,8 @@ protected:
|
|||
|
||||
void reallocSimu(CosmoTool::SimuData *s, long newNumPart);
|
||||
|
||||
|
||||
void basicPreprocessing(CosmoTool::SimuData *d, SimulationPreprocessor *preproc);
|
||||
void applyTransformations(CosmoTool::SimuData *s);
|
||||
|
||||
void copyParticleToSimu(const SingleParticle& p, CosmoTool::SimuData *s, long index)
|
||||
|
@ -89,15 +102,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class SimulationPreprocessor
|
||||
{
|
||||
public:
|
||||
SimulationPreprocessor() {}
|
||||
virtual ~SimulationPreprocessor() {}
|
||||
|
||||
virtual long getEstimatedPostprocessed(long numParticles) { return numParticles; };
|
||||
virtual bool accept(const SingleParticle& p) { return true; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void delete_adaptor(void *ptr)
|
||||
|
@ -113,6 +117,9 @@ SimulationLoader *gadgetLoader(const std::string& snapshot, double Mpc_unitLengt
|
|||
SimulationLoader *flashLoader(const std::string& snapshot, int flags, SimulationPreprocessor *p);
|
||||
SimulationLoader *multidarkLoader(const std::string& snapshot, SimulationPreprocessor *p);
|
||||
SimulationLoader *ramsesLoader(const std::string& snapshot, int baseid, bool double_precision, int flags, SimulationPreprocessor *p);
|
||||
SimulationLoader *sdfLoader(const std::string& snapshot, int flags, int num_splitting, SimulationPreprocessor *p);
|
||||
|
||||
/* This is required for some parallel I/O handler (thus MPI beneath it) */
|
||||
void simulationLoadersInit(int& argc, char **& argv);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,11 +18,15 @@
|
|||
#include <stdio.h>
|
||||
#include <netcdfcpp.h>
|
||||
#include "pruneVoids_conf.h"
|
||||
#include <vector>
|
||||
|
||||
#define LIGHT_SPEED 299792.458
|
||||
#define MPC2Z 100./LIGHT_SPEED
|
||||
#define Z2MPC LIGHT_SPEED/100.
|
||||
|
||||
#define CENTRAL_VOID 1
|
||||
#define EDGE_VOID 2
|
||||
|
||||
typedef struct partStruct {
|
||||
float x, y, z, vol;
|
||||
} PART;
|
||||
|
@ -44,32 +48,38 @@ typedef struct voidStruct {
|
|||
float nearestEdge;
|
||||
float center[3], barycenter[3];
|
||||
int accepted;
|
||||
int voidType;
|
||||
gsl_vector *eval;
|
||||
gsl_matrix *evec;
|
||||
} VOID;
|
||||
|
||||
void outputVoid(int iVoid, VOID outVoid, FILE* fpZobov, FILE* fpCenters,
|
||||
FILE* fpCenterNoCut,
|
||||
FILE* fpSkyPositions, FILE* fpBarycenters, FILE* fpDistances,
|
||||
FILE* fpShapes, bool isObservation, double *boxLen);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
// initialize arguments
|
||||
pruneVoids_info args_info;
|
||||
pruneVoids_info args;
|
||||
pruneVoids_conf_params args_params;
|
||||
|
||||
pruneVoids_conf_init(&args_info);
|
||||
pruneVoids_conf_init(&args);
|
||||
pruneVoids_conf_params_init(&args_params);
|
||||
|
||||
args_params.check_required = 0;
|
||||
if (pruneVoids_conf_ext (argc, argv, &args_info, &args_params))
|
||||
if (pruneVoids_conf_ext (argc, argv, &args, &args_params))
|
||||
return 1;
|
||||
|
||||
if (!args_info.configFile_given) {
|
||||
if (pruneVoids_conf_required (&args_info,
|
||||
if (!args.configFile_given) {
|
||||
if (pruneVoids_conf_required (&args,
|
||||
PRUNEVOIDS_CONF_PACKAGE))
|
||||
return 1;
|
||||
} else {
|
||||
args_params.check_required = 1;
|
||||
args_params.initialize = 0;
|
||||
if (pruneVoids_conf_config_file (args_info.configFile_arg,
|
||||
&args_info,
|
||||
if (pruneVoids_conf_config_file (args.configFile_arg,
|
||||
&args,
|
||||
&args_params))
|
||||
return 1;
|
||||
}
|
||||
|
@ -77,12 +87,15 @@ int main(int argc, char **argv) {
|
|||
int i, p, p2, numPartTot, numZonesTot, dummy, iVoid, iZ;
|
||||
int numVoids, mockIndex, numKept;
|
||||
double tolerance;
|
||||
FILE *fp, *fpBarycenter, *fpDistances, *fpSkyPositions, *fpInfo;
|
||||
FILE *fpShapes;
|
||||
FILE *fp, *fpZobovCentral, *fpZobovAll, *fpCentersCentral, *fpCentersAll,
|
||||
*fpCentersNoCutCentral, *fpCentersNoCutAll, *fpBarycenterCentral,
|
||||
*fpBarycenterAll, *fpDistancesCentral, *fpDistancesAll,
|
||||
*fpShapesCentral, *fpShapesAll, *fpSkyPositionsCentral,
|
||||
*fpSkyPositionsAll;
|
||||
PART *part, *voidPart;
|
||||
ZONE2PART *zones2Parts;
|
||||
VOID2ZONE *void2Zones;
|
||||
VOID *voids;
|
||||
std::vector<VOID> voids;
|
||||
float *temp, junk, voidVol;
|
||||
int junkInt, voidID, numPart, numZones, zoneID, partID, maxNumPart;
|
||||
int coreParticle, zoneNumPart;
|
||||
|
@ -98,30 +111,30 @@ int main(int argc, char **argv) {
|
|||
|
||||
gsl_eigen_symmv_workspace *eigw = gsl_eigen_symmv_alloc(3);
|
||||
|
||||
numVoids = args_info.numVoids_arg;
|
||||
mockIndex = args_info.mockIndex_arg;
|
||||
tolerance = args_info.tolerance_arg;
|
||||
numVoids = args.numVoids_arg;
|
||||
mockIndex = args.mockIndex_arg;
|
||||
tolerance = args.tolerance_arg;
|
||||
|
||||
clock1 = clock();
|
||||
printf("Pruning parameters: %f %f %f %s\n", args_info.zMin_arg,
|
||||
args_info.zMax_arg,
|
||||
args_info.rMin_arg,
|
||||
args_info.periodic_arg);
|
||||
printf("Pruning parameters: %f %f %f %s\n", args.zMin_arg,
|
||||
args.zMax_arg,
|
||||
args.rMin_arg,
|
||||
args.periodic_arg);
|
||||
|
||||
// check for periodic box
|
||||
periodicX = 0;
|
||||
periodicY = 0;
|
||||
periodicZ = 0;
|
||||
if (!args_info.isObservation_flag) {
|
||||
if ( strchr(args_info.periodic_arg, 'x') != NULL) {
|
||||
if (!args.isObservation_flag) {
|
||||
if ( strchr(args.periodic_arg, 'x') != NULL) {
|
||||
periodicX = 1;
|
||||
printf("Will assume x-direction is periodic.\n");
|
||||
}
|
||||
if ( strchr(args_info.periodic_arg, 'y') != NULL) {
|
||||
if ( strchr(args.periodic_arg, 'y') != NULL) {
|
||||
periodicY = 1;
|
||||
printf("Will assume y-direction is periodic.\n");
|
||||
}
|
||||
if ( strchr(args_info.periodic_arg, 'z') != NULL) {
|
||||
if ( strchr(args.periodic_arg, 'z') != NULL) {
|
||||
periodicZ = 1;
|
||||
printf("Will assume z-direction is periodic.\n");
|
||||
}
|
||||
|
@ -129,7 +142,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// load box size
|
||||
printf("\n Getting info...\n");
|
||||
NcFile f_info(args_info.extraInfo_arg);
|
||||
NcFile f_info(args.extraInfo_arg);
|
||||
ranges[0][0] = f_info.get_att("range_x_min")->as_double(0);
|
||||
ranges[0][1] = f_info.get_att("range_x_max")->as_double(0);
|
||||
ranges[1][0] = f_info.get_att("range_y_min")->as_double(0);
|
||||
|
@ -143,7 +156,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// read in all particle positions
|
||||
printf("\n Loading particles...\n");
|
||||
fp = fopen(args_info.partFile_arg, "r");
|
||||
fp = fopen(args.partFile_arg, "r");
|
||||
fread(&dummy, 1, 4, fp);
|
||||
fread(&numPartTot, 1, 4, fp);
|
||||
fread(&dummy, 1, 4, fp);
|
||||
|
@ -154,7 +167,7 @@ int main(int argc, char **argv) {
|
|||
volNorm = numPartTot/(boxLen[0]*boxLen[1]*boxLen[2]);
|
||||
printf(" VOL NORM = %f\n", volNorm);
|
||||
|
||||
printf(" CENTRAL DEN = %f\n", args_info.maxCentralDen_arg);
|
||||
printf(" CENTRAL DEN = %f\n", args.maxCentralDen_arg);
|
||||
|
||||
fread(&dummy, 1, 4, fp);
|
||||
fread(temp, numPartTot, 4, fp);
|
||||
|
@ -174,7 +187,7 @@ int main(int argc, char **argv) {
|
|||
for (p = 0; p < numPartTot; p++)
|
||||
part[p].z = mul*temp[p];
|
||||
|
||||
if (!args_info.isObservation_flag) {
|
||||
if (!args.isObservation_flag) {
|
||||
for (p = 0; p < numPartTot; p++) {
|
||||
part[p].x += ranges[0][0];
|
||||
part[p].y += ranges[1][0];
|
||||
|
@ -189,12 +202,12 @@ int main(int argc, char **argv) {
|
|||
|
||||
// read in desired voids
|
||||
printf(" Loading voids...\n");
|
||||
fp = fopen(args_info.voidDesc_arg ,"r");
|
||||
fp = fopen(args.voidDesc_arg ,"r");
|
||||
fgets(line, sizeof(line), fp);
|
||||
sscanf(line, "%d %s %d %s", &junkInt, junkStr, &junkInt, junkStr);
|
||||
fgets(line, sizeof(line), fp);
|
||||
|
||||
voids = (VOID *) malloc(numVoids * sizeof(VOID));
|
||||
voids.resize(numVoids);
|
||||
i = 0;
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
sscanf(line, "%d %d %d %f %f %d %d %f %d %f %f\n", &iVoid, &voidID,
|
||||
|
@ -223,7 +236,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// load up the zone membership for each void
|
||||
printf(" Loading void-zone membership info...\n");
|
||||
fp = fopen(args_info.void2Zone_arg, "r");
|
||||
fp = fopen(args.void2Zone_arg, "r");
|
||||
fread(&numZonesTot, 1, 4, fp);
|
||||
void2Zones = (VOID2ZONE *) malloc(numZonesTot * sizeof(VOID2ZONE));
|
||||
|
||||
|
@ -241,7 +254,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// now the particles-zone
|
||||
printf(" Loading particle-zone membership info...\n");
|
||||
fp = fopen(args_info.zone2Part_arg, "r");
|
||||
fp = fopen(args.zone2Part_arg, "r");
|
||||
fread(&dummy, 1, 4, fp);
|
||||
fread(&numZonesTot, 1, 4, fp);
|
||||
|
||||
|
@ -259,7 +272,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// and finally volumes
|
||||
printf(" Loading particle volumes...\n");
|
||||
fp = fopen(args_info.partVol_arg, "r");
|
||||
fp = fopen(args.partVol_arg, "r");
|
||||
fread(&mask_index, 1, 4, fp);
|
||||
if (mask_index != mockIndex) {
|
||||
printf("NON-MATCHING MOCK INDICES!? %d %d\n", mask_index, mockIndex);
|
||||
|
@ -366,7 +379,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// compute central density
|
||||
centralRad = voids[iVoid].radius/args_info.centralRadFrac_arg;
|
||||
centralRad = voids[iVoid].radius/args.centralRadFrac_arg;
|
||||
centralDen = 0.;
|
||||
int numCentral = 0;
|
||||
for (p = 0; p < voids[iVoid].numPart; p++) {
|
||||
|
@ -386,7 +399,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// compute maximum extent
|
||||
/*
|
||||
if (args_info.isObservation_flag) {
|
||||
if (args.isObservation_flag) {
|
||||
maxDist = 0.;
|
||||
for (p = 0; p < voids[iVoid].numPart; p++) {
|
||||
for (p2 = p; p2 < voids[iVoid].numPart; p2++) {
|
||||
|
@ -419,7 +432,7 @@ int main(int argc, char **argv) {
|
|||
voids[iVoid].maxRadius = sqrt(maxDist);
|
||||
// }
|
||||
|
||||
if (args_info.isObservation_flag) {
|
||||
if (args.isObservation_flag) {
|
||||
// compute distance from center to nearest mock
|
||||
minDist = 1.e99;
|
||||
for (p = mockIndex; p < numPartTot; p++) {
|
||||
|
@ -436,16 +449,16 @@ int main(int argc, char **argv) {
|
|||
voids[iVoid].nearestMock = 1.e99;
|
||||
}
|
||||
|
||||
if (args_info.isObservation_flag) {
|
||||
if (args.isObservation_flag) {
|
||||
voids[iVoid].redshiftInMpc =
|
||||
sqrt(pow(voids[iVoid].barycenter[0] - boxLen[0]/2.,2) +
|
||||
pow(voids[iVoid].barycenter[1] - boxLen[1]/2.,2) +
|
||||
pow(voids[iVoid].barycenter[2] - boxLen[2]/2.,2));
|
||||
voids[iVoid].redshiftInMpc = voids[iVoid].redshiftInMpc;
|
||||
redshift = voids[iVoid].redshiftInMpc;
|
||||
nearestEdge = fabs(redshift-args_info.zMax_arg*LIGHT_SPEED/100.);
|
||||
//nearestEdge = fmin(fabs(redshift-args_info.zMin_arg*LIGHT_SPEED/100.),
|
||||
// fabs(redshift-args_info.zMax_arg*LIGHT_SPEED/100.));
|
||||
nearestEdge = fabs(redshift-args.zMax_arg*LIGHT_SPEED/100.);
|
||||
//nearestEdge = fmin(fabs(redshift-args.zMin_arg*LIGHT_SPEED/100.),
|
||||
// fabs(redshift-args.zMax_arg*LIGHT_SPEED/100.));
|
||||
voids[iVoid].redshift = voids[iVoid].redshiftInMpc/LIGHT_SPEED*100.;
|
||||
|
||||
} else {
|
||||
|
@ -504,200 +517,273 @@ int main(int argc, char **argv) {
|
|||
|
||||
int numWrong = 0;
|
||||
int numHighDen = 0;
|
||||
int numCentral = 0;
|
||||
int numEdge = 0;
|
||||
int numNearZ = 0;
|
||||
int numTooSmall = 0;
|
||||
|
||||
printf(" Picking winners and losers...\n");
|
||||
for (iVoid = 0; iVoid < numVoids; iVoid++) {
|
||||
printf(" Starting with %d voids\n", voids.size());
|
||||
|
||||
for (iVoid = 0; iVoid < voids.size(); iVoid++) {
|
||||
voids[iVoid].accepted = 1;
|
||||
}
|
||||
|
||||
for (iVoid = 0; iVoid < numVoids; iVoid++) {
|
||||
/*
|
||||
int j = 0;
|
||||
for (iVoid = 0; iVoid < voids.size(); iVoid++) {
|
||||
if (voids[iVoid].densCon < 1.5) {
|
||||
// voids[iVoid].accepted = -4;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (voids[iVoid].centralDen > args_info.maxCentralDen_arg) {
|
||||
// toss out voids that are obviously wrong
|
||||
int iGood = 0;
|
||||
for (iVoid = 0; iVoid < voids.size(); iVoid++) {
|
||||
if (voids[iVoid].densCon > 1.e4) {
|
||||
numWrong++;
|
||||
} else {
|
||||
voids[iGood++] = voids[iVoid];
|
||||
}
|
||||
}
|
||||
voids.resize(iGood);
|
||||
printf(" 1st filter: reiGoodected %d obviously bad\n", numWrong);
|
||||
|
||||
iGood = 0;
|
||||
for (iVoid = 0; iVoid < voids.size(); iVoid++) {
|
||||
if (voids[iVoid].radius < args.rMin_arg) {
|
||||
numTooSmall++;
|
||||
} else {
|
||||
voids[iGood++] = voids[iVoid];
|
||||
}
|
||||
}
|
||||
voids.resize(iGood);
|
||||
printf(" 2nd filter: reiGoodected %d too small\n", numTooSmall);
|
||||
|
||||
|
||||
iGood = 0;
|
||||
for (iVoid = 0; iVoid < voids.size(); iVoid++) {
|
||||
// *always* clean out near edges since there are no mocks there
|
||||
if (tolerance*voids[iVoid].maxRadius > voids[iVoid].nearestEdge) {
|
||||
numNearZ++;
|
||||
} else {
|
||||
voids[iGood++] = voids[iVoid];
|
||||
}
|
||||
}
|
||||
voids.resize(iGood);
|
||||
printf(" 3rd filter: reiGoodected %d too close to high redshift boundaries\n", numNearZ);
|
||||
|
||||
numNearZ = 0;
|
||||
iGood = 0;
|
||||
for (iVoid = 0; iVoid < voids.size(); iVoid++) {
|
||||
// assume the lower z-boundary is "soft" in observations
|
||||
if (args.isObservation_flag &&
|
||||
voids[iVoid].redshift < args.zMin_arg) {
|
||||
numNearZ++;
|
||||
} else {
|
||||
voids[iGood++] = voids[iVoid];
|
||||
}
|
||||
}
|
||||
voids.resize(iGood);
|
||||
printf(" 4th filter: reiGoodected %d too close to low redshift boundaries\n", numNearZ);
|
||||
|
||||
for (iVoid = 0; iVoid < voids.size(); iVoid++) {
|
||||
if (voids[iVoid].centralDen > args.maxCentralDen_arg) {
|
||||
voids[iVoid].accepted = -1;
|
||||
numHighDen++;
|
||||
}
|
||||
}
|
||||
|
||||
// toss out voids that are obviously wrong
|
||||
if (voids[iVoid].densCon > 1.e4) {
|
||||
voids[iVoid].accepted = -4;
|
||||
numWrong++;
|
||||
}
|
||||
|
||||
if (strcmp(args_info.dataPortion_arg, "edge") == 0 &&
|
||||
tolerance*voids[iVoid].maxRadius < voids[iVoid].nearestMock) {
|
||||
voids[iVoid].accepted = -3;
|
||||
for (iVoid = 0; iVoid < voids.size(); iVoid++) {
|
||||
if (tolerance*voids[iVoid].maxRadius < voids[iVoid].nearestMock) {
|
||||
voids[iVoid].voidType = CENTRAL_VOID;
|
||||
numCentral++;
|
||||
} else {
|
||||
voids[iVoid].voidType = EDGE_VOID;
|
||||
numEdge++;
|
||||
}
|
||||
|
||||
if (strcmp(args_info.dataPortion_arg, "central") == 0 &&
|
||||
tolerance*voids[iVoid].maxRadius > voids[iVoid].nearestMock) {
|
||||
voids[iVoid].accepted = -3;
|
||||
numEdge++;
|
||||
}
|
||||
|
||||
if (voids[iVoid].radius < args_info.rMin_arg) {
|
||||
voids[iVoid].accepted = -2;
|
||||
numTooSmall++;
|
||||
}
|
||||
|
||||
// *always* clean out near edges since there are no mocks there
|
||||
if (tolerance*voids[iVoid].maxRadius > voids[iVoid].nearestEdge) {
|
||||
voids[iVoid].accepted = -3;
|
||||
if (voids[iVoid].accepted == 1) numEdge++;
|
||||
}
|
||||
|
||||
// assume the lower z-boundary is "soft" in observations
|
||||
if (args_info.isObservation_flag &&
|
||||
voids[iVoid].redshift < args_info.zMin_arg) {
|
||||
voids[iVoid].accepted = -3;
|
||||
if (voids[iVoid].accepted == 1) numEdge++;
|
||||
}
|
||||
}
|
||||
|
||||
numKept = 0;
|
||||
for (iVoid = 0; iVoid < numVoids; iVoid++) {
|
||||
if (voids[iVoid].accepted == 1) numKept++;
|
||||
}
|
||||
|
||||
printf(" Number kept: %d (out of %d)\n", numKept, numVoids);
|
||||
printf(" Rejected %d near the edge\n", numEdge);
|
||||
printf(" Rejected %d too small\n", numTooSmall);
|
||||
printf(" Rejected %d obviously bad\n", numWrong);
|
||||
printf(" Rejected %d too high central density\n", numHighDen);
|
||||
printf(" Number kept: %d (out of %d)\n", voids.size(), numVoids);
|
||||
printf(" We have %d edge voids\n", numEdge);
|
||||
printf(" We have %d central voids\n", numCentral);
|
||||
printf(" We have %d too high central density\n", numHighDen);
|
||||
|
||||
printf(" Output...\n");
|
||||
fp = fopen(args_info.output_arg, "w");
|
||||
fpBarycenter = fopen(args_info.outCenters_arg, "w");
|
||||
fpInfo = fopen(args_info.outInfo_arg, "w");
|
||||
fpDistances = fopen(args_info.outDistances_arg, "w");
|
||||
fpSkyPositions = fopen(args_info.outSkyPositions_arg, "w");
|
||||
fpShapes = fopen(args_info.outShapes_arg, "w");
|
||||
fprintf(fp, "%d particles, %d voids.\n", mockIndex, numKept);
|
||||
fprintf(fp, "see column in master void file\n");
|
||||
fprintf(fpInfo, "# center x,y,z (Mpc/h), volume (normalized), radius (Mpc/h), redshift, volume (Mpc/h^3), void ID, density contrast\n");
|
||||
fprintf(fpSkyPositions, "# RA, dec, redshift, radius (Mpc/h), void ID\n");
|
||||
fprintf(fpShapes, "# void ID, eig(1), eig(2), eig(3), eigv(1)-x, eiv(1)-y, eigv(1)-z, eigv(2)-x, eigv(2)-y, eigv(2)-z, eigv(3)-x, eigv(3)-y, eigv(3)-z\n");
|
||||
for (iVoid = 0; iVoid < numVoids; iVoid++) {
|
||||
fpZobovCentral = fopen((std::string(args.outputDir_arg)+"/voidDesc_central_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpZobovCentral, "%d particles, %d voids.\n", mockIndex, numKept);
|
||||
fprintf(fpZobovCentral, "Void# FileVoid# CoreParticle CoreDens ZoneVol Zone#Part Void#Zones VoidVol Void#Part VoidDensContrast VoidProb\n");
|
||||
|
||||
if (voids[iVoid].accepted != 1) continue;
|
||||
fpZobovAll = fopen((std::string(args.outputDir_arg)+"/voidDesc_all_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpZobovAll, "%d particles, %d voids.\n", mockIndex, numKept);
|
||||
fprintf(fpZobovAll, "Void# FileVoid# CoreParticle CoreDens ZoneVol Zone#Part Void#Zones VoidVol Void#Part VoidDensContrast VoidProb\n");
|
||||
|
||||
fprintf(fp, "%d %d %d %f %f %d %d %f %d %f %f\n",
|
||||
iVoid,
|
||||
voids[iVoid].voidID,
|
||||
voids[iVoid].coreParticle,
|
||||
voids[iVoid].coreDens,
|
||||
voids[iVoid].zoneVol,
|
||||
voids[iVoid].zoneNumPart,
|
||||
voids[iVoid].numZones,
|
||||
voids[iVoid].vol,
|
||||
voids[iVoid].numPart,
|
||||
voids[iVoid].densCon,
|
||||
voids[iVoid].voidProb);
|
||||
fpBarycenterCentral = fopen((std::string(args.outputDir_arg)+"/barycenters_central_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fpBarycenterAll = fopen((std::string(args.outputDir_arg)+"/barycenters_all_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
|
||||
fprintf(fpBarycenter, "%d %e %e %e\n",
|
||||
voids[iVoid].voidID,
|
||||
voids[iVoid].barycenter[0],
|
||||
voids[iVoid].barycenter[1],
|
||||
voids[iVoid].barycenter[2]);
|
||||
fpCentersCentral = fopen((std::string(args.outputDir_arg)+"/centers_central_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpCentersCentral, "# center x,y,z (Mpc/h), volume (normalized), radius (Mpc/h), redshift, volume (Mpc/h^3), void ID, density contrast, num part\n");
|
||||
|
||||
fprintf(fpDistances, "%d %e\n",
|
||||
voids[iVoid].voidID,
|
||||
voids[iVoid].nearestMock);
|
||||
fpCentersAll = fopen((std::string(args.outputDir_arg)+"/centers_all_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpCentersAll, "# center x,y,z (Mpc/h), volume (normalized), radius (Mpc/h), redshift, volume (Mpc/h^3), void ID, density contrast, num part\n");
|
||||
|
||||
double outCenter[3];
|
||||
outCenter[0] = voids[iVoid].barycenter[0];
|
||||
outCenter[1] = voids[iVoid].barycenter[1];
|
||||
outCenter[2] = voids[iVoid].barycenter[2];
|
||||
fpCentersNoCutCentral = fopen((std::string(args.outputDir_arg)+"/centers_nocut_central_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpCentersNoCutCentral, "# center x,y,z (Mpc/h), volume (normalized), radius (Mpc/h), redshift, volume (Mpc/h^3), void ID, density contrast, num part\n");
|
||||
|
||||
if (args_info.isObservation_flag) {
|
||||
outCenter[0] = (voids[iVoid].barycenter[0]-boxLen[0]/2.)*100.;
|
||||
outCenter[1] = (voids[iVoid].barycenter[1]-boxLen[1]/2.)*100.;
|
||||
outCenter[2] = (voids[iVoid].barycenter[2]-boxLen[2]/2.)*100.;
|
||||
}
|
||||
|
||||
fprintf(fpInfo, "%.2f %.2f %.2f %.2f %.2f %.5f %.2f %d %f\n",
|
||||
outCenter[0],
|
||||
outCenter[1],
|
||||
outCenter[2],
|
||||
voids[iVoid].vol,
|
||||
voids[iVoid].radius,
|
||||
voids[iVoid].redshift,
|
||||
4./3.*M_PI*pow(voids[iVoid].radius, 3),
|
||||
voids[iVoid].voidID,
|
||||
voids[iVoid].densCon);
|
||||
|
||||
fprintf(fpSkyPositions, "%.2f %.2f %.5f %.2f %d\n",
|
||||
atan((voids[iVoid].barycenter[1]-boxLen[1]/2.) /
|
||||
(voids[iVoid].barycenter[0]-boxLen[0]/2.)) * 180/M_PI + 180,
|
||||
asin((voids[iVoid].barycenter[2]-boxLen[2]/2.) /
|
||||
voids[iVoid].redshiftInMpc) * 180/M_PI,
|
||||
voids[iVoid].redshift,
|
||||
voids[iVoid].radius,
|
||||
voids[iVoid].voidID);
|
||||
|
||||
fprintf(fpShapes, "%d %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n",
|
||||
voids[iVoid].voidID,
|
||||
gsl_vector_get(voids[iVoid].eval, 0),
|
||||
gsl_vector_get(voids[iVoid].eval, 1),
|
||||
gsl_vector_get(voids[iVoid].eval, 2),
|
||||
gsl_matrix_get(voids[iVoid].evec, 0 ,0),
|
||||
gsl_matrix_get(voids[iVoid].evec, 0 ,1),
|
||||
gsl_matrix_get(voids[iVoid].evec, 0 ,2),
|
||||
gsl_matrix_get(voids[iVoid].evec, 1 ,0),
|
||||
gsl_matrix_get(voids[iVoid].evec, 1 ,1),
|
||||
gsl_matrix_get(voids[iVoid].evec, 1 ,2),
|
||||
gsl_matrix_get(voids[iVoid].evec, 2 ,0),
|
||||
gsl_matrix_get(voids[iVoid].evec, 2 ,1),
|
||||
gsl_matrix_get(voids[iVoid].evec, 2 ,2)
|
||||
);
|
||||
}
|
||||
fclose(fp);
|
||||
fclose(fpInfo);
|
||||
fclose(fpBarycenter);
|
||||
fclose(fpDistances);
|
||||
|
||||
// print the centers catalog again but without central density cuts
|
||||
fpInfo = fopen(args_info.outNoCutInfo_arg, "w");
|
||||
fprintf(fpInfo, "# center x,y,z (km/s), volume (normalized), radius (Mpc/h), redshift, volume (Mpc/h^3), void ID\n");
|
||||
for (iVoid = 0; iVoid < numVoids; iVoid++) {
|
||||
|
||||
if (voids[iVoid].accepted < -1) continue;
|
||||
|
||||
double outCenter[3];
|
||||
outCenter[0] = voids[iVoid].barycenter[0];
|
||||
outCenter[1] = voids[iVoid].barycenter[1];
|
||||
outCenter[2] = voids[iVoid].barycenter[2];
|
||||
|
||||
if (args_info.isObservation_flag) {
|
||||
outCenter[0] = (voids[iVoid].barycenter[0]-boxLen[0]/2.)*100.;
|
||||
outCenter[1] = (voids[iVoid].barycenter[1]-boxLen[1]/2.)*100.;
|
||||
outCenter[2] = (voids[iVoid].barycenter[2]-boxLen[2]/2.)*100.;
|
||||
}
|
||||
fpCentersNoCutAll = fopen((std::string(args.outputDir_arg)+"/centers_nocut_all_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpCentersNoCutAll, "# center x,y,z (Mpc/h), volume (normalized), radius (Mpc/h), redshift, volume (Mpc/h^3), void ID, density contrast, num part\n");
|
||||
|
||||
|
||||
fprintf(fpInfo, "%.2f %.2f %.2f %.2f %.2f %.5f %.2f %d %f\n",
|
||||
outCenter[0],
|
||||
outCenter[1],
|
||||
outCenter[2],
|
||||
voids[iVoid].vol,
|
||||
voids[iVoid].radius,
|
||||
voids[iVoid].redshift,
|
||||
4./3.*M_PI*pow(voids[iVoid].radius, 3),
|
||||
voids[iVoid].voidID,
|
||||
voids[iVoid].densCon);
|
||||
}
|
||||
fclose(fpInfo);
|
||||
fpDistancesCentral = fopen((std::string(args.outputDir_arg)+"boundaryDistancesCentral_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fpDistancesAll = fopen((std::string(args.outputDir_arg)+"boundaryDistancesAll_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
|
||||
fpSkyPositionsCentral = fopen((std::string(args.outputDir_arg)+"/sky_positions_central_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpSkyPositionsCentral, "# RA, dec, redshift, radius (Mpc/h), void ID\n");
|
||||
|
||||
fpSkyPositionsAll = fopen((std::string(args.outputDir_arg)+"/sky_positions_all_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpSkyPositionsAll, "# RA, dec, redshift, radius (Mpc/h), void ID\n");
|
||||
|
||||
fpShapesCentral = fopen((std::string(args.outputDir_arg)+"/shapes_central_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpShapesCentral, "# void ID, eig(1), eig(2), eig(3), eigv(1)-x, eiv(1)-y, eigv(1)-z, eigv(2)-x, eigv(2)-y, eigv(2)-z, eigv(3)-x, eigv(3)-y, eigv(3)-z\n");
|
||||
|
||||
fpShapesAll = fopen((std::string(args.outputDir_arg)+"/shapes_all_"+std::string(args.sampleName_arg)+".out").c_str(), "w");
|
||||
fprintf(fpShapesAll, "# void ID, eig(1), eig(2), eig(3), eigv(1)-x, eiv(1)-y, eigv(1)-z, eigv(2)-x, eigv(2)-y, eigv(2)-z, eigv(3)-x, eigv(3)-y, eigv(3)-z\n");
|
||||
|
||||
|
||||
for (iVoid = 0; iVoid < voids.size(); iVoid++) {
|
||||
|
||||
if (voids[iVoid].voidType == CENTRAL_VOID) {
|
||||
outputVoid(iVoid, voids[iVoid], fpZobovCentral, fpCentersCentral,
|
||||
fpCentersNoCutCentral, fpSkyPositionsCentral,
|
||||
fpBarycenterCentral, fpDistancesCentral, fpShapesCentral,
|
||||
args.isObservation_flag, boxLen);
|
||||
}
|
||||
|
||||
if (voids[iVoid].voidType == EDGE_VOID ||
|
||||
voids[iVoid].voidType == CENTRAL_VOID) {
|
||||
outputVoid(iVoid, voids[iVoid], fpZobovAll, fpCentersAll,
|
||||
fpCentersNoCutAll, fpSkyPositionsAll,
|
||||
fpBarycenterAll, fpDistancesAll, fpShapesAll,
|
||||
args.isObservation_flag, boxLen);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fpZobovCentral);
|
||||
fclose(fpZobovAll);
|
||||
fclose(fpCentersCentral);
|
||||
fclose(fpCentersAll);
|
||||
fclose(fpCentersNoCutCentral);
|
||||
fclose(fpCentersNoCutAll);
|
||||
fclose(fpBarycenterCentral);
|
||||
fclose(fpBarycenterAll);
|
||||
fclose(fpDistancesCentral);
|
||||
fclose(fpDistancesAll);
|
||||
fclose(fpShapesCentral);
|
||||
fclose(fpShapesAll);
|
||||
fclose(fpSkyPositionsCentral);
|
||||
fclose(fpSkyPositionsAll);
|
||||
|
||||
clock2 = clock();
|
||||
printf(" Time: %f sec (for %d voids)\n", (1.*clock2-clock1)/CLOCKS_PER_SEC, numVoids);
|
||||
printf(" Time: %f sec (for %d voids)\n",
|
||||
(1.*clock2-clock1)/CLOCKS_PER_SEC, numVoids);
|
||||
clock1 = clock();
|
||||
|
||||
|
||||
printf("Done!\n");
|
||||
return 0;
|
||||
} // end main
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void outputVoid(int iVoid, VOID outVoid, FILE* fpZobov, FILE* fpCenters,
|
||||
FILE* fpCenterNoCut, FILE* fpSkyPositions,
|
||||
FILE* fpBarycenters, FILE* fpDistances, FILE* fpShapes,
|
||||
bool isObservation, double *boxLen) {
|
||||
|
||||
fprintf(fpZobov, "%d %d %d %f %f %d %d %f %d %f %f\n",
|
||||
iVoid,
|
||||
outVoid.voidID,
|
||||
outVoid.coreParticle,
|
||||
outVoid.coreDens,
|
||||
outVoid.zoneVol,
|
||||
outVoid.zoneNumPart,
|
||||
outVoid.numZones,
|
||||
outVoid.vol,
|
||||
outVoid.numPart,
|
||||
outVoid.densCon,
|
||||
outVoid.voidProb);
|
||||
|
||||
fprintf(fpBarycenters, "%d %e %e %e\n",
|
||||
outVoid.voidID,
|
||||
outVoid.barycenter[0],
|
||||
outVoid.barycenter[1],
|
||||
outVoid.barycenter[2]);
|
||||
|
||||
fprintf(fpDistances, "%d %e\n",
|
||||
outVoid.voidID,
|
||||
outVoid.nearestMock);
|
||||
|
||||
double outCenter[3];
|
||||
outCenter[0] = outVoid.barycenter[0];
|
||||
outCenter[1] = outVoid.barycenter[1];
|
||||
outCenter[2] = outVoid.barycenter[2];
|
||||
|
||||
if (isObservation) {
|
||||
outCenter[0] = (outVoid.barycenter[0]-boxLen[0]/2.)*100.;
|
||||
outCenter[1] = (outVoid.barycenter[1]-boxLen[1]/2.)*100.;
|
||||
outCenter[2] = (outVoid.barycenter[2]-boxLen[2]/2.)*100.;
|
||||
}
|
||||
|
||||
if (outVoid.accepted == 1) {
|
||||
fprintf(fpCenters, "%.2f %.2f %.2f %.2f %.2f %.5f %.2f %d %f %d\n",
|
||||
outCenter[0],
|
||||
outCenter[1],
|
||||
outCenter[2],
|
||||
outVoid.vol,
|
||||
outVoid.radius,
|
||||
outVoid.redshift,
|
||||
4./3.*M_PI*pow(outVoid.radius, 3),
|
||||
outVoid.voidID,
|
||||
outVoid.densCon,
|
||||
outVoid.numPart);
|
||||
}
|
||||
|
||||
fprintf(fpCenterNoCut, "%.2f %.2f %.2f %.2f %.2f %.5f %.2f %d %f %d\n",
|
||||
outCenter[0],
|
||||
outCenter[1],
|
||||
outCenter[2],
|
||||
outVoid.vol,
|
||||
outVoid.radius,
|
||||
outVoid.redshift,
|
||||
4./3.*M_PI*pow(outVoid.radius, 3),
|
||||
outVoid.voidID,
|
||||
outVoid.densCon,
|
||||
outVoid.numPart);
|
||||
|
||||
fprintf(fpSkyPositions, "%.2f %.2f %.5f %.2f %d\n",
|
||||
atan((outVoid.barycenter[1]-boxLen[1]/2.) /
|
||||
(outVoid.barycenter[0]-boxLen[0]/2.)) * 180/M_PI + 180,
|
||||
asin((outVoid.barycenter[2]-boxLen[2]/2.) /
|
||||
outVoid.redshiftInMpc) * 180/M_PI,
|
||||
outVoid.redshift,
|
||||
outVoid.radius,
|
||||
outVoid.voidID);
|
||||
|
||||
fprintf(fpShapes, "%d %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n",
|
||||
outVoid.voidID,
|
||||
gsl_vector_get(outVoid.eval, 0),
|
||||
gsl_vector_get(outVoid.eval, 1),
|
||||
gsl_vector_get(outVoid.eval, 2),
|
||||
gsl_matrix_get(outVoid.evec, 0 ,0),
|
||||
gsl_matrix_get(outVoid.evec, 0 ,1),
|
||||
gsl_matrix_get(outVoid.evec, 0 ,2),
|
||||
gsl_matrix_get(outVoid.evec, 1 ,0),
|
||||
gsl_matrix_get(outVoid.evec, 1 ,1),
|
||||
gsl_matrix_get(outVoid.evec, 1 ,2),
|
||||
gsl_matrix_get(outVoid.evec, 2 ,0),
|
||||
gsl_matrix_get(outVoid.evec, 2 ,1),
|
||||
gsl_matrix_get(outVoid.evec, 2 ,2)
|
||||
);
|
||||
|
||||
} // end outputVoid
|
||||
|
|
|
@ -26,21 +26,8 @@ option "zMax" - "Maximum redshift of sample" double optional default="10.0"
|
|||
|
||||
option "rMin" - "Minimum allowable void radius" double optional default="0.0"
|
||||
|
||||
|
||||
option "output" - "Output void file" string required
|
||||
option "outDistances" - "output of distances from centers to nearest mock particle" string required
|
||||
|
||||
option "outCenters" - "output barycenters of voids" string required
|
||||
|
||||
option "outInfo" - "output info of voids" string required
|
||||
|
||||
option "outNoCutInfo" - "output info of voids" string required
|
||||
|
||||
option "outSkyPositions" - "output sky positions of voids" string required
|
||||
|
||||
option "outShapes" - "output shape information of voids" string required
|
||||
|
||||
option "dataPortion" - "all, central, or edge" string required
|
||||
option "outputDir" - "Directory to place outputs" string required
|
||||
option "sampleName" - "unique string to assign to outputs" string required
|
||||
|
||||
option "periodic" - "Set of edges which are periodic" string optional default="xy"
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace CosmoTool
|
|||
HealpixSpectrum<T> *new_spectrum = new HealpixSpectrum<T>(in_spec.Lmax());
|
||||
T *out_d = new_spectrum->data();
|
||||
|
||||
std::copy(data, data + min(size,new_spectrum->size()), out_d);
|
||||
std::copy(data, data + std::min(size,new_spectrum->size()), out_d);
|
||||
|
||||
return Spectrum_ptr(new_spectrum);
|
||||
}
|
||||
|
|
40
external/external_build.cmake
vendored
40
external/external_build.cmake
vendored
|
@ -1,6 +1,7 @@
|
|||
include(FindOpenMP)
|
||||
|
||||
OPTION(ENABLE_OPENMP "Set to Yes if Healpix and/or you need openMP" OFF)
|
||||
OPTION(SDF_SUPPORT "Set to Yes to activate support for SDF" OFF)
|
||||
|
||||
IF(ENABLE_OPENMP)
|
||||
|
||||
|
@ -76,7 +77,7 @@ if (INTERNAL_GENGETOPT)
|
|||
CC=${CMAKE_C_COMPILER}
|
||||
CXX=${CMAKE_CXX_COMPILER}
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_COMMAND make install
|
||||
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install
|
||||
)
|
||||
SET(GENGETOPT ${GENGETOPT_BIN_DIR}/bin/gengetopt CACHE FILEPATH "Path GenGetOpt binary")
|
||||
else(INTERNAL_GENGETOPT)
|
||||
|
@ -100,7 +101,7 @@ if (INTERNAL_HDF5)
|
|||
CPPFLAGS=${CONFIGURE_CPP_FLAGS} CC=${CMAKE_C_COMPILER}
|
||||
CXX=${CMAKE_CXX_COMPILER}
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_COMMAND make install
|
||||
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install
|
||||
)
|
||||
SET(cosmotool_DEPS ${cosmotool_DEPS} hdf5)
|
||||
SET(hdf5_built hdf5)
|
||||
|
@ -144,7 +145,7 @@ if (INTERNAL_NETCDF)
|
|||
--disable-examples ${EXTRA_NC_FLAGS} CC=${CMAKE_C_COMPILER}
|
||||
CXX=${CMAKE_CXX_COMPILER}
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_COMMAND make install
|
||||
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install
|
||||
)
|
||||
SET(CONFIGURE_CPP_LDFLAGS "${CONFIGURE_LDFLAGS}")
|
||||
SET(EXTRA_NC_FLAGS CPPFLAGS=${CONFIGURE_CPP_FLAGS} LDFLAGS=${CONFIGURE_CPP_LDFLAGS})
|
||||
|
@ -198,8 +199,8 @@ IF(INTERNAL_GSL)
|
|||
--with-pic --libdir=${CMAKE_BINARY_DIR}/ext_build/gsl/lib
|
||||
CPPFLAGS=${CONFIGURE_CPP_FLAGS} CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER}
|
||||
BUILD_IN_SOURCE 1
|
||||
BUILD_COMMAND make
|
||||
INSTALL_COMMAND make install
|
||||
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install
|
||||
)
|
||||
SET(GSL_INTERNAL_LIBS ${CMAKE_BINARY_DIR}/ext_build/gsl/lib)
|
||||
SET(GSL_LIBRARY ${GSL_INTERNAL_LIBS}/libgsl.a CACHE STRING "GSL internal path" FORCE)
|
||||
|
@ -249,9 +250,9 @@ ExternalProject_Add(cfitsio
|
|||
CPPFLAGS=${CONFIGURE_CPP_FLAGS}
|
||||
CC=${CMAKE_C_COMPILER}
|
||||
CXX=${CMAKE_CXX_COMPILER}
|
||||
BUILD_COMMAND make
|
||||
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_COMMAND make install
|
||||
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install
|
||||
)
|
||||
SET(CFITSIO_PREFIX ${CMAKE_BINARY_DIR}/ext_build/cfitsio)
|
||||
SET(CFITSIO_LIBRARY ${CFITSIO_PREFIX}/lib/libcfitsio.a)
|
||||
|
@ -266,7 +267,7 @@ ExternalProject_Add(healpix
|
|||
PREFIX ${BUILD_PREFIX}/healpix-prefix
|
||||
SOURCE_DIR ${CMAKE_SOURCE_DIR}/external/healpix
|
||||
CONFIGURE_COMMAND echo No configure
|
||||
BUILD_COMMAND make
|
||||
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
HEALPIX_TARGET=sampler
|
||||
HEALPIX_CC=${CMAKE_C_COMPILER}
|
||||
HEALPIX_CXX=${CMAKE_CXX_COMPILER}
|
||||
|
@ -315,9 +316,28 @@ endif(INTERNAL_QHULL)
|
|||
|
||||
SET(QHULL_LIBRARIES ${QHULL_CPP_LIBRARY} ${QHULL_LIBRARY} )
|
||||
|
||||
|
||||
###############
|
||||
# Build libSDF
|
||||
###############
|
||||
IF(SDF_SUPPORT)
|
||||
SET(LIBSDF_ARCH x86_64)
|
||||
SET(LIBSDF_PATH ${CMAKE_SOURCE_DIR}/external/libsdf)
|
||||
|
||||
ExternalProject_Add(libSDF
|
||||
PREFIX ${BUILD_PREFIX}/libSDF-prefix
|
||||
SOURCE_DIR ${LIBSDF_PATH}
|
||||
CONFIGURE_COMMAND echo No configure
|
||||
BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} ARCH=${LIBSDF_ARCH}
|
||||
INSTALL_COMMAND echo No install
|
||||
BUILD_IN_SOURCE 1
|
||||
)
|
||||
SET(LIBSDF_INCLUDE_PATH ${LIBSDF_PATH}/include)
|
||||
SET(LIBSDF_LIBRARY ${LIBSDF_PATH}/Objfiles/${LIBSDF_ARCH}/libsw.a)
|
||||
ENDIF(SDF_SUPPORT)
|
||||
|
||||
include_directories(${CMAKE_BINARY_DIR}/src
|
||||
${NETCDF_INCLUDE_PATH} ${GSL_INCLUDE_PATH}
|
||||
${HDF5_INCLUDE_PATH} ${COSMOTOOL_INCLUDE_PATH}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${QHULL_INCLUDE_PATH})
|
||||
|
||||
${QHULL_INCLUDE_PATH} ${LIBSDF_INCLUDE_PATH})
|
||||
|
|
34
external/libsdf/GNUmakefile
vendored
Normal file
34
external/libsdf/GNUmakefile
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
tarname:=tree19
|
||||
ARCH=x86_64
|
||||
|
||||
# Make.$(ARCH) sets many of the variables that are then used in
|
||||
# Make.generic. Leaving it out can cause problems, for example,
|
||||
# Make.$(ARCH) wants to redefine 'TAR'. On the other hand, leaving
|
||||
# it in can cause problems (apparently) with older versions of GNUmake
|
||||
# because, e.g., assignements like LOADLIBES:=-foo $(LOADLIBES) get
|
||||
# 'executed' multiple times. Once in this Makefile, and once in the
|
||||
# daughter makefiles.
|
||||
|
||||
###include Make-common/Make.$(ARCH)
|
||||
|
||||
# we should also go into SDFcvt, SDF2fld, commtst, lsv, lsvtst, (anything
|
||||
# else?) and build them. Possibly under a different target?
|
||||
|
||||
all: All
|
||||
|
||||
# Make.generic has targets for clean, all, etc., so we need to
|
||||
# spell them a little differently in this file...
|
||||
include Make-common/Make.generic
|
||||
|
||||
subdirs:= libSDF libmpmy
|
||||
|
||||
All:
|
||||
for dir in $(subdirs); do (cd $$dir; $(MAKE) ARCH=$(ARCH) all); done
|
||||
|
||||
Depends :
|
||||
for dir in $(subdirs); do (cd $$dir; $(MAKE) ARCH=$(ARCH) depends); done
|
||||
|
||||
Clean :
|
||||
for dir in $(subdirs); do (cd $$dir; $(MAKE) ARCH=$(ARCH) clean); done
|
||||
|
||||
# $(treedir)
|
87
external/libsdf/Make-common/Make.default
vendored
Normal file
87
external/libsdf/Make-common/Make.default
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
# You can override the specification of any of these variables with
|
||||
# make command line arguments. Those that should not be completely
|
||||
# replaced require the "override" modifier.
|
||||
|
||||
# You can further modify these values in the Make.$(ARCH) files
|
||||
|
||||
ifndef defaultPAROS
|
||||
defaultPAROS:=seq
|
||||
endif
|
||||
|
||||
ifndef defaultCC
|
||||
defaultCC:=cc
|
||||
endif
|
||||
|
||||
ifndef defaultFC
|
||||
defaultFC:=g77
|
||||
endif
|
||||
|
||||
ifndef OPTIMIZE
|
||||
OPTIMIZE:=-O2
|
||||
CC_SPECIFIC:=$(CC_SPECIFIC) -g -Wall
|
||||
endif
|
||||
|
||||
ifndef FOPTIMIZE
|
||||
OPTIMIZE=-O
|
||||
endif
|
||||
|
||||
PAROS:=$(defaultPAROS)
|
||||
CC:=$(defaultCC)
|
||||
FC:=$(defaultFC)
|
||||
|
||||
ifneq ($(PAROS),$(defaultPAROS))
|
||||
PAROSsuf:=-$(PAROS)
|
||||
endif
|
||||
|
||||
# Put a non-default CC into ARCH
|
||||
ifneq ($(defaultCC),$(CC))
|
||||
override ARCH:=$(ARCH)-$(CC)
|
||||
endif
|
||||
|
||||
ifeq ($(FC),g77)
|
||||
OPTIMIZE:=-O2
|
||||
FC_SPECIFIC:=$(FC_SPECIFIC) -g -ffast-math
|
||||
endif
|
||||
|
||||
# Some compilers turn off optimization with -g, so we don't specify
|
||||
# -g by default on those machines.
|
||||
ifdef DEBUG
|
||||
override ARCH:=$(ARCH)-g
|
||||
OPTIMIZE:=
|
||||
endif
|
||||
|
||||
# i.e., specify PROFILE=-p or PROFILE=-pg
|
||||
ifdef PROFILE
|
||||
override ARCH:=$(ARCH)-p
|
||||
endif
|
||||
|
||||
ifeq ($(PAROS),pvm)
|
||||
PAROSCFLAGS:=-I$(PVM_ROOT)/include
|
||||
LOADLIBES:=$(LOADLIBES) $(PVM_ROOT)/lib/$(PVM_ARCH)/libpvm3.a
|
||||
endif
|
||||
|
||||
ifeq ($(EXTRALIB),efence)
|
||||
PRELIBS:=$(treedir)/Objfiles/$(ARCH)/libefence.a
|
||||
programname:=$(programname)-efence
|
||||
endif
|
||||
|
||||
ifndef ARFLAGS
|
||||
ARFLAGS:=r
|
||||
endif
|
||||
|
||||
ifndef RANLIB
|
||||
RANLIB:=@echo no ranlib
|
||||
endif
|
||||
|
||||
ifdef fsrc
|
||||
LD:=$(FC)
|
||||
else
|
||||
LD:=$(CC)
|
||||
endif
|
||||
objsuf:=.o
|
||||
libext:=.a
|
||||
|
||||
CFLAGS:=$(DEBUG) $(OPTIMIZE) $(PROFILE) $(CC_SPECIFIC) $(ARCH_SPECIFIC)
|
||||
FFLAGS:=$(DEBUG) $(FOPTIMIZE) $(PROFILE) $(FC_SPECIFIC) $(ARCH_SPECIFIC)
|
||||
LDFLAGS:=$(DEBUG) $(PROFILE) $(LDFLAGS)
|
||||
|
217
external/libsdf/Make-common/Make.generic
vendored
Normal file
217
external/libsdf/Make-common/Make.generic
vendored
Normal file
|
@ -0,0 +1,217 @@
|
|||
## This is a 'generic' makefile with all the stuff that we seem to
|
||||
## repeat over and over in all our application (and library!) Makefiles.
|
||||
|
||||
incdir=$(treedir)/include/libsdf
|
||||
objdir=Objfiles/$(ARCH)
|
||||
libdir=$(treedir)/Objfiles/$(ARCH)
|
||||
override CFLAGS:=-I$(incdir) $(CFLAGS) $(EXTRACFLAGS)
|
||||
override LDFLAGS:=$(LDFLAGS) $(EXTRALDFLAGS)
|
||||
ifndef tarname
|
||||
tarname:=$(programname)
|
||||
endif
|
||||
tarpath:=$(TARPREFIX)$(tarname)
|
||||
excludepath:=$(TARPREFIX)exclude
|
||||
|
||||
# Allow the local directory to do arch-specific stuff...
|
||||
localmake:=$(wildcard Make.$(ARCH))
|
||||
ifneq ($(localmake),)
|
||||
include $(localmake)
|
||||
endif
|
||||
|
||||
ifeq ($(PAROS),$(defaultPAROS))
|
||||
# we don't need mpmy if we are using the default PAROS!
|
||||
LIBDEPENDS=$(libdir)/libsw.a
|
||||
else
|
||||
LIBDEPENDS=$(libdir)/mpmy_$(PAROS)$(objsuf) \
|
||||
$(libdir)/libsw.a
|
||||
endif
|
||||
|
||||
# If we're going to the trouble to list out the full directory names
|
||||
# in LIBDEPENDS, there's not much point in making the linker figure them
|
||||
# out (possibly erroneously) again with -L... -l...
|
||||
LOADLIBES_:=$(PRELIBS) $(LIBDEPENDS) -L$(libdir) -lm $(POSTLIBS) $(LOADLIBES)
|
||||
|
||||
ifdef programname
|
||||
bin:=$(programname).$(ARCH)$(PAROSsuf)
|
||||
# Substitue for the string PAROS in the 'src' variable
|
||||
# It would be really nice if we could then check to make sure the
|
||||
# file exists, and if not, substitue with, e.g., "generic". But
|
||||
# I can't figure out how to do that.
|
||||
_src:=$(subst PAROS,$(PAROS),$(src))
|
||||
obj=$(patsubst %.c,$(objdir)/%$(objsuf),$(src)) \
|
||||
$(patsubst %.cu,$(objdir)/%$(objsuf),$(cusrc)) \
|
||||
$(patsubst %.f,$(objdir)/%$(objsuf),$(fsrc))
|
||||
ifndef special_rule_for_all
|
||||
all: $(bin)
|
||||
endif
|
||||
|
||||
$(bin) : $(objdir) $(obj) $(LIBDEPENDS)
|
||||
$(LD) $(LDFLAGS) -o $@ $(obj) $(LOADLIBES_)
|
||||
$(finishlink)
|
||||
|
||||
release : $(bin)
|
||||
rsync -abq $(bin) ../release
|
||||
else
|
||||
bin:=
|
||||
endif
|
||||
|
||||
ifdef libname
|
||||
lib:=$(libdir)/$(libname)$(libext)
|
||||
libobj=$(patsubst %.c,$(lib)($(objdir)/%$(objsuf)),$(src))
|
||||
ifeq ($(libname),libsw)
|
||||
libobj:=$(libobj) $(patsubst %.c,$(lib)($(objdir)/%$(objsuf)),$(swsrc)) \
|
||||
$(patsubst %.s,$(lib)($(objdir)/%$(objsuf)),$(asmsrc)) \
|
||||
$(patsubst %.S,$(lib)($(objdir)/%$(objsuf)),$(cppasmsrc))
|
||||
endif
|
||||
ifndef special_rule_for_all
|
||||
all: $(lib)
|
||||
endif
|
||||
|
||||
|
||||
$(lib) : $(objdir) $(libdir) $(libobj)
|
||||
$(RANLIB) $@
|
||||
|
||||
endif
|
||||
|
||||
$(objdir)/%$(objsuf) : %.c
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
-@mv $*$(objsuf) $@
|
||||
|
||||
$(objdir)/%$(objsuf) : %.cu
|
||||
$(CUDACC) $(CUDACFLAGS) -c $<
|
||||
-@mv $*$(objsuf) $@
|
||||
|
||||
$(objdir)/%$(objsuf) : %.f
|
||||
$(FC) $(FFLAGS) -c $<
|
||||
-@mv $*$(objsuf) $@
|
||||
|
||||
$(objdir)/%$(objsuf) : $(asmdir)/%.s
|
||||
(cd $(asmdir); $(AS) $(ASFLAGS) -o $*$(objsuf) $*.s)
|
||||
-@mv $(asmdir)/$*$(objsuf) $@
|
||||
|
||||
$(objdir)/%$(objsuf) : $(asmdir)/%.S
|
||||
(cd $(asmdir); $(CC) $(ASFLAGS) -c -o $*$(objsuf) $*.S)
|
||||
-@mv $(asmdir)/$*$(objsuf) $@
|
||||
|
||||
# Gnu tar doesn't seem to do -X exclude properly?? It's probably
|
||||
# because it uses names without a leading './'. I could add a sed to
|
||||
# double each line in exclude???
|
||||
ifndef TAR
|
||||
TAR=/bin/tar
|
||||
endif
|
||||
|
||||
ifndef FIND
|
||||
FIND=/usr/bin/find
|
||||
endif
|
||||
|
||||
MAKEDEPEND=makedepend
|
||||
|
||||
ifndef RANLIB
|
||||
RANLIB=/usr/bin/ranlib
|
||||
endif
|
||||
|
||||
$(objdir) :
|
||||
if [ ! -d Objfiles ]; then mkdir Objfiles; fi
|
||||
if [ ! -d $(objdir) ]; then mkdir $(objdir); fi
|
||||
|
||||
$(libdir) :
|
||||
if [ ! -d $(treedir)/Objfiles ]; then mkdir $(treedir)/Objfiles; fi
|
||||
if [ ! -d $(libdir) ]; then mkdir $(libdir); fi
|
||||
|
||||
# Use appexcludes to exclude any particular application-specific directories.
|
||||
# e.g.,
|
||||
# appexcludes="-name data -prune -o -name secret_dir -prune"
|
||||
ifdef appexcludes
|
||||
extraexcludes=\( $(appexcludes) \) -o
|
||||
endif
|
||||
|
||||
ifndef treedir_sed
|
||||
treedir_sed:=$(treedir)
|
||||
endif
|
||||
|
||||
# Exclude emacs backups (*~), and auto-saves (#*#)
|
||||
# Exclude anything in one of the object dirs, or misc.*,
|
||||
# anything named 'core' or *.tar.* or anything that's executable and
|
||||
# bigger than 10k or anything at all that's bigger than 100k.
|
||||
# In addition, just in case they don't exist yet, we have to explicitly
|
||||
# exclude the $(tarname).tar.Z and .gz targets.
|
||||
# Finally exclude the "proprietary" ibm assembly language
|
||||
$(excludepath) : FORCE
|
||||
($(FIND) . $(extraexcludes) -name Objfiles -prune -o -name '*.o' -o -name '#*#' -o -name '*~' -o -name '*-' -o -name '*.bak' -o -name '*.bak2' -o -name Obsolete -o -name NOT_PORTED -o -name '*.orig' -o -name core -o -name 'lsv.core.*' -o -name 'misc.*' -o -name '*.tar.*' -o -name '*gz' -o \( -perm +0111 -and -size +10k \) -o -size +100k -o -name '*readrtc.s*' ; \
|
||||
echo ./$(tarname).tar.Z ; \
|
||||
echo ./$(tarname).tgz ; \
|
||||
echo ./$(tarname)-dist.tgz ; \
|
||||
) | sed "s/^\.\//`basename $$PWD`\//" > $@
|
||||
|
||||
tar : $(tarpath).tgz
|
||||
|
||||
dist : $(tarpath)-dist.tgz
|
||||
|
||||
$(tarpath).tar.Z: $(excludepath)
|
||||
(dir=`basename $$PWD`; cd `dirname $$PWD`; $(TAR) cvfX - $$dir/$(excludepath) $$dir)| compress > $(tarpath).tar.Z
|
||||
|
||||
$(tarpath).tgz: $(excludepath)
|
||||
(dir=`basename $$PWD`; cd `dirname $$PWD`; $(TAR) cvfX - $$dir/$(excludepath) $$dir)| gzip > $(tarpath).tgz
|
||||
|
||||
$(tarpath)-dist.tgz: $(excludepath)
|
||||
(dir=`basename $$PWD`; cd `dirname $$PWD`; $(TAR) cvfX - $$dir/$(excludepath) $$dir/COPY* $$dir/Make-common $$dir/INSTRUCTIONS $$dir/GNUmakefile $$dir/include $$dir/relerr $$dir/Change* $$dir/lib* $$dir/bin $$dir/lsv $$dir/shmz $$dir/snsph $$dir/nln)| gzip > $(tarpath)-dist.tgz
|
||||
|
||||
# Make a floppy by writing a meta-tar file containing $(tarname).tgz
|
||||
floppy: $(tarname).tgz
|
||||
$(TAR) cvf /dev/fd0 $(tarname).tgz
|
||||
|
||||
# clean...how much should we attempt to clean up?? Should there be
|
||||
# additional clean-ables set in the application-makefile?
|
||||
|
||||
# clean-clutter will remove the ~ files, the #*#, etc.
|
||||
clean-clutter: FORCE
|
||||
rm -f *~ #*# *.bak *.bakk
|
||||
|
||||
# clean will remove the binary and object files associated with the
|
||||
# current ARCH-PAROS pair
|
||||
clean: FORCE clean-clutter
|
||||
rm $(bin) $(objdir)/*
|
||||
|
||||
# clean-all will attempt to remove all object files in Objfiles/ and
|
||||
# all executables in . associated with them. USE WITH CARE!!
|
||||
clean-all: FORCE clean-clutter
|
||||
for dir in `ls Objfiles`; do \
|
||||
set arch=`basename $$dir`; \
|
||||
rm -rf Objfiles/$$dir; \
|
||||
rm -f $(programname).$$dir* ; \
|
||||
done
|
||||
|
||||
# Run makedepend, and then massage the Makfile to the symbolic names
|
||||
# for the files in $(treedir). WARNING! If $(treedir) contains
|
||||
# sed meta-characters you lose in a big way! We fix this by letting you
|
||||
# override it with $(treedir_sed), e.g., if treedir=.., you should
|
||||
# probably set treedir_sed=\.\. . This should be automatic :-(.
|
||||
# This command kills the entire line with the /usr/ dependency.
|
||||
# -e '/ \/usr/d' Makefile.bak2 > foo
|
||||
# The sed below leaves lines with no dependency. Is that a problem?
|
||||
MAKEFILENAME=GNUmakefile
|
||||
#depends:
|
||||
# $(MAKEDEPEND) -f$(MAKEFILENAME) '-o$$(objsuf)' '-p$$(objdir)/' -- $(CFLAGS) -- $(src)
|
||||
# cp $(MAKEFILENAME) $(MAKEFILENAME).bak2
|
||||
# sed \
|
||||
# -e '/DO NOT DELETE/,$$s!$(treedir_sed)!$$(treedir)!g'\
|
||||
# -e '/DO NOT DELETE/,$$s@ /usr/[^ ]*@@g'\
|
||||
# $(MAKEFILENAME).bak2 > $(MAKEFILENAME)
|
||||
|
||||
# The last rule replaces -p$$(objdir)/ which doesn't work in openwin
|
||||
# and presumably in X11R4 or earlier
|
||||
depends:
|
||||
$(MAKEDEPEND) -f$(MAKEFILENAME) '-o$$(objsuf)' -- $(CFLAGS) -- $(src)
|
||||
cp $(MAKEFILENAME) $(MAKEFILENAME).bak2
|
||||
sed \
|
||||
-e '/DO NOT DELETE/,$$s!$(treedir_sed)!$$(treedir)!g'\
|
||||
-e '/DO NOT DELETE/,$$s@ /usr/[^ ]*@@g'\
|
||||
-e '/DO NOT DELETE/,$$s@ float.h@@g'\
|
||||
-e '/DO NOT DELETE/,$$s@ stdarg.h@@g'\
|
||||
-e '/DO NOT DELETE/,$$s@^\([A-Za-z]\)@$$(objdir)/\1@g'\
|
||||
$(MAKEFILENAME).bak2 > $(MAKEFILENAME)
|
||||
|
||||
depends-nosed:
|
||||
$(MAKEDEPEND) -f$(MAKEFILENAME) '-o$$(objsuf)' '-p$$(objdir)/' -- $(CFLAGS) -- $(src)
|
||||
|
||||
FORCE:
|
25
external/libsdf/Make-common/Make.x86_64
vendored
Normal file
25
external/libsdf/Make-common/Make.x86_64
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
defaultCC:=gcc
|
||||
|
||||
CC_SPECIFIC:=-g -Wall
|
||||
ARCH_SPECIFIC:=-D__iX86__=x86_64 -DLONG_NK1_KEY -DSTK_FORCE_ALIGNMENT=4 -D_FILE_OFFSET_BITS=64 -DUSE_SYSTEM_MALLOC -DUSE_MPIIO -DUSE_HWCLOCK -DPROCS_PER_NODE=8
|
||||
OPTIMIZE=-O2
|
||||
AGGRESSIVE_OPT=-Ofast
|
||||
LDFLAGS=-g
|
||||
LEX:=flex
|
||||
YACC:=bison -y
|
||||
|
||||
include $(treedir)/Make-common/Make.default
|
||||
|
||||
swsrc:=lsv.c swampi.c
|
||||
asmdir:=asm-sse
|
||||
asmsrc=
|
||||
cppasmsrc=
|
||||
|
||||
LOADLIBES=-lrt
|
||||
|
||||
MPI_ROOT=/softs/openmpi/1.6.4-ifort-13.0-torque-CentOS5
|
||||
ifeq ($(PAROS),mpi)
|
||||
LOADLIBES:=-L$(MPI_ROOT)/lib -L$(MPI_ROOT)/lib64 -lmpi
|
||||
PAROSCFLAGS:=-I$(MPI_ROOT)/include
|
||||
endif
|
||||
|
1
external/libsdf/_NOTES_
vendored
Normal file
1
external/libsdf/_NOTES_
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
This is Tree19, a snapshot of some of Michael S. Warren's code to handle SDF data format and parallel IO.
|
23
external/libsdf/include/libsdf/Assert.h
vendored
Normal file
23
external/libsdf/include/libsdf/Assert.h
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* A drop-in replacement for assert.h, but it calls "error" which */
|
||||
/* deposits a message in the msgbuf, the terminal, your home answering */
|
||||
/* machine, and in skywriting at Malibu beach. */
|
||||
#undef assert
|
||||
# ifndef NDEBUG
|
||||
/* Error may be #defined */
|
||||
#include "error.h"
|
||||
|
||||
#ifndef NO_STRINGIFICATION
|
||||
# define assert(ex) ((void)((ex)?0 :\
|
||||
((SWError)("Assertion (%s) failed: file \"%s\", line %d\n",\
|
||||
#ex, __FILE__, __LINE__),0)))
|
||||
#else
|
||||
/* Not only do we not have Stringification, but we assume that we have */
|
||||
/* the brain-damaged macro substitution into "..." */
|
||||
/* Note that this breaks if the substituted string has " " in it!, e.g.
|
||||
assert(SDFhasname("x", sdfp));
|
||||
*/
|
||||
# define assert(ex) ((void)((ex)?0 : ((SWError)("Assertion (%s) failed: file \"%s\", line %d\n", "ex", __FILE__, __LINE__), 0)))
|
||||
#endif /* NO_STRINGIFICATION */
|
||||
# else
|
||||
# define assert(ex) ((void)0)
|
||||
# endif
|
37
external/libsdf/include/libsdf/Malloc.h
vendored
Normal file
37
external/libsdf/include/libsdf/Malloc.h
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef _MAlloCDOTh
|
||||
#define _MAlloCDOTh
|
||||
|
||||
#include <stddef.h>
|
||||
#include "error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
/* Set the default behavior of the Malloc family when encountering */
|
||||
/* errors, e.g., NULL returns, etc. */
|
||||
Error_t MallocHandler(Error_t);
|
||||
|
||||
void xFree (void *ptr, const char *file, int lineno);
|
||||
void *xMalloc (size_t, const char *file, int lineno);
|
||||
void *xRealloc (void *ptr, size_t, const char *file, int lineno);
|
||||
void *xCalloc (size_t, size_t, const char *file, int lineno);
|
||||
/* No extra parens needed ?? */
|
||||
void Free_f (void *ptr);
|
||||
void *Malloc_f (size_t);
|
||||
void *Realloc_f (void *ptr, size_t);
|
||||
void *Calloc_f (size_t, size_t);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* Some pre-processors are so stupid that they will convert
|
||||
foo(Realloc);
|
||||
into
|
||||
foo(xRealloc(,,__FILE__, __LINE__));
|
||||
Thus, we can't use Realloc as function name.
|
||||
*/
|
||||
#define Free(p) xFree(p, __FILE__, __LINE__)
|
||||
#define Malloc(n) xMalloc(n, __FILE__, __LINE__)
|
||||
#define Calloc(n,s) xCalloc(n, s, __FILE__, __LINE__)
|
||||
#define Realloc(p, n) xRealloc(p, n, __FILE__, __LINE__)
|
||||
|
||||
#endif /* _MAllocDOTh */
|
88
external/libsdf/include/libsdf/Msgs.h
vendored
Normal file
88
external/libsdf/include/libsdf/Msgs.h
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* Declarations for the functions defined in Msgs.c */
|
||||
#ifndef MsgsDOTh
|
||||
#define MsgsDOTh
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "gccextensions.h"
|
||||
|
||||
/* These two typedefs simplify the task of casting function ptrs */
|
||||
/* to the appropriate type when calling Msg_addfile */
|
||||
typedef int (*Msgvfprintf_t)(void *, const char *, va_list);
|
||||
typedef int (*Msgfflush_t)(void *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* The fflush_like function pointer MUST BE ASYNCHRONOUSLY CALLABLE */
|
||||
/* If you don't have one, don't worry. Pass NULL instead. */
|
||||
int Msg_addfile(void *fp, /* add fp to the list of msg files */
|
||||
int (*vfprintf_like)(void *, const char *, va_list),
|
||||
int (*fflush_like)(void *));
|
||||
int Msg_delfile(void *fp); /* fp should no longer receive msgs */
|
||||
int Msg_on(const char *); /* turn on a specific type of msgs */
|
||||
int Msg_off(const char *); /* turn off a specific type of msgs */
|
||||
/* Normally, you should use the Msg_test macro instead. */
|
||||
int _Msg_test(const char *); /* is a specific type on or off? */
|
||||
int Msg_set_enable(int); /* enable (1) or disable (0) all message */
|
||||
/* return the previous state. */
|
||||
void Msg_turnon(const char *msg_turn_on); /* an interface to Msg_on */
|
||||
/* that calls Msg_on for every file */
|
||||
/* in a comma-whitespace delimited list */
|
||||
/* of names. If a name is specified as */
|
||||
/* NAME:lo-hi or NAME:procnum, then */
|
||||
/* messages are on only in the corresponding */
|
||||
/* processors. If the string is "nomsgs", */
|
||||
/* then msgs are totally disabled. */
|
||||
void MsgdirInit(const char *path); /* tries to do a mkdir and open */
|
||||
/* msg files for each process */
|
||||
int Msg_do(const char *fmt, ...) /* Unconditionally say something. */
|
||||
__attribute__ ((format (printf, 1, 2))) ; /* it's printf-like! */
|
||||
int Msg_doalist(const char *fmt, va_list)
|
||||
/* this is broken in gcc2.4.0 through 2.4.4 */
|
||||
#ifndef BROKEN_GCC_FORMAT_ATTRIBUTE
|
||||
__attribute__ ((format (printf, 1, 0)))
|
||||
#endif
|
||||
;
|
||||
|
||||
int Msg_flush(void); /* flush all the buffers now. */
|
||||
int Msg_flushalways(int newval);/* flush buffers after every Msg_do.
|
||||
return the previous value.*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Don't use these! _Msg_enabled */
|
||||
extern int _Msg_enabled;
|
||||
|
||||
/* Msg is called with an extra set of parentheses, to hide */
|
||||
/* the variadic arguments, e.g.
|
||||
Msg("foo", ("Hello world this is a \"foo\" message\n"));
|
||||
or
|
||||
Msg(__FILE__, ("Hello from file: %s, line: %d\n", __FILE__, __LINE__));
|
||||
|
||||
The macro 'Msgf' is a shorthand for the Msg(__FILE__, ...) construction.
|
||||
The macro 'Msglno' is a shorthand for:
|
||||
Msg(name, "%s(%d):" <fmt> , __FILE__, __LINE__, <otherargs>);
|
||||
The macro 'Msgfunc' is a shorthand for Msg(__FUNCTION__, ...).
|
||||
Thus, you can turn on messaging at the function level.
|
||||
*/
|
||||
|
||||
#define Msglno(name, args) Msg(name, ("%s(%d): ", __FILE__, __LINE__)),Msg(name, args)
|
||||
#define Msgf(args) Msg(__FILE__, args)
|
||||
#define Msglnof(args) Msglno(__FILE__, args)
|
||||
#ifdef __FUNCTION__
|
||||
#define Msgfunc(args) Msg(__FUNCTION__, args)
|
||||
#else
|
||||
#define Msgfunc(args)
|
||||
#endif
|
||||
|
||||
#ifndef NO_MSGS
|
||||
#define Msg_test(name) (_Msg_enabled && _Msg_test(name))
|
||||
#define Msg(name, args) ((void)((Msg_test(name))? Msg_do args : 0 ))
|
||||
#else
|
||||
#define Msg_test(name) (0)
|
||||
#define Msg(name, args) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* MsgsDOTh */
|
165
external/libsdf/include/libsdf/SDF.h
vendored
Normal file
165
external/libsdf/include/libsdf/SDF.h
vendored
Normal file
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
SDF Library for reading Self-Describing Files
|
||||
Copyright (C) 1991,1992 John K. Salmon
|
||||
|
||||
Terms and conditions are specified in the file "copyright.h",
|
||||
and more precisely in the file COPYING.LIB which you should have
|
||||
received with this library.
|
||||
*/
|
||||
#ifndef sdfDOTh
|
||||
#define sdfDOTh
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#define SDF_SEEK_SET 0
|
||||
#define SDF_SEEK_CUR 1
|
||||
#define SDF_SEEK_END 2
|
||||
|
||||
#define SDF_SYNC 0
|
||||
#define SDF_ASYNC 1
|
||||
|
||||
#define SDF_SINGL 0
|
||||
#define SDF_MULTI 1
|
||||
|
||||
#ifndef INT64_MAX
|
||||
#if __WORDSIZE==64
|
||||
#define INT64_MAX LONG_MAX
|
||||
#else
|
||||
/* #define INT64_MAX LLONG_MAX Why doesn't this work? */
|
||||
#define INT64_MAX 9223372036854775807LL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef sdfprivateDOTh
|
||||
/* It isn't really this, but I don't want to tell you what it is. */
|
||||
/* If you believe it's this, then your compiler can check prototypes */
|
||||
/* for you. */
|
||||
typedef char *SDF[32];
|
||||
|
||||
/* Identical to declaration in SDF-private.h */
|
||||
enum SDF_type_enum{SDF_NOTYPE,
|
||||
SDF_CHAR,
|
||||
SDF_SHORT,
|
||||
SDF_INT,
|
||||
SDF_LONG,
|
||||
SDF_INT64,
|
||||
SDF_FLOAT,
|
||||
SDF_DOUBLE,
|
||||
SDF_STRING};
|
||||
#endif
|
||||
|
||||
/* Provided for backwards compatibility. Not recommended! */
|
||||
#ifdef SDF_OLD_ENUM_NAMES
|
||||
#define CHAR SDF_CHAR
|
||||
#define SHORT SDF_SHORT
|
||||
#define INT SDF_INT
|
||||
#define FLOAT SDF_FLOAT
|
||||
#define DOUBLE SDF_DOUBLE
|
||||
#define STRING SDF_STRING
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Two arrays indexed by a type_enum */
|
||||
extern char *SDFtype_names[];
|
||||
extern int SDFtype_sizes[];
|
||||
|
||||
extern char SDFerrstring[];
|
||||
|
||||
int SDFissdf(const char *filename); /* Not guaranteed correct! */
|
||||
SDF *SDFopen(const char *hdrfname, const char *datafname);
|
||||
int SDFseekable(SDF *hdr); /* are non-sequential reads allowed? */
|
||||
int SDFclose(SDF *hdr);
|
||||
int SDFnvecs(SDF *hdr);
|
||||
int SDFhasname(const char *name, SDF *hdr);
|
||||
char **SDFvecnames(SDF *hdr);
|
||||
int64_t SDFnrecs(const char *name, SDF *hdr);
|
||||
int SDFarrcnt(const char *name, SDF *hdr);
|
||||
enum SDF_type_enum SDFtype(const char *name, SDF *hdr);
|
||||
int SDFseek(const char *name, int64_t offset, int whence, SDF *hdr);
|
||||
int SDFtell(const char *name, SDF *hdr);
|
||||
unsigned int SDFcpubyteorder(void);
|
||||
unsigned int SDFbyteorder(SDF *hdr);
|
||||
int SDFswap(SDF *hdr);
|
||||
int SDFnoswap(SDF *hdr);
|
||||
int SDFisswapping(SDF *hdr);
|
||||
int SDFsetmaxbufsz(int new_size);
|
||||
int SDFrdvecs(SDF *hdr, ...
|
||||
/* char *name, int n, void *address, int stride,
|
||||
... ,
|
||||
NULL */ );
|
||||
int SDFrdvecsv(SDF *hdr, va_list ap);
|
||||
/* Where is the const supposed to go? */
|
||||
int SDFrdvecsarr(SDF *hdr, int nreq,
|
||||
char **names, int *ns, void **addresses, int *strides);
|
||||
|
||||
int SDFseekrdvecs(SDF *hdr, ...
|
||||
/* char *name, int start, int n, void *addr, int stride,
|
||||
... ,
|
||||
NULL */ );
|
||||
int SDFseekrdvecsv(SDF *hdr, va_list ap);
|
||||
int SDFseekrdvecsarr(SDF *hdr, int nreq,
|
||||
char **names, int64_t *starts, int *ns, void **addresses, int *strides);
|
||||
void SDFsetiomode(int mode);
|
||||
|
||||
/* These two subvert the SDF "abstraction" and tell you about */
|
||||
/* the actual layout of the file. Are you absolutely sure you need */
|
||||
/* to call these? */
|
||||
int64_t SDFfileoffset(const char *name, SDF *hdr);
|
||||
int64_t SDFfilestride(const char *name, SDF *hdr);
|
||||
|
||||
/* These four are harder to write than one might guess. */
|
||||
/* They're in the library to avoid duplicating code. */
|
||||
int SDFgetint(SDF *sdfp, char *name, int *value);
|
||||
int SDFgetint64(SDF *sdfp, char *name, int64_t *value);
|
||||
int SDFgetfloat(SDF *sdfp, char *name, float *value);
|
||||
int SDFgetdouble(SDF *sdfp, char *name, double *value);
|
||||
int SDFgetstring(SDF *sdfp, const char *name, char *string, int size);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* four macros that call SDFget and bail out if the value isn't there */
|
||||
#define SDFgetintOrDie(sdfp, name, value) \
|
||||
do{ if( SDFgetint(sdfp, name, value) ) \
|
||||
Error("SDFgetint(\"%s\") failed\n", name); } while(0)
|
||||
|
||||
#define SDFgetint64OrDie(sdfp, name, value) \
|
||||
do{ if( SDFgetint64(sdfp, name, value) ) \
|
||||
Error("SDFgetint64(\"%s\") failed\n", name); } while(0)
|
||||
|
||||
#define SDFgetfloatOrDie(sdfp, name, value) \
|
||||
do{ if( SDFgetfloat(sdfp, name, value) ) \
|
||||
Error("SDFgetfloat(\"%s\") failed\n", name); } while(0)
|
||||
|
||||
#define SDFgetdoubleOrDie(sdfp, name, value) \
|
||||
do{ if( SDFgetdouble(sdfp, name, value) ) \
|
||||
Error("SDFgetdouble(\"%s\") failed\n", name); } while(0)
|
||||
|
||||
#define SDFgetstringOrDie(sdfp, name, string, size) \
|
||||
do{ if( SDFgetstring(sdfp, name, string, size) ) \
|
||||
Error("SDFgetstring(\"%s\") failed", name); } while(0)
|
||||
|
||||
/* And four more that use a default if the value isn't there */
|
||||
#define SDFgetintOrDefault(sdfp, name, value, def) \
|
||||
do{ if( SDFgetint(sdfp, name, value) ){ \
|
||||
*value = def;}} while(0)
|
||||
|
||||
#define SDFgetint64OrDefault(sdfp, name, value, def) \
|
||||
do{ if( SDFgetint64(sdfp, name, value) ){ \
|
||||
*value = def;}} while(0)
|
||||
|
||||
#define SDFgetfloatOrDefault(sdfp, name, value, def) \
|
||||
do{ if( SDFgetfloat(sdfp, name, value) ){ \
|
||||
*value = def;} } while(0)
|
||||
|
||||
|
||||
#define SDFgetdoubleOrDefault(sdfp, name, value, def) \
|
||||
do{ if( SDFgetdouble(sdfp, name, value) ){ \
|
||||
*value = def;} } while(0)
|
||||
|
||||
#define SDFgetstringOrDefault(sdfp, name, value, size, def) \
|
||||
do{ if( SDFgetstring(sdfp, name, value, size) ){ \
|
||||
strncpy(value, def, size);} } while(0)
|
||||
|
||||
#endif /* sdfDOTh */
|
39
external/libsdf/include/libsdf/SDFread.h
vendored
Normal file
39
external/libsdf/include/libsdf/SDFread.h
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef _RdDataDOTh
|
||||
#define _RdDataDOTh
|
||||
|
||||
#include "timers.h"
|
||||
#include "SDF.h"
|
||||
/* Can read distributed datafiles if csdfp contains something like:
|
||||
struct {char datafiles[64];}[4] = {"foo1", "foo2", "foo3", "foo4"};
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern Timer_t SDFreadTm;
|
||||
|
||||
/* By default, SDFread will look for a "char datafile[]" in csdfp and
|
||||
read data from there. The name of the variable to look for is
|
||||
stored in this variable. I.e., it defaults to "datafile". Set it
|
||||
to NULL to turn this feature off altogether. */
|
||||
extern char *SDFread_datafile;
|
||||
|
||||
/* Do the same thing with "hdrfile" */
|
||||
extern char *SDFread_hdrfile;
|
||||
|
||||
/* Also by default, SDFread will look for a variable "int npart" in csdfp
|
||||
and attempt to read that many "particles" from datafile. This variable
|
||||
storest the name of that variable. Default: "npart"; */
|
||||
extern char *SDFread_npart;
|
||||
|
||||
SDF *SDFread(SDF *csdfp, void **btabp, int *gnobjp, int *nobjp, int stride,
|
||||
/* char *name, offset_t offset, int *confirm */...);
|
||||
SDF *SDFread64(SDF *csdfp, void **btabp, int64_t *gnobjp, int *nobjp, int stride,
|
||||
/* char *name, offset_t offset, int *confirm */...);
|
||||
SDF *SDFreadf(char *hdr, char *name, void **btabp, int *gnobjp, int *nobjp,
|
||||
int stride, /* char *name, offset_t offset, int *confirm */...);
|
||||
SDF *SDFreadf64(char *hdr, char *name, void **btabp, int64_t *gnobjp, int *nobjp,
|
||||
int stride, /* char *name, offset_t offset, int *confirm */...);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
28
external/libsdf/include/libsdf/SDFwrite.h
vendored
Normal file
28
external/libsdf/include/libsdf/SDFwrite.h
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef _SDFWriteDOTh
|
||||
#define _SDFWRiteDOTh
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void SDFwrite(const char *filename, int gnobj, int nobj, const void *btab,
|
||||
int bsize, const char *bodydesc,
|
||||
/* const char *name, SDF_type_enum type, <type> val */ ...);
|
||||
void SDFwrite64(const char *filename, int64_t gnobj, int64_t nobj, const void *btab,
|
||||
int bsize, const char *bodydesc,
|
||||
/* const char *name, SDF_type_enum type, <type> val */ ...);
|
||||
void SDFappend64(const char *filename, int64_t gnobj, int64_t nobj, const void *btab,
|
||||
int bsize, const char *bodydesc,
|
||||
/* const char *name, SDF_type_enum type, <type> val */ ...);
|
||||
|
||||
/* A trivial special case, just don't write any body data */
|
||||
void SDFwritehdr(const char *filename, const char *bodydesc,
|
||||
/* const char *name, SDF_type_enum type, <type> val */ ...);
|
||||
|
||||
void SDFunsetwroteheader(void);
|
||||
void SDFsetwroteheader(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
21
external/libsdf/include/libsdf/byteswap.h
vendored
Normal file
21
external/libsdf/include/libsdf/byteswap.h
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef _ByteSwapDOTh
|
||||
#define _ByteSwapDOTh
|
||||
|
||||
/* A general, in-place, byte-swapper. */
|
||||
/* It swaps a total of unit_len*n_units bytes, unit_len bytes at a time. */
|
||||
/* Thus, you can use it for arrays of doubles with unit_len=8, or */
|
||||
/* arrays of chars with unit_len=1 (which is equivalent to memcpy). */
|
||||
/* It checks for stupid arguments. It works fine when */
|
||||
/* from and to are identical. It breaks if from and to are */
|
||||
/* almost the same. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int Byteswap(int unit_len, int n_units, void *from, void *to);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* It would probalby be worthwhile to inline these! */
|
||||
|
||||
#endif
|
141
external/libsdf/include/libsdf/chn.h
vendored
Normal file
141
external/libsdf/include/libsdf/chn.h
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
#ifndef chnDOTh
|
||||
#define chnDOTh
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
CHN.C: Routines for allocating and freeing memory
|
||||
in fixed length blocks. CHN is mnemonic for either 'chain' or 'chunk'.
|
||||
The idea is that malloc is called infrequently to get large chunks
|
||||
which are broken down into smaller pieces which are chained together
|
||||
to make a freelist. ChnAlloc and ChnFree are very fast O(1), and
|
||||
use memory efficiently even for small objects. In contrast,
|
||||
malloc and free are often slow and typically waste several bytes per
|
||||
allocated object. The down side is that fragmentation problems can be
|
||||
magnified. Once a large chunk is allocated it never gets freed, even
|
||||
if all the objects in it have been freed.
|
||||
Entry points:
|
||||
void ChnInit(Chn *id, int sz, int nalloc,
|
||||
void *(realloc_like)(void *, size_t));
|
||||
void *ChnAlloc(Chn *id);
|
||||
void ChnFree(Chn *id, Void *p);
|
||||
void ChnFreeAll(Chn *id);
|
||||
void ChnTerminate(Chn *id);
|
||||
int ChnCheck(Chn *id);
|
||||
int ChnFreeCnt(Chn *id);
|
||||
int ChnAllocCnt(Chn *id);
|
||||
It wouldn't be hard to write "ChnCrunch" which would look for chunks
|
||||
that have been completely freed, and return them to the system. This
|
||||
has limited utility, but it might be handy when running near the edge
|
||||
of memory.
|
||||
|
||||
For diagnostic purposes, use ChnFreeCnt to get the length of the current
|
||||
freelist. Note that more space will be dynamically allocated, so this
|
||||
is NOT an upper limit. ChnAllocCnt is the count of how many chunks
|
||||
are currently allocated.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int sz;
|
||||
int nalloc;
|
||||
void *free_list;
|
||||
void *first_chunk;
|
||||
int free_cnt;
|
||||
int nmalloced; /* diagnostic purposes only */
|
||||
int tbl_sz;
|
||||
void *(*realloc_like)(void *, size_t);
|
||||
} Chn;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
extern int ChnMoreMem(Chn *id);
|
||||
extern void ChnInit(Chn *new, int sz, int nalloc,
|
||||
void *(*realloc_like)(void *, size_t));
|
||||
extern void ChnTerminate(Chn *id);
|
||||
extern void ChnFreeAll(Chn *id);
|
||||
extern int ChnCheck(Chn *id);
|
||||
#if !(__STDC_VERSION__ >= 199901L)
|
||||
extern void *ChnAlloc(Chn *id);
|
||||
extern void ChnFree(Chn *id, void *p);
|
||||
extern int ChnFreeCnt(Chn *id);
|
||||
extern int ChnAllocCnt(Chn *id);
|
||||
extern size_t ChnUnitSz(Chn *id);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (defined(__GNUC__) || defined(__ICC__)) || defined(CHNdotC)
|
||||
|
||||
#undef INLINE
|
||||
#if (__STDC_VERSION__ >= 199901L) && !defined (CHNdotC)
|
||||
#define INLINE inline
|
||||
#else
|
||||
#if (defined (__GNUC__) || defined(__ICC__)) && !defined (CHNdotC)
|
||||
#define INLINE extern __inline__
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ChnNext) || defined(ChnMagic) || defined(ChnMAGIC)
|
||||
# error define conflict in __FILE__
|
||||
#endif
|
||||
#define ChnNext(x) (*(void**)(x))
|
||||
#define ChnMagic(x) (*(int *)((void**)x+1))
|
||||
#define ChnMAGIC 0x82345078
|
||||
|
||||
#ifndef assert
|
||||
#include "Assert.h"
|
||||
#endif
|
||||
|
||||
INLINE void *ChnAlloc(Chn *id)
|
||||
{
|
||||
void *c;
|
||||
|
||||
if (id->free_cnt <= 0) {
|
||||
if(ChnMoreMem(id))
|
||||
return 0;
|
||||
}
|
||||
c = id->free_list;
|
||||
|
||||
assert(c);
|
||||
assert(ChnMagic(c) == ChnMAGIC);
|
||||
|
||||
id->free_cnt--;
|
||||
id->free_list = ChnNext(c);
|
||||
return (c);
|
||||
}
|
||||
|
||||
INLINE void ChnFree(Chn *id, void *p)
|
||||
{
|
||||
/* This assertion can give a false-error reading if the "user" */
|
||||
/* has stored the exact value ChnMAGIC in the right location. */
|
||||
/* assert(ChnMagic(p) != ChnMAGIC); */
|
||||
ChnNext(p) = id->free_list;
|
||||
ChnMagic(p) = ChnMAGIC;
|
||||
id->free_list = p;
|
||||
id->free_cnt++;
|
||||
}
|
||||
|
||||
INLINE int ChnFreeCnt(Chn *id){
|
||||
return id->free_cnt;
|
||||
}
|
||||
|
||||
INLINE int ChnAllocCnt(Chn *id){
|
||||
return id->nmalloced - id->free_cnt;
|
||||
}
|
||||
|
||||
INLINE size_t ChnUnitSz(Chn *id){
|
||||
return id->sz;
|
||||
}
|
||||
|
||||
#ifndef CHNdotC
|
||||
#undef ChnNext
|
||||
#undef ChnMagic
|
||||
#undef ChnMAGIC
|
||||
#endif
|
||||
#undef INLINE
|
||||
|
||||
#endif /* __GNUC__ || CHNdotC */
|
||||
#endif
|
113
external/libsdf/include/libsdf/cosmo.h
vendored
Normal file
113
external/libsdf/include/libsdf/cosmo.h
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
/* Hide the cosmological parameters in here.
|
||||
Keep them self-consistent... */
|
||||
|
||||
struct cosmo_s {
|
||||
double t;
|
||||
double a;
|
||||
double H0;
|
||||
double Omega0;
|
||||
double Omega_m;
|
||||
double Omega_r;
|
||||
double Omega_de;
|
||||
double w0;
|
||||
double wa;
|
||||
double Lambda;
|
||||
double Gnewt;
|
||||
double Zel_f;/* the 'f' factor for linearly growing modes */
|
||||
};
|
||||
|
||||
/* new struct for CLASS interface */
|
||||
/* some names have changed definition (Omega_m/Omega_r not constants now) */
|
||||
typedef struct cosmology {
|
||||
double z;
|
||||
double t;
|
||||
double tau;
|
||||
double a;
|
||||
double H;
|
||||
double Omega_m;
|
||||
double Omega_r;
|
||||
double conf_distance;
|
||||
double kick; /* union with tau? */
|
||||
double drift;
|
||||
double growthfac;
|
||||
double velfac;
|
||||
double velfac2;
|
||||
/* constants */
|
||||
double h_100;
|
||||
double H0;
|
||||
double Omega0; /* m+r+lambda+fld */
|
||||
double Omega0_m; /* cdm+b+ur+some ncdm */
|
||||
double Omega0_r; /* g+ur+rest of ncdm */
|
||||
double Omega0_lambda;
|
||||
double Omega0_cdm;
|
||||
double Omega0_ncdm_tot;
|
||||
double Omega0_b;
|
||||
double Omega0_g;
|
||||
double Omega0_ur;
|
||||
double Omega0_fld;
|
||||
double w0_fld;
|
||||
double wa_fld;
|
||||
double Gnewt;
|
||||
double age;
|
||||
void *reserved;
|
||||
void (*background_at_z)(struct cosmology *c, double z);
|
||||
void (*background_at_t)(struct cosmology *c, double t);
|
||||
void (*background_at_tau)(struct cosmology *c, double tau);
|
||||
double (*t_at_z)(struct cosmology *c, double z);
|
||||
double (*z_at_t)(struct cosmology *c, double t);
|
||||
double (*a_at_t)(struct cosmology *c, double t);
|
||||
double (*t_at_a)(struct cosmology *c, double a);
|
||||
double (*H_at_z)(struct cosmology *c, double z);
|
||||
double (*H_at_t)(struct cosmology *c, double t);
|
||||
double (*conformal_distance_at_z)(struct cosmology *c, double z);
|
||||
double (*conformal_distance_at_t)(struct cosmology *c, double t);
|
||||
double (*angular_diameter_distance_at_z)(struct cosmology *c, double z);
|
||||
double (*angular_diameter_distance_at_t)(struct cosmology *c, double t);
|
||||
double (*luminosity_distance_at_z)(struct cosmology *c, double z);
|
||||
double (*luminosity_distance_at_t)(struct cosmology *c, double t);
|
||||
double (*growthfac_at_z)(struct cosmology *c, double z);
|
||||
double (*growthfac_at_t)(struct cosmology *c, double t);
|
||||
double (*velfac_at_z)(struct cosmology *c, double z);
|
||||
double (*velfac_at_t)(struct cosmology *c, double t);
|
||||
double (*kick_t0_t1)(struct cosmology *c, double t0, double t1);
|
||||
double (*drift_t0_t1)(struct cosmology *c, double t0, double t1);
|
||||
void (*free)(struct cosmology *c);
|
||||
} cosmology;
|
||||
|
||||
void class_init(cosmology *c, char *class_ini, char *class_pre, double zmax);
|
||||
void class_params(cosmology *c, char *class_ini);
|
||||
void tbl_init(cosmology *c, char *tbl);
|
||||
|
||||
double Anow(struct cosmo_s *c, double time);
|
||||
double Znow(struct cosmo_s *c, double time);
|
||||
double Hnow(struct cosmo_s *c, double time);
|
||||
double growthfac_from_Z(struct cosmo_s *c, double z);
|
||||
double velfac_from_Z(struct cosmo_s *c, double z);
|
||||
double velfac_approx_from_Z(struct cosmo_s *c, double z);
|
||||
double t_from_Z(struct cosmo_s *c, double z);
|
||||
double comoving_distance_from_Z(struct cosmo_s *c, double z);
|
||||
double dp_from_Z(struct cosmo_s *c, double z);
|
||||
double hubble_from_Z(struct cosmo_s *c, double z);
|
||||
double kick_delta(struct cosmo_s *c, double t0, double t1);
|
||||
double drift_delta(struct cosmo_s *c, double t0, double t1);
|
||||
void CosmoPush(struct cosmo_s *c, double time);
|
||||
|
||||
#define one_kpc 3.08567802e16 /* km */
|
||||
#define one_Gyr 3.1558149984e16 /* sec */
|
||||
#define cm_kpc 3.08567802e21
|
||||
#define sec_Gyr 3.1558149984e16
|
||||
#define g_Msol 1.98892e33
|
||||
#define g_Msol10 1.98892e43 /* 10^10 Msol */
|
||||
/* http://physics.nist.gov/cgi-bin/cuu/Value?bg|search_for=G */
|
||||
/* #define G_cgs (6.67384e-8) cm3 g-1 s-2 */
|
||||
#define G_cgs (6.67259e-8)
|
||||
#define speed_of_light (299792.458) /* km/sec */
|
||||
/* Gaussian Gravitational Constant */
|
||||
#define k_cgs 0.01720209895
|
||||
#define GM_cgs 1.32712442099e26
|
||||
/* GM_cgs*sec_Gyr*sec_Gyr/cm_kpc*cm_kpc*cm_kpc */
|
||||
#define GNEWT 44986.564
|
||||
|
||||
|
||||
|
||||
|
69
external/libsdf/include/libsdf/error.h
vendored
Normal file
69
external/libsdf/include/libsdf/error.h
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
#ifndef _ErrorDOTh
|
||||
#define _ErrorDOTh
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "gccextensions.h"
|
||||
|
||||
/* Define an Error_t to describe error-like functions. */
|
||||
typedef void (*Error_t)(const char *, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif /* __cplusplus */
|
||||
void SWError(const char *, ...)
|
||||
/* noreturn only works in 2.5 or higher */
|
||||
#if (__GNUC_MINOR__>=5 && __GNUC__==2)||__GNUC__>2
|
||||
__attribute__ ((format (printf, 1, 2),noreturn));
|
||||
#else
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
#endif
|
||||
|
||||
void vError(const char *, va_list)
|
||||
/* noreturn only works in 2.5 or higher */
|
||||
#if (__GNUC_MINOR__>=5 && __GNUC__==2)||__GNUC__>2
|
||||
__attribute__ ((format (printf, 1, 0),noreturn));
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
void SinglError(const char *, ...)
|
||||
/* noreturn only works in 2.5 or higher */
|
||||
#if (__GNUC_MINOR__>=5 && __GNUC__==2)||__GNUC__>2
|
||||
__attribute__ ((format (printf, 1, 2),noreturn));
|
||||
#else
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
#endif
|
||||
void Warning(const char *, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
void SinglWarning(const char *, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
void SeriousWarning(const char *, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
void Shout(const char *mesg, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
void SinglShout(const char *mesg, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if __GNUC__>1 /* Actually, only 2.4 or higher? */
|
||||
/* We have varargs macros! */
|
||||
#define Error(format, args...) \
|
||||
(SWError)("%s (%d) in %s :\n" format, __FILE__, __LINE__, __FUNCTION__, ##args)
|
||||
#define SinglError(format, args...) \
|
||||
(SinglError)("%s (%d) in %s :\n" format, __FILE__, __LINE__, __FUNCTION__, ##args)
|
||||
#define Warning(format, args...) \
|
||||
(Warning)("%s (%d) in %s :\n" format, __FILE__, __LINE__, __FUNCTION__, ##args)
|
||||
#define SinglWarning(format, args...) \
|
||||
(SinglWarning)("%s (%d) in %s :\n" format, __FILE__, __LINE__, __FUNCTION__, ##args)
|
||||
#define SeriousWarning(format, args...) \
|
||||
(SeriousWarning)("%s (%d) in %s :\n" format, __FILE__, __LINE__, __FUNCTION__, ##args)
|
||||
|
||||
#else /* No wacky GNUC varargs stuff...*/
|
||||
/* This prevents namespace collisions when linking SDF into perl5! (really!) */
|
||||
#define Error SWError
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _ErrorDOTh */
|
34
external/libsdf/include/libsdf/gccextensions.h
vendored
Normal file
34
external/libsdf/include/libsdf/gccextensions.h
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef _GccExtensionsDOTh
|
||||
#define _GccExtensionsDOTh
|
||||
|
||||
/* this is broken in gcc2.4.0 through 2.4.4 */
|
||||
#if __GNUC__<2 || (__GNUC__== 2 && __GNUC_MINOR__<=4)
|
||||
#define BROKEN_GCC_FORMAT_ATTRIBUTE
|
||||
#endif
|
||||
|
||||
/* This isn't an entirely perfect way to deal with functions that
|
||||
don't return because sometimes we want more than one __attribute__.
|
||||
See, for example, the code in error.h and mpmy_abnormal.h */
|
||||
#if (__GNUC_MINOR__>=5 && __GNUC__==2)||__GNUC__>2
|
||||
#define __NORETURN__ __attribute__ ((noreturn))
|
||||
#else
|
||||
#define __NORETURN__
|
||||
#endif
|
||||
|
||||
#undef __attribute__
|
||||
#if !defined(__GNUC__) || defined(printf) || defined(scanf)
|
||||
#define __attribute__(x)
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
/* NoInline can be used to prevent inlining of function calls at the */
|
||||
/* calling location. I.e., NoInline(func)(arg) instead of func(arg) */
|
||||
/* We leave everything alone if we're not optimizing because there */
|
||||
/* are no inlines in that case anyway. */
|
||||
#if defined(__GNUC__) && defined(__OPTIMIZE__)
|
||||
#define NoInline(f) ({typeof(f) *fp = &f; *fp;})
|
||||
#else
|
||||
#define NoInline(f) f
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
15
external/libsdf/include/libsdf/memfile.h
vendored
Normal file
15
external/libsdf/include/libsdf/memfile.h
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef _MemfilEdotH
|
||||
#define _MemfilEdotH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
void memfile_init(int sz) ;
|
||||
void memfile_delete(void) ;
|
||||
void memfile_vfprintf(void *junk, const char *fmt, va_list args) ;
|
||||
void PrintMemfile(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
164
external/libsdf/include/libsdf/mpmy.h
vendored
Normal file
164
external/libsdf/include/libsdf/mpmy.h
vendored
Normal file
|
@ -0,0 +1,164 @@
|
|||
#ifndef _MpMYdotH
|
||||
#define _MpMYdotH
|
||||
|
||||
#include "timers.h"
|
||||
|
||||
typedef void *MPMY_Comm_request;
|
||||
typedef struct {
|
||||
int tag;
|
||||
int src;
|
||||
int count;
|
||||
}MPMY_Status;
|
||||
|
||||
#define MPMY_SUCCESS (0)
|
||||
#define MPMY_FAILED (1)
|
||||
/* This corresponds to the ANY-source in udp.c. */
|
||||
/* What about other PAROS??? */
|
||||
#define MPMY_SOURCE_ANY -2
|
||||
#define MPMY_TAG_ANY -1
|
||||
|
||||
/* Data types and operations supported in MPMY_Combine */
|
||||
|
||||
typedef enum {
|
||||
MPMY_SUM, MPMY_PROD, MPMY_MAX, MPMY_MIN, MPMY_BAND, MPMY_BOR, MPMY_BXOR
|
||||
} MPMY_Op;
|
||||
|
||||
typedef void (*MPMY_user_comb_func)(const void *from1, const void *from2,
|
||||
void *to);
|
||||
|
||||
typedef enum {
|
||||
MPMY_FLOAT, MPMY_DOUBLE, MPMY_INT, MPMY_CHAR, MPMY_SHORT, MPMY_LONG,
|
||||
MPMY_UNSIGNED_INT, MPMY_UNSIGNED_CHAR, MPMY_UNSIGNED_SHORT,
|
||||
MPMY_UNSIGNED_LONG, MPMY_OFFT, MPMY_INT64, MPMY_USER_DATA
|
||||
} MPMY_Datatype;
|
||||
|
||||
extern unsigned int MPMY_Datasize[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif /* __cplusplus */
|
||||
/* Reduction prototypes */
|
||||
int MPMY_Combine(const void *sendbuf, void *recvbuf, const int count,
|
||||
const MPMY_Datatype datatype, const MPMY_Op op);
|
||||
int MPMY_ICombine_Init(MPMY_Comm_request *reqp);
|
||||
int MPMY_ICombine_Wait(MPMY_Comm_request req);
|
||||
int MPMY_ICombine(const void *sendbuf, void *recvbuf, int count,
|
||||
MPMY_Datatype datatype, MPMY_Op op,
|
||||
MPMY_Comm_request req);
|
||||
/* A separate entry point for the user-specified-function version */
|
||||
int MPMY_ICombine_func(const void *sendbuf, void *recvbuf, int size,
|
||||
MPMY_user_comb_func func,
|
||||
MPMY_Comm_request req);
|
||||
int MPMY_AllGather(const void *sndbuf, int count, MPMY_Datatype type,
|
||||
void *rcvbuf);
|
||||
int MPMY_Gather(const void *sendbuf, int count, MPMY_Datatype type,
|
||||
void *recvbuf, int recvproc);
|
||||
int MPMY_NGather(const void *sendbuf, int count, MPMY_Datatype type,
|
||||
void **recvhndl, int recvproc);
|
||||
int MPMY_Bcast(void *buf, int count, MPMY_Datatype type, int sendproc);
|
||||
int MPMY_BcastTag(void *buf, int count, MPMY_Datatype type, int sendproc, int Tag0);
|
||||
int MPMY_Alltoall(void *sendbuf, int sendcount, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int recvcount, MPMY_Datatype recvtype);
|
||||
int MPMY_Alltoallv(void *sendbuf, int *sendcounts, int *sendoffsets, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int *recvcounts, int *recvoffsets, MPMY_Datatype recvtype);
|
||||
int Native_MPMY_Allgather(void *sendbuf, int sendcount, MPMY_Datatype type, void *recvbuf);
|
||||
int Native_MPMY_Allgatherv(void *sendbuf, int sendcount, MPMY_Datatype type, void *recvbuf,
|
||||
int *rcounts, int *roffsets);
|
||||
int Native_MPMY_Alltoall(void *sendbuf, int sendcount, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int recvcount, MPMY_Datatype recvtype);
|
||||
int Native_MPMY_Alltoallv(void *sendbuf, int *sendcounts, int *sendoffsets, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int *recvcounts, int *recvoffsets, MPMY_Datatype recvtype);
|
||||
|
||||
/*
|
||||
A NULL stat argument is allowed, indicating that you aren't interested in
|
||||
the status.
|
||||
*/
|
||||
int MPMY_Init(int *argcp, char ***argvp);
|
||||
int MPMY_Isend(const void *buf, int cnt, int dest, int tag, MPMY_Comm_request *req);
|
||||
int MPMY_Irsend(const void *buf, int cnt, int dest, int tag, MPMY_Comm_request *req);
|
||||
int MPMY_Irecv(void *buf, int cnt, int src, int tag, MPMY_Comm_request *req);
|
||||
int MPMY_Test(MPMY_Comm_request request, int *flag, MPMY_Status *stat);
|
||||
int MPMY_Wait(MPMY_Comm_request request, MPMY_Status *stat);
|
||||
/* I don't know how to write the general WaitN, but we seem to use Wait2
|
||||
often enough that it's worth providing in the library. Note that this
|
||||
waits for BOTH. Not EITHER. */
|
||||
int MPMY_Wait2(MPMY_Comm_request req1, MPMY_Status *stat1,
|
||||
MPMY_Comm_request req2, MPMY_Status *stat2);
|
||||
/* send with wait */
|
||||
void MPMY_send(const void *buf, int cnt, int dest, int tag);
|
||||
/* Blocking recv of exactly cnt bytes */
|
||||
void MPMY_recvn(void *buf, int cnt, int src, int tag);
|
||||
int MPMY_Finalize(void);
|
||||
|
||||
/* These are occasionally useful and seem to be highly system-dependent */
|
||||
int MPMY_Sync(void);
|
||||
int MPMY_Flick(void);
|
||||
|
||||
/* Desperate times require desperate measures... (c.f. malloc_print)
|
||||
Consider using Msg_do or Shout as the argument. Note that, despite
|
||||
the name, they aren't strictly printf-identical because they don't
|
||||
return an int. C'est la vie. */
|
||||
void MPMY_Diagnostic(int (*printflike)(const char *, ...));
|
||||
|
||||
/* And a version suitable for passing to OnAbnormal */
|
||||
void PrintMPMYDiags(void);
|
||||
|
||||
/* These don't really have analogues in mpi. MPI does have Sendrecv
|
||||
and Sendrecv_replace, but those are both more general (allowing
|
||||
different sources and destinations, allowing tags, allowing *_ANY)
|
||||
and less general ('replace' instead of 'overlap').
|
||||
|
||||
*/
|
||||
int MPMY_Shift(int proc, void *recvbuf, int recvcnt,
|
||||
const void *sendbuf, int sendcnt, MPMY_Status *stat);
|
||||
|
||||
int MPMY_Shift_overlap(int proc, void *recvbuf, int recvcnt,
|
||||
const void *sendbuf, int sendcnt, MPMY_Status *stat);
|
||||
|
||||
|
||||
/* In MPI, they actually give you the name of the field element. For backward
|
||||
compatibility, I'll also give them as macros */
|
||||
#define MPMY_SOURCE src
|
||||
#define MPMY_TAG tag
|
||||
#define MPMY_Source(stat) ((stat)->src)
|
||||
#define MPMY_Tag(stat) ((stat)->tag)
|
||||
/* In MPI, this is still a function because it has to deal with typing.
|
||||
We don't worry about typing... */
|
||||
#define MPMY_COUNT count
|
||||
#define MPMY_Count(stat) ((stat)->count)
|
||||
|
||||
int MPMY_Nproc(void);
|
||||
int MPMY_Procnum(void);
|
||||
/* Returns a pointer to a static char string describing the phys node. */
|
||||
const char *MPMY_Physnode(void);
|
||||
/* We call these an awful lot. Let's just set them up in init and
|
||||
save a function-call */
|
||||
extern int _MPMY_nproc_;
|
||||
extern int _MPMY_procnum_;
|
||||
extern int _MPMY_procs_per_node_;
|
||||
#define MPMY_Nproc() (_MPMY_nproc_)
|
||||
#define MPMY_Procnum() (_MPMY_procnum_)
|
||||
#define MPMY_ProcsPerNode() (_MPMY_procs_per_node_)
|
||||
|
||||
/* How can a "subsystem" like SDF know if MPMY has been initialized? */
|
||||
extern int MPMY_Initialized(void);
|
||||
extern int _MPMY_initialized_; /* internal use only! */
|
||||
|
||||
/* Counters for the number of Isends, Irecvs and (successful Tests + Waits) */
|
||||
extern Counter_t MPMYSendCnt;
|
||||
extern Counter_t MPMYRecvCnt;
|
||||
extern Counter_t MPMYDoneCnt;
|
||||
|
||||
void MPMY_CheckpointSetup(int job_seconds, int interval_seconds, int step_seconds);
|
||||
int MPMY_CheckpointDue(int next_output_seconds);
|
||||
void MPMY_CheckpointFinished(void);
|
||||
int MPMY_JobDone(void);
|
||||
int MPMY_JobRemaining(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* INTERNAL USE ONLY!! */
|
||||
|
||||
#endif
|
71
external/libsdf/include/libsdf/mpmy_abnormal.h
vendored
Normal file
71
external/libsdf/include/libsdf/mpmy_abnormal.h
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
#ifndef _MPMYAbnormalDOTh_
|
||||
#define _MPMYAbnormalDOTh_
|
||||
#include "gccextensions.h"
|
||||
|
||||
/* Abhndlrs are void functions of void. Use them as arguments to
|
||||
MPMY_OnAbnormal. */
|
||||
typedef void (*Abhndlr)(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
/* MPMY_Abort will execute MPMY_RaiseAbnormal(SIGABRT) and then call
|
||||
MPMY_SystemAbort. Don't be surprised if the OnAbnormal functions
|
||||
themselves call MPMY_SystemAbort first, though. */
|
||||
void MPMY_Abort(void) __NORETURN__;
|
||||
|
||||
extern int MPMY_Abnormal_signum;
|
||||
extern int MPMY_stop_abnormal_processing;
|
||||
void MPMY_RaiseAbnormal(int sig); /* fake a signal of type 'sig' */
|
||||
|
||||
/* Push a handler to the stack that will be executed on abnormal termination.
|
||||
Some useful arguments to consider are:
|
||||
malloc_print();
|
||||
PrintMemfile();
|
||||
Msg_flush();
|
||||
MPMY_abchdir(); (with MPMY_abchdir_arg set beforehand)
|
||||
MPMY_SystemAbort();
|
||||
MPMY_SystemExit(); (with MPMY_exit_arg set beforehand)
|
||||
|
||||
They are called in the reverse chronological order from the order that
|
||||
they were requested by MPMY_OnAbnormal, so later functions
|
||||
might 'override' earlier ones. This isn't perfect, but it's better than
|
||||
the monolithic handler we had before. The handler can
|
||||
find out which signal is being handled by looking at
|
||||
int MPMY_current_signal ;
|
||||
|
||||
As a final twist, it is possible to bail out of the stack and just
|
||||
return from the handler immediately by setting:
|
||||
int MPMY_stop_abnormal_processing;
|
||||
to non-zero.
|
||||
*/
|
||||
void MPMY_OnAbnormal(Abhndlr hndlr);
|
||||
|
||||
/* Really, truly, abort(). Now! */
|
||||
void MPMY_SystemAbort(void) __NORETURN__;
|
||||
|
||||
/* Really, truly, exit(MPMY_exit_arg). Now! */
|
||||
extern int MPMY_exit_arg;
|
||||
void MPMY_SystemExit(void) __NORETURN__; /* An Abhndlr */
|
||||
|
||||
/* Do a mkdir/chdir to the directory named by MPMY_abchdir_arg.
|
||||
This can be extremely useful before dumping core... */
|
||||
extern char MPMY_Abchdir_arg[];
|
||||
void MPMY_Abchdir(void); /* An Abhndlr */
|
||||
|
||||
/* Announce (Shout) that we are handling a signal. Try not to repeat
|
||||
yourself if it's been said already... */
|
||||
void MPMY_Abannounce(void);
|
||||
|
||||
/* Arrange to crash and burn if n seconds elapse before Reset is called */
|
||||
void MPMY_TimeoutSet(int n);
|
||||
void MPMY_TimeoutReset(int n);
|
||||
void MPMY_TimeoutCancel(void);
|
||||
|
||||
/* Not for public use. */
|
||||
void _MPMY_setup_absigs(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _MPMYAbnormalDOTh_ */
|
62
external/libsdf/include/libsdf/mpmy_io.h
vendored
Normal file
62
external/libsdf/include/libsdf/mpmy_io.h
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
#ifndef MPMY_IOdotH
|
||||
#define MPMY_IOdotH
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef void MPMYFile;
|
||||
|
||||
/* mode flags for open */
|
||||
/* The first three correspond to the analogous modes O_??? that seem
|
||||
to be fairly common on different unices (linux, sunos, solaris). I
|
||||
guess that's a good thing. But who decided that OR'ing zero
|
||||
(O_RDONLY) with other values should be used as a flag???? The latter
|
||||
ones show no commonality between other flavors of unix anyway, so
|
||||
there's nothing to remain analogous to... */
|
||||
#define MPMY_RDONLY 00000000
|
||||
#define MPMY_WRONLY 00000001
|
||||
#define MPMY_RDWR 00000002
|
||||
#define MPMY_APPEND 00000004
|
||||
#define MPMY_CREAT 00000010
|
||||
#define MPMY_TRUNC 00000020
|
||||
/* io modes */
|
||||
#define MPMY_SINGL 00010000 /* like cubix single mode */
|
||||
#define MPMY_MULTI 00020000 /* like cubix multi mode */
|
||||
/* These four are used by the 'mpmy_pario' implementation, but that is
|
||||
no longer linked with any of our default systems... */
|
||||
#define MPMY_UNIX 00040000 /* one file, UNIX multi-process semantics */
|
||||
#define MPMY_IOZERO 00100000 /* if(procnum==0){...} */
|
||||
#define MPMY_INDEPENDENT 00200000 /* many files. Complete independence */
|
||||
#define MPMY_NFILE 00400000 /* many files. Really. */
|
||||
|
||||
/* modes for seek */
|
||||
#define MPMY_SEEK_SET 0
|
||||
#define MPMY_SEEK_CUR 1
|
||||
#define MPMY_SEEK_END 2
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif /* __cplusplus */
|
||||
MPMYFile *MPMY_Fopen(const char *path, int flags);
|
||||
int MPMY_SetIOMode(MPMYFile *fp, int iomode);
|
||||
int MPMY_Fclose(MPMYFile *fp);
|
||||
int MPMY_Mkdir(const char *path, int mode);
|
||||
size_t MPMY_Fread(void *ptr, size_t size, size_t nitems, MPMYFile *fp);
|
||||
size_t MPMY_Fwrite(const void *ptr, size_t size, size_t nitems, MPMYFile *fp);
|
||||
off_t MPMY_Fseek(MPMYFile *fp, off_t offset, int whence);
|
||||
off_t MPMY_Ftell(MPMYFile *fp);
|
||||
off_t MPMY_Flen(MPMYFile *fp);
|
||||
int MPMY_Getc(MPMYFile *fp);
|
||||
int MPMY_Ungetc(char c, MPMYFile *fp);
|
||||
size_t MPMY_Fseekrd(MPMYFile *fp, off_t offset, int whence, void *buf, size_t reclen,
|
||||
size_t nrecs);
|
||||
int MPMY_Fprintf(MPMYFile *fp, const char *fmt, ...);
|
||||
int MPMY_Vfprintf(MPMYFile *fp, const char *fmt, va_list args);
|
||||
int MPMY_Fflush(MPMYFile *fp);
|
||||
int MPMY_Nfileio(int val);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* MPMY_IOdotH */
|
23
external/libsdf/include/libsdf/mpmy_time.h
vendored
Normal file
23
external/libsdf/include/libsdf/mpmy_time.h
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef MPMY_timeDOTh
|
||||
#define MPMY_timeDOTh
|
||||
|
||||
/* some simple system-dependent routines to facilitate timing */
|
||||
|
||||
#define MPMY_CPU_TIME 1
|
||||
#define MPMY_WC_TIME 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif /* __cplusplus */
|
||||
void *MPMY_CreateTimer(int type);
|
||||
int MPMY_StartTimer(void *);
|
||||
int MPMY_CopyTimer(void *, void *);
|
||||
int MPMY_StopTimer(void *);
|
||||
int MPMY_ClearTimer(void *);
|
||||
double MPMY_ReadTimer(void *);
|
||||
int MPMY_DestroyTimer(void *);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
128
external/libsdf/include/libsdf/protos.h
vendored
Normal file
128
external/libsdf/include/libsdf/protos.h
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* This is where we keep the code to shut up warnings about implicit */
|
||||
/* declarations. */
|
||||
|
||||
/*
|
||||
* Copyright 1991 Michael S. Warren and John K. Salmon. All Rights Reserved.
|
||||
*/
|
||||
#ifndef _ProtosDOTh
|
||||
#define _ProtosDOTh
|
||||
|
||||
/* gcc's fixprotos changed in 2.5 so that it is no longer necessary
|
||||
to have protos for all these. If __GNUC__ and __GNUC_MINOR are undefined,
|
||||
ANSI says the pre-processor should treat them as 0, so the test should
|
||||
pass and we should see the prototypes - fingers crossed.
|
||||
*/
|
||||
/* AIEEEE!!! The above comment only applied to the short-lived
|
||||
aberation 2.5.4. It is broken again in 2.5.5. Unfortunately,
|
||||
there is no __GNUC__SUBMINOR__ so I can't switch on it. The
|
||||
following conditional worked for 2.5.4...
|
||||
#if defined(sun) && !defined(__SUN5__) && __GNUC__<=2 && __GNUC_MINOR__<=4
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* ----------------BEGIN--SUNOS------------------------ */
|
||||
/*------------------------------------------------------*/
|
||||
#if defined(sun)
|
||||
#include <stddef.h>
|
||||
/* Sunos4.1.3 sometimes seems to come with prototypes...And they're wrong! */
|
||||
/* Setting ARCH=sun4proto will activate this */
|
||||
#ifndef _SUNOS4_PROTOTYPES_
|
||||
extern int bcopy(const void *from, void *to, size_t);
|
||||
#if !defined(__SUN5__) && !defined (_SUNACC)
|
||||
/* Sun's stdio doesn't have protos for fflush, printf, what else?? */
|
||||
/* I can't predict whether FILE is meaningful, so I use void* */
|
||||
/* Furthermore, I can't give a prototype for sprintf because gcc complains */
|
||||
/* about a conflict between old-style decl and one with an ellipsis */
|
||||
#include "gccextensions.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Sigh... In 2.5.6 and 2.5.7 (at least). fixincludes gives full
|
||||
prototypes for all the non-integer-return functions in std*.h. */
|
||||
#if 0
|
||||
extern char *sprintf();
|
||||
#endif
|
||||
|
||||
extern int printf( const char *, ... )
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
extern int fprintf(void *, const char *, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
extern int vfprintf(void *, const char *, va_list)
|
||||
__attribute__((format (printf, 2, 0)));
|
||||
extern int vsprintf(char *, const char *, va_list)
|
||||
__attribute__((format (printf, 2, 0)));
|
||||
extern int scanf(const char *, ...)
|
||||
__attribute__((format (scanf, 1, 2)));
|
||||
extern int sscanf(const char *, const char *, ...)
|
||||
__attribute__((format (scanf, 2, 3)));
|
||||
extern int fflush(void *);
|
||||
extern int fwrite(const void *, size_t, size_t, void/*FILE*/ *);
|
||||
extern int fseek(void/*FILE*/ *, long, int);
|
||||
extern int fread(void *, size_t, size_t, void/*FILE*/ *);
|
||||
extern int fclose(void *);
|
||||
extern int raise(int);
|
||||
extern int _filbuf(void *);
|
||||
extern int _flsbuf(int, void *);
|
||||
#ifndef ungetc
|
||||
extern int ungetc(int, void*);
|
||||
#endif
|
||||
extern int setvbuf(void *, void *, int, size_t);
|
||||
/* We carefully include stdlib.h when we use these, */
|
||||
/* but Sun has elected to leave them out of stdlib.h...go figure */
|
||||
extern void *memmove(void *, const void *, size_t);
|
||||
extern void *memccpy (void *, const void *, int, size_t );
|
||||
extern void *memchr (const void *, int, size_t );
|
||||
extern void *memcpy (void *, const void *, size_t );
|
||||
extern void *memset (void *, int, size_t );
|
||||
#endif /* __SUN5__ */
|
||||
#endif /* _SUNOS4_PROTOTYPES_ */
|
||||
#endif /* sun */
|
||||
/*------------------------------------------------------*/
|
||||
/* ------------------END--SUNOS------------------------ */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* ------------------BEGIN--INTEL---------------------- */
|
||||
/*------------------------------------------------------*/
|
||||
#if defined(__INTEL_SSD__)
|
||||
#include <stddef.h>
|
||||
extern int bcopy(const void *from, void *to, size_t);
|
||||
|
||||
/* This should be in nx.h or cube.h or mesh.h */
|
||||
extern void flick(void);
|
||||
|
||||
#if defined(__DELTA__) || defined(__GAMMA__)
|
||||
/* This should be in fcntl.h */
|
||||
int open(const char *, int flags, ...);
|
||||
int creat(const char *, int/* mode_t */);
|
||||
|
||||
/* These should be in unistd.h */
|
||||
int close(int);
|
||||
int unlink(const char *);
|
||||
int read(int, void *buf, unsigned int);
|
||||
int write(int, const void *, unsigned int);
|
||||
/*off_t*/long lseek(int, long/*off_t*/, int);
|
||||
|
||||
/* Should be in sys/stat.h */
|
||||
int mkdir(const char *, int);
|
||||
#ifdef S_IRGRP
|
||||
/* this means we already included <sys/stat.h> */
|
||||
int fstat(int, struct stat *);
|
||||
#endif
|
||||
#endif /* __DELTA__ || __GAMMA__ */
|
||||
|
||||
#endif /* !__INTEL_SSD__ */
|
||||
/*------------------------------------------------------*/
|
||||
/* ------------------END--INTEL------------------------ */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------*/
|
||||
/* ------------------BEGIN--SOLARIS/STARDENT----------- */
|
||||
/*------------------------------------------------------*/
|
||||
#if defined(__STARDENT__) || defined(__SUN5__)
|
||||
int finite(double);
|
||||
#endif
|
||||
/*------------------------------------------------------*/
|
||||
/* --------------------END--SOLARIS/STARDENT----------- */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
#endif /* _PrototDOTh */
|
14
external/libsdf/include/libsdf/singlio.h
vendored
Normal file
14
external/libsdf/include/libsdf/singlio.h
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef _SinglIODOTh
|
||||
#define _SinglIODOTh
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif /* __cplusplus */
|
||||
int singlPrintf(const char *, ...);
|
||||
void singlFflush(void);
|
||||
int singlAutoflush(int);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
78
external/libsdf/include/libsdf/timers.h
vendored
Normal file
78
external/libsdf/include/libsdf/timers.h
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 1991, 1992, 1993 Michael S. Warren and John K. Salmon.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _TimersDOTh
|
||||
#define _TimersDOTh
|
||||
#include <stdint.h>
|
||||
|
||||
/* This used to look more like a Counter_t, but it was just too much */
|
||||
/* trouble to deal with the archtecture specific differences, so we */
|
||||
/* hide all the ugliness behind another layer of indirection. In */
|
||||
/* fact, it would make more sense if, e.g., EnableTimer returned a void* */
|
||||
/* but that would require too much changing of "application" code. */
|
||||
typedef struct {
|
||||
int enabled;
|
||||
void *mpmy_tm;
|
||||
char *name;
|
||||
double min, max, mean;
|
||||
} Timer_t;
|
||||
|
||||
typedef struct {
|
||||
int enabled;
|
||||
int64_t counter;
|
||||
int64_t max, min;
|
||||
double mean, sum;
|
||||
char *name;
|
||||
} Counter_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif /* __cplusplus */
|
||||
void StartTimer(Timer_t *t);
|
||||
void StopTimer(Timer_t *t);
|
||||
void SumTimers(void);
|
||||
void CopyTimer(Timer_t *src, Timer_t *dest);
|
||||
void EnableWCTimer(Timer_t *t, char *name);
|
||||
void EnableCPUTimer(Timer_t *t, char *name);
|
||||
void DisableTimer(Timer_t *t);
|
||||
void ClearTimer(Timer_t *t);
|
||||
void ClearEnabledTimers(void);
|
||||
void OutputTimers(int (*Printf_Like)(const char *, ...));
|
||||
void OutputTimer(Timer_t *t, int (*Printf_Like)(const char *, ...));
|
||||
void OutputIndividualTimers(int (*Printf_Like)(const char *, ...));
|
||||
double ReadTimer(Timer_t *t);
|
||||
|
||||
void SumCounters(void);
|
||||
void EnableCounter(Counter_t *t, char *name);
|
||||
void DisableCounter(Counter_t *t);
|
||||
void ClearCounter(Counter_t *c);
|
||||
void ClearEnabledCounters(void);
|
||||
void OutputCounters(int (*Printf_Like)(const char *, ...));
|
||||
void OutputIndividualCounters(int (*Printf_Like)(const char *, ...));
|
||||
void OutputOneCounter(Counter_t *c, int (*Printf_Like)(const char *, ...));
|
||||
int64_t ReadCounter(Counter_t *c);
|
||||
int64_t ReadCounter64(Counter_t *c);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define EnableTimer(t, name) EnableWCTimer(t, name)
|
||||
|
||||
#ifdef NOTIMERS
|
||||
#define StartTimer(x) /**/
|
||||
#define StopTimer(x) /**/
|
||||
#define StartWCTimer(x) /**/
|
||||
#define StopWCTimer(x) /**/
|
||||
#endif
|
||||
|
||||
#ifndef NOCOUNTERS
|
||||
#define IncrCounter(c) ((c)->counter++)
|
||||
#define AddCounter(c, add) ((c)->counter += (add))
|
||||
#else
|
||||
#define IncrCounter(c)
|
||||
#define AddCounter(c, add)
|
||||
#endif
|
||||
|
||||
#endif /* _TimersDOTh */
|
313
external/libsdf/libSDF/ChangeLog.14
vendored
Normal file
313
external/libsdf/libSDF/ChangeLog.14
vendored
Normal file
|
@ -0,0 +1,313 @@
|
|||
Fri Jan 7 13:50:53 1994 John Salmon (johns@haggis)
|
||||
|
||||
* Terminate this ChangeLog. Future changes to be logged
|
||||
in the parent directory.
|
||||
|
||||
Wed Dec 29 08:57:39 1993 John Salmon (johns@sampson)
|
||||
|
||||
* fseekrd.c (fseekrd): #include protos.h and error.h
|
||||
|
||||
Mon Dec 27 18:05:36 1993 John Salmon (johns@lux)
|
||||
|
||||
* fseekrd.c: Bail out with Error in the event of an error.
|
||||
|
||||
Sun Oct 10 21:02:27 1993 John Salmon (johns@sockeye)
|
||||
|
||||
* SDFget.c: Added protos.h. Silenced a warning.
|
||||
|
||||
Tue Jul 13 11:19:20 1993 John Salmon (johns@lux)
|
||||
|
||||
* libSDF/: changed some formats to silence complaints about
|
||||
incorrect argument passing to printf. These SHOULD all be
|
||||
changed to singlWarning.
|
||||
|
||||
Thu Jun 10 15:34:01 1993 John Salmon (johns@haggis)
|
||||
|
||||
* SDF.h, SDFget.c: Added the functions SDFgetint, SDFgetdouble
|
||||
SDFgetfloat and SDFgetstring to the library. In addition, added
|
||||
the macros SDFget*OrDie and SDFget*OrDefault to SDF.h. The macros
|
||||
use Error and singlWarning, which can be found in the swutils
|
||||
library, or which the user may redefine to taste.
|
||||
|
||||
Thu Jun 3 16:32:18 1993 John Salmon (johns at haggis)
|
||||
|
||||
* Revert back to the i860_utils style of managing the PGI,
|
||||
IPSC_XDEV, etc. environment variables. "The management apologizes
|
||||
for the inconvenience." The reason is that i860_target doesn't
|
||||
interact well with Make running inside emacs.
|
||||
|
||||
Tue Jun 1 20:51:16 1993 John Salmon (johns@sockeye)
|
||||
|
||||
* (../SDF): Changed Make.common so it creates libraries in, e.g.,
|
||||
sun4/libSDF.a. Make the old-style SDF_sun4.a a symbolic link to
|
||||
the new file. Use of <ARCH>/libSDF.a is encouraged.
|
||||
|
||||
Tue Jun 1 20:47:04 1993 John Salmon (johns at haggis)
|
||||
|
||||
* Added (this) ChangeLog to the list of docs copied into .tar files!
|
||||
|
||||
Wed May 26 20:02:14 1993 John Salmon (johns at sampson)
|
||||
|
||||
* Removed the -delta flags from Make.delta. Use the i860_target
|
||||
technology instead.
|
||||
|
||||
* Fixed two bugs related to ascii data. On line 399 of
|
||||
SDF-parse.y and line 646 of SDFfuncs.c. Recompiled sun4 and delta
|
||||
versions. It should now correctly handle ascii data.
|
||||
|
||||
Tue Mar 2 20:26:09 1993 John Salmon (johns at sampson)
|
||||
|
||||
* Conditionalized the #define YYDEBUG 1 so it won't get linked on
|
||||
the delta. It surely can't do us any good!
|
||||
|
||||
* Added a comment (but no code) to SDF-parse.y that worries about
|
||||
what to do when a string constant is too long to fit in a char array.
|
||||
|
||||
* Changed SDFtst.c so it prints the first element of every vector
|
||||
in the file it reads. Just another diagnostic that might show up
|
||||
an error...
|
||||
|
||||
Wed Feb 10 20:12:15 1993 John Salmon (johns at sampson)
|
||||
|
||||
* Don't close stdin in SDFissdf!
|
||||
|
||||
Wed Dec 9 11:36:53 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Changed the #ifdef SEEK_SET conditionals in SDF.h. Now
|
||||
the 'preferred' usage is SDF_SEEK_SET, etc., but they are
|
||||
almost guaranteed to be the same as SEEK_SET from stdio.h.
|
||||
If they aren't, complete and untraceable confusion will surely
|
||||
result. Changed SEEK_SET, etc. in SDFfuncs.c to SDF_SEEK_SET,
|
||||
etc.
|
||||
|
||||
Wed Dec 2 17:55:08 1992 John Salmon (johns at pollux)
|
||||
|
||||
* Added ncube2 support. This means setting up a Make.ncube2,
|
||||
and getting alloca.c (unmodified) from the emacs distribution,
|
||||
and saying 'extrasrc:=alloca.c' in Make.ncube2. Also added
|
||||
a call to alloca(0) to SDFopen just after yyparse, which should
|
||||
clean up any mess left behind by the C alloca.
|
||||
|
||||
Fri Nov 13 18:42:33 1992 John Salmon (johns at sampson)
|
||||
|
||||
* Reset yylineno in SDFyyprepare(). Otherwise error message
|
||||
line numbers accumulate!
|
||||
|
||||
Tue Nov 10 20:21:11 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Changed the typedef for SDF in SDF.h. It still doesn't tell
|
||||
you what's really going on in an SDF hdr, but at least prototypes
|
||||
get checked for correctness, and printing an SDF* under gdb might
|
||||
even tell you most of what you care to know.
|
||||
|
||||
Tue Oct 27 12:24:50 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Fixed a bug in SDF-lex.l that didn't recognize signed
|
||||
integer constants. How did this last for so long?! The
|
||||
{Sign} specifier was simply missing from the regex.
|
||||
|
||||
Fri Oct 16 11:10:13 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added halocenterx, halocentery and halocenterz to the
|
||||
generic tree.sdfh and tree_ap.sdfh files. These are used
|
||||
by the isothermal halo integrator (i.e., Carl).
|
||||
|
||||
Thu Oct 15 21:34:20 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Try to be even more defensive in SDFclose, in order to not
|
||||
get SEGV when bailing out of a parse error. This is not
|
||||
a finished project! Careful cleanup should be attempted in
|
||||
yyerror().
|
||||
|
||||
Fri Oct 9 08:34:50 1992 John Salmon (johns at delilah)
|
||||
|
||||
* SDF now only uses SEEK_CUR to reposition itself in the file.
|
||||
fseekrd() will work with SEEK_CUR and any positive offset by
|
||||
freading into a junk buffer, regardless of whether the file is
|
||||
seekable. Thus, operations on unseekable files need not be
|
||||
sequential. They must still be "monotonic increasing".
|
||||
|
||||
Thu Oct 8 10:06:49 1992 John Salmon (johns at delilah)
|
||||
|
||||
* Added support for reading from unseekable files. This means
|
||||
keeping track of the "seek pointer" ourselves, and checking
|
||||
whether seeking is really necessary to accomodate requests. If
|
||||
the caller doesn't require us to seek, then we don't. If he does,
|
||||
then we fail.
|
||||
|
||||
* Added SDFsetbufsz/SDFgetbufsz, which induce SDF to malloc a
|
||||
buffer and call setvbuf in all subsequent SDFopen's. Use for
|
||||
tuning access to tape devices and pipes.
|
||||
|
||||
Wed Sep 16 11:12:40 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added the keyword "long" to the set of possible types.
|
||||
It behaves EXACTLY the same as "int". There is no corresponding
|
||||
SDF_LONG. Is this really a good idea (the same was done for unsigned).
|
||||
|
||||
* Fixed a bug in SDF-parse.y which caused miscounting the
|
||||
lengths of implicit arrays, e.g., char greeting[] = "hello";
|
||||
|
||||
* Added Const to many of the arguments in SDF.h.
|
||||
|
||||
Tue Sep 15 17:10:48 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Eliminated the huge redundancy in SDFrdvecsarr, and made it
|
||||
call SDFseekrdvecsarr. This not only shortens the code, but it
|
||||
probably means more reasonable behavior on return from errors.
|
||||
Ever wonder what would happen if you do an SDFrdvecsarr and the
|
||||
last "name" you give it doesn't exist? Well it's much better now.
|
||||
|
||||
Wed Sep 2 15:12:06 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Changed the strategy for grabbing temporary space in SDFrdvecsarr
|
||||
and SDFseekrdvecsarr. Now if malloc fails, we try successively
|
||||
smaller requests until we get something. We only give up with
|
||||
an error if we can't get enough for a single "record" (i.e.,
|
||||
struct). The memory is freed at the end of the execution of
|
||||
SDF*rdvecsarr.
|
||||
|
||||
* In the interests of reducing namespace pollution, changed the enum
|
||||
names in SDF_type_enum to be SDF_INT, SDF_FLOAT, etc. This will
|
||||
break some old codes. Old codes can be made to compile by
|
||||
adding a #define OLD_ENUM_NAMES before #include "SDF.h".
|
||||
|
||||
* Changed the external name of swapn to SDFswapn. This should
|
||||
not effect anything.
|
||||
|
||||
Tue Sep 1 10:13:05 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added an if( hdr==NULL ) test to each of the exported SDF
|
||||
functions. This should cut down on memory faults from users
|
||||
who don't check the return from SDFopen. It might even be
|
||||
worthwhile to put a magic number in the SDF hdr.
|
||||
|
||||
Mon Aug 31 17:43:25 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Fixed a typo in SDF-lex.l and recompiled delta and sun4.
|
||||
|
||||
* Checked the return of realloc against NULL in the middle of
|
||||
SDFrdvecsarr and SDFseekrdvecsarr. The program now fails with
|
||||
a message rather than getting a Segv. It is probably not recoverable.
|
||||
We really should reduce the size of some of these buffers by
|
||||
staging them.
|
||||
|
||||
Tue Jun 30 02:39:30 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Removed some spurious newlines from the ends of the .sdfh files.
|
||||
These make trouble if you try to do "cat tree.sdfh foo.tree > foo.sdf"
|
||||
|
||||
* INCOMPATIBLE CHANGE: changed the calling convention for
|
||||
SDFopen. Now we pass in two char strings, both filenames, one
|
||||
for the header and one for the data. This has a number of
|
||||
beneficial effects:
|
||||
1) It means we don't have to 'agree' on what kind of FILE is
|
||||
in use with the 'user'. (e.g., CUBIX, NX, SRV, etc.) All the nasty
|
||||
business gets handled inside SDF in the Makefile and such.
|
||||
2) It's easier for a 'user' to specify a header that comes from a
|
||||
file. The user doesn't have to stat the file, malloc space, read
|
||||
it in and then call SDFopen with the contents as an arg.
|
||||
3) SDF is reasonably careful about checking out whether fopen
|
||||
returns NULL. This means less obscure failure when a bad name
|
||||
is provided.
|
||||
|
||||
If the hdrname is NULL, or if it is empty or if it strcmp's
|
||||
equal to the datafname, then the data file is treated as an
|
||||
SDF file with a header attached.
|
||||
|
||||
* Made a similar change to SDFissdf, so that one calls it with
|
||||
a name rather than a FILE *. "-" is stdin.
|
||||
|
||||
Tue Jun 9 17:30:13 1992 John Salmon (johns at delilah)
|
||||
|
||||
* Created SDF_sun4.a SDF_risc6000.a and SDF_delta.a.
|
||||
|
||||
* Added some new functions to SDF.h and SDFfuncs.c:
|
||||
SDFissdf, SDFbyteorder, SDFswap, SDFnoswap, SDFisswapping.
|
||||
|
||||
These make it simpler to use generic header files for things
|
||||
like pjq, tree, etc. files. The nbio_ routines are no longer
|
||||
the preferred way to read old-style files. It might be worth
|
||||
writing a function that reads an alternative header directly
|
||||
from disk, rather than from a string. It really is a shame
|
||||
that there is no portable way to treat a string as a FILE *.
|
||||
|
||||
Sat Apr 4 09:34:16 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Created SDF_risc6000.a.
|
||||
|
||||
* Changed the declaration of do_value_param so it DOES NOT say
|
||||
Static int do_value_param(...., const_t const);
|
||||
This caused the AIX compiler to fail in a very obscure way!
|
||||
|
||||
Thu Mar 26 05:20:04 1992 John Salmon (johns at kastor)
|
||||
|
||||
* Some minor surgery on SDF-parse.y to deal with zero-length
|
||||
blocks at the end of the data file. We now try to fstat the
|
||||
file to figure out how many records will fit in the file. This
|
||||
should make writing generic tree-file readers easier, because
|
||||
"npart" is implicit.
|
||||
|
||||
Tue Mar 24 09:32:01 1992 John Salmon (johns at haggis)
|
||||
|
||||
* "Released" v1.2.0.
|
||||
|
||||
* Changed the Makefile, SDFfuncs.c and SDF-parse.y so the
|
||||
bison-generated externals now start with SDFyy, i.e.,
|
||||
SDFyyparse, SDFyyerror, etc. This makes it easier to merge
|
||||
SDF with programs like sm.
|
||||
|
||||
Thu Mar 19 05:05:12 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Removed #pragma once from the rest of the .h files
|
||||
|
||||
* Changed malloc to calloc in SDFopen.
|
||||
|
||||
Fri Mar 13 08:24:32 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Rebuilt SDF_delta.a and SDF_sun4.a
|
||||
|
||||
* Removed #pragma once from all the .h files.
|
||||
|
||||
* Added dependency for SDF-lex.c and SDF-parse.o to Makefile
|
||||
so changes to SDF-lex.l are understood by make.
|
||||
|
||||
* Added the 'unsigned' keyword to SDF-lex.l. It's a total
|
||||
no-op. It may make it somewhat easier (and dangerous?) to
|
||||
convert C structs into SDF headers.
|
||||
|
||||
* Changed the definition of the end-of-header symbol.
|
||||
Now it's any comment line containing the string SDF-EOH.
|
||||
The newline is the last character in the header. It is
|
||||
highly recommended that users add their own form-feeds
|
||||
to this line, but it is now at the user's discretion.
|
||||
|
||||
Thu Mar 12 22:23:37 1992 Mike Warren (msw at sampson)
|
||||
|
||||
* (nbio_open) Added a break to the case NBIO_SDF_TYPE:
|
||||
|
||||
Sun Feb 9 13:26:20 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added some more error reporting to nbio. On most errors,
|
||||
something is now written into nbio_errstring. If the error
|
||||
is detected by SDF, then we (usually) copy SDFerrstring too.
|
||||
|
||||
* Added the SDFhasname() and nbio_hasname() functions to test
|
||||
for the existence of a name in a file.
|
||||
|
||||
Fri Feb 7 18:32:04 1992 John Salmon (johns at haggis)
|
||||
|
||||
* Added missing ';' in the "parameter byteorder=blaa; "
|
||||
strings in nbio.c
|
||||
|
||||
* Added the char nbio_errstring[] array for messages.
|
||||
|
||||
* Added the char *nbio_type_names[] array.
|
||||
|
||||
* Added the "seekrd" functions to SDF and nbio, which use the
|
||||
fseekrd(...) "primitive". Hopefully, this will be supported
|
||||
by servix on all future parallel machines.
|
||||
|
||||
* Fiddled around with the header files. There's now only
|
||||
one copy of the prototypes in the "public" files, nbio.h and
|
||||
SDF.h.
|
64
external/libsdf/libSDF/GNUmakefile
vendored
Normal file
64
external/libsdf/libSDF/GNUmakefile
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Make.$(ARCH) sets many of the variables used below including:
|
||||
# CC, CFLAGS, AS, RANLIB, objdir, objsuf, asmdir
|
||||
|
||||
treedir=..
|
||||
treedir_sed=\.\.
|
||||
appexcludes=
|
||||
# Put everything into the libsw library!!!
|
||||
libname=libsw
|
||||
|
||||
# The "SDF" library
|
||||
src:= \
|
||||
SDF-parse.c SDFfuncs.c SDFget.c SDFhdrio.c
|
||||
|
||||
include $(treedir)/Make-common/Make.$(ARCH)
|
||||
|
||||
include $(treedir)/Make-common/Make.generic
|
||||
|
||||
# These rules are slight modifications of the builtin ones
|
||||
$(objdir)/%.c : %.y
|
||||
$(YACC.y) $<
|
||||
mv -f y.tab.c $@
|
||||
|
||||
$(objdir)/%.c : %.l
|
||||
# commands to execute (built-in):
|
||||
@$(RM) $@
|
||||
$(LEX.l) $< > $@
|
||||
|
||||
# Makedepends can't pick these up...
|
||||
$(objdir)/SDF-parse$(objsuf): SDF-private.h $(objdir)/SDF-lex.c $(objdir)/SDF-parse.c
|
||||
(cd $(objdir); $(CC) $(CFLAGS) -I../../../include -I../.. -c SDF-parse.c)
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
$(objdir)/SDF-parse$(objsuf):
|
||||
$(objdir)/SDF-parse$(objsuf):
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/gccextensions.h SDF-private.h stdio.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/mpmy_io.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/SDF.h $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/SDF-parse$(objsuf): $(treedir)/include/libsdf/error.h SDF-lex.c
|
||||
$(objdir)/SDF-parse$(objsuf):
|
||||
$(objdir)/SDF-parse$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/SDFfuncs$(objsuf): stdio.h $(treedir)/include/libsdf/mpmy_io.h SDF-private.h
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/SDF.h
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/byteswap.h $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/SDFfuncs$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/SDFfuncs$(objsuf):
|
||||
$(objdir)/SDFget$(objsuf): stdio.h $(treedir)/include/libsdf/mpmy_io.h
|
||||
$(objdir)/SDFget$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/SDFget$(objsuf): $(treedir)/include/libsdf/SDF.h
|
||||
$(objdir)/SDFhdrio$(objsuf):
|
||||
$(objdir)/SDFhdrio$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/SDFhdrio$(objsuf): $(treedir)/include/libsdf/error.h SDF-private.h
|
||||
$(objdir)/SDFhdrio$(objsuf): stdio.h
|
||||
$(objdir)/SDFhdrio$(objsuf): $(treedir)/include/libsdf/mpmy_io.h
|
||||
$(objdir)/SDFhdrio$(objsuf):
|
||||
$(objdir)/SDFhdrio$(objsuf): $(treedir)/include/libsdf/SDF.h
|
199
external/libsdf/libSDF/README
vendored
Normal file
199
external/libsdf/libSDF/README
vendored
Normal file
|
@ -0,0 +1,199 @@
|
|||
--------README from 1.3 -------------
|
||||
|
||||
This is version 1.3 of SDF. This version has been de-stdio-ized. It
|
||||
uses MY* functions in lieu of all stdio functions. Unless I've missed
|
||||
something, the only stdio function that remains is sprintf. Because
|
||||
lex is brain-damaged and insists on writing #include "stdio.h" into
|
||||
its output, I created a "./stdio.h" to override the system one. This
|
||||
is not strictly ANSI, but then, what is?
|
||||
|
||||
--------README from 1.2-------
|
||||
|
||||
This is version 1.2 of SDF ("Self Describing Files" or "Super-Duper
|
||||
Files, depending on how impressed you are). It is the first version
|
||||
of the last i/o package you'll ever need. SDF files are binary data
|
||||
files with an optional header which contains 1) a description of the
|
||||
layout of the data, and 2) optional ascii constants. There is no
|
||||
output capability because the sdf files are so easy to write :-).
|
||||
This document is completely unstructured, and probably
|
||||
incomprehensible to anyone but the author. It's a
|
||||
stream-of-consciousness first-draft. Be generous.
|
||||
|
||||
The user-callable SDF programs are declared with prototypes in SDF.h.
|
||||
I refuse to consider systems that can't deal with prototypes,
|
||||
<stdarg.h> and the ellipsis for variadic functions and enum types. If
|
||||
you don't have gcc on your Sun, then call up Sun and give them a piece
|
||||
of your mind, and then go get gcc. The ANSI standard has been out for
|
||||
long enough now. Accept no substitutes. The object modules are in
|
||||
the library SDF_<machine>.a. I have tried to keep the "name-space
|
||||
pollution" to a minimum. Unfortunately, there are a few additional
|
||||
external names used by the SDF package that do not appear explicitly in
|
||||
SDF.h. These include anything starting with "obstack_" (SDF uses the
|
||||
gnu obstack package) and all names starting with "SDF".
|
||||
|
||||
There are no provisions for writing SDF files. The reason is that
|
||||
it would be more complicated to go through a programmatic interface than
|
||||
to just create the files with fprintf() and fwrite(). The basic
|
||||
idea behind SDF files is that they are self-describing. That is, they
|
||||
have an ASCII header (human-readable, machine-parseable), which describes
|
||||
the contents of the file. The ascii header may contain explicit
|
||||
values, like:
|
||||
|
||||
float npart = 200000.;
|
||||
int int_npart = 200000;
|
||||
char text[] = "Perhaps a few words about the file's pedigree could go here";
|
||||
|
||||
Notice the similarity to C declarations.
|
||||
|
||||
In addition, the header contains declarations for the binary
|
||||
data that appears immediately after it. The allowed data
|
||||
types are char, short, int, float and double, arrays of same, and
|
||||
structs containing the basic types and arrays. (Multi-dimensional arrays
|
||||
are not supported. Nor are nested structures. But some kinds of two
|
||||
dimensional arrays can be captured by an array of structs, c.f., the
|
||||
'id' vector in .tree files. These limitations may be relaxed in the
|
||||
future.)
|
||||
|
||||
The header is terminated by a comment of the form
|
||||
|
||||
# <anything> SDF-EOH <anything> \n
|
||||
|
||||
That is, any comment containing the string SDF-EOH.
|
||||
The final new-line is the last character of the header. The
|
||||
binary data follows immediately after the new-line character.
|
||||
It is strongly recommended that the terminal comment contain
|
||||
one or more form-feeds (ctrl-L, \f in ANSI, \014 (octal), 0xc (hex),
|
||||
12 (decimal)). That way, 'more' or similar programs can be
|
||||
used on the file without getting confused by the binary data.
|
||||
Similarly, it is strongly recommended that the first line
|
||||
of an SDF file contain the comment:
|
||||
|
||||
# SDF <anything> \n
|
||||
|
||||
This makes it easy for a modified version of 'file', as well as
|
||||
other utilities to figure out that they are dealing with an SDF file.
|
||||
|
||||
Thus, the header for the output of an nbody simulation might look like:
|
||||
|
||||
# SDF
|
||||
float npart;
|
||||
float iter;
|
||||
float time;
|
||||
...
|
||||
char tree_header_text[384];
|
||||
struct {float mass;
|
||||
float x, y, z;
|
||||
char id[4];
|
||||
float vx, vy, vz;
|
||||
} [];
|
||||
# SDF-EOH ^L^L
|
||||
|
||||
This header means that the floats npart, iter, time, etc. are stored
|
||||
as binary data following the header. Then comes a 384 byte character
|
||||
array, followed by an array (of unspecified length) containing the
|
||||
vectors mass, x, y, z, id, vx, vy, vz. Only the last array in the
|
||||
header may be of unspecifiec length. It means that when the file is
|
||||
read, the array is assumed to extend to the end of the file. SDF
|
||||
routines figure out the length of the file by asking the OS, and hence
|
||||
can determine the number of elements in arrays of unspecified length.
|
||||
Specifications with unknown length are useful for creating generic SDF
|
||||
headers, i.e., headers that describe binary files that you may already
|
||||
be using.
|
||||
|
||||
If one were writing out a new SDF file, it is possible to write a
|
||||
header exactly as above, followed by the identical binary data.
|
||||
However, it would be much more convenient to write the "scalar" data
|
||||
as ascii values into the header. A new SDF file might look like:
|
||||
|
||||
# SDF
|
||||
/* Comments may be between C-like comment delimiters */
|
||||
# Or they follow the shell-like comment delimiter to end-of-line
|
||||
# This file was created by dave@h9k.hal.com on January 12, 1992...
|
||||
float npart = 200000.;
|
||||
int int_npart = 200000;
|
||||
float Gnewt = 1.0;
|
||||
float iter = 17.;
|
||||
float masstot = 1.1;
|
||||
float epsilon = 0.02;
|
||||
...
|
||||
struct {float mass;
|
||||
float x, y, z;
|
||||
char id[4];
|
||||
float vx, vy, vz;} [200000];
|
||||
# SDF-EOH ^L^L
|
||||
|
||||
This has the great advantage that most of the file's parameters are
|
||||
now both human-readable and machine-readable. A disadvantage to
|
||||
putting "history" information into comments is that it becomes
|
||||
inaccessable to programs (since SDF doesn't record comments). Another
|
||||
option is to put it in a character string:
|
||||
|
||||
char history[] =
|
||||
"This file created by ... on ...
|
||||
200000 body torqued Jaffe model constructed using:
|
||||
cubix ...
|
||||
";
|
||||
|
||||
Don't bother with C-syntax for newlines, etc in character strings.
|
||||
SDF just scans till it hits another " character. It doesn't do any
|
||||
escape-interpretation, so don't bother with '\n' and especially don't
|
||||
try to put the double-quote character inside strings.
|
||||
|
||||
Byte order is another headache. The function SDFcpubyteorder()
|
||||
returns an unsigned int which "describes" the host-cpu's byte order,
|
||||
in a format which may be placed into an SDF header with the.
|
||||
"parameter byteorder" keyword.
|
||||
|
||||
parameter byteorder = 0x12345678;
|
||||
|
||||
You can make this line in a C program with:
|
||||
fprintf(fp, "parameter byteorder = 0x%x;\n", SDFcpubyteorder());
|
||||
|
||||
If such a parameter is in the header, then SDFread functions will
|
||||
assume that the binary data is written in the file in the byte order
|
||||
specified by the parameter. If the machine doing the reading has a
|
||||
different byte order, then bytes are swapped automatically. If there
|
||||
is no such parameter, you can tell the read functions to swap with
|
||||
SDFswapon(). Similarly, you can turn off swapping (for whatever
|
||||
reason) with SDFswapoff(), and you can inquire about swapping with
|
||||
SDFisswapping();
|
||||
|
||||
Non-ieee floats are completely out of the question. Don't even
|
||||
mention them in my presence.
|
||||
|
||||
Dictionaries
|
||||
------------
|
||||
|
||||
Nbody files contain a number of scalars, and a number of vectors. The
|
||||
names of these objects must be agreed upon between the entity creating
|
||||
the file and the entity reading the file. Since the creators of pjq,
|
||||
tree and tree_ap files could barely agree that the sun rises in the
|
||||
east and sets in the west, I have created a set of names for the items
|
||||
in common amongst these file types. The list is in the file
|
||||
"./dictionary". SDF files name their own contents. It's important
|
||||
that the names continue to agree with the names in ./dictionary.
|
||||
Thus, with the current dictionary it is agreed that the name "npart"
|
||||
refers to a float value equal to the number of bodies in the file.
|
||||
Similarly, the name "masstot" refers to the total mass of the file.
|
||||
These are the strings that you have to pass as names to SDFread routines in
|
||||
order to extract the appropriate values from a file. What you call
|
||||
these quantities inside your program is completely irrelevant, but if
|
||||
you create another SDF file, it's important to use the same names.
|
||||
|
||||
The SDFopen function now takes two char* arguments, one for the
|
||||
filename of the header and one for the data. If they strcmp the same,
|
||||
or if the header is NULL or if the header is "", the descriptor is
|
||||
found at the beginning of the data file. If the name is "-", then
|
||||
stdin is used. If you really must open a file called "-", then you
|
||||
can do it by opening "./-". SDF will not gratuitously do random seeks
|
||||
around the file. In fact, it will struggle mightily to read the file
|
||||
sequentially. In many cases, SDFread will succeed on files that are
|
||||
not seekable. However, there are some requests that simply require
|
||||
rewinding the file. If your program does such a thing, then it MUST
|
||||
be possible to do arbitrary seeks on the data file, so taking stdin
|
||||
from a tty or a pipe would be a bad idea.
|
||||
|
||||
You're supposed to get an error message in SDFerrstring for this (and
|
||||
all other) errors. Segmentation violations are increasingly rare. I'm
|
||||
certain that bugs still remain which will blow SDF right away, but
|
||||
they're getting harder to find every day.
|
2055
external/libsdf/libSDF/SDF-lex.c
vendored
Normal file
2055
external/libsdf/libSDF/SDF-lex.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
139
external/libsdf/libSDF/SDF-lex.l
vendored
Normal file
139
external/libsdf/libSDF/SDF-lex.l
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
%{
|
||||
/*
|
||||
SDF Library for reading Self-Describing Files
|
||||
Copyright (C) 1991,1992 John K. Salmon
|
||||
|
||||
Terms and conditions are specified in the file "copyright.h",
|
||||
and more precisely in the file COPYING.LIB which you should have
|
||||
received with this library.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
/* This define means we don't have to link with the lex library! */
|
||||
#define YY_SKIP_YYWRAP
|
||||
#define yywrap() 1
|
||||
|
||||
/* This one is ugly.
|
||||
Lex's output contains fprintf(yyout, of various error messages.
|
||||
We try here to redirect them to a Msg_doalist. */
|
||||
#include <stdarg.h>
|
||||
#include "Msgs.h"
|
||||
#undef fprintf
|
||||
#define fprintf MYFprintf
|
||||
void MYFprintf(int *junk, const char *fmt, ...){
|
||||
va_list alist;
|
||||
va_start(alist, fmt);
|
||||
Msg_doalist(fmt, alist);
|
||||
va_end(alist);
|
||||
}
|
||||
|
||||
#ifdef FLEX_SCANNER
|
||||
/* Flex DOES have a much better way to handle non-standard input strategies.
|
||||
This doesn't have to be this twisted to work with Flex, but if we are
|
||||
going to continue to support lex, it's easiest to just follow along */
|
||||
#define YY_INPUT(buf, result, maxsize) \
|
||||
{ \
|
||||
int c = SDF_Hdrgetc(); \
|
||||
/* Msgf(("YY_INPUT: c=%c\n", c)); */\
|
||||
result = (c==EOF) ? YY_NULL : (buf[0] = c, 1); \
|
||||
}
|
||||
/* Flex also has some new-and-different behavior AFTER YY_INPUT has returned
|
||||
NULL. In particular, all subsequent calls to yylex will immediately
|
||||
return NULL unless yyrestart is called. If we were always using Flex,
|
||||
I could attach this to the BEGIN rule, but I can't do that with lex,
|
||||
so I have to call it from outside, e.g., in SDFyyprepare. */
|
||||
void SDFlexprepare(void){
|
||||
yyrestart(NULL);
|
||||
}
|
||||
#else /* Not FLEX_SCANNER */
|
||||
void SDFlexprepare(void){}
|
||||
#endif
|
||||
%}
|
||||
White [ \f\t\n]
|
||||
Dig [0-9]
|
||||
Alpha [A-Za-z_]
|
||||
Hex [A-Fa-f0-9]
|
||||
Octal [0-7]
|
||||
Alphanum [A-Za-z0-9_]
|
||||
Expon [Ee]{Sign}{Dig}+
|
||||
Punct "="|"["|"]"|"{"|"}"|";"|","
|
||||
Sign [-+]?
|
||||
%%
|
||||
#.*SDF-EOH.* {SDFlineno++; return EOHDR;} /* Terminate the header on a comment line */
|
||||
#.* {SDFlineno++;} /* Otherwise, skip comments from '#' to eol. */
|
||||
{White} {if(yytext[0] == '\n') SDFlineno++;} /* skip white space. count lines*/
|
||||
"/*" { int c;
|
||||
loop:
|
||||
while((c=input()) != '*') {if(c=='\n') SDFlineno++;}
|
||||
switch(input()){
|
||||
case '/': break;
|
||||
case '*': unput('*');
|
||||
default: goto loop;
|
||||
}
|
||||
} /* Skip normal C comments. (no nesting) */
|
||||
char {yylval.type = SDF_CHAR; return TYPE;}
|
||||
short {yylval.type = SDF_SHORT; return TYPE;}
|
||||
int {yylval.type = SDF_INT; return TYPE;}
|
||||
long {yylval.type = SDF_LONG; return TYPE;}
|
||||
int64_t {yylval.type = SDF_INT64; return TYPE;}
|
||||
float {yylval.type = SDF_FLOAT; return TYPE;}
|
||||
double {yylval.type = SDF_DOUBLE; return TYPE;}
|
||||
struct {return STRUCT;}
|
||||
unsigned ; /* WARNING. The keyword 'unsigned' is skipped entirely. */
|
||||
parameter {return PARAMETER;}
|
||||
byteorder {yylval.valueparam = BYTEORDER; return VALUEPARAM;}
|
||||
{Alpha}{Alphanum}* {yylval.string = Malloc(yyleng+1);
|
||||
strcpy(yylval.string, (char *)yytext);
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("lex-malloc(%d) at 0x%lx\n",
|
||||
yyleng+1, (unsigned long)yylval.string);
|
||||
#endif
|
||||
return NAME;}
|
||||
\"[^"]*\" {
|
||||
/* strings extend to the next double-quote. */
|
||||
/* there are no escapes, and no exceptions. */
|
||||
/* We fiddle with the yyleng so we only get the contents in yylval. */
|
||||
/* Newlines embedded in strings will be missed by SDFlineno! */
|
||||
yylval.constant.u.stringval = Malloc(yyleng-1);
|
||||
strncpy(yylval.constant.u.stringval, (char *)yytext+1, yyleng-2);
|
||||
yylval.constant.u.stringval[yyleng-2] = '\0';
|
||||
yylval.constant.type = SDF_STRING;
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("lex-malloc(%d) = 0x%lx\n", yyleng-1,
|
||||
(unsigned long)yylval.constant.u.stringval);
|
||||
#endif
|
||||
return CONST;}
|
||||
{Sign}{Dig}+"."{Dig}*({Expon})? |
|
||||
{Sign}{Dig}*"."{Dig}+({Expon})? |
|
||||
{Sign}{Dig}+{Expon} {
|
||||
yylval.constant.type = SDF_DOUBLE;
|
||||
sscanf((char *)yytext, "%lf", &yylval.constant.u.doubleval);
|
||||
return CONST;}
|
||||
0x{Hex}+ {
|
||||
yylval.constant.type = SDF_INT64;
|
||||
#if __WORDSIZE==64
|
||||
sscanf((char *)yytext+2, "%lx", &yylval.constant.u.int64val);
|
||||
#else
|
||||
sscanf((char *)yytext+2, "%llx", &yylval.constant.u.int64val);
|
||||
#endif
|
||||
return CONST;}
|
||||
0{Octal}+ {
|
||||
yylval.constant.type = SDF_INT64;
|
||||
#if __WORDSIZE==64
|
||||
sscanf((char *)yytext+1, "%lo", &yylval.constant.u.int64val);
|
||||
#else
|
||||
sscanf((char *)yytext+1, "%llo", &yylval.constant.u.int64val);
|
||||
#endif
|
||||
return CONST;}
|
||||
{Sign}{Dig}+ {
|
||||
yylval.constant.type = SDF_INT64;
|
||||
#if __WORDSIZE==64
|
||||
sscanf((char *)yytext, "%ld", &yylval.constant.u.int64val);
|
||||
#else
|
||||
sscanf((char *)yytext, "%lld", &yylval.constant.u.int64val);
|
||||
#endif
|
||||
return CONST;}
|
||||
{Punct} {return yytext[0];}
|
||||
. {yyerror("lexer confusion on char: <%c>, line: %d\n", (yytext[0])?yytext[0]:'?',
|
||||
SDFlineno); return LEXERROR;}
|
2366
external/libsdf/libSDF/SDF-parse.c
vendored
Normal file
2366
external/libsdf/libSDF/SDF-parse.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
754
external/libsdf/libSDF/SDF-parse.y
vendored
Normal file
754
external/libsdf/libSDF/SDF-parse.y
vendored
Normal file
|
@ -0,0 +1,754 @@
|
|||
%{
|
||||
/*
|
||||
SDF Library for reading Self-Describing Files
|
||||
Copyright (C) 1991,1992 John K. Salmon
|
||||
|
||||
Terms and conditions are specified in the file "copyright.h",
|
||||
and more precisely in the file COPYING.LIB which you should have
|
||||
received with this library.
|
||||
*/
|
||||
|
||||
/* We don't rely on bison's -p argument any more.
|
||||
Instead, just #define the name changes ourselves. These are taken
|
||||
from the beginning of bison -p output. These are far from a complete
|
||||
set of external 'yy' names, as a quick run throug 'nm' will show. Maybe
|
||||
all the others come from lex. I dunno. In any event, the namespace is only
|
||||
partially cleaned up. Perhaps we should apply for Superfund money
|
||||
to finish the cleanup? bison -p does no better.
|
||||
*/
|
||||
#define yyparse SDFyyparse
|
||||
#define yylex SDFyylex
|
||||
#define yyerror SDFyyerror
|
||||
#define yylval SDFyylval
|
||||
#define yychar SDFyychar
|
||||
#define yydebug SDFyydebug
|
||||
#define yynerrs SDFyynerrs
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include "protos.h"
|
||||
#include "Msgs.h"
|
||||
#include "SDF-private.h"
|
||||
#include "obstack.h"
|
||||
#include "Malloc.h"
|
||||
|
||||
#ifndef __DELTA__
|
||||
#define YYDEBUG 1
|
||||
#endif
|
||||
|
||||
#if YYDEBUG
|
||||
/* yacc sends its debug output throught printf. We change that... */
|
||||
#define printf Msg_do /* MUST be after protos.h!!! */
|
||||
#endif
|
||||
|
||||
#ifdef cray
|
||||
/* This wants to be a long on the cray?? */
|
||||
extern long int yydebug;
|
||||
#else
|
||||
extern int yydebug;
|
||||
#endif
|
||||
extern void yyerror(char *fmt, ...);
|
||||
|
||||
|
||||
static enum SDF_type_enum curtype;
|
||||
static blk_descrip_t cur_blk;
|
||||
static int cur_file_offset;
|
||||
static int cur_data_offset;
|
||||
static SDF *cur_hdr;
|
||||
static int no_more_data_blks;
|
||||
static int zero_len_blknum;
|
||||
|
||||
char *SDFtype_names[] = {"notype", "char", "short", "int", "long", "int64_t",
|
||||
"float", "double", "string"};
|
||||
|
||||
int SDFtype_sizes[] = {0, sizeof(char), sizeof(short), sizeof(int), sizeof(long),
|
||||
sizeof(int64_t), sizeof(float), sizeof(double), sizeof(char *)};
|
||||
|
||||
static int do_value_param(enum value_param_enum type, const_t value);
|
||||
static int data_dcl(declaration_t dcl);
|
||||
static int const_dcl(declaration_t dcl, const_list_t consts);
|
||||
static void finish_curblk(void);
|
||||
static const_t convert_const(const_t *cp, enum SDF_type_enum type);
|
||||
static int finish_parse(void);
|
||||
|
||||
%}
|
||||
|
||||
%token STRUCT
|
||||
%token <string> NAME
|
||||
%token <type> TYPE
|
||||
%token <constant> CONST
|
||||
%token <valueparam> VALUEPARAM
|
||||
%token PARAMETER
|
||||
%token EOHDR LEXERROR
|
||||
%token ';' '=' '[' ']' '{' '}' ','
|
||||
%type <declaration> declaration
|
||||
%type <one_dcl> dcl1
|
||||
%type <const_list> const_lst comma_sep_consts
|
||||
%type <dcl_list> comma_sep_dcls typed_dcl_list many_typed_dcl_list
|
||||
%union{
|
||||
enum SDF_type_enum type;
|
||||
enum value_param_enum valueparam;
|
||||
char *string;
|
||||
const_t constant;
|
||||
declaration_t declaration;
|
||||
dcl_list_t dcl_list;
|
||||
one_dcl_t one_dcl;
|
||||
const_list_t const_list;
|
||||
}
|
||||
%%
|
||||
hdr : hdr1 {if(finish_parse()) YYERROR;}
|
||||
| hdr1 EOHDR {if(finish_parse()) YYERROR; else YYACCEPT;}
|
||||
| LEXERROR {YYERROR;}
|
||||
;
|
||||
|
||||
hdr1 : stmt
|
||||
| hdr1 stmt
|
||||
;
|
||||
|
||||
stmt : declaration ';' {if(data_dcl($1)) YYERROR;}
|
||||
| declaration '=' const_lst ';' {if(const_dcl($1, $3)) YYERROR;}
|
||||
| PARAMETER VALUEPARAM '=' CONST ';' {if(do_value_param($2, $4)) YYERROR;}
|
||||
;
|
||||
|
||||
declaration : typed_dcl_list {$$.dcl_list = $1; $$.Nrec = 1;}
|
||||
| STRUCT '{' many_typed_dcl_list ';' '}' {$$.dcl_list=$3; $$.Nrec=1;}
|
||||
| STRUCT '{' many_typed_dcl_list ';' '}' '[' CONST ']'
|
||||
{
|
||||
if( $7.type != SDF_INT64 ){
|
||||
yyerror("Expected integer constant");
|
||||
YYERROR;
|
||||
}else{
|
||||
$$.dcl_list = $3; $$.Nrec = $7.u.int64val;
|
||||
}
|
||||
}
|
||||
| STRUCT '{' many_typed_dcl_list ';' '}' '[' ']'
|
||||
{ $$.dcl_list = $3; $$.Nrec = 0;}
|
||||
;
|
||||
|
||||
many_typed_dcl_list : typed_dcl_list {$$ = $1;}
|
||||
| many_typed_dcl_list ';' typed_dcl_list
|
||||
{
|
||||
int sz;
|
||||
|
||||
$$.ndcl = $1.ndcl + $3.ndcl;
|
||||
$$.obs = $1.obs;
|
||||
sz = obstack_object_size(&$3.obs);
|
||||
(void)obstack_grow(&$$.obs, obstack_finish(&$3.obs), sz);
|
||||
(void)obstack_free(&$3.obs, NULL);
|
||||
}
|
||||
;
|
||||
|
||||
typed_dcl_list: TYPE {curtype = $1;} comma_sep_dcls {$$ = $3;}
|
||||
;
|
||||
|
||||
comma_sep_dcls: dcl1
|
||||
{
|
||||
obstack_begin(&$$.obs, 16*sizeof($1));
|
||||
$$.ndcl = 1;
|
||||
(void)obstack_grow(&$$.obs, &$1, sizeof($1));
|
||||
}
|
||||
| comma_sep_dcls ',' dcl1
|
||||
{
|
||||
$$ = $1;
|
||||
$$.ndcl += 1;
|
||||
(void)obstack_grow(&$$.obs, &$3, sizeof($3));
|
||||
}
|
||||
;
|
||||
|
||||
dcl1 : NAME {$$.name = $1; $$.type = curtype; $$.arrcnt = 1;}
|
||||
| NAME '[' CONST ']'
|
||||
{
|
||||
if( $3.type != SDF_INT64 ){
|
||||
yyerror("Expected integer constant");
|
||||
YYERROR;
|
||||
}else{
|
||||
$$.name = $1; $$.type = curtype; $$.arrcnt = $3.u.int64val;
|
||||
}
|
||||
}
|
||||
| NAME '[' ']' {$$.name=$1; $$.type=curtype; $$.arrcnt = 0;}
|
||||
;
|
||||
|
||||
const_lst : CONST
|
||||
{
|
||||
$$.nconst = 1;
|
||||
obstack_begin(&$$.obs, 16*sizeof($1));
|
||||
(void)obstack_grow(&$$.obs, &$1, sizeof($1));
|
||||
}
|
||||
| '{' comma_sep_consts '}' {$$ = $2;}
|
||||
;
|
||||
|
||||
comma_sep_consts : CONST
|
||||
{
|
||||
$$.nconst = 1;
|
||||
obstack_begin(&$$.obs, 16*sizeof($1));
|
||||
(void)obstack_grow(&$$.obs, &$1, sizeof($1));
|
||||
}
|
||||
| comma_sep_consts ',' CONST
|
||||
{
|
||||
$$ = $1;
|
||||
$$.nconst += 1;
|
||||
(void)obstack_grow(&$$.obs, &$3, sizeof($3));
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
static int SDFlineno;
|
||||
|
||||
static const char *Dataname, *Hdrname;
|
||||
|
||||
#ifdef STANDALONE
|
||||
char SDFerrstring[512];
|
||||
unsigned int SDFcpubyteorder(void){return 0;}
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
SDF hdr;
|
||||
|
||||
if(argc > 1){
|
||||
yydebug = 1;
|
||||
}else{
|
||||
yydebug = 0;
|
||||
}
|
||||
SDFyyprepare(&hdr, "-", "-");
|
||||
if(yyparse()){
|
||||
printf("Terminated on error. \n");
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int SDF_iomode = MPMY_RDONLY | MPMY_MULTI;
|
||||
|
||||
void SDFsetiomode(int mode)
|
||||
{
|
||||
if (mode == SDF_SINGL) {
|
||||
SDF_iomode = MPMY_RDONLY | MPMY_SINGL;
|
||||
} else {
|
||||
SDF_iomode = MPMY_RDONLY | MPMY_MULTI;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SDFyyerror(char *fmt, ...)
|
||||
{
|
||||
char *p;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(SDFerrstring, fmt, ap);
|
||||
p = SDFerrstring + strlen(SDFerrstring);
|
||||
sprintf(p, " lineno = %d\n", SDFlineno);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
int SDFyyprepare(SDF *hdr, const char *hdrname, const char *dataname)
|
||||
{
|
||||
no_more_data_blks = 0;
|
||||
|
||||
cur_file_offset = 0;
|
||||
cur_data_offset = 0;
|
||||
|
||||
cur_blk.Nrec = 1;
|
||||
cur_blk.inmem = 1;
|
||||
cur_blk.begin_offset = 0;
|
||||
cur_blk.reclen = 0;
|
||||
|
||||
cur_hdr = hdr;
|
||||
cur_hdr->nblks = 0;
|
||||
cur_hdr->nvecs = 0;
|
||||
/* Assume that MPMY_Fopen does the 'right' thing with "-" */
|
||||
if( SDF_Hdropen(hdrname) < 0 ){
|
||||
sprintf(SDFerrstring, "SDFopen: could not open %s\n", hdrname);
|
||||
return -1;
|
||||
}
|
||||
Dataname = dataname;
|
||||
Hdrname = hdrname;
|
||||
SDFlineno = 0; /* or 1? It's always +-1 anyway */
|
||||
SDFlexprepare();
|
||||
|
||||
obstack_begin(&cur_hdr->blks_obs, 16*sizeof(blk_descrip_t));
|
||||
obstack_begin(&cur_hdr->vecs_obs, 32*sizeof(vec_descrip_t));
|
||||
obstack_begin(&cur_hdr->data_obs, 2048);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int finish_parse(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
finish_curblk();
|
||||
cur_hdr->blks = (blk_descrip_t *)obstack_finish(&cur_hdr->blks_obs);
|
||||
cur_hdr->vecs = (vec_descrip_t *)obstack_finish(&cur_hdr->vecs_obs);
|
||||
cur_hdr->data = obstack_finish(&cur_hdr->data_obs);
|
||||
cur_hdr->vec_names = Malloc(cur_hdr->nvecs * sizeof(char *));
|
||||
for(i=0; i<cur_hdr->nvecs; i++){
|
||||
cur_hdr->vec_names[i] = cur_hdr->vecs[i].name;
|
||||
}
|
||||
|
||||
if( (Dataname == NULL) || (Dataname[0] == '\0')
|
||||
|| (strcmp(Hdrname, Dataname)==0)){
|
||||
cur_hdr->begin_file_offset = SDF_Hdroffset();
|
||||
if( cur_hdr->begin_file_offset < 0 ){
|
||||
yyerror("Can't get offset of end of header\n");
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
cur_hdr->begin_file_offset = 0;
|
||||
}
|
||||
SDF_Hdrclose();
|
||||
|
||||
/* cur_hdr->datafp = MPMY_Fopen(Dataname, MPMY_RDONLY); */
|
||||
/* If we come up with a better model for IO, call it here.. */
|
||||
cur_hdr->datafp = MPMY_Fopen(Dataname, SDF_iomode);
|
||||
|
||||
Msgf(("cur_hdr->datafp = %p\n", cur_hdr->datafp));
|
||||
|
||||
if( cur_hdr->datafp == NULL ){
|
||||
sprintf(SDFerrstring, "SDFopen: could not open data file: %s\n",
|
||||
Dataname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(no_more_data_blks){
|
||||
blk_descrip_t *zerolenblk;
|
||||
off_t bytesleft, recsleft;
|
||||
off_t datalen;
|
||||
|
||||
zerolenblk = &cur_hdr->blks[zero_len_blknum];
|
||||
if(zerolenblk->Nrec != 0){
|
||||
yyerror("Zero length block has non-zero length!?\n");
|
||||
return -1;
|
||||
}
|
||||
if( cur_hdr->begin_file_offset < 0 ){
|
||||
yyerror("Can't have zero-len blk in an unseekable file\n");
|
||||
return -1;
|
||||
}
|
||||
Msgf(("About to call MPMY_Flen\n"));
|
||||
if( (datalen = MPMY_Flen(cur_hdr->datafp)) < 0 ){
|
||||
yyerror("Could not get length of data file.\n");
|
||||
return -1;
|
||||
}
|
||||
bytesleft = datalen
|
||||
- (zerolenblk->begin_offset + cur_hdr->begin_file_offset);
|
||||
Msgf(("datalen = %ld, butesleft = %ld\n",
|
||||
(long)datalen, (long)bytesleft));
|
||||
if( bytesleft < 0 ){
|
||||
yyerror("File too short.\n");
|
||||
return -1;
|
||||
}
|
||||
recsleft = bytesleft/zerolenblk->reclen;
|
||||
if( recsleft*zerolenblk->reclen != bytesleft ){
|
||||
printf("datalen is %ld, bytesleft is %ld\n", (long)datalen, (long)bytesleft);
|
||||
yyerror("File ends between record boundaries\n");
|
||||
return -1;
|
||||
}
|
||||
zerolenblk->Nrec = recsleft;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_value_param(enum value_param_enum param, const_t value)
|
||||
{
|
||||
switch(param){
|
||||
case BYTEORDER:
|
||||
if( value.type != SDF_INT64 )
|
||||
return -1;
|
||||
cur_hdr->byteorder = value.u.int64val;
|
||||
cur_hdr->swapping = (cur_hdr->byteorder != SDFcpubyteorder());
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int data_dcl(declaration_t dcl)
|
||||
{
|
||||
dcl_list_t *dcl_list;
|
||||
one_dcl_t *base, *dclp;
|
||||
int i, offset;
|
||||
vec_descrip_t vec_descrip;
|
||||
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("Declaration of %ld records:\n", dcl.Nrec);
|
||||
#endif
|
||||
if(no_more_data_blks){
|
||||
yyerror("You can't have data following an implicit-length dcl.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test to see if we can append this dcl to the current */
|
||||
/* block. */
|
||||
if(cur_blk.inmem || cur_blk.Nrec != 1 || dcl.Nrec != 1){
|
||||
finish_curblk();
|
||||
cur_blk.Nrec = dcl.Nrec;
|
||||
cur_blk.reclen = 0;
|
||||
cur_blk.inmem = 0;
|
||||
cur_blk.begin_offset = cur_file_offset;
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("New block (%d) at offset %d in file\n",
|
||||
cur_hdr->nblks, cur_file_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(dcl.Nrec == 0){
|
||||
no_more_data_blks = 1;
|
||||
zero_len_blknum = cur_hdr->nblks;
|
||||
}
|
||||
|
||||
offset = cur_blk.reclen;
|
||||
|
||||
dcl_list = &dcl.dcl_list;
|
||||
base = (one_dcl_t *)obstack_base(&dcl_list->obs);
|
||||
for(i=0; i<dcl_list->ndcl; i++){
|
||||
dclp = &base[i];
|
||||
vec_descrip.name = dclp->name;
|
||||
vec_descrip.arrcnt = dclp->arrcnt;
|
||||
vec_descrip.type = dclp->type;
|
||||
vec_descrip.blk_off = offset;
|
||||
vec_descrip.blk_num = cur_hdr->nblks;
|
||||
vec_descrip.nread = 0;
|
||||
offset += SDFtype_sizes[dclp->type] * dclp->arrcnt;
|
||||
cur_hdr->nvecs++;
|
||||
(void)obstack_grow(&cur_hdr->vecs_obs,
|
||||
&vec_descrip, sizeof(vec_descrip));
|
||||
#if YYDEBUG
|
||||
if(yydebug){
|
||||
printf("\t %s %s[%d]", SDFtype_names[dclp->type], dclp->name,
|
||||
dclp->arrcnt);
|
||||
printf(" in block %ld at offset %ld\n",
|
||||
vec_descrip.blk_num, vec_descrip.blk_off);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
(void)obstack_free(&dcl_list->obs, NULL);
|
||||
cur_blk.reclen = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void finish_curblk(void)
|
||||
{
|
||||
cur_hdr->nblks++;
|
||||
(void)obstack_grow(&cur_hdr->blks_obs, &cur_blk, sizeof(cur_blk));
|
||||
if(cur_blk.inmem){
|
||||
cur_data_offset += cur_blk.reclen * cur_blk.Nrec;
|
||||
}else{
|
||||
cur_file_offset += cur_blk.reclen * cur_blk.Nrec;
|
||||
}
|
||||
}
|
||||
|
||||
static int const_dcl(declaration_t dcl, const_list_t consts)
|
||||
{
|
||||
dcl_list_t *dcl_list;
|
||||
one_dcl_t *dclbase, *dclp;
|
||||
const_t *cp, *cbase, converted;
|
||||
vec_descrip_t vec_descrip;
|
||||
int i, j, k;
|
||||
int offset;
|
||||
void *to;
|
||||
|
||||
dcl_list = &dcl.dcl_list;
|
||||
if(dcl.Nrec == 0){
|
||||
dcl.Nrec = consts.nconst;
|
||||
#if 0 /* Was it really this easy?? */
|
||||
yyerror("Cannot deal with implicit length constant dcls.");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Test to see if we can append this dcl to the current */
|
||||
/* block. */
|
||||
if(!cur_blk.inmem || cur_blk.Nrec != 1 || dcl.Nrec != 1){
|
||||
finish_curblk();
|
||||
cur_blk.Nrec = dcl.Nrec;
|
||||
cur_blk.reclen = 0;
|
||||
cur_blk.inmem = 1;
|
||||
cur_blk.begin_offset = cur_data_offset;
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("New block (%d) at offset %d in data\n",
|
||||
cur_hdr->nblks, cur_data_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
offset = cur_blk.reclen;
|
||||
cbase = (const_t *)obstack_base(&consts.obs);
|
||||
dclbase = (one_dcl_t *)obstack_base(&dcl_list->obs);
|
||||
|
||||
for(i=0; i<dcl_list->ndcl; i++){
|
||||
dclp = &dclbase[i];
|
||||
if(dclp->arrcnt == 0){
|
||||
if(dclp->type == SDF_CHAR
|
||||
&& cbase[i].type == SDF_STRING
|
||||
&& dcl.Nrec == 1){
|
||||
dclp->arrcnt = strlen(cbase[i].u.stringval)+1;
|
||||
/* Round up for padding purposes. */
|
||||
dclp->arrcnt = (dclp->arrcnt + 7)& (~0x7);
|
||||
}else if(i == dcl_list->ndcl-1 && dcl.Nrec == 1){
|
||||
dclp->arrcnt = consts.nconst - i;
|
||||
}else{
|
||||
yyerror("Can't figure out implicit dcl from context.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
vec_descrip.name = dclp->name;
|
||||
vec_descrip.arrcnt = dclp->arrcnt;
|
||||
vec_descrip.type = dclp->type;
|
||||
vec_descrip.blk_off = offset;
|
||||
vec_descrip.blk_num = cur_hdr->nblks;
|
||||
vec_descrip.nread = 0;
|
||||
offset += SDFtype_sizes[dclp->type] * dclp->arrcnt;
|
||||
cur_hdr->nvecs++;
|
||||
(void)obstack_grow(&cur_hdr->vecs_obs,
|
||||
&vec_descrip, sizeof(vec_descrip));
|
||||
#if YYDEBUG
|
||||
if(yydebug){
|
||||
printf("\t %s %s[%d]", SDFtype_names[dclp->type], dclp->name,
|
||||
dclp->arrcnt);
|
||||
printf(" in block %ld at offset %ld\n",
|
||||
vec_descrip.blk_num, vec_descrip.blk_off);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
cur_blk.reclen = offset;
|
||||
|
||||
cp = cbase;
|
||||
for(i=0; i<dcl.Nrec; i++){
|
||||
for(j=0; j<dcl_list->ndcl; j++){
|
||||
dclp = &dclbase[j];
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("\t %s %s[%d] (%d) = ",
|
||||
SDFtype_names[dclp->type], dclp->name,
|
||||
dclp->arrcnt, i);
|
||||
#endif
|
||||
if( dclp->type == SDF_CHAR && cp->type == SDF_STRING){
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("\"%s\"\n", cp->u.stringval);
|
||||
#endif
|
||||
to = obstack_next_free(&cur_hdr->data_obs);
|
||||
(void)obstack_blank(&cur_hdr->data_obs, dclp->arrcnt);
|
||||
/* Should we warn
|
||||
if strlen(cp->u.stringval) > dclp->arrcnt ????
|
||||
It implies that the 'string' won't be null-terminated? */
|
||||
(void)strncpy(to, cp->u.stringval, dclp->arrcnt);
|
||||
#ifdef YYDEBUG
|
||||
if(yydebug)
|
||||
printf("Freeing const string 0x%lx\n",
|
||||
(unsigned long)cp->u.stringval);
|
||||
#endif
|
||||
Free(cp->u.stringval);
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
for(k=0; k<dclp->arrcnt; k++){
|
||||
converted = convert_const(cp, dclp->type);
|
||||
if(converted.type == SDF_NOTYPE){
|
||||
yyerror("Failed constant conversion.");
|
||||
return -1;
|
||||
}
|
||||
(void)obstack_grow(&cur_hdr->data_obs, &converted.u,
|
||||
SDFtype_sizes[converted.type]);
|
||||
|
||||
#ifdef YYDEBUG
|
||||
if(yydebug){
|
||||
printf("(%s)", SDFtype_names[cp->type]);
|
||||
switch(converted.type){
|
||||
case SDF_CHAR:
|
||||
printf("%c", converted.u.charval);
|
||||
break;
|
||||
case SDF_SHORT:
|
||||
printf("%d", converted.u.shortval);
|
||||
break;
|
||||
case SDF_INT:
|
||||
printf("%d", converted.u.intval);
|
||||
break;
|
||||
case SDF_LONG:
|
||||
printf("%ld", converted.u.longval);
|
||||
break;
|
||||
case SDF_INT64:
|
||||
#if __WORDSIZE==64
|
||||
printf("%ld", converted.u.int64val);
|
||||
#else
|
||||
printf("%lld", converted.u.int64val);
|
||||
#endif
|
||||
break;
|
||||
case SDF_FLOAT:
|
||||
printf("%.7g", converted.u.floatval);
|
||||
break;
|
||||
case SDF_DOUBLE:
|
||||
printf("%.17g", converted.u.doubleval);
|
||||
break;
|
||||
default:
|
||||
printf("Unrecognized type: %d\n", converted.type);
|
||||
break;
|
||||
}
|
||||
if(k == dclp->arrcnt-1){
|
||||
printf("\n");
|
||||
}else{
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)obstack_free(&dcl_list->obs, NULL);
|
||||
(void)obstack_free(&consts.obs, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const_t convert_const(const_t *cp, enum SDF_type_enum newtype)
|
||||
/* Return a constant of type NEWTYPE, with the same value as */
|
||||
/* *CP. If the conversion does not preserve value, then */
|
||||
/* return a constant of NOTYPE, with garbage value. */
|
||||
{
|
||||
const_t value;
|
||||
double dval = 0.;
|
||||
int64_t ival = 0;
|
||||
|
||||
if(cp->type == newtype){
|
||||
/* IRIX -32 bug fix */
|
||||
memcpy(&value, cp, sizeof(value));
|
||||
/* value = *cp; */
|
||||
return value;
|
||||
}
|
||||
|
||||
if(cp->type == SDF_STRING || newtype == SDF_STRING){
|
||||
value.type = SDF_NOTYPE;
|
||||
yyerror("Cannot do const conversions with strings.\n");
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Now rely on the fact that a double can faithfully hold */
|
||||
/* any other arithmetic type (except long ints on 64-bit archs). */
|
||||
switch(cp->type){
|
||||
case SDF_CHAR:
|
||||
dval = (double)cp->u.charval;
|
||||
break;
|
||||
case SDF_SHORT:
|
||||
dval = (double)cp->u.shortval;
|
||||
break;
|
||||
case SDF_INT:
|
||||
dval = (double)cp->u.intval;
|
||||
ival = cp->u.intval;
|
||||
break;
|
||||
case SDF_LONG:
|
||||
dval = (double)cp->u.longval;
|
||||
ival = cp->u.longval;
|
||||
break;
|
||||
case SDF_INT64:
|
||||
dval = (double)cp->u.int64val;
|
||||
ival = cp->u.int64val;
|
||||
break;
|
||||
case SDF_FLOAT:
|
||||
dval = cp->u.floatval;
|
||||
break;
|
||||
case SDF_DOUBLE:
|
||||
dval = cp->u.doubleval;
|
||||
break;
|
||||
default:
|
||||
dval = 0.0;
|
||||
yyerror("Cannot do const conversions with strings.\n");
|
||||
}
|
||||
|
||||
value.type = newtype;
|
||||
switch(newtype){
|
||||
case SDF_CHAR:
|
||||
value.u.charval = (char)dval;
|
||||
if( value.u.charval != dval ){
|
||||
yyerror("Can't fit value into char.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
case SDF_SHORT:
|
||||
value.u.shortval = (short)dval;
|
||||
if( value.u.shortval != dval ){
|
||||
yyerror("Can't fit value into short.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
case SDF_INT:
|
||||
value.u.intval = (int)dval;
|
||||
if( value.u.intval != dval ){
|
||||
value.u.intval = ival;
|
||||
if( value.u.intval != ival ){
|
||||
yyerror("Can't fit value into int.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDF_LONG:
|
||||
value.u.longval = (long)dval;
|
||||
if( value.u.longval != dval ){
|
||||
value.u.longval = ival;
|
||||
if( value.u.longval != ival ){
|
||||
yyerror("Can't fit value into long.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDF_INT64:
|
||||
value.u.int64val = (int64_t)dval;
|
||||
if( value.u.int64val != dval ){
|
||||
value.u.int64val = ival;
|
||||
if( value.u.int64val != ival ){
|
||||
yyerror("Can't fit value into int64_t.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDF_FLOAT:
|
||||
if(dval > FLT_MAX || dval < -FLT_MAX){
|
||||
yyerror("Can't fit value into float.");
|
||||
value.type = SDF_NOTYPE;
|
||||
}
|
||||
value.u.floatval = dval;
|
||||
break;
|
||||
case SDF_DOUBLE:
|
||||
value.u.doubleval = dval;
|
||||
break;
|
||||
default:
|
||||
yyerror("Impossible case.\n");
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void *SDFobstack_chunk_alloc(size_t n)
|
||||
{
|
||||
void *p = Malloc(n);
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("malloc(%ld) = 0x%lx\n", (long)n, (unsigned long)p);
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
void SDFobstack_chunk_free(void *p)
|
||||
{
|
||||
#if YYDEBUG
|
||||
if(yydebug)
|
||||
printf("free(0x%lx)\n", (unsigned long)p);
|
||||
#endif
|
||||
Free(p);
|
||||
}
|
||||
|
||||
/* This symbol tells a Flex-based scanner not to bother trying to
|
||||
call isatty to figure out whether to do char-at-a-time input. The
|
||||
actual behavior is under our explicit control anyway (see SDF-lex.l),
|
||||
but linking against fileno() and isatty() can be annoying. */
|
||||
#define YY_ALWAYS_INTERACTIVE 1
|
||||
#include "SDF-lex.c"
|
119
external/libsdf/libSDF/SDF-private.h
vendored
Normal file
119
external/libsdf/libSDF/SDF-private.h
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
SDF Library for reading Self-Describing Files
|
||||
Copyright (C) 1991,1992 John K. Salmon
|
||||
|
||||
Terms and conditions are specified in the file "copyright.h",
|
||||
and more precisely in the file COPYING.LIB which you should have
|
||||
received with this library.
|
||||
*/
|
||||
#ifndef sdfprivateDOTh
|
||||
#define sdfprivateDOTh
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include "stdio.h" /* from this directory!! */
|
||||
#include "obstack.h"
|
||||
|
||||
/* Exact copy of declaration in SDF.h */
|
||||
enum SDF_type_enum{SDF_NOTYPE,
|
||||
SDF_CHAR,
|
||||
SDF_SHORT,
|
||||
SDF_INT,
|
||||
SDF_LONG,
|
||||
SDF_INT64,
|
||||
SDF_FLOAT,
|
||||
SDF_DOUBLE,
|
||||
SDF_STRING};
|
||||
|
||||
extern char SDFerrstring[];
|
||||
|
||||
enum toggle_param_enum{NOTHING};
|
||||
|
||||
enum value_param_enum{BYTEORDER};
|
||||
|
||||
/* How the lexical analyzer returns constants. */
|
||||
typedef struct{
|
||||
enum SDF_type_enum type;
|
||||
union{
|
||||
char charval;
|
||||
short shortval;
|
||||
int intval;
|
||||
long longval;
|
||||
int64_t int64val;
|
||||
float floatval;
|
||||
double doubleval;
|
||||
char *stringval;
|
||||
} u;
|
||||
} const_t;
|
||||
|
||||
typedef struct{
|
||||
int nconst;
|
||||
struct obstack obs;
|
||||
} const_list_t;
|
||||
|
||||
typedef struct{
|
||||
char *name;
|
||||
enum SDF_type_enum type;
|
||||
int arrcnt;
|
||||
} one_dcl_t;
|
||||
|
||||
typedef struct{
|
||||
int ndcl;
|
||||
struct obstack obs;
|
||||
} dcl_list_t;
|
||||
|
||||
typedef struct{
|
||||
dcl_list_t dcl_list;
|
||||
int64_t Nrec;
|
||||
} declaration_t;
|
||||
|
||||
typedef struct{
|
||||
char *name;
|
||||
enum SDF_type_enum type;
|
||||
int arrcnt;
|
||||
int64_t blk_off;
|
||||
int64_t blk_num;
|
||||
int64_t nread;
|
||||
} vec_descrip_t;
|
||||
|
||||
typedef struct{
|
||||
int reclen;
|
||||
int inmem;
|
||||
int64_t Nrec;
|
||||
int64_t begin_offset;
|
||||
} blk_descrip_t;
|
||||
|
||||
typedef struct{
|
||||
int nblks;
|
||||
struct obstack blks_obs;
|
||||
blk_descrip_t *blks;
|
||||
int nvecs;
|
||||
struct obstack vecs_obs;
|
||||
vec_descrip_t *vecs;
|
||||
char **vec_names;
|
||||
struct obstack data_obs;
|
||||
void *data;
|
||||
MPMYFile *datafp;
|
||||
int64_t begin_file_offset;
|
||||
int byteorder;
|
||||
int swapping;
|
||||
int hashsz;
|
||||
vec_descrip_t **hashtbl;
|
||||
} SDF;
|
||||
|
||||
void SDFlexprepare(void);
|
||||
int SDFyyprepare(SDF *hdr, const char *hdrname, const char *dataname);
|
||||
void SDFobstack_chunk_free(void *p);
|
||||
void *SDFobstack_chunk_alloc(size_t n);
|
||||
|
||||
int SDF_Hdropen(const char *name);
|
||||
void SDF_Hdrclose(void);
|
||||
int SDF_Hdroffset(void);
|
||||
int SDF_Hdrgetc();
|
||||
|
||||
#define obstack_chunk_alloc SDFobstack_chunk_alloc
|
||||
#define obstack_chunk_free SDFobstack_chunk_free
|
||||
|
||||
#include "SDF.h"
|
||||
|
||||
|
||||
#endif /* sdfprivateDOTh */
|
941
external/libsdf/libSDF/SDFfuncs.c
vendored
Normal file
941
external/libsdf/libSDF/SDFfuncs.c
vendored
Normal file
|
@ -0,0 +1,941 @@
|
|||
/*
|
||||
SDF Library for reading Self-Describing Files
|
||||
Copyright (C) 1991,1992 John K. Salmon
|
||||
|
||||
Terms and conditions are specified in the file "copyright.h",
|
||||
and more precisely in the file COPYING.LIB which you should have
|
||||
received with this library.
|
||||
*/
|
||||
/* Implement the user-visible functions that make up the */
|
||||
/* SDF package. */
|
||||
|
||||
/* Using alloca reduces memory fragmentation, and allows the halo */
|
||||
/* finder to work on larger datasets */
|
||||
#define USE_ALLOCA
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#ifdef USE_ALLOCA
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#include "Msgs.h"
|
||||
#include "stdio.h" /* for sprintf, etc. No 'real' stdio */
|
||||
#include "SDF-private.h"
|
||||
#include "obstack.h"
|
||||
#include "byteswap.h"
|
||||
#include "Malloc.h"
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
#include "mpmy_io.h"
|
||||
|
||||
/* max_bufsz is the maximum read-buffer that we will attempt to
|
||||
malloc. The code in rdvecs is capable of requesting arbitrarily
|
||||
large blocks and scaling back (in powers of 2) until malloc returns
|
||||
non-NULL. That doesn't seem like a good idea on virtual systems,
|
||||
though, so the maximum first attempt is dynamically settable with
|
||||
SDFsetmaxbufsz. Setting it to zero will remove the limit. This is
|
||||
the initial value. */
|
||||
#define DEFAULT_MAX_BUFSZ (256LL*1024*1024)
|
||||
|
||||
static void buildhash(SDF *hdr);
|
||||
static vec_descrip_t *lookup(const char *name, SDF *hdr);
|
||||
static int compar_func(const void *p1, const void *p2);
|
||||
static vec_descrip_t **compar_vds;
|
||||
static unsigned char junk[4] = {0x12, 0x34, 0x56, 0x78};
|
||||
static unsigned int *cpubyteorder = (unsigned int *)&junk[0];
|
||||
static int max_bufsz = DEFAULT_MAX_BUFSZ;
|
||||
|
||||
char SDFerrstring[256];
|
||||
extern int SDFyyparse(void);
|
||||
|
||||
/* This is a non-guaranteed way to test if a file is SDF or not. */
|
||||
/* It really only tests the initial comment! This is not fail-safe! */
|
||||
int SDFissdf(const char *name){
|
||||
MPMYFile *fp;
|
||||
int result = 1;
|
||||
int c;
|
||||
char buf[64];
|
||||
int bufcnt = 0;
|
||||
|
||||
if( MPMY_Initialized() == 0 ){
|
||||
MPMY_Init(0, NULL);
|
||||
}
|
||||
/* Assume we do the 'right' thing with "-" */
|
||||
/* but what IS the right thing?? (see below) */
|
||||
fp = MPMY_Fopen(name, MPMY_RDONLY | MPMY_SINGL | MPMY_IOZERO);
|
||||
if( fp == NULL )
|
||||
return 0;
|
||||
|
||||
buf[bufcnt] = 0; /* In case read returns nothing */
|
||||
MPMY_Fread(buf, 1, 64, fp);
|
||||
if( (c=buf[bufcnt++]) != '#' ){ result=0; goto done;}
|
||||
while( isspace(c = buf[bufcnt++]) && c != '\n' );
|
||||
if( c == '\n' ) { result=0; goto done; }
|
||||
if( c != 'S' ) { result=0; goto done; }
|
||||
if( buf[bufcnt++] != 'D' ) { result=0; goto done; }
|
||||
if( buf[bufcnt++] != 'F' ) { result=0; goto done; }
|
||||
done:
|
||||
MPMY_Fclose(fp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SDF *SDFopen(const char *hdrfname, const char *datafname)
|
||||
{
|
||||
SDF *hdr;
|
||||
int parseerr;
|
||||
|
||||
/* Is this a good idea? Does it promote sloppy programming? Or does
|
||||
it allow a program that has no interest in MPMY to behave as
|
||||
expected? Or does it belong in MPMY_Fopen instead? */
|
||||
if( MPMY_Initialized() == 0 ){
|
||||
MPMY_Init(0, NULL);
|
||||
}
|
||||
|
||||
if( datafname == NULL ){
|
||||
sprintf(SDFerrstring, "SDFopen: NULL data file %s\n", datafname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hdr = Calloc(1, sizeof(SDF));
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFopen: could not calloc space for hdr\n");
|
||||
return NULL;
|
||||
}
|
||||
/* Handle the case of only one name in the arg list. */
|
||||
/* Don't worry about which one it is. Is this right? */
|
||||
if( hdrfname == NULL || hdrfname[0] == '\0' )
|
||||
hdrfname = datafname;
|
||||
if( datafname == NULL || datafname[0] == '\0' )
|
||||
datafname = hdrfname;
|
||||
|
||||
Msgf(("SDFopen: Calling SDFyyprepare(ptr, hdr=%s, data=%s)\n", hdrfname, datafname));
|
||||
if( SDFyyprepare(hdr, hdrfname, datafname) < 0 ){
|
||||
/* Hopefully, errstring was already set... */
|
||||
Free(hdr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parseerr= SDFyyparse();
|
||||
|
||||
if(parseerr){
|
||||
/* Try to free up whatever's been allocated inside the hdr */
|
||||
SDFclose(hdr);
|
||||
return NULL;
|
||||
}else{
|
||||
Msgf(("SDFopen: SDFyyparse completed ok\n"));
|
||||
/* buildhash belongs in SDF_finishparse, but then I'd need to add
|
||||
a bunch more externals... Yuck. */
|
||||
buildhash(hdr);
|
||||
return hdr;
|
||||
}
|
||||
}
|
||||
|
||||
int SDFclose(SDF *hdr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFclose: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
/* The check here is necessary in case we are trying to bail */
|
||||
/* out from inside SDFopen on a parse error. Cleaning up the */
|
||||
/* mess after a parse error still needs work! */
|
||||
if( hdr->vecs ){
|
||||
for(i=0; i<hdr->nvecs; i++){
|
||||
Free(hdr->vecs[i].name);
|
||||
}
|
||||
}
|
||||
obstack_free(&hdr->blks_obs, NULL);
|
||||
obstack_free(&hdr->vecs_obs, NULL);
|
||||
obstack_free(&hdr->data_obs, NULL);
|
||||
if( hdr->vec_names )
|
||||
Free(hdr->vec_names);
|
||||
if( hdr->datafp )
|
||||
MPMY_Fclose(hdr->datafp);
|
||||
if( hdr->hashtbl )
|
||||
Free(hdr->hashtbl);
|
||||
Free(hdr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDFnvecs(SDF *hdr)
|
||||
{
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFnvecs: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
return hdr->nvecs;
|
||||
}
|
||||
|
||||
int SDFseekable(SDF *hdr)
|
||||
{
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseekable: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
return (MPMY_Fseek(hdr->datafp, 0, MPMY_SEEK_CUR) >= 0);
|
||||
}
|
||||
|
||||
int SDFhasname(const char *name, SDF *hdr)
|
||||
{
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFhasname: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
return (lookup(name, hdr)) ? 1 : 0;
|
||||
}
|
||||
|
||||
char **SDFvecnames(SDF *hdr)
|
||||
{
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFvecnames: not an SDF hdr\n");
|
||||
return NULL;
|
||||
}
|
||||
return hdr->vec_names;
|
||||
}
|
||||
|
||||
int64_t SDFnrecs(const char *name, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFnrecs: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc)
|
||||
return hdr->blks[desc->blk_num].Nrec;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDFarrcnt(const char *name, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFarrcnt: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc)
|
||||
return desc->arrcnt;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum SDF_type_enum SDFtype(const char *name, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFtype: not an SDF hdr\n");
|
||||
return SDF_NOTYPE;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc)
|
||||
return desc->type;
|
||||
else
|
||||
return SDF_NOTYPE;
|
||||
}
|
||||
|
||||
int SDFtell(const char *name, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFtell: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc)
|
||||
return desc->nread;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SDFseek(const char *name, int64_t offset, int whence, SDF *hdr)
|
||||
{
|
||||
vec_descrip_t *desc;
|
||||
int64_t nrec;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseek: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc == NULL)
|
||||
return -1;
|
||||
|
||||
switch(whence){
|
||||
case SDF_SEEK_SET:
|
||||
desc->nread = offset;
|
||||
break;
|
||||
case SDF_SEEK_CUR:
|
||||
desc->nread += offset;
|
||||
break;
|
||||
case SDF_SEEK_END:
|
||||
nrec = hdr->blks[desc->blk_num].Nrec ;
|
||||
if(nrec == 0)
|
||||
return -1;
|
||||
desc->nread = nrec + offset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SDFfileoffset and SDFfilestride are for those who think they */
|
||||
/* can outsmart SDF*rdvecs*. They tell you the offset of the FIRST */
|
||||
/* element of NAME in the file, and the stride between successive */
|
||||
/* elements. They do not pay any attention to the current seek pointer. */
|
||||
/* We do not provide SDFfilefp because we don't want you to mess with */
|
||||
/* our file pointer. Open the file yourself if you're so smart... */
|
||||
int64_t SDFfileoffset(const char *name, SDF *hdr){
|
||||
vec_descrip_t *desc;
|
||||
blk_descrip_t *blk;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFfileoffset: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
if( hdr->begin_file_offset < 0 ){
|
||||
sprintf(SDFerrstring, "SDFfileoffset: unseekable file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
desc = lookup(name, hdr);
|
||||
if(desc == NULL)
|
||||
return -1;
|
||||
blk = &hdr->blks[desc->blk_num];
|
||||
if( blk->inmem ){
|
||||
sprintf(SDFerrstring, "SDFfileoffset: %s not in data segment\n", name);
|
||||
return -1;
|
||||
}
|
||||
return blk->begin_offset + desc->blk_off + hdr->begin_file_offset;
|
||||
}
|
||||
|
||||
int64_t SDFfilestride(const char *name, SDF *hdr){
|
||||
vec_descrip_t *desc;
|
||||
blk_descrip_t *blk;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFfilestride: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
desc = lookup(name, hdr);
|
||||
if(desc == NULL)
|
||||
return -1;
|
||||
blk = &hdr->blks[desc->blk_num];
|
||||
if( blk->inmem ){
|
||||
sprintf(SDFerrstring, "SDFfilestride: %s not in data segment\n", name);
|
||||
return -1;
|
||||
}
|
||||
return blk->reclen;
|
||||
}
|
||||
|
||||
unsigned int SDFcpubyteorder(void){
|
||||
return *cpubyteorder;
|
||||
}
|
||||
|
||||
unsigned int SDFbyteorder(SDF *hdr){
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFbyteorder: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
/* This is either 0 or the value set by a 'parameter byteorder=' stmt */
|
||||
return hdr->byteorder;
|
||||
}
|
||||
|
||||
int SDFswap(SDF *hdr){
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFswap: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
hdr->swapping = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDFnoswap(SDF *hdr){
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFnoswap: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
hdr->swapping = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDFisswapping(SDF *hdr){
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFisswapping: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
return hdr->swapping;
|
||||
}
|
||||
|
||||
int SDFsetmaxbufsz(int new){
|
||||
int ret = max_bufsz;
|
||||
max_bufsz = new;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFrdvecs(SDF *hdr, ...
|
||||
/* char *name, int n, void *address, int stride, ... */ )
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFrdvecs: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
va_start(ap, hdr);
|
||||
ret = SDFrdvecsv(hdr, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFrdvecsv(SDF *hdr, va_list ap)
|
||||
{
|
||||
int *narray;
|
||||
char **namearray;
|
||||
void **addressarray;
|
||||
int *stridearray;
|
||||
struct obstack nobs;
|
||||
struct obstack nameobs;
|
||||
struct obstack addressobs;
|
||||
struct obstack strideobs;
|
||||
int nrequests;
|
||||
char *name;
|
||||
int stride, n;
|
||||
void *address;
|
||||
int ret;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFrdvecsv: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
obstack_begin(&nameobs, 32*sizeof(char *));
|
||||
obstack_begin(&strideobs, 32*sizeof(int));
|
||||
obstack_begin(&nobs, 32*sizeof(int));
|
||||
obstack_begin(&addressobs, 32*sizeof(void *));
|
||||
|
||||
nrequests = 0;
|
||||
while( (name = va_arg(ap, char *)) ){
|
||||
nrequests++;
|
||||
obstack_ptr_grow(&nameobs, name);
|
||||
n = va_arg(ap, int);
|
||||
obstack_int_grow(&nobs, n);
|
||||
address = va_arg(ap, void *);
|
||||
obstack_ptr_grow(&addressobs, address);
|
||||
stride = va_arg(ap, int);
|
||||
obstack_int_grow(&strideobs, stride);
|
||||
}
|
||||
obstack_int_grow(&nobs, 0);
|
||||
obstack_int_grow(&strideobs, 0);
|
||||
obstack_ptr_grow(&nameobs, NULL);
|
||||
obstack_ptr_grow(&addressobs, NULL);
|
||||
|
||||
narray = (int *)obstack_finish(&nobs);
|
||||
namearray = (char **)obstack_finish(&nameobs);
|
||||
addressarray = (void **)obstack_finish(&addressobs);
|
||||
stridearray = (int *)obstack_finish(&strideobs);
|
||||
ret = SDFrdvecsarr(hdr, nrequests,
|
||||
namearray, narray, addressarray, stridearray);
|
||||
obstack_free(&nobs, NULL);
|
||||
obstack_free(&nameobs, NULL);
|
||||
obstack_free(&addressobs, NULL);
|
||||
obstack_free(&strideobs, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFrdvecsarr(SDF *hdr, int nreq,
|
||||
char **names, int *ns, void **addresses, int *strides)
|
||||
{
|
||||
int64_t *starts;
|
||||
int i;
|
||||
int ret;
|
||||
vec_descrip_t *descrip;
|
||||
|
||||
starts = Malloc(nreq*sizeof(int64_t));
|
||||
if( starts == NULL && nreq>0 ){
|
||||
sprintf(SDFerrstring, "Could not malloc tmp space in SDFrdvecsarr\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i=0; i<nreq; i++){
|
||||
if( (descrip = lookup(names[i], hdr)) == NULL ){
|
||||
ret = -1;
|
||||
sprintf(SDFerrstring, "SDFrdvecsarr: \"%s\" name not found\n",
|
||||
names[i]);
|
||||
goto outahere;
|
||||
}
|
||||
starts[i] = descrip->nread;
|
||||
}
|
||||
if( (ret = SDFseekrdvecsarr(hdr, nreq, names,
|
||||
starts, ns, addresses, strides)) ){
|
||||
goto outahere;
|
||||
}
|
||||
/* At this point, we have successfully looked up all */
|
||||
/* the names twice (at least). */
|
||||
for(i=0; i<nreq; i++){
|
||||
descrip = lookup(names[i], hdr);
|
||||
/* assert(descrip); */
|
||||
descrip->nread += ns[i];
|
||||
}
|
||||
outahere:
|
||||
Free(starts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFseekrdvecs(SDF *hdr, ...
|
||||
/* char *name, int start, int n, void *addr, int stride, ... */ )
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseekrdvecs: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
va_start(ap, hdr);
|
||||
ret = SDFseekrdvecsv(hdr, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDFseekrdvecsv(SDF *hdr, va_list ap)
|
||||
{
|
||||
int *narray;
|
||||
int64_t *startarray;
|
||||
char **namearray;
|
||||
void **addressarray;
|
||||
int *stridearray;
|
||||
struct obstack nobs;
|
||||
struct obstack nameobs;
|
||||
struct obstack startobs;
|
||||
struct obstack addressobs;
|
||||
struct obstack strideobs;
|
||||
int nrequests;
|
||||
char *name;
|
||||
int64_t start;
|
||||
int64_t zero64 = 0;
|
||||
int stride, n;
|
||||
void *address;
|
||||
int ret;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseekrdvecsv: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
obstack_begin(&nameobs, 32*sizeof(char *));
|
||||
obstack_begin(&startobs, 32*sizeof(int64_t));
|
||||
obstack_begin(&strideobs, 32*sizeof(int));
|
||||
obstack_begin(&nobs, 32*sizeof(int));
|
||||
obstack_begin(&addressobs, 32*sizeof(void *));
|
||||
|
||||
nrequests = 0;
|
||||
while( (name = va_arg(ap, char *)) ){
|
||||
nrequests++;
|
||||
obstack_ptr_grow(&nameobs, name);
|
||||
start = va_arg(ap, int64_t);
|
||||
obstack_grow(&startobs, &start, sizeof(int64_t));
|
||||
n = va_arg(ap, int);
|
||||
obstack_int_grow(&nobs, n);
|
||||
address = va_arg(ap, void *);
|
||||
obstack_ptr_grow(&addressobs, address);
|
||||
stride = va_arg(ap, int);
|
||||
obstack_int_grow(&strideobs, stride);
|
||||
}
|
||||
obstack_int_grow(&nobs, 0);
|
||||
obstack_grow(&startobs, &zero64, sizeof(int64_t));
|
||||
obstack_int_grow(&strideobs, 0);
|
||||
obstack_ptr_grow(&nameobs, NULL);
|
||||
obstack_ptr_grow(&addressobs, NULL);
|
||||
|
||||
narray = (int *)obstack_finish(&nobs);
|
||||
namearray = (char **)obstack_finish(&nameobs);
|
||||
startarray = (int64_t *)obstack_finish(&startobs);
|
||||
addressarray = (void **)obstack_finish(&addressobs);
|
||||
stridearray = (int *)obstack_finish(&strideobs);
|
||||
ret = SDFseekrdvecsarr(hdr, nrequests,
|
||||
namearray, startarray, narray, addressarray, stridearray);
|
||||
obstack_free(&nobs, NULL);
|
||||
obstack_free(&nameobs, NULL);
|
||||
obstack_free(&startobs, NULL);
|
||||
obstack_free(&addressobs, NULL);
|
||||
obstack_free(&strideobs, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
void no_problem(const char *fmt, ...){
|
||||
/* Pass this to the MallocHandler function to tell Malloc that we
|
||||
know what we're doing, and we really can recover from malloc
|
||||
returning null! */
|
||||
return;
|
||||
}
|
||||
|
||||
int SDFseekrdvecsarr(SDF *hdr, int nreq,
|
||||
char **names, int64_t *starts, int *ns, void **addresses, int *strides)
|
||||
{
|
||||
int nn;
|
||||
off_t fileoffset;
|
||||
int i;
|
||||
int64_t nrec;
|
||||
int vecnum, first;
|
||||
int next_blknum;
|
||||
int last_blknum;
|
||||
int64_t sz_needed;
|
||||
int *sort_index;
|
||||
vec_descrip_t *descrip, **vd_array;
|
||||
char *fromptr, *toptr;
|
||||
char *recptr, *buf;
|
||||
int64_t buf_sz;
|
||||
int64_t last_rec, first_rec, new_last_rec;
|
||||
blk_descrip_t *blk;
|
||||
int stride, sz;
|
||||
int ret;
|
||||
int64_t nread, rec_cnt, rec_left, ncopy, ntry;
|
||||
int64_t *nleft, *seekto;
|
||||
char **toptr_arr;
|
||||
int64_t whole_sz;
|
||||
Error_t oldmallochandler;
|
||||
|
||||
if( hdr == NULL ){
|
||||
sprintf(SDFerrstring, "SDFseekrdvecsarr: not an SDF hdr\n");
|
||||
return -1;
|
||||
}
|
||||
buf = NULL;
|
||||
buf_sz = 0;
|
||||
#ifdef USE_ALLOCA
|
||||
sort_index = alloca(nreq*sizeof(int));
|
||||
vd_array = alloca(nreq*sizeof(vec_descrip_t *));
|
||||
nleft = alloca(nreq*sizeof(int64_t));
|
||||
toptr_arr = alloca(nreq*sizeof(char *));
|
||||
seekto = alloca(nreq*sizeof(int64_t));
|
||||
#else
|
||||
sort_index = Malloc(nreq*sizeof(int));
|
||||
vd_array = Malloc(nreq*sizeof(vec_descrip_t *));
|
||||
nleft = Malloc(nreq*sizeof(int64_t));
|
||||
toptr_arr = Malloc(nreq*sizeof(char *));
|
||||
seekto = Malloc(nreq*sizeof(int64_t));
|
||||
#endif
|
||||
|
||||
if( nreq>0 && (sort_index == NULL
|
||||
|| vd_array == NULL || nleft == NULL || toptr_arr == NULL
|
||||
|| seekto == NULL) ){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFseekrdvecsarr: Malloc failed\n"
|
||||
"sort_index(%lu) = 0x%lx, vd_array(%lu) = 0x%lx\n",
|
||||
(unsigned long)nreq*sizeof(int), (unsigned long)sort_index,
|
||||
(unsigned long)nreq*sizeof(vec_descrip_t),
|
||||
(unsigned long)vd_array);
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
|
||||
for(i=0; i<nreq; i++){
|
||||
sort_index[i] = i;
|
||||
if( (descrip = lookup(names[i], hdr)) != NULL ){
|
||||
vd_array[i] = descrip;
|
||||
}else{
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
/* Check to make sure we don't go past the end of a record */
|
||||
nrec = hdr->blks[vd_array[i]->blk_num].Nrec;
|
||||
if(nrec > 0 && starts[i] + ns[i] > nrec){
|
||||
ret = -1;
|
||||
Msg_do("nrec %ld i %d starts[i] %ld ns[i] %d\n",
|
||||
nrec, i, starts[i], ns[i]);
|
||||
sprintf(SDFerrstring,
|
||||
"SDFseekrdvecsarr: attempt to read past end of vector \"%s\"",
|
||||
names[i]);
|
||||
goto outahere;
|
||||
}
|
||||
}
|
||||
|
||||
compar_vds = vd_array;
|
||||
qsort(sort_index, nreq, sizeof(sort_index[0]), compar_func);
|
||||
/* Now the descrip_list is sorted so that we can do all the */
|
||||
/* vectors in the same block at once. */
|
||||
|
||||
vecnum = 0;
|
||||
while( vecnum < nreq ){
|
||||
descrip = vd_array[sort_index[vecnum]];
|
||||
first = vecnum;
|
||||
next_blknum = descrip->blk_num;
|
||||
blk = &hdr->blks[next_blknum];
|
||||
first_rec = starts[sort_index[vecnum]];
|
||||
last_rec = first_rec;
|
||||
do{
|
||||
new_last_rec = ns[sort_index[vecnum]] + starts[sort_index[vecnum]];
|
||||
if(new_last_rec > last_rec)
|
||||
last_rec = new_last_rec;
|
||||
last_blknum = next_blknum;
|
||||
if(++vecnum == nreq)
|
||||
break;
|
||||
descrip = vd_array[sort_index[vecnum]];
|
||||
next_blknum = descrip->blk_num;
|
||||
}while( last_blknum==next_blknum );
|
||||
|
||||
/* We are going to do all the vectors between first and vecnum */
|
||||
/* all at once. They all point at the same block. */
|
||||
rec_left = rec_cnt = last_rec - first_rec;
|
||||
for(i=first; i<vecnum; i++){
|
||||
nleft[i] = ns[sort_index[i]];
|
||||
toptr_arr[i] = addresses[sort_index[i]];
|
||||
seekto[i] = starts[sort_index[i]];
|
||||
}
|
||||
if(blk->inmem){
|
||||
recptr = ((char *)hdr->data) + blk->begin_offset + blk->reclen*first_rec;
|
||||
fileoffset = 0; /* not necessary, but it quiets a warning */
|
||||
}else{
|
||||
whole_sz = blk->reclen * rec_left;
|
||||
if( max_bufsz > 0 && whole_sz > max_bufsz ){
|
||||
sz_needed = (max_bufsz/blk->reclen)*blk->reclen;
|
||||
if( sz_needed < blk->reclen )
|
||||
sz_needed = blk->reclen;
|
||||
}else{
|
||||
sz_needed = whole_sz;
|
||||
}
|
||||
if( sz_needed > buf_sz ){
|
||||
oldmallochandler = MallocHandler(no_problem);
|
||||
if( buf )
|
||||
Free(buf);
|
||||
buf_sz = sz_needed;
|
||||
buf = Malloc(buf_sz);
|
||||
while( buf == NULL && buf_sz >= blk->reclen ){
|
||||
buf_sz >>= 1;
|
||||
buf = Malloc(buf_sz);
|
||||
}
|
||||
MallocHandler(oldmallochandler);
|
||||
if( buf == NULL ){
|
||||
sprintf(SDFerrstring, "SDFrdvecsarr: no space!\n");
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
}
|
||||
recptr = buf;
|
||||
/* Repaired by msw Mon Jul 11 14:35:19 PDT 1994 */
|
||||
/* Repaired again by johns Tue Jun 27 14:55:42 EST 1995 */
|
||||
fileoffset = blk->begin_offset + (off_t)blk->reclen * first_rec
|
||||
+ hdr->begin_file_offset;
|
||||
Msgf(("blk->reclen %d, first_rec %ld\n", blk->reclen, first_rec));
|
||||
Msgf(("fileoffset is %ld\n", fileoffset));
|
||||
Msgf(("buf_sz is %ld\n", buf_sz));
|
||||
}
|
||||
|
||||
while( rec_left > 0 ){
|
||||
if(blk->inmem){
|
||||
nread = rec_left;
|
||||
rec_left = 0;
|
||||
}else{
|
||||
if( blk->reclen > buf_sz ){
|
||||
sprintf(SDFerrstring, "SDFrdvecsarr: not enough for one record!\n");
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
whole_sz = blk->reclen * rec_left;
|
||||
if( whole_sz > buf_sz ){
|
||||
ntry = (buf_sz-blk->reclen)/blk->reclen + 1;
|
||||
}else{
|
||||
ntry = rec_left;
|
||||
}
|
||||
|
||||
/* SDFlib2 model has one file pointer, thus use SEEK_SET */
|
||||
if((nread = MPMY_Fseekrd(hdr->datafp, fileoffset,
|
||||
MPMY_SEEK_SET, buf, blk->reclen, ntry))
|
||||
!= ntry ){
|
||||
ret = -1;
|
||||
sprintf(SDFerrstring,
|
||||
"SDFrdvecsarr: fseekrd(offset=%ld, SEEK_CUR, reclen=%d, ntry=%ld) only got %ld, errno=%d\n",
|
||||
fileoffset, blk->reclen, ntry, nread, errno);
|
||||
goto outahere;
|
||||
}
|
||||
rec_left -= nread;
|
||||
fileoffset += blk->reclen * (off_t)nread;
|
||||
}
|
||||
|
||||
for(i=first; i<vecnum; i++){
|
||||
descrip = vd_array[sort_index[i]];
|
||||
if( seekto[i] > (first_rec + nread) || nleft[i] == 0 )
|
||||
continue;
|
||||
fromptr = recptr + (seekto[i] - first_rec)*blk->reclen
|
||||
+ descrip->blk_off;
|
||||
ncopy = nread - (seekto[i] - first_rec);
|
||||
if( ncopy > nleft[i] ){
|
||||
ncopy = nleft[i];
|
||||
}
|
||||
toptr = toptr_arr[i];
|
||||
stride = strides[sort_index[i]];
|
||||
sz = SDFtype_sizes[descrip->type];
|
||||
if( stride == 0 )
|
||||
stride = sz*descrip->arrcnt;
|
||||
if( sz*descrip->arrcnt > stride ){
|
||||
/* This could have been checked earlier!!! */
|
||||
sprintf(SDFerrstring, "stride for %s not long enough to step over successive elements. arrcnt=%d, unit_sz=%d, stride=%d\n",
|
||||
descrip->name, descrip->arrcnt, sz, stride);
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
for(nn=0; nn< ncopy; nn++){
|
||||
if(!blk->inmem && hdr->swapping){
|
||||
if(Byteswap( sz, descrip->arrcnt, fromptr, toptr)){
|
||||
sprintf(SDFerrstring, "SDFswapn(%d, %d, 0x%lx, 0x%lx) Failed",
|
||||
sz, descrip->arrcnt,
|
||||
(unsigned long)fromptr,
|
||||
(unsigned long)toptr);
|
||||
/* There's probably more cleaning up to do! */
|
||||
ret = -1;
|
||||
goto outahere;
|
||||
}
|
||||
}else{
|
||||
(void)memcpy( toptr, fromptr, sz * descrip->arrcnt);
|
||||
}
|
||||
fromptr += blk->reclen;
|
||||
toptr += stride;
|
||||
}
|
||||
seekto[i] += ncopy;
|
||||
nleft[i] -= ncopy;
|
||||
toptr_arr[i] = toptr;
|
||||
}
|
||||
first_rec += nread;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
outahere:
|
||||
/* alloca would be simpler! */
|
||||
/* The tests are not necessary according to ANSI... */
|
||||
#ifndef USE_ALLOCA
|
||||
if( seekto ) Free(seekto);
|
||||
if( toptr_arr ) Free(toptr_arr);
|
||||
if( nleft ) Free(nleft);
|
||||
if( vd_array ) Free(vd_array);
|
||||
if( sort_index ) Free(sort_index);
|
||||
#endif
|
||||
if( buf ) Free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int compar_func(const void *p1, const void *p2){
|
||||
int i1 = *(int *)p1;
|
||||
int i2 = *(int *)p2;
|
||||
vec_descrip_t *d1 = compar_vds[i1];
|
||||
vec_descrip_t *d2 = compar_vds[i2];
|
||||
|
||||
if(d1->blk_num < d2->blk_num)
|
||||
return -1;
|
||||
else if(d1->blk_num > d2->blk_num)
|
||||
return 1;
|
||||
else if(d1->nread < d2->nread)
|
||||
return -1;
|
||||
else if(d1->nread > d2->nread)
|
||||
return 1;
|
||||
else if(d1->blk_off < d2->blk_off)
|
||||
return -1;
|
||||
else if(d1->blk_off > d2->blk_off)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a few prime numbers chosen entirely at random... */
|
||||
#define NCOEF (sizeof(hashcoef)/sizeof(*hashcoef))
|
||||
static int hashcoef[] = { 17, 37, 3, 97, 57, 23, 151, 7, 41 };
|
||||
|
||||
/*
|
||||
This completely bogus hash function computes a linear combination of
|
||||
characters in the word.
|
||||
*/
|
||||
static int SDFhash(const char *word, SDF *hdr){
|
||||
int i;
|
||||
const char *p;
|
||||
int sum = 0;
|
||||
|
||||
p = word;
|
||||
i = 0;
|
||||
while(*p){
|
||||
sum += hashcoef[i] * *p;
|
||||
p++;
|
||||
if( ++i == NCOEF )
|
||||
i = 0;
|
||||
}
|
||||
Msgf(("hash(%s) = %d%%%d = %d\n", word, sum, hdr->hashsz, sum%hdr->hashsz));
|
||||
return sum % hdr->hashsz;
|
||||
}
|
||||
|
||||
static int isprime(int n){
|
||||
int d;
|
||||
/* this only needs to work for small O(few hundred) values of n */
|
||||
/* first make sure it's not even */
|
||||
if( (n&1) == 0 )
|
||||
return 0;
|
||||
/* Extremely naive. Now check all odd potential divisors up to sqrt(n) */
|
||||
for(d = 3; d*d<=n ; d+=2){
|
||||
if( n%d == 0 )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nextprime(int n){
|
||||
Msgf(("nextprime(%d) = ", n));
|
||||
if( (n&1) == 0 )
|
||||
n++;
|
||||
while(!isprime(n)) n+=2;
|
||||
Msgf(("%d\n", n));
|
||||
return n;
|
||||
}
|
||||
|
||||
static void buildhash(SDF *hdr){
|
||||
int sz;
|
||||
int i, h;
|
||||
|
||||
sz = nextprime(5*hdr->nvecs);
|
||||
Msgf(("hash table of size %d\n", sz));
|
||||
hdr->hashsz = sz;
|
||||
hdr->hashtbl = Calloc(sz, sizeof(*hdr->hashtbl));
|
||||
|
||||
for(i=0; i<hdr->nvecs; i++){
|
||||
h = SDFhash(hdr->vecs[i].name, hdr);
|
||||
while( hdr->hashtbl[h] != NULL ){
|
||||
Msgf(("build: hcollision between %s and %s in name-space\n",
|
||||
hdr->hashtbl[h]->name, hdr->vecs[i].name));
|
||||
h++;
|
||||
if(h==sz) /* wrap */
|
||||
h = 0;
|
||||
}
|
||||
hdr->hashtbl[h] = &hdr->vecs[i];
|
||||
}
|
||||
}
|
||||
|
||||
static vec_descrip_t *lookup(const char *name, SDF *hdr)
|
||||
{
|
||||
int i, istart;
|
||||
vec_descrip_t *possible;
|
||||
|
||||
i = istart = SDFhash(name, hdr);
|
||||
do{
|
||||
possible = hdr->hashtbl[i];
|
||||
if( possible == NULL ){
|
||||
break;
|
||||
}
|
||||
if( strcmp(possible->name, name) == 0 )
|
||||
return possible;
|
||||
|
||||
Msgf(("lookup: hcollision i=%d, name=%s, tblname=%s\n",
|
||||
i, name, possible->name));
|
||||
i++;
|
||||
if( i==hdr->hashsz ) /* wrap */
|
||||
i = 0;
|
||||
/* It ought to be imposible to fall off the bottom of this loop */
|
||||
}while(i!= istart);
|
||||
|
||||
sprintf(SDFerrstring, "No such name, \"%s\" in file.", name);
|
||||
return NULL;
|
||||
}
|
278
external/libsdf/libSDF/SDFget.c
vendored
Normal file
278
external/libsdf/libSDF/SDFget.c
vendored
Normal file
|
@ -0,0 +1,278 @@
|
|||
#include <stddef.h>
|
||||
/* stdio only needed for sprintf proto */
|
||||
#include <stdio.h>
|
||||
#include "error.h"
|
||||
#include "SDF.h"
|
||||
/*
|
||||
|
||||
These routines return 0 on success and 1 on failure. They set
|
||||
SDFerrstring if they think something strange is happening. They
|
||||
don't change the value under the VALUE argument until they are sure
|
||||
that everything is OK, so it's possible (but what would Henry Spencer
|
||||
say?) to use them by setting a default value, then calling the routine,
|
||||
and not worrying about the error condition.
|
||||
|
||||
*/
|
||||
|
||||
/* An abbreviation used many times... */
|
||||
|
||||
#define SDFget(sdfp, name, addr) \
|
||||
if(SDFseekrdvecs(sdfp, name, 0, 1, addr, 0, NULL)) return -1
|
||||
|
||||
/* I'll resist the temptation to make one macro to cover all these cases */
|
||||
/* Should we check for loss of precision in float too? */
|
||||
int
|
||||
SDFgetfloat(SDF *sdfp, char *name, float *value)
|
||||
{
|
||||
double double_value;
|
||||
int int_value;
|
||||
long long_value;
|
||||
int64_t int64_value;
|
||||
float float_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
*value = float_value;
|
||||
return 0;
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
*value = (float) double_value;
|
||||
return 0;
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = (float) int_value;
|
||||
return 0;
|
||||
case SDF_LONG:
|
||||
SDFget(sdfp, name, &long_value);
|
||||
*value = (float) long_value;
|
||||
return 0;
|
||||
case SDF_INT64:
|
||||
SDFget(sdfp, name, &int64_value);
|
||||
*value = (float) int64_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetfloat: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetdouble(SDF *sdfp, char *name, double *value)
|
||||
{
|
||||
double double_value;
|
||||
float float_value;
|
||||
int int_value;
|
||||
long long_value;
|
||||
int64_t int64_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
*value = double_value;
|
||||
return 0;
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
*value = (double) float_value;
|
||||
return 0;
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = (double) int_value;
|
||||
return 0;
|
||||
case SDF_LONG:
|
||||
SDFget(sdfp, name, &long_value);
|
||||
*value = (double) long_value;
|
||||
return 0;
|
||||
case SDF_INT64:
|
||||
SDFget(sdfp, name, &int64_value);
|
||||
*value = (double) int64_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetdouble: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetint(SDF *sdfp, char *name, int *value)
|
||||
{
|
||||
int int_value;
|
||||
float float_value;
|
||||
double double_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
int_value = (int) double_value;
|
||||
if ((double)int_value != double_value){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetint: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
int_value = (int) float_value;
|
||||
if ((float)int_value != float_value){
|
||||
Warning("SDFgetint: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring, "SDFgetint: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetlong(SDF *sdfp, char *name, long *value)
|
||||
{
|
||||
int int_value;
|
||||
float float_value;
|
||||
double double_value;
|
||||
long long_value;
|
||||
int64_t int64_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_LONG:
|
||||
SDFget(sdfp, name, &long_value);
|
||||
*value = long_value;
|
||||
return 0;
|
||||
case SDF_INT64:
|
||||
SDFget(sdfp, name, &int64_value);
|
||||
long_value = (long) int64_value;
|
||||
if ((int64_t)long_value != int64_value){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetint: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int64_value;
|
||||
return 0;
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
long_value = (long) double_value;
|
||||
if ((double)int_value != double_value){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetlong: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
long_value = (long) float_value;
|
||||
if ((float)long_value != float_value){
|
||||
Warning("SDFgetlong: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = long_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring, "SDFgetint: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetint64(SDF *sdfp, char *name, int64_t *value)
|
||||
{
|
||||
int int_value;
|
||||
float float_value;
|
||||
double double_value;
|
||||
long long_value;
|
||||
int64_t int64_value;
|
||||
|
||||
if( sdfp == NULL || !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
switch(SDFtype(name, sdfp)){
|
||||
case SDF_INT:
|
||||
SDFget(sdfp, name, &int_value);
|
||||
*value = int_value;
|
||||
return 0;
|
||||
case SDF_LONG:
|
||||
SDFget(sdfp, name, &long_value);
|
||||
*value = long_value;
|
||||
return 0;
|
||||
case SDF_INT64:
|
||||
SDFget(sdfp, name, &int64_value);
|
||||
*value = int64_value;
|
||||
return 0;
|
||||
case SDF_DOUBLE:
|
||||
SDFget(sdfp, name, &double_value);
|
||||
int64_value = (int64_t) double_value;
|
||||
if ((double)int64_value != double_value){
|
||||
sprintf(SDFerrstring,
|
||||
"SDFgetint64: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int64_value;
|
||||
return 0;
|
||||
case SDF_FLOAT:
|
||||
SDFget(sdfp, name, &float_value);
|
||||
int64_value = (int64_t) float_value;
|
||||
if ((float)int64_value != float_value){
|
||||
Warning("SDFgetint64: \"%s\" has lost precision\n", name);
|
||||
return -1;
|
||||
}
|
||||
*value = int64_value;
|
||||
return 0;
|
||||
default:
|
||||
sprintf(SDFerrstring, "SDFgetint: \"%s\" must be either float or int.\n", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDFgetstring(SDF *sdfp, const char *name, char *string, int size){
|
||||
int len;
|
||||
int ret;
|
||||
|
||||
if( sdfp == NULL ){
|
||||
sprintf(SDFerrstring, "SDFgetint: NULL sdfp\n");
|
||||
return -1;
|
||||
}
|
||||
if( !SDFhasname(name, sdfp) ){
|
||||
return -1;
|
||||
}
|
||||
if( SDFtype(name, sdfp) != SDF_CHAR ){
|
||||
return -1;
|
||||
}
|
||||
if( (len=SDFarrcnt(name, sdfp)) >= size ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = SDFseekrdvecs(sdfp, name, 0, 1, string, 0, NULL);
|
||||
if( string[len-1] != '\0' ){
|
||||
sprintf(SDFerrstring,
|
||||
"Read non-terminated string in SDFgetstring(\"%s\")\n", name);
|
||||
string[len] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
86
external/libsdf/libSDF/SDFhdrio.c
vendored
Normal file
86
external/libsdf/libSDF/SDFhdrio.c
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* An implementation of getc, using MPMY functions. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include "Msgs.h"
|
||||
#include "error.h"
|
||||
#include "SDF-private.h"
|
||||
#include "stdio.h"
|
||||
#include "mpmy_io.h"
|
||||
|
||||
#define MYBUFSZ 4096
|
||||
|
||||
/* Assumption: we can only have one header at a time being read.
|
||||
The header is opened, read anc closed, all during the course of SDFopen
|
||||
so we don't have to screw around with multiple open files, etc. */
|
||||
|
||||
static MPMYFile *fp;
|
||||
static char buf[MYBUFSZ];
|
||||
static char *ptr;
|
||||
static char *endbuf;
|
||||
static int buf_offset;
|
||||
|
||||
|
||||
int SDF_Hdropen(const char *name){
|
||||
fp = MPMY_Fopen(name, MPMY_RDONLY|MPMY_SINGL);
|
||||
if( fp == NULL )
|
||||
return -1;
|
||||
endbuf = ptr = buf;
|
||||
buf_offset = 0;
|
||||
Msg("SDF", ("SDFhdropen: return fp=%p\n", fp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SDF_Hdrclose(void){
|
||||
Msg("SDF", ("SDFhdrclose called\n"));
|
||||
MPMY_Fclose(fp);
|
||||
endbuf = ptr = NULL;
|
||||
fp = NULL;
|
||||
buf_offset = -1;
|
||||
}
|
||||
|
||||
int SDF_Hdroffset(void){
|
||||
if( ptr == NULL )
|
||||
return -1;
|
||||
return buf_offset + (ptr - buf);
|
||||
}
|
||||
|
||||
int SDF_Hdrgetc(){
|
||||
int nread;
|
||||
|
||||
if( ptr == NULL ){
|
||||
Msgf(("SDFhdrgetc: Returning EOF, ptr==NULL\n"));
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if( ptr < endbuf ){
|
||||
if( *ptr == '\0' ){
|
||||
SinglWarning("Returning NULL at char %d in SDFhdrio\n", (int)(ptr-buf));
|
||||
}
|
||||
Msgf(("SDF_hdrgetc: %c\n", *ptr));
|
||||
return *ptr++;
|
||||
}
|
||||
|
||||
nread = MPMY_Fread(buf, 1, MYBUFSZ, fp);
|
||||
{int i;
|
||||
int sum = 0;
|
||||
for(i=0; i<nread; i++){
|
||||
sum ^= buf[i];
|
||||
}
|
||||
Msgf(("SDFhdrio Fread(%d), obtained %d, sum=%d\n", MYBUFSZ, nread, sum));
|
||||
}
|
||||
if(nread <= 0 ) {
|
||||
if( nread < 0 ){
|
||||
SinglWarning("SDFhdrio: MPMY_Fread returns %d, errno=%d\n", nread, errno);
|
||||
}
|
||||
Msgf(("SDFhdrgetc: Returning EOF, nread=%d, errno=%d\n", nread, errno));
|
||||
return EOF; /* don't distinguish between error and EOF? */
|
||||
}
|
||||
buf_offset += endbuf - buf;
|
||||
ptr = buf;
|
||||
endbuf = ptr + nread;
|
||||
/* This tail recursion is guaranteed to terminate on the second try
|
||||
because we have guaranteed that endbuf>ptr */
|
||||
return SDF_Hdrgetc();
|
||||
}
|
||||
|
54
external/libsdf/libSDF/dictionary
vendored
Normal file
54
external/libsdf/libSDF/dictionary
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
This is a dictionary of "known" names in nbody files.
|
||||
It will be extended as the need arises.
|
||||
|
||||
The first few come from the headers:
|
||||
|
||||
float npart
|
||||
float iter
|
||||
float time
|
||||
float ke
|
||||
float pe
|
||||
float masstot
|
||||
float l_ang
|
||||
float Gnewt
|
||||
float epsilon
|
||||
float zinitial
|
||||
float omega
|
||||
float hubble
|
||||
float box_size
|
||||
float znow
|
||||
float initial_rsize
|
||||
float initial_rmin_x
|
||||
float initial_rmin_y
|
||||
float initial_rmin_z
|
||||
float veltime
|
||||
float sizeof_ext
|
||||
float alpha
|
||||
float beta
|
||||
float curvature
|
||||
float lambda
|
||||
float cosm_integral
|
||||
float radius
|
||||
int int_npart
|
||||
int int_sizeof_ext
|
||||
char tree_header_text[384];
|
||||
|
||||
The following arrays are of length (int)nbody. Unfortunately,
|
||||
in order to maintain historical compatibilty, the length of the
|
||||
array is stored as a binary float in the files, so consider using
|
||||
nbio_rd_double(..., "nbody") to figure out how long these vectors are.
|
||||
|
||||
float x[], y[], z[]
|
||||
float vx[], vy[], vz[]
|
||||
float mass[]
|
||||
|
||||
From the msw .ap files, we also have
|
||||
float acc[]
|
||||
float phi[]
|
||||
|
||||
Presumably, we should also reserve:
|
||||
float ax[], ay[], az[]
|
||||
|
||||
The char id[][4] is specified by tree and tree_ap files.
|
||||
|
||||
There will undoubtedly be others.
|
35
external/libsdf/libSDF/stdio.h
vendored
Normal file
35
external/libsdf/libSDF/stdio.h
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* This file is a replacement for the few parts of stdio.h */
|
||||
/* that are assumed by the output of lex and yacc. */
|
||||
/* It is here because lex's output contains #include "stdio.h" */
|
||||
/* and we don't want to be contaminated by the system stdio.h */
|
||||
|
||||
#ifndef MYSTDIOdotH
|
||||
#define MYSTDIOdotH
|
||||
#include "mpmy_io.h"
|
||||
|
||||
/* These are replacements for stdio */
|
||||
#undef getc
|
||||
#define getc(fp) SDF_Hdrgetc()
|
||||
/* Putc is used by 'output'. This is the easiest way to deal with it */
|
||||
#undef putc
|
||||
#define putc(c, fp) (Msg_do("%c", c))
|
||||
#undef FILE
|
||||
#define FILE MPMYFile
|
||||
#undef stdin
|
||||
#define stdin NULL
|
||||
#undef stdout
|
||||
#define stdout NULL
|
||||
#undef stderr
|
||||
#define stderr NULL
|
||||
#undef EOF
|
||||
#define EOF (-1)
|
||||
#undef BUFSIZ
|
||||
#define BUFSIZ 512
|
||||
|
||||
/* A couple of prototypes that are in stdio are also needed */
|
||||
#include <stdarg.h>
|
||||
int sscanf(const char *, const char *, ...);
|
||||
int vsprintf(char *, const char *, va_list);
|
||||
int sprintf(char *, const char *, ...);
|
||||
|
||||
#endif
|
106
external/libsdf/libmpmy/GNUmakefile
vendored
Normal file
106
external/libsdf/libmpmy/GNUmakefile
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
# Make.$(ARCH) sets many of the variables used below including:
|
||||
# CC, CFLAGS, AS, RANLIB, objdir, objsuf, asmdir
|
||||
|
||||
# This Makefile is 'non-standard' because we are trying to create a .o
|
||||
# file in the '$(libdir)' directory. Furthermore, the name of the
|
||||
# file we are creating can't be determined until after we have 'include'd
|
||||
# the $(ARCH)-specific makefile (so we can use the default PAROS).
|
||||
#
|
||||
# The dependencies are even more unreliable than usual.
|
||||
#
|
||||
# It's amazing that it works at all...
|
||||
|
||||
treedir=..
|
||||
treedir_sed=\.\.
|
||||
appexcludes=
|
||||
libname=NO_NAME
|
||||
# This is here only to allow 'make depends' to work.
|
||||
src=mpmy_seq.c mpmy_lsv.c mpmy_nx.c mpmy_vertex.c mpmy_sunmos.c mpmy_mpi.c mpmy_eui.c mpmy_pvm.c mpmy_craypvm.c
|
||||
|
||||
special_rule_for_all=YES
|
||||
all: special
|
||||
|
||||
include $(treedir)/Make-common/Make.$(ARCH)
|
||||
|
||||
include $(treedir)/Make-common/Make.generic
|
||||
|
||||
override CFLAGS:=$(PAROSCFLAGS) $(CFLAGS)
|
||||
|
||||
# I think these should be handled with PAROSCFLAGS
|
||||
# So sue me!
|
||||
#ifeq ($(PAROS),eui)
|
||||
#CFLAGS:=-I/usr/lpp/euih/eui $(CFLAGS)
|
||||
#endif
|
||||
|
||||
#ifeq ($(PAROS),mpi)
|
||||
#CFLAGS:=-I/usr/lpp/mpif $(CFLAGS)
|
||||
#endif
|
||||
|
||||
#ifeq ($(PAROS),srv)
|
||||
#CFLAGS:=-I$(SRVHOME)/include/cros3 $(CFLAGS)
|
||||
#endif
|
||||
|
||||
#ifeq ($(PAROS),pvm)
|
||||
#CFLAGS:=-I$(PVM_ROOT)/include $(CFLAGS)
|
||||
#endif
|
||||
|
||||
# order is important here. We need to make $(libdir)
|
||||
special: $(libdir)/mpmy_$(PAROS)$(objsuf)
|
||||
|
||||
$(libdir)/mpmy_$(PAROS)$(objsuf) : $(objdir)/mpmy_$(PAROS)$(objsuf) $(libdir)
|
||||
cp $< $@
|
||||
|
||||
$(objdir)/mpmy_$(PAROS)$(objsuf) : $(objdir)
|
||||
|
||||
# If there's a default PAROS for this architecture, then we put
|
||||
# mpmy_$(PAROS).o into libsw.a. To override it, it is
|
||||
# necessary to list mpmy_$(alternative).o AHEAD of libsw.a in the
|
||||
# link command. But if you just want the defaults (typically _seq), then
|
||||
# the only thing to link against is libsw.a.
|
||||
ifeq ($(PAROS),$(defaultPAROS))
|
||||
special: $(libdir)/libsw$(libext)($(objdir)/mpmy_$(PAROS)$(objsuf))
|
||||
$(RANLIB) $(libdir)/libsw$(libext)
|
||||
|
||||
$(libdir)/libsw$(libext)($(objdir)/mpmy_$(PAROS)$(objsuf)) : $(libdir)
|
||||
|
||||
endif
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
$(objdir)/mpmy_seq$(objsuf):
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/mpmy.h
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/Assert.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/mpmy_io.h $(treedir)/include/libsdf/mpmy_time.h
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/mpmy_abnormal.h timers_hwclock.c
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/chn.h mpmy_io.c
|
||||
$(objdir)/mpmy_seq$(objsuf):
|
||||
$(objdir)/mpmy_seq$(objsuf):
|
||||
$(objdir)/mpmy_seq$(objsuf):
|
||||
$(objdir)/mpmy_seq$(objsuf):
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/protos.h iozero.h
|
||||
$(objdir)/mpmy_seq$(objsuf): iozero.c io_generic.c mpmy_abnormal.c
|
||||
$(objdir)/mpmy_seq$(objsuf):
|
||||
$(objdir)/mpmy_seq$(objsuf): $(treedir)/include/libsdf/singlio.h
|
||||
$(objdir)/mpmy_seq$(objsuf): mpmy_generic.c
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/mpmy_abnormal.h
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/chn.h $(treedir)/include/libsdf/Assert.h
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/mpmy_mpi$(objsuf):
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/memfile.h
|
||||
$(objdir)/mpmy_mpi$(objsuf): timers_hwclock.c
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/mpmy_time.h
|
||||
$(objdir)/mpmy_mpi$(objsuf): mpmy_mpiio.c
|
||||
$(objdir)/mpmy_mpi$(objsuf):
|
||||
$(objdir)/mpmy_mpi$(objsuf):
|
||||
$(objdir)/mpmy_mpi$(objsuf):
|
||||
$(objdir)/mpmy_mpi$(objsuf):
|
||||
$(objdir)/mpmy_mpi$(objsuf):
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/mpmy_io.h io_generic.c mpmy_abnormal.c
|
||||
$(objdir)/mpmy_mpi$(objsuf): $(treedir)/include/libsdf/singlio.h
|
||||
$(objdir)/mpmy_mpi$(objsuf): mpmy_generic.c
|
59
external/libsdf/libmpmy/io_generic.c
vendored
Normal file
59
external/libsdf/libmpmy/io_generic.c
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Some i/o routines that are likely to be common... */
|
||||
|
||||
#ifndef HAVE_MPMY_FPRINTF
|
||||
|
||||
int MPMY_Fprintf(MPMYFile *fp, const char *fmt, ...){
|
||||
int ret;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
ret = MPMY_Vfprintf(fp, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_VFPRINTF
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static char buf[1024];
|
||||
|
||||
int MPMY_Vfprintf(MPMYFile *fp, const char *fmt, va_list args){
|
||||
/* What a pain. Sometimes sprintf returns a char* and sometimes
|
||||
it returns an int. There's no good way to tell, but this
|
||||
should do.*/
|
||||
long ret = (long)vsprintf(buf, fmt, args);
|
||||
|
||||
/* Broken versions of sprintf return their first arg... */
|
||||
if( ret == (long)buf )
|
||||
ret = strlen(buf);
|
||||
|
||||
if( ret < 0 ){
|
||||
return ret;
|
||||
}
|
||||
if( ret >= sizeof(buf) ){
|
||||
/* This is serious. We've probably scribbled over memory.
|
||||
Maybe we should just bail out now?
|
||||
*/
|
||||
static int recursion;
|
||||
if( recursion++ == 0 )
|
||||
Error("MPMY_Vfprintf overflow. Data corruption likely!\n");
|
||||
recursion--;
|
||||
}
|
||||
|
||||
if( MPMY_Fwrite(buf, 1, ret, fp) != ret ){
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_FLUSH
|
||||
|
||||
/* This is here just for completeness... The higher levels all do
|
||||
their I/O using unbuffered primitives (read/write/open/close), so
|
||||
we don't have to do anything special to flush output */
|
||||
int MPMY_Fflush(MPMYFile *fp){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
360
external/libsdf/libmpmy/iozero.c
vendored
Normal file
360
external/libsdf/libmpmy/iozero.c
vendored
Normal file
|
@ -0,0 +1,360 @@
|
|||
/* More include madness. This is such good stuff, that I can't resist */
|
||||
/* just "#include"ing it into all the mpmy_??io.c files...*/
|
||||
|
||||
/* Try to use different tags for the different kinds of broadcasts... */
|
||||
#define BCAST_CLOSE 0x3579
|
||||
#define BCAST_OPEN 0x3779
|
||||
#define BCAST_READ1 0x3979
|
||||
#define BCAST_READ2 0x3b79
|
||||
#define BCAST_WRITE 0x3d79
|
||||
#define BCAST_LSEEK 0x3f79
|
||||
#define BCAST_TELL 0x4179
|
||||
#define BCAST_FLEN 0x4379
|
||||
#define BCAST_MKDIR 0x4579
|
||||
|
||||
static int
|
||||
open0(const char *path, int flags, int mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* paragon left the const out of the prototype */
|
||||
Msgf(("open0(path=%s, flags=%#x, mode=%#x\n", path, flags, mode));
|
||||
if (MPMY_Procnum() == 0){
|
||||
ret = open((char *)path, flags, mode);
|
||||
Msgf(("open returns %d on node 0\n", ret));
|
||||
}
|
||||
MPMY_BcastTag(&ret, 1, MPMY_INT, 0, BCAST_OPEN);
|
||||
Msgf(("open0 returning %d\n", ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
close0(int fd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (MPMY_Procnum() == 0) ret = close(fd);
|
||||
MPMY_BcastTag(&ret, 1, MPMY_INT, 0, BCAST_CLOSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long
|
||||
read0(int fd, void *buf, unsigned long nbytes)
|
||||
{
|
||||
long ret;
|
||||
|
||||
if (MPMY_Procnum() == 0){
|
||||
ret = read(fd, buf, nbytes);
|
||||
Msgf(("read0: read(fd=%d, nbytes=%ld) returns %ld\n",
|
||||
fd, nbytes, ret));
|
||||
}
|
||||
MPMY_BcastTag(&ret, 1, MPMY_LONG, 0, BCAST_READ1);
|
||||
Msgf(("read0: after Bcast ret = %ld\n", ret));
|
||||
if( ret > 0 )
|
||||
MPMY_BcastTag(buf, ret, MPMY_CHAR, 0, BCAST_READ2);
|
||||
if( Msg_test(__FILE__)){
|
||||
int i;
|
||||
int sum = 0;
|
||||
char *cbuf = buf;
|
||||
for(i=0; i<ret; i++){
|
||||
sum ^= cbuf[i];
|
||||
}
|
||||
Msg_do("iozero: Fread(%ld), got %ld, sum=%d\n", nbytes, ret, sum);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
write0(int fd, const void *buf, unsigned long nbytes)
|
||||
{
|
||||
long ret;
|
||||
|
||||
/* paragon left the const out of the prototype */
|
||||
if (MPMY_Procnum() == 0) ret = write(fd, (void *)buf, nbytes);
|
||||
MPMY_BcastTag(&ret, 1, MPMY_INT, 0, BCAST_WRITE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static off_t
|
||||
lseek0(int fd, off_t offset, int whence)
|
||||
{
|
||||
off_t ret;
|
||||
|
||||
if (MPMY_Procnum() == 0) ret = lseek(fd, offset, whence);
|
||||
MPMY_BcastTag(&ret, 1, MPMY_OFFT, 0, BCAST_LSEEK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static off_t
|
||||
tell0(int fd)
|
||||
{
|
||||
off_t ret;
|
||||
|
||||
if (MPMY_Procnum() == 0) ret = lseek(fd, 0L, SEEK_CUR);
|
||||
MPMY_BcastTag(&ret, 1, MPMY_OFFT, 0, BCAST_TELL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static off_t
|
||||
flen(int fd)
|
||||
{
|
||||
off_t ret;
|
||||
|
||||
ret = lseek(fd, 0, SEEK_END);
|
||||
Msg_do("lseek on %d returns %ld, errno is %d\n", fd, ret, errno);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static off_t
|
||||
flen0(int fd)
|
||||
{
|
||||
off_t ret;
|
||||
|
||||
if (MPMY_Procnum() == 0) {
|
||||
ret = flen(fd);
|
||||
Msgf(("flen0 of %d returns %ld\n", fd, (long)ret));
|
||||
}
|
||||
MPMY_BcastTag(&ret, 1, MPMY_OFFT, 0, BCAST_FLEN);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mkdir0(const char *path, int mode){
|
||||
#if defined(__SUNMOS__) || defined(__AP1000__)
|
||||
return -1;
|
||||
#else
|
||||
int ret;
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
ret = mkdir(path, mode);
|
||||
if( ret && errno == EEXIST ){
|
||||
/* Let's just pretend we really made it... */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
MPMY_BcastTag(&ret, 1, MPMY_INT, 0, BCAST_MKDIR );
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static long
|
||||
fseekrd0(int fd, off_t offset, int whence, void *buf, int reclen,
|
||||
int nrecs)
|
||||
{
|
||||
int doseek;
|
||||
int real_whence;
|
||||
void *tmpbuf;
|
||||
int i;
|
||||
long nread;
|
||||
off_t len;
|
||||
struct {
|
||||
off_t offset;
|
||||
long whence;
|
||||
long reclen;
|
||||
long nrecs;
|
||||
} parbuf, *allbuf;
|
||||
|
||||
Msgf(("fseekrd0: (fd=%d, offset=%ld, whence=%d, buf=%p, reclen=%d, nrecs=%d)\n",
|
||||
fd, offset, whence, buf, reclen, nrecs));
|
||||
|
||||
parbuf.offset = offset;
|
||||
parbuf.whence = whence;
|
||||
parbuf.reclen = reclen;
|
||||
parbuf.nrecs = nrecs;
|
||||
|
||||
if (MPMY_Procnum() == 0) {
|
||||
allbuf = Malloc(sizeof(parbuf)*MPMY_Nproc());
|
||||
MPMY_Gather(&parbuf, sizeof(parbuf), MPMY_CHAR, allbuf,0);
|
||||
tmpbuf = Malloc(reclen*nrecs);
|
||||
for (i = 0; i < MPMY_Nproc(); i++) {
|
||||
offset = allbuf[i].offset;
|
||||
whence = allbuf[i].whence;
|
||||
reclen = allbuf[i].reclen;
|
||||
nrecs = allbuf[i].nrecs;
|
||||
|
||||
if( whence == MPMY_SEEK_CUR ){
|
||||
/* I'm not sure this is a well-defined operation */
|
||||
doseek = (offset != 0);
|
||||
}else if( whence == MPMY_SEEK_SET ){
|
||||
off_t cur_off = lseek(fd, 0, SEEK_CUR);
|
||||
if (cur_off < 0){
|
||||
static int issued_seek_warning;
|
||||
if( errno == ESPIPE ){
|
||||
if( !issued_seek_warning ){
|
||||
SeriousWarning("fseekrd: Can't seek on a pipe.\nAssuming the seek is a no-op. Good luck. You will not be warned again\n");
|
||||
issued_seek_warning = 1;
|
||||
}
|
||||
}else{
|
||||
Error("fseekrd: lseek(%d, 0, SEEK_CUR) failed, errno=%d\n",
|
||||
fd, errno);
|
||||
}
|
||||
doseek = 0;
|
||||
}else{
|
||||
doseek = (offset != cur_off);
|
||||
}
|
||||
}else{
|
||||
doseek = 1;
|
||||
}
|
||||
if( doseek ){
|
||||
switch(whence){
|
||||
case MPMY_SEEK_SET:
|
||||
real_whence = SEEK_SET;
|
||||
break;
|
||||
case MPMY_SEEK_CUR:
|
||||
real_whence = SEEK_CUR;
|
||||
break;
|
||||
case MPMY_SEEK_END:
|
||||
real_whence = SEEK_END;
|
||||
break;
|
||||
default:
|
||||
Error("Illegal value of whence (%d) in fseekrd\n", whence);
|
||||
}
|
||||
if (lseek(fd, offset, real_whence) == -1L) {
|
||||
Error("fseekrd: cycle %d lseek(%d, %ld, %d) failed, errno=%d\n",
|
||||
i, fd, offset, whence, errno);
|
||||
}
|
||||
}
|
||||
len = 0;
|
||||
while (len < reclen*nrecs) {
|
||||
nread = read(fd, (char *)tmpbuf+len, reclen*nrecs-len);
|
||||
if (nread == -1) {
|
||||
Error("fseekrd: read(%d, %ld) failed, errno=%d\n",
|
||||
fd, reclen*nrecs-len, errno);
|
||||
} else if (nread == 0) {
|
||||
Error("fseekrd: read(%d, %ld) got EOF\n",
|
||||
fd, reclen*nrecs-len);
|
||||
} else {
|
||||
Msgf(("fseekrd: got %ld\n", nread));
|
||||
len += nread;
|
||||
}
|
||||
}
|
||||
if (len != reclen*nrecs) {
|
||||
Error("fseekrd: Wrong amount of data\n");
|
||||
}
|
||||
if (i) {
|
||||
MPMY_send(tmpbuf, reclen*nrecs, i, MPMY_IOTAG);
|
||||
} else {
|
||||
memcpy(buf, tmpbuf, reclen*nrecs);
|
||||
}
|
||||
}
|
||||
Free(tmpbuf);
|
||||
Free(allbuf);
|
||||
} else {
|
||||
MPMY_Gather(&parbuf, sizeof(parbuf)/sizeof(long), MPMY_LONG, NULL, 0);
|
||||
MPMY_recvn(buf, reclen*nrecs, 0, MPMY_IOTAG);
|
||||
}
|
||||
return parbuf.nrecs;
|
||||
}
|
||||
|
||||
#define MAX_IOBUF (64*1024*1024)
|
||||
|
||||
static long
|
||||
write0_multi(int fd, const void *buf, off_t nbytes)
|
||||
{
|
||||
long ret;
|
||||
off_t *sizes;
|
||||
int i, n, sync;
|
||||
char *tmpbuf = 0;
|
||||
off_t total_bytes;
|
||||
int nproc = MPMY_Nproc();
|
||||
int procnum = MPMY_Procnum();
|
||||
|
||||
MPMY_Combine(&nbytes, &total_bytes, 1, MPMY_OFFT, MPMY_SUM);
|
||||
Msgf(("write0_multi, nbytes is %ld, total_bytes is %ld\n", nbytes, total_bytes));
|
||||
/* If the total is small enough, we might as well concat it on proc 0 */
|
||||
if (total_bytes <= MAX_IOBUF) {
|
||||
MPMY_NGather(buf, nbytes, MPMY_CHAR, (void **)&tmpbuf, 0);
|
||||
if (procnum == 0) {
|
||||
ret = write(fd, tmpbuf, total_bytes);
|
||||
if (ret != total_bytes) Error("write failed, errno=%d\n", errno);
|
||||
Msgf(("write0 %ld (one block)\n", ret));
|
||||
Free(tmpbuf);
|
||||
}
|
||||
return nbytes;
|
||||
} else if (procnum == 0) {
|
||||
sizes = Malloc(sizeof(off_t)*nproc);
|
||||
MPMY_Gather(&nbytes, 1, MPMY_OFFT, sizes, 0);
|
||||
ret = 0;
|
||||
while (nbytes > 0) {
|
||||
off_t nwrite = (nbytes > MAX_IOBUF) ? MAX_IOBUF : nbytes;
|
||||
off_t wrote;
|
||||
wrote = write(fd, buf+ret, nwrite);
|
||||
if (wrote != nwrite) Shout("write failed, errno=%d\n", errno);
|
||||
ret += wrote;
|
||||
nbytes -= wrote;
|
||||
}
|
||||
Msgf(("write0 %ld\n", ret));
|
||||
if (nproc > 1) {
|
||||
tmpbuf = Malloc(nbytes);
|
||||
for (i = procnum+1; i < nproc; i++) {
|
||||
/* This could be double-buffered */
|
||||
tmpbuf = Realloc(tmpbuf, sizes[i]);
|
||||
/* Avoid deluge of messages by sync */
|
||||
MPMY_send(&sync, sizeof(int), i, MPMY_IOTAG);
|
||||
MPMY_recvn(tmpbuf, sizes[i], i, MPMY_IOTAG);
|
||||
n = write(fd, tmpbuf, sizes[i]);
|
||||
if (n != sizes[i]) Shout("write failed, errno=%d\n", errno);
|
||||
Msgf(("write%d %d\n", i, n));
|
||||
/* should we send errno as well? */
|
||||
MPMY_send(&n, sizeof(int), i, MPMY_IOTAG);
|
||||
}
|
||||
Free(tmpbuf);
|
||||
}
|
||||
Free(sizes);
|
||||
} else {
|
||||
MPMY_Gather(&nbytes, 1, MPMY_OFFT, NULL, 0);
|
||||
MPMY_recvn(&sync, sizeof(int), 0, MPMY_IOTAG);
|
||||
Msgf(("sending %ld bytes\n", nbytes));
|
||||
MPMY_send(buf, nbytes, 0, MPMY_IOTAG);
|
||||
MPMY_recvn(&ret, sizeof(int), 0, MPMY_IOTAG);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long
|
||||
read0_multi(int fd, void *buf, off_t nbytes)
|
||||
{
|
||||
int ret;
|
||||
off_t *sizes;
|
||||
int i, n;
|
||||
char *tmpbuf;
|
||||
int nproc = MPMY_Nproc();
|
||||
int procnum = MPMY_Procnum();
|
||||
|
||||
if (sizeof(off_t) != sizeof(long long)) {
|
||||
Error("Type problem in write0_multi\n");
|
||||
}
|
||||
if (procnum == 0) {
|
||||
sizes = Malloc(sizeof(off_t)*nproc);
|
||||
MPMY_Gather(&nbytes, 1, MPMY_OFFT, sizes, 0);
|
||||
ret = read(fd, buf, nbytes);
|
||||
if (ret != nbytes) Shout("read failed, errno=%d\n", errno);
|
||||
Msgf(("read0 %d\n", ret));
|
||||
if (nproc > 1) {
|
||||
tmpbuf = Malloc(nbytes);
|
||||
for (i = procnum+1; i < nproc; i++) {
|
||||
/* This could be double-buffered */
|
||||
tmpbuf = Realloc(tmpbuf, sizes[i]);
|
||||
n = read(fd, tmpbuf, sizes[i]);
|
||||
MPMY_send(tmpbuf, n, i, MPMY_IOTAG);
|
||||
if (n != sizes[i]) Shout("read failed, errno=%d\n", errno);
|
||||
Msgf(("read%d %d\n", i, n));
|
||||
}
|
||||
Free(tmpbuf);
|
||||
}
|
||||
Free(sizes);
|
||||
} else {
|
||||
MPMY_Status stat;
|
||||
MPMY_Comm_request req;
|
||||
|
||||
MPMY_Gather(&nbytes, 1, MPMY_OFFT, NULL, 0);
|
||||
MPMY_Irecv(buf, nbytes, 0, MPMY_IOTAG, &req);
|
||||
MPMY_Wait(req, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
20
external/libsdf/libmpmy/iozero.h
vendored
Normal file
20
external/libsdf/libmpmy/iozero.h
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef IOzeroDOTh
|
||||
#define IOzeroDOTh
|
||||
|
||||
#define MPMY_IOTAG (0x183)
|
||||
#define IoZero(fp) (fp->flags & MPMY_IOZERO)
|
||||
|
||||
static int open0(const char *path, int flags, int mode);
|
||||
static int close0(int fd);
|
||||
static int mkdir0(const char *path, int mode);
|
||||
static long read0(int fd, void *buf, unsigned long nbytes);
|
||||
static long write0(int fd, const void *buf, unsigned long nbytes);
|
||||
static off_t lseek0(int fd, off_t offset, int whence);
|
||||
static off_t tell0(int fd);
|
||||
static off_t flen(int fd);
|
||||
static off_t flen0(int fd);
|
||||
static long fseekrd0(int fd, off_t offset, int whence, void *buf,
|
||||
int reclen, int nrecs);
|
||||
static long write0_multi(int fd, const void *buf, off_t nbytes);
|
||||
static long read0_multi(int fd, void *buf, off_t nbytes);
|
||||
#endif
|
2
external/libsdf/libmpmy/mpmy-private.h
vendored
Normal file
2
external/libsdf/libmpmy/mpmy-private.h
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
|
||||
|
259
external/libsdf/libmpmy/mpmy_abnormal.c
vendored
Normal file
259
external/libsdf/libmpmy/mpmy_abnormal.c
vendored
Normal file
|
@ -0,0 +1,259 @@
|
|||
/* Yet another attempt to rationalize the abnormal termination of
|
||||
parallel programs.
|
||||
|
||||
Issues to consider:
|
||||
- Do core files exist, and are they useful.
|
||||
- Do we need to chdir before dumping a core file.
|
||||
- Exactly how do we go about dumping a core file.
|
||||
- Do we want to do anything else before quitting.
|
||||
- Sometimes we get the most information when we just return
|
||||
from a signal handler (delta).
|
||||
- Parts will need to be over-ridden by mpmy_<paros>.c, but
|
||||
duplication of code should be minimized.
|
||||
- include files, values of signals, etc. are all wildly system
|
||||
specific.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include "singlio.h"
|
||||
#include "Msgs.h"
|
||||
#include "mpmy_abnormal.h"
|
||||
|
||||
#ifndef MPMY_ABORT
|
||||
void MPMY_Abort(void){
|
||||
MPMY_RaiseAbnormal(SIGABRT);
|
||||
MPMY_SystemAbort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
/* dje says AIX dumps core fine, but the debuggers are confused by
|
||||
the signal handlers. Another way of achieving this might be
|
||||
to set absiglist and MPMY_HAVE_ABSIGLIST in the mpmy_paros.c file. */
|
||||
#define NO_SIGNALS
|
||||
#endif
|
||||
|
||||
#if !defined( HAVE_ABSIG_LIST ) && !defined(NO_SIGNALS)
|
||||
static int absiglist[]={
|
||||
#if 0 && defined(SIGABRT) /* ANSI */
|
||||
/* DO NOT TRAP SIGABRT! Just leave it completely alone. We studiously
|
||||
avoid calling abort in our code, so we should just let SIGABRT do its
|
||||
normal, unmodified thing. */
|
||||
SIGABRT,
|
||||
#endif
|
||||
#ifdef SIGFPE /* ANSI */
|
||||
SIGFPE,
|
||||
#endif
|
||||
#ifdef SIGIILL /* ANSI */
|
||||
SIGILL,
|
||||
#endif
|
||||
#ifdef SIGIOT /* ANSI */
|
||||
SIGIOT,
|
||||
#endif
|
||||
#ifdef SIGSEGV /* ANSI */
|
||||
SIGSEGV,
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
SIGQUIT,
|
||||
#endif
|
||||
#ifdef SIGTRAP
|
||||
SIGTRAP,
|
||||
#endif
|
||||
#ifdef SIGEMT
|
||||
SIGEMT,
|
||||
#endif
|
||||
#ifdef SIGKILL
|
||||
SIGKILL, /* for form's sake */
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
SIGBUS,
|
||||
#endif
|
||||
#ifdef SIGSYS
|
||||
SIGSYS,
|
||||
#endif
|
||||
#ifdef SIGPIPE
|
||||
SIGPIPE,
|
||||
#endif
|
||||
/* Do we need to worry about a trailing comma?? */
|
||||
};
|
||||
#endif /* HAVE_ABSIGLIST */
|
||||
|
||||
#ifndef HAVE_SETUP_ABSIGS
|
||||
void _MPMY_setup_absigs(void){
|
||||
int i;
|
||||
#if !defined(NO_SIGNALS)
|
||||
for(i=0; i< sizeof(absiglist)/sizeof(*absiglist); i++){
|
||||
signal(absiglist[i], MPMY_RaiseAbnormal);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ABNORMAL
|
||||
#define MAXUSERFUNCS 64
|
||||
|
||||
static int nuserfuncs = 0;
|
||||
static Abhndlr userfuncs[MAXUSERFUNCS];
|
||||
/* Lots of functions are suitable for use as userfuncs to be called in
|
||||
the event of abnormal termination. These might include:
|
||||
malloc_print();
|
||||
PrintMemfile();
|
||||
PrintMPMYDiags();
|
||||
Msg_flush();
|
||||
MPMY_abchdir(); (with MPMY_abchdir_arg set beforehand)
|
||||
MPMY_SystemAbort();
|
||||
MPMY_SystemExit(); (with MPMY_exit_arg set beforehand)
|
||||
MPMY_Abannounce();
|
||||
|
||||
They are called in the reverse chronological order, so later functions
|
||||
might 'override' earlier ones. This isn't perfect, but it's better than
|
||||
the monolithic handler we had before.
|
||||
*/
|
||||
|
||||
void MPMY_OnAbnormal(Abhndlr hndlr){
|
||||
if(nuserfuncs < MAXUSERFUNCS)
|
||||
userfuncs[nuserfuncs++] = hndlr;
|
||||
}
|
||||
|
||||
int MPMY_Abnormal_signum;
|
||||
int MPMY_stop_abnormal_processing;
|
||||
void MPMY_RaiseAbnormal(int sig){
|
||||
int i;
|
||||
|
||||
MPMY_Abnormal_signum = sig;
|
||||
MPMY_stop_abnormal_processing = 0;
|
||||
/* Just cycle through the 'user' functions. */
|
||||
for(i=nuserfuncs-1; i>=0 && !MPMY_stop_abnormal_processing; i--){
|
||||
(*userfuncs[i])();
|
||||
}
|
||||
MPMY_Abnormal_signum = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SYSTEM_ABORT
|
||||
void MPMY_SystemAbort(void){
|
||||
/* This should be unnecessary, since we didn't trap SIGABRT above. */
|
||||
signal(SIGABRT, SIG_DFL);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SYSTEM_EXIT
|
||||
int MPMY_exit_arg = 0;
|
||||
void MPMY_SystemExit(void){
|
||||
exit(MPMY_exit_arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_CHDIR
|
||||
/* This is pretty generic, but if the system can't even link against
|
||||
mkdir and chdir, then it will be necessary to override this with
|
||||
a noop in the PAROS-specific file. */
|
||||
#include <unistd.h>
|
||||
#ifndef __INTEL_SSD__ /* Intel's headers aren't safe for multiple inclusion! */
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
char MPMY_Abchdir_arg[128];
|
||||
|
||||
/* Suitable for use as a userfunc */
|
||||
void MPMY_Abchdir(void){
|
||||
if( strlen(MPMY_Abchdir_arg) ){
|
||||
errno=0;
|
||||
if( mkdir(MPMY_Abchdir_arg, 0777) && errno != EEXIST ){
|
||||
Msg_do("Can't mkdir(\"%s\"): %d\n", MPMY_Abchdir_arg, errno);
|
||||
}
|
||||
errno = 0;
|
||||
if( chdir(MPMY_Abchdir_arg) ){
|
||||
Msg_do("Can't chdir(\"%s\"): %d\n", MPMY_Abchdir_arg, errno);
|
||||
}else{
|
||||
Msg_do("New directory: \"%s\"\n", MPMY_Abchdir_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ABANNOUNCE
|
||||
void MPMY_Abannounce(void){
|
||||
static int announced;
|
||||
/* Don't repeat yourself! */
|
||||
if (!announced){
|
||||
Msg_do("MPMY_ABNORMAL_SIGNUM: %d\n", MPMY_Abnormal_signum);
|
||||
MPMY_Diagnostic(Msg_do);
|
||||
}
|
||||
Msg_flush();
|
||||
announced = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PRINTMPMY_DIAGS
|
||||
void PrintMPMYDiags(void){
|
||||
MPMY_Diagnostic(Msg_do);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_TIMEOUT
|
||||
/* Aieeee!!! Some systems can link alarm, but when the execute it,
|
||||
they die (cm5). Other systems can't even link it (sunmos, ap1000).
|
||||
Others will crash mysteriously if they use alarm (lsv). This isn't
|
||||
really a PAROS thing, and it's not really ARCH either. Aargh. */
|
||||
#ifdef CANT_USE_ALARM
|
||||
#define HAVE_MPMY_TIMEOUT
|
||||
void
|
||||
MPMY_TimeoutSet(int n){
|
||||
SinglWarning("Can't use alarm(). Timeout not set!\n");
|
||||
}
|
||||
|
||||
void
|
||||
MPMY_TimeoutReset(int n){
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
MPMY_TimeoutCancel(void){
|
||||
return;
|
||||
}
|
||||
|
||||
#else /* CANT_USE_ALARM */
|
||||
|
||||
static int nt;
|
||||
static void
|
||||
alrm_hndlr(int sig)
|
||||
{
|
||||
/* Should this be Shout followed by MPMY_RaiseAbnormal()?? */
|
||||
Error("Exceeded timeout (%d sec)\n", nt);
|
||||
}
|
||||
|
||||
void
|
||||
MPMY_TimeoutSet(int n)
|
||||
{
|
||||
void (*prev_sig)(int);
|
||||
prev_sig = signal(SIGALRM, alrm_hndlr);
|
||||
if( prev_sig == SIG_DFL || prev_sig == NULL || prev_sig == SIG_IGN ){
|
||||
singlPrintf("Setting timeout to %d seconds.\n", n);
|
||||
alarm(n);
|
||||
nt = n;
|
||||
}else{
|
||||
singlPrintf("There is already a handler for SIGALRM at %p\n",
|
||||
prev_sig);
|
||||
singlPrintf("NOT setting timeout!\n");
|
||||
signal(SIGALRM, prev_sig);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MPMY_TimeoutReset(int n)
|
||||
{
|
||||
alarm(n);
|
||||
nt = n;
|
||||
}
|
||||
|
||||
void
|
||||
MPMY_TimeoutCancel(void)
|
||||
{
|
||||
alarm(0);
|
||||
signal(SIGALRM, SIG_DFL);
|
||||
}
|
||||
#endif /* CANT_USE_ALARM */
|
||||
#endif /* HAVE_MPMY_TIMEOUT */
|
286
external/libsdf/libmpmy/mpmy_generic.c
vendored
Normal file
286
external/libsdf/libmpmy/mpmy_generic.c
vendored
Normal file
|
@ -0,0 +1,286 @@
|
|||
/* This file is included in most (all?) of the mpmy_PAROS files.
|
||||
It defines several of the required mpmy functions in terms of a
|
||||
more primitive set. In some cases, however, there will be a PAROS
|
||||
specific way to achieve these results defined in the mpmy_PAROS file
|
||||
When that happens, the mpmy_PAROS file will also
|
||||
#define HAVE_MPMY_FUNCNAME
|
||||
so we know that we shouldn't define it here. */
|
||||
|
||||
/* These are set to the "right" thing on a uniprocessor, where it is
|
||||
most likely that we will neglect to call MPMY_Init, but where
|
||||
we really can proceed without any problems. I tried
|
||||
setting them to -1, but that just led to hard-to-understand
|
||||
crashes. We really should test occasionally that MPMY_Init has
|
||||
been called. But I'll leave that for another day... */
|
||||
int _MPMY_procnum_ = 0;
|
||||
int _MPMY_nproc_ = 1;
|
||||
int _MPMY_procs_per_node_ = 1;
|
||||
int _MPMY_initialized_ = 0;
|
||||
|
||||
Counter_t MPMYSendCnt;
|
||||
Counter_t MPMYRecvCnt;
|
||||
Counter_t MPMYDoneCnt;
|
||||
|
||||
#ifndef HAVE_MPMY_FLICK
|
||||
int MPMY_Flick(void){return MPMY_SUCCESS;}
|
||||
#endif /* HAVE_MPMY_FLICK */
|
||||
|
||||
#ifndef HAVE_MPMY_IRSEND
|
||||
int MPMY_Irsend(const void *buf, int cnt, int dest, int tag, MPMY_Comm_request *req){
|
||||
return MPMY_Isend(buf, cnt, dest, tag, req);
|
||||
}
|
||||
#endif /* HAVE_MPMY_IRSEND */
|
||||
|
||||
#ifndef HAVE_MPMY_SHIFT
|
||||
/* An implementation of shift that just uses mpmy_isend/irecv */
|
||||
/* Some systems will have a better option, but this should always work. */
|
||||
|
||||
#define SHIFT_TAG 0x1492
|
||||
/* Because NX can't distinguish different sources when reading */
|
||||
/* messages, we help it out by adding processor info to the tag. */
|
||||
/* Is this really necessary for the "generic" implementation? */
|
||||
int MPMY_Shift(int proc, void *recvbuf, int recvcnt,
|
||||
const void *sendbuf, int sendcnt, MPMY_Status *stat){
|
||||
MPMY_Comm_request inreq, outreq;
|
||||
Msgf(("Starting MPMY_Shift(proc=%d, recvcnt=%d, sendcnt=%d:\n",
|
||||
proc, recvcnt, sendcnt));
|
||||
if (proc > _MPMY_procnum_) {
|
||||
MPMY_Irecv(recvbuf, recvcnt, proc, SHIFT_TAG+proc, &inreq);
|
||||
Msgf(("Irecv posted\n"));
|
||||
MPMY_Wait(inreq, stat);
|
||||
Msgf(("Irecv done\n"));
|
||||
MPMY_Isend(sendbuf, sendcnt, proc, SHIFT_TAG+MPMY_Procnum(), &outreq);
|
||||
Msgf(("Isend posted\n"));
|
||||
MPMY_Wait(outreq, NULL);
|
||||
Msgf(("Isend done\n"));
|
||||
} else {
|
||||
MPMY_Isend(sendbuf, sendcnt, proc, SHIFT_TAG+MPMY_Procnum(), &outreq);
|
||||
Msgf(("Isend posted\n"));
|
||||
MPMY_Wait(outreq, NULL);
|
||||
Msgf(("Isend done\n"));
|
||||
MPMY_Irecv(recvbuf, recvcnt, proc, SHIFT_TAG+proc, &inreq);
|
||||
Msgf(("Irecv posted\n"));
|
||||
MPMY_Wait(inreq, stat);
|
||||
Msgf(("Irecv done\n"));
|
||||
}
|
||||
|
||||
Msgf(("Finished MPMY_Shift\n"));
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
#endif /* HAVE_MPMY_SHIFT */
|
||||
|
||||
/*
|
||||
This could be smarter. In particular, it could recover gracefully
|
||||
from malloc failing to deliver.
|
||||
*/
|
||||
#ifndef HAVE_MPMY_SHIFT_OVERLAP
|
||||
#include "Malloc.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int MPMY_Shift_overlap(int proc, void *recvbuf, int recvcnt,
|
||||
const void *sendbuf, int sendcnt, MPMY_Status *stat){
|
||||
void *tmp = Malloc(sendcnt);
|
||||
int ret;
|
||||
|
||||
if( tmp == NULL && sendcnt>0 )
|
||||
return MPMY_FAILED;
|
||||
memcpy(tmp, sendbuf, sendcnt);
|
||||
ret = MPMY_Shift(proc, recvbuf, recvcnt, tmp, sendcnt, stat);
|
||||
Free(tmp);
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_MPMY_SHIFT_OVERLAP */
|
||||
|
||||
#ifndef HAVE_MPMY_SYNC
|
||||
/* Implementation of MPMY_Sync in terms of the 'combine' functions. */
|
||||
/* Some systems might provide a more useful interface. */
|
||||
|
||||
int MPMY_Sync(void){
|
||||
int junk=0;
|
||||
|
||||
/* I'm sure this is overkill! */
|
||||
return MPMY_Combine(&junk, &junk, 1, MPMY_INT, MPMY_BOR);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_FINALIZE
|
||||
/* Any system specific stuff gets handled by a system-specific finalizer */
|
||||
int MPMY_Finalize(void){
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_WAIT
|
||||
/* An implementation of mpmy_wait that just busy-waits on MPMY_Test. */
|
||||
/* Some systems will have a better option, but this should always work. */
|
||||
|
||||
int MPMY_Wait(MPMY_Comm_request req, MPMY_Status *stat){
|
||||
/* Should we do a 'MPMY_Flick'' ? */
|
||||
int flag = 0;
|
||||
int ret;
|
||||
|
||||
do{
|
||||
MPMY_Flick();
|
||||
ret = MPMY_Test(req, &flag, stat);
|
||||
}while( ret == MPMY_SUCCESS && flag==0 );
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_MPMY_WAIT */
|
||||
|
||||
#ifndef HAVE_MPMY_WAIT2
|
||||
int MPMY_Wait2(MPMY_Comm_request req1, MPMY_Status *stat1,
|
||||
MPMY_Comm_request req2, MPMY_Status *stat2){
|
||||
/* Should we do a 'MPMY_Flick'' ? */
|
||||
int done1, done2;
|
||||
int ret;
|
||||
|
||||
done1 = done2 = 0;
|
||||
do{ /* loop until at least one is finished */
|
||||
MPMY_Flick();
|
||||
ret = MPMY_Test(req1, &done1, stat1);
|
||||
if( ret != MPMY_SUCCESS )
|
||||
return ret;
|
||||
ret = MPMY_Test(req2, &done2, stat2);
|
||||
if( ret != MPMY_SUCCESS )
|
||||
return ret;
|
||||
}while( done1 == 0 && done2 == 0 );
|
||||
|
||||
/* Now there's only one left, so we can call MPMY_Wait */
|
||||
if( !done1 ){
|
||||
ret = MPMY_Wait(req1, stat1);
|
||||
if( ret != MPMY_SUCCESS )
|
||||
return ret;
|
||||
}
|
||||
if( !done2 ){
|
||||
ret = MPMY_Wait(req2, stat2);
|
||||
if( ret != MPMY_SUCCESS )
|
||||
return ret;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_MPMY_DIAGNOSTIC
|
||||
void MPMY_Diagnostic(int (*printflike)(const char *, ...)){
|
||||
(*printflike)("No Diagnostic info for this MPMY\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_INITIALIZED
|
||||
int MPMY_Initialized(void){
|
||||
return _MPMY_initialized_;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_PHYSNODE
|
||||
const char *MPMY_Physnode(void){
|
||||
return "?";
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_TIMERS
|
||||
/* This is a nightmare! Timers should really be ARCH dependent */
|
||||
/* but because of the CM5's special closeness to ARCH=sun4, they */
|
||||
/* are PAROS dependent, instead. That means that we would otherwise */
|
||||
/* repeat this code block in lots of mpmy_PAROS.c files */
|
||||
#ifdef _AIX
|
||||
/* No longer working?? Nov 3 1994
|
||||
# include "timers_readrtc.c" */
|
||||
#if !defined(USE_HWCLOCK) && !defined(USE_GETTIME)
|
||||
#include "timers_posix.c"
|
||||
#endif
|
||||
/* it's not inconceivable to compile sequentially for the intels */
|
||||
/* However, we won't necessarily be linking against, e.g, hwclock
|
||||
#elif defined(__INTEL_SSD__)
|
||||
# include "timers_nx.c"
|
||||
*/
|
||||
#else
|
||||
#if !defined(USE_HWCLOCK) && !defined(USE_GETTIME)
|
||||
# include "timers_posix.c"
|
||||
#endif
|
||||
#endif /* _AIX */
|
||||
#endif /* HAVE_MPMY_TIMERS */
|
||||
|
||||
static time_t job_start;
|
||||
static time_t job_end;
|
||||
static time_t checkpoint_last;
|
||||
static time_t checkpoint_next;
|
||||
static time_t checkpoint_interval;
|
||||
static int checkpoint_setup;
|
||||
|
||||
void
|
||||
MPMY_CheckpointSetup(int job_seconds, int interval_seconds, int step_seconds)
|
||||
{
|
||||
if (MPMY_Procnum() == 0) {
|
||||
job_start = time(NULL);
|
||||
if (job_seconds == -1) job_end = -1;
|
||||
else job_end = job_start + job_seconds - step_seconds;
|
||||
checkpoint_interval = interval_seconds - step_seconds;
|
||||
checkpoint_last = job_start;
|
||||
checkpoint_next = job_start + checkpoint_interval;
|
||||
Msg_do("Checkpoint Setup interval %ld start %ld next %ld end %ld\n",
|
||||
checkpoint_interval, job_start, checkpoint_next, job_end);
|
||||
}
|
||||
checkpoint_setup = 1;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_CheckpointDue(int next_output_seconds)
|
||||
{
|
||||
time_t t;
|
||||
int retval = 0;
|
||||
|
||||
if (MPMY_Procnum() == 0) {
|
||||
t = time(NULL);
|
||||
if (t >= checkpoint_next) retval = 1;
|
||||
if (next_output_seconds < checkpoint_interval/4) {
|
||||
Msg_do("Postponing checkpoint since output expected in %d seconds\n",
|
||||
next_output_seconds);
|
||||
retval = 0;
|
||||
}
|
||||
if (job_end > 0 && t >= job_end) retval = 1;
|
||||
}
|
||||
if (retval) Msg_do("Checkpoint Due\n");
|
||||
MPMY_Bcast(&retval, 1, MPMY_INT, 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
MPMY_CheckpointFinished(void)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
if (MPMY_Procnum() == 0) {
|
||||
t = time(NULL);
|
||||
checkpoint_last = t;
|
||||
checkpoint_next = t + checkpoint_interval;
|
||||
if (job_end > 0 && checkpoint_next > job_end) checkpoint_next = job_end;
|
||||
Msg_do("next checkpoint %ld (%ld from now)\n", checkpoint_next, checkpoint_next-t);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_JobDone(void)
|
||||
{
|
||||
time_t t;
|
||||
int retval = 0;
|
||||
|
||||
if (MPMY_Procnum() == 0) {
|
||||
t = time(NULL);
|
||||
if (job_end > 0 && t >= job_end) {
|
||||
retval = 1;
|
||||
Msg_do("Job Done\n");
|
||||
}
|
||||
}
|
||||
MPMY_Bcast(&retval, 1, MPMY_INT, 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifndef HAVE_MPMY_JOBREMAINING
|
||||
int
|
||||
MPMY_JobRemaining(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
525
external/libsdf/libmpmy/mpmy_io.c
vendored
Normal file
525
external/libsdf/libmpmy/mpmy_io.c
vendored
Normal file
|
@ -0,0 +1,525 @@
|
|||
|
||||
/* The default I/O model here is that only proc 0 can read/write etc. */
|
||||
/* There are two I/O modes for read and write, MULTI and SINGL */
|
||||
/* All other functions do not have an I/O mode associated with them */
|
||||
/* All calls must be loosely synchronous. There is a single file pointer */
|
||||
/* This model works on all machines, but it may not be the most efficient */
|
||||
|
||||
/* MPMY_NFILE extends the mpmy_io model to include multiple file segments */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "Assert.h"
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
#include "mpmy_io.h"
|
||||
#include "Msgs.h"
|
||||
#include "Malloc.h"
|
||||
#include "iozero.h"
|
||||
|
||||
#ifndef EINVAL
|
||||
/* just in case... */
|
||||
#define EINVAL 0
|
||||
#endif
|
||||
|
||||
#define NFILES 4096
|
||||
static struct _File{
|
||||
int fd;
|
||||
int iomode;
|
||||
int iotype;
|
||||
} _files[NFILES];
|
||||
|
||||
#define DEFAULT_PERMS 0644
|
||||
static int do_nfileio;
|
||||
|
||||
int
|
||||
MPMY_Nfileio(int val){
|
||||
int oldval = do_nfileio;
|
||||
do_nfileio = val;
|
||||
return oldval;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_SetIOMode(MPMYFile *Fp, int iomode)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
|
||||
fp->iomode = iomode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
MPMYFile *
|
||||
MPMY_Fopen(const char *path, int mpmy_flags)
|
||||
{
|
||||
int fd;
|
||||
int flags = 0;
|
||||
int iomode = MPMY_SINGL;
|
||||
int iotype = 0;
|
||||
|
||||
Msgf(("Fopen %s\n", path));
|
||||
if (mpmy_flags & MPMY_RDONLY) flags |= O_RDONLY;
|
||||
if (mpmy_flags & MPMY_WRONLY) flags |= O_WRONLY;
|
||||
if (mpmy_flags & MPMY_RDWR) flags |= O_RDWR;
|
||||
if (mpmy_flags & MPMY_APPEND) flags |= O_APPEND;
|
||||
if (mpmy_flags & MPMY_TRUNC) flags |= O_TRUNC;
|
||||
if (mpmy_flags & MPMY_CREAT) flags |= O_CREAT;
|
||||
|
||||
if (mpmy_flags & MPMY_MULTI) iomode = MPMY_MULTI;
|
||||
if (mpmy_flags & MPMY_SINGL) iomode = MPMY_SINGL;
|
||||
|
||||
/* This is a sub-mode which can work with either of the above */
|
||||
if (mpmy_flags & MPMY_NFILE) iotype = MPMY_NFILE;
|
||||
|
||||
if (mpmy_flags & MPMY_INDEPENDENT) {
|
||||
iotype = MPMY_INDEPENDENT;
|
||||
iomode = MPMY_MULTI;
|
||||
}
|
||||
|
||||
/* We need an external control for nfile mode */
|
||||
if (do_nfileio) iotype = MPMY_NFILE;
|
||||
|
||||
if (iotype == MPMY_NFILE) {
|
||||
char real_path[256];
|
||||
sprintf(real_path, "%s.p%03d", path, MPMY_Procnum());
|
||||
fd = open(real_path, flags, DEFAULT_PERMS);
|
||||
} else if (iotype == MPMY_INDEPENDENT) {
|
||||
fd = open(path, flags, DEFAULT_PERMS);
|
||||
} else {
|
||||
if( strcmp(path, "-") != 0 ){
|
||||
fd = open0(path, flags, DEFAULT_PERMS);
|
||||
}else{
|
||||
/* Be very afraid. */
|
||||
/* We made MPMY_RDONLY zero because O_RDONLY==0. But why
|
||||
did 'they' do that?! */
|
||||
if ( (mpmy_flags & MPMY_RDWR) )
|
||||
Error("Can't open '-' RDWR\n");
|
||||
#if MPMY_RDONLY != 0
|
||||
# error Aargh.
|
||||
#endif
|
||||
if(mpmy_flags & MPMY_WRONLY )
|
||||
fd = 1; /* stdout */
|
||||
else /* we can't test for MPMY_RDONLY! */
|
||||
fd = 0; /* stdout */
|
||||
}
|
||||
}
|
||||
|
||||
if (fd >= NFILES) Error("fd too large (%d)\n", fd);
|
||||
if(fd >= 0){
|
||||
_files[fd].iomode = iomode;
|
||||
_files[fd].iotype = iotype;
|
||||
_files[fd].fd = fd;
|
||||
Msgf(("Fopen returns %d, iomode=%d, flags=0x%x\n", fd, iomode, flags));
|
||||
return &(_files[fd]);
|
||||
}else{
|
||||
Msgf(("Fopen fails, errno=%d\n", errno));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Fclose(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
int ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iotype & MPMY_NFILE || fp->iotype & MPMY_INDEPENDENT) {
|
||||
ret = close(fp->fd);
|
||||
} else {
|
||||
ret = close0(fp->fd);
|
||||
}
|
||||
fp->fd = -1;
|
||||
Msgf(("Close returns %d\n", ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Mkdir(const char *path, int mode){
|
||||
return mkdir0(path, mode);
|
||||
}
|
||||
|
||||
size_t
|
||||
MPMY_Fread(void *ptr, size_t size, size_t nitems, MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
ssize_t ret = -1;
|
||||
|
||||
Msgf(("Fread(ptr=%p, size=%ld, nitems=%ld, FILE=%p)\n",
|
||||
ptr, size, nitems, Fp));
|
||||
Msg_flush();
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (fp->iomode) {
|
||||
case MPMY_SINGL:
|
||||
ret = read0(fp->fd, ptr, (long)size*nitems);
|
||||
break;
|
||||
case MPMY_MULTI:
|
||||
if (fp->iotype & MPMY_NFILE || fp->iotype & MPMY_INDEPENDENT)
|
||||
ret = read(fp->fd, ptr, (long)size*nitems);
|
||||
else
|
||||
ret = read0_multi(fp->fd, ptr, (long)size*nitems);
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
Msgf(("Fread returns %ld.\n", ret));
|
||||
if( ret < 0 ){
|
||||
Warning("MPMY_Fread: read returns %ld, errno=%d\n", ret, errno);
|
||||
return -1;
|
||||
}
|
||||
if (ret % size)
|
||||
Shout("MPMY_Fread has a problem, ret=%ld, size=%ld\n", ret, size);
|
||||
return ret/size;
|
||||
}
|
||||
|
||||
size_t
|
||||
MPMY_Fwrite(const void *ptr, size_t size, size_t nitems, MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
ssize_t ret = -1;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (fp->iomode) {
|
||||
case MPMY_SINGL:
|
||||
ret = write0(fp->fd, ptr, size*nitems);
|
||||
break;
|
||||
case MPMY_MULTI:
|
||||
if (fp->iotype & MPMY_NFILE || fp->iotype & MPMY_INDEPENDENT)
|
||||
ret = write(fp->fd, ptr, size*nitems);
|
||||
else
|
||||
ret = write0_multi(fp->fd, ptr, size*nitems);
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
Shout("Bad iomode in Fwrite\n");
|
||||
}
|
||||
|
||||
Msgf(("Fwrite returns %ld.\n", ret));
|
||||
if( ret < 0 ){
|
||||
Warning("MPMY_Fwrite: write returns %ld, errno=%d\n", ret, errno);
|
||||
return -1;
|
||||
}
|
||||
if (ret % size)
|
||||
Shout("MPMY_Fwrite has a problem: ret=%ld, size=%ld\n", ret, size);
|
||||
return ret/size;
|
||||
}
|
||||
|
||||
off_t
|
||||
MPMY_Fseek(MPMYFile *Fp, off_t offset, int whence)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
off_t ret;
|
||||
int real_whence = 0;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (whence == MPMY_SEEK_SET) real_whence = SEEK_SET;
|
||||
if (whence == MPMY_SEEK_CUR) real_whence = SEEK_CUR;
|
||||
if (whence == MPMY_SEEK_END) real_whence = SEEK_END;
|
||||
|
||||
if (fp->iotype == MPMY_INDEPENDENT) {
|
||||
ret = lseek(fp->fd, offset, real_whence);
|
||||
} else {
|
||||
ret = lseek0(fp->fd, offset, real_whence);
|
||||
}
|
||||
if (ret != -1) ret = 0;
|
||||
Msgf(("Fseek returns %ld\n", (long)ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
off_t
|
||||
MPMY_Ftell(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
off_t ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iotype == MPMY_INDEPENDENT) {
|
||||
ret = lseek(fp->fd, 0L, SEEK_CUR);
|
||||
} else {
|
||||
ret = tell0(fp->fd);
|
||||
}
|
||||
Msgf(("Ftell returns %ld\n", (long)ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
off_t
|
||||
MPMY_Flen(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
off_t ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iotype & MPMY_NFILE) {
|
||||
ret = flen(fp->fd);
|
||||
Msgf(("flen segment %ld\n", (long)ret));
|
||||
if (sizeof(ret) != sizeof(long)) {
|
||||
Error("Bad types in MPMY_Flen\n");
|
||||
}
|
||||
MPMY_Combine(&ret, &ret, 1, MPMY_LONG, MPMY_SUM);
|
||||
} else if (fp->iotype == MPMY_INDEPENDENT) {
|
||||
ret = flen(fp->fd);
|
||||
} else {
|
||||
ret = flen0(fp->fd);
|
||||
}
|
||||
Msgf(("Flen returns %ld\n", (long)ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MAXREQ 4
|
||||
|
||||
static int
|
||||
fseekrd_nfile(int fd, off_t offset, int whence, void *buf, int reclen,
|
||||
int nrecs)
|
||||
{
|
||||
off_t offend;
|
||||
void *tmpbuf = 0; /* realloc null first time */
|
||||
int i;
|
||||
off_t nread;
|
||||
long size;
|
||||
struct {
|
||||
off_t offset;
|
||||
off_t flen;
|
||||
off_t start;
|
||||
long reclen;
|
||||
long nrecs;
|
||||
} parbuf, *allbuf;
|
||||
MPMY_Status stat;
|
||||
MPMY_Comm_request req[MAXREQ]; /* should be dynamic? */
|
||||
int nreq = 0;
|
||||
int procnum = MPMY_Procnum();
|
||||
off_t my_start, my_size, my_end;
|
||||
int nproc = MPMY_Nproc();
|
||||
|
||||
if (whence != MPMY_SEEK_SET)
|
||||
Error("Fseekrd Nfiles must use SEEK_SET\n");
|
||||
|
||||
parbuf.offset = offset;
|
||||
parbuf.reclen = reclen;
|
||||
parbuf.nrecs = nrecs;
|
||||
parbuf.flen = flen(fd);
|
||||
|
||||
allbuf = Malloc(sizeof(parbuf)*nproc);
|
||||
|
||||
MPMY_AllGather(&parbuf, sizeof(parbuf)/sizeof(long), MPMY_LONG, allbuf);
|
||||
|
||||
my_start = 0;
|
||||
for (i = 0; i < nproc; i++) {
|
||||
allbuf[i].start = my_start;
|
||||
my_start += allbuf[i].flen;
|
||||
}
|
||||
offend = offset+nrecs*reclen;
|
||||
my_start = allbuf[procnum].start;
|
||||
my_size = allbuf[procnum].flen;
|
||||
my_end = my_start+my_size;
|
||||
|
||||
Msgf(("reclen %d\n", reclen));
|
||||
Msgf(("offset %ld\n", offset));
|
||||
Msgf(("nrecs*reclen %d\n", nrecs*reclen));
|
||||
Msgf(("my_start %ld\n", my_start));
|
||||
Msgf(("my_size %ld\n", my_size));
|
||||
Msgf(("my_end %ld\n", my_end));
|
||||
|
||||
/* post Irecvs for my data */
|
||||
for (i = 0; i < nproc; i++) {
|
||||
if (allbuf[i].start<=offset && offset<allbuf[i].start+allbuf[i].flen) {
|
||||
size = allbuf[i].start+allbuf[i].flen-offset;
|
||||
if (size > reclen*nrecs) size = reclen*nrecs;
|
||||
Msgf(("irecv %ld from %d\n", size, i));
|
||||
if (nreq >= MAXREQ) Error("Too many Irecvs in fseekrd\n");
|
||||
MPMY_Irecv(buf, size, i, MPMY_IOTAG, &req[nreq]);
|
||||
++nreq;
|
||||
} else if (offset <= allbuf[i].start && offend > allbuf[i].start+allbuf[i].flen) {
|
||||
size = allbuf[i].flen;
|
||||
Msgf(("irecv %ld from %d\n", size, i));
|
||||
if (nreq >= MAXREQ) Error("Too many Irecvs in fseekrd\n");
|
||||
MPMY_Irecv((char *)buf+allbuf[i-1].start+allbuf[i-1].flen-offset,
|
||||
size, i, MPMY_IOTAG+2, &req[nreq]);
|
||||
++nreq;
|
||||
} else if (allbuf[i].start<offend && offend<=allbuf[i].start+allbuf[i].flen) {
|
||||
size = offend-allbuf[i].start;
|
||||
Msgf(("irecv %ld from %d\n", size, i));
|
||||
if (nreq >= MAXREQ) Error("Too many Irecvs in fseekrd\n");
|
||||
MPMY_Irecv((char *)buf+reclen*nrecs-size, size, i,
|
||||
MPMY_IOTAG+1, &req[nreq]);
|
||||
++nreq;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nproc; i++) {
|
||||
offset = allbuf[i].offset;
|
||||
reclen = allbuf[i].reclen;
|
||||
nrecs = allbuf[i].nrecs;
|
||||
offend = offset+reclen*nrecs;
|
||||
|
||||
if (my_start <= offset && offset < my_end) {
|
||||
size = my_end-offset;
|
||||
if (size > reclen*nrecs) size = reclen*nrecs;
|
||||
lseek(fd, offset-my_start, SEEK_SET);
|
||||
tmpbuf = Realloc(tmpbuf, size);
|
||||
nread = read(fd, tmpbuf, size);
|
||||
Msgf(("send %ld to %d\n", size, i));
|
||||
MPMY_send(tmpbuf, size, i, MPMY_IOTAG);
|
||||
} else if (offset <= my_start && offend > my_end) {
|
||||
size = my_end-my_start;
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
tmpbuf = Realloc(tmpbuf, size);
|
||||
nread = read(fd, tmpbuf, size);
|
||||
Msgf(("send %ld to %d\n", size, i));
|
||||
MPMY_send(tmpbuf, size, i, MPMY_IOTAG+2);
|
||||
} else if (my_start < offend && offend <= my_end) {
|
||||
size = offend-my_start;
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
tmpbuf = Realloc(tmpbuf, size);
|
||||
nread = read(fd, tmpbuf, size);
|
||||
Msgf(("send %ld to %d\n", size, i));
|
||||
MPMY_send(tmpbuf, size, i, MPMY_IOTAG+1);
|
||||
}
|
||||
}
|
||||
Free(tmpbuf);
|
||||
Free(allbuf);
|
||||
nread = 0;
|
||||
Msg_flush();
|
||||
#if 0
|
||||
for (i = 0; i < nreq; i++) {
|
||||
MPMY_Wait(req[i], &stat);
|
||||
Msgf(("Got %d from %d\n", stat.count, stat.src));
|
||||
nread += stat.count;
|
||||
}
|
||||
#else
|
||||
i = 0;
|
||||
while( nreq ){
|
||||
int done;
|
||||
/* Msgf(("Testing req[%d] = %p\n", i, req[i])); */
|
||||
MPMY_Test(req[i], &done, &stat);
|
||||
if( done ){
|
||||
Msgf(("Got %d from %d\n", stat.count, stat.src));
|
||||
nread += stat.count;
|
||||
Msgf(("Moving req[%d] = req[%d] = ", i, nreq-1));
|
||||
req[i] = req[--nreq];
|
||||
Msgf(("%p\n", req[i]));
|
||||
}else{
|
||||
/* Msgf(("Req[%d] not done yet\n", i)); */
|
||||
i++;
|
||||
}
|
||||
assert(i <= nreq );
|
||||
if( i == nreq )
|
||||
i = 0;
|
||||
}
|
||||
#endif
|
||||
Msgf(("fseekrd_nfile returning = %ld\n", nread/reclen));
|
||||
return nread/reclen;
|
||||
}
|
||||
|
||||
/* This should be called from fseekrd0 instead of replicating code */
|
||||
|
||||
static int
|
||||
fseekrd(int fd, off_t offset, int whence, void *buf, int reclen,
|
||||
int nrecs)
|
||||
{
|
||||
int doseek;
|
||||
int real_whence;
|
||||
off_t nread = 0;
|
||||
off_t len;
|
||||
|
||||
if( whence == SEEK_CUR ){
|
||||
doseek = (offset != 0);
|
||||
}else if( whence == SEEK_SET ){
|
||||
/* don't worry about errors. If ftell returns -1, */
|
||||
/* doseek will be turned on, and the fseek below will */
|
||||
/* (probably) fail */
|
||||
doseek = (lseek(fd, 0L, SEEK_CUR) != offset);
|
||||
}else{
|
||||
doseek = 1;
|
||||
}
|
||||
|
||||
if( doseek ){
|
||||
switch(whence){
|
||||
case MPMY_SEEK_SET:
|
||||
real_whence = SEEK_SET;
|
||||
break;
|
||||
case MPMY_SEEK_CUR:
|
||||
real_whence = SEEK_CUR;
|
||||
break;
|
||||
case MPMY_SEEK_END:
|
||||
real_whence = SEEK_END;
|
||||
break;
|
||||
default:
|
||||
Shout("Illegal value of whence (%d) in fseekrd\n", whence);
|
||||
return -1;
|
||||
}
|
||||
if (lseek(fd, offset, real_whence) == -1) {
|
||||
Error("fseekrd: lseek(%d, %ld, %d) failed, errno=%d\n",
|
||||
fd, (long)offset, whence, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
len = 0;
|
||||
while (len < reclen*nrecs) {
|
||||
nread = read(fd, (char *)buf+len, reclen*nrecs-len);
|
||||
if (nread == -1) {
|
||||
Error("fseekrd: read(%d, %ld) failed, errno=%d\n",
|
||||
fd, (long)reclen*nrecs-len, errno);
|
||||
return -1;
|
||||
} else if (nread == 0) {
|
||||
Error("fseekrd: read(%d, %ld) got EOF\n",
|
||||
fd, (long)reclen*nrecs-len);
|
||||
return -1;
|
||||
} else {
|
||||
printf("%d fseekrd(%d): got %ld\n", fd, MPMY_Procnum(), (long)nread);
|
||||
len += nread;
|
||||
}
|
||||
}
|
||||
if (len != reclen*nrecs) Error("fseekrd: Wrong amount of data\n");
|
||||
return nread/reclen;
|
||||
}
|
||||
|
||||
size_t
|
||||
MPMY_Fseekrd(MPMYFile *Fp, off_t offset, int whence, void *buf, size_t reclen,
|
||||
size_t nrecs)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iotype & MPMY_NFILE) {
|
||||
nrecs = fseekrd_nfile(fp->fd, offset, whence, buf, reclen, nrecs);
|
||||
} else if (fp->iotype == MPMY_INDEPENDENT) {
|
||||
nrecs = fseekrd(fp->fd, offset, whence, buf, reclen, nrecs);
|
||||
} else {
|
||||
nrecs = fseekrd0(fp->fd, offset, whence, buf, reclen, nrecs);
|
||||
}
|
||||
return nrecs;
|
||||
}
|
||||
|
||||
#include "iozero.c"
|
||||
#include "io_generic.c"
|
399
external/libsdf/libmpmy/mpmy_mpi.c
vendored
Normal file
399
external/libsdf/libmpmy/mpmy_mpi.c
vendored
Normal file
|
@ -0,0 +1,399 @@
|
|||
#ifdef _SWAMPI
|
||||
#include <swampi.h>
|
||||
#else
|
||||
#include <mpi.h>
|
||||
#endif
|
||||
#include "mpmy_abnormal.h"
|
||||
|
||||
#include "Malloc.h"
|
||||
|
||||
#include "chn.h"
|
||||
#include "mpmy.h"
|
||||
#include "Assert.h"
|
||||
#include "timers.h"
|
||||
#include "Msgs.h"
|
||||
#include "error.h"
|
||||
#include "memfile.h"
|
||||
|
||||
struct comm_s {
|
||||
MPI_Request hndl;
|
||||
int inout;
|
||||
};
|
||||
|
||||
static Chn commchn;
|
||||
#define NCOMM 2048
|
||||
#define IN 1
|
||||
#define OUT 2
|
||||
|
||||
int MPMY_Isend(const void *buf, int cnt, int dest, int tag,
|
||||
MPMY_Comm_request *reqp) {
|
||||
struct comm_s *comm = ChnAlloc(&commchn);
|
||||
|
||||
Msgf(("Isend: buf=%p, cnt=%d, dest=%d, tag=%d\n",
|
||||
buf, cnt, dest, tag));
|
||||
if (MPI_Isend((void *)buf, cnt, MPI_BYTE, dest, tag, MPI_COMM_WORLD,
|
||||
&comm->hndl) != MPI_SUCCESS)
|
||||
Error("MPMY_Isend MPI_Isend failed\n");
|
||||
comm->inout = OUT;
|
||||
Msgf(("Isend: hndl=%ld\n", (long) comm->hndl));
|
||||
*reqp = comm;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define HAVE_MPMY_IRSEND
|
||||
int MPMY_Irsend(const void *buf, int cnt, int dest, int tag,
|
||||
MPMY_Comm_request *reqp) {
|
||||
struct comm_s *comm = ChnAlloc(&commchn);
|
||||
|
||||
Msgf(("Irsend: buf=%p, dest=%d, tag=%d\n",
|
||||
buf, dest, tag));
|
||||
if (MPI_Irsend(buf, cnt, MPI_BYTE, dest, tag, MPI_COMM_WORLD,
|
||||
&comm->hndl) != MPI_SUCCESS)
|
||||
Error("MPMY_Isend MPI_Irsend failed\n");
|
||||
comm->inout = OUT;
|
||||
Msgf(("Irsend: hndl=%d\n", (int) comm->hndl));
|
||||
*reqp = comm;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
int MPMY_Irecv(void *buf, int cnt, int src, int tag, MPMY_Comm_request *reqp) {
|
||||
struct comm_s *comm = ChnAlloc(&commchn);
|
||||
|
||||
if (tag == MPMY_TAG_ANY) tag = MPI_ANY_TAG;
|
||||
if (src == MPMY_SOURCE_ANY) {
|
||||
src = MPI_ANY_SOURCE;
|
||||
} else if (src < 0 || src >= MPMY_Nproc()) {
|
||||
Error("Bad src (%d) in Irecv\n", src);
|
||||
}
|
||||
Msgf(("Irecv: buf=%p, src=%d, tag=%d\n",
|
||||
buf, src, tag));
|
||||
if (MPI_Irecv(buf, cnt, MPI_BYTE, src, tag, MPI_COMM_WORLD,
|
||||
&comm->hndl) != MPI_SUCCESS)
|
||||
Error("MPMY_Irecv MPI_Irecv failed\n");
|
||||
comm->inout = IN;
|
||||
Msgf(("Irecv: hndl=%ld\n", (long) comm->hndl));
|
||||
*reqp = comm;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_Test(MPMY_Comm_request req, int *flag, MPMY_Status *stat) {
|
||||
struct comm_s *comm = req;
|
||||
MPI_Status status;
|
||||
int cnt;
|
||||
int ret = 0;
|
||||
|
||||
Msgf(("MPMY_Test hndl=%ld at %p\n", (long) comm->hndl, &comm->hndl));
|
||||
if ((ret = MPI_Test(&comm->hndl, flag, &status)) != MPI_SUCCESS) {
|
||||
Error("MPMY_Test MPI_Test failed (%d), MPI_ERROR %d, hndl=%ld at %p, flag=%p, status=%p\n",
|
||||
ret, status.MPI_ERROR, (long)comm->hndl, &comm->hndl, flag, &status);
|
||||
}
|
||||
Msgf(("Tested (%s), %d\n",
|
||||
(comm->inout==IN)?"in":"out", *flag));
|
||||
if (*flag) {
|
||||
if(comm->inout == IN) {
|
||||
MPI_Get_count(&status, MPI_BYTE, &cnt);
|
||||
Msgf(("Recvd(T) from %d, tag %d, count: %d\n",
|
||||
status.MPI_SOURCE, status.MPI_TAG, cnt));
|
||||
if (stat) {
|
||||
stat->src = status.MPI_SOURCE;
|
||||
stat->tag = status.MPI_TAG;
|
||||
stat->count = cnt;
|
||||
}
|
||||
}
|
||||
ChnFree(&commchn, comm);
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
#define HAVE_MPMY_WAIT
|
||||
int MPMY_Wait(MPMY_Comm_request req, MPMY_Status *stat) {
|
||||
struct comm_s *comm = req;
|
||||
MPI_Status status;
|
||||
int cnt;
|
||||
|
||||
Msgf(("Wait for %ld\n", (long) comm->hndl));
|
||||
if (MPI_Wait(&comm->hndl, &status) != MPI_SUCCESS)
|
||||
Error("MPMY_Wait MPI_Wait failed\n");
|
||||
Msgf(("Waited for (%s), deallocated\n",
|
||||
(comm->inout==IN)?"in":"out"));
|
||||
if(comm->inout == IN) {
|
||||
MPI_Get_count(&status, MPI_BYTE, &cnt);
|
||||
Msgf(("Recvd(W) from %d, tag %d, count: %d\n",
|
||||
status.MPI_SOURCE, status.MPI_TAG, cnt));
|
||||
if (stat) {
|
||||
stat->src = status.MPI_SOURCE;
|
||||
stat->tag = status.MPI_TAG;
|
||||
stat->count = cnt;
|
||||
}
|
||||
}
|
||||
ChnFree(&commchn, comm);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
#define HAVE_MPMY_SHIFT
|
||||
#define SHIFT_TAG 0x1492
|
||||
int MPMY_Shift(int proc, void *recvbuf, int recvcnt,
|
||||
const void *sendbuf, int sendcnt, MPMY_Status *stat) {
|
||||
MPI_Status status;
|
||||
int count;
|
||||
|
||||
Msgf(("Starting MPMY_Shift(proc=%d, recvcnt=%d, sendcnt=%d, recvbuf=%p, sendbuf=%p\n",
|
||||
proc, recvcnt, sendcnt, recvbuf, sendbuf));
|
||||
|
||||
if (MPI_Sendrecv((void *)sendbuf, sendcnt, MPI_BYTE, proc, SHIFT_TAG,
|
||||
recvbuf, recvcnt, MPI_BYTE, proc, SHIFT_TAG,
|
||||
MPI_COMM_WORLD, &status) != MPI_SUCCESS)
|
||||
Error("MPMY_Shift MPI_Sendrecv failed\n");
|
||||
MPI_Get_count(&status, MPI_BYTE, &count);
|
||||
Msgf(("MPMY_Shift done, received=%d\n", count));
|
||||
if (stat) {
|
||||
stat->count = count;
|
||||
stat->src = status.MPI_SOURCE;
|
||||
stat->tag = status.MPI_TAG;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
Native_MPMY_Alltoall(void *sendbuf, int sendcount, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int recvcount, MPMY_Datatype recvtype)
|
||||
{
|
||||
MPI_Datatype st, rt;
|
||||
|
||||
switch (sendtype){
|
||||
case MPMY_FLOAT:
|
||||
st = MPI_FLOAT;
|
||||
break;
|
||||
case MPMY_DOUBLE:
|
||||
st = MPI_DOUBLE;
|
||||
break;
|
||||
case MPMY_INT:
|
||||
st = MPI_INT;
|
||||
break;
|
||||
case MPMY_CHAR:
|
||||
st = MPI_CHAR;
|
||||
break;
|
||||
default:
|
||||
Error("No type match in alltoall\n");
|
||||
}
|
||||
switch (recvtype){
|
||||
case MPMY_FLOAT:
|
||||
rt = MPI_FLOAT;
|
||||
break;
|
||||
case MPMY_DOUBLE:
|
||||
rt = MPI_DOUBLE;
|
||||
break;
|
||||
case MPMY_INT:
|
||||
rt = MPI_INT;
|
||||
break;
|
||||
case MPMY_CHAR:
|
||||
rt = MPI_CHAR;
|
||||
break;
|
||||
default:
|
||||
Error("No type match in alltoall\n");
|
||||
}
|
||||
MPI_Alltoall(sendbuf, sendcount, st,
|
||||
recvbuf, recvcount, rt, MPI_COMM_WORLD);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
Native_MPMY_Alltoallv(void *sendbuf, int *sendcounts, int *sendoffsets, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int *recvcounts, int *recvoffsets, MPMY_Datatype recvtype)
|
||||
{
|
||||
MPI_Datatype st, rt;
|
||||
|
||||
switch (sendtype){
|
||||
case MPMY_FLOAT:
|
||||
st = MPI_FLOAT;
|
||||
break;
|
||||
case MPMY_DOUBLE:
|
||||
st = MPI_DOUBLE;
|
||||
break;
|
||||
case MPMY_INT:
|
||||
st = MPI_INT;
|
||||
break;
|
||||
case MPMY_CHAR:
|
||||
st = MPI_CHAR;
|
||||
break;
|
||||
case MPMY_SHORT:
|
||||
st = MPI_SHORT;
|
||||
break;
|
||||
case MPMY_LONG:
|
||||
st = MPI_LONG;
|
||||
break;
|
||||
default:
|
||||
Error("No type match in alltoallv\n");
|
||||
}
|
||||
switch (recvtype){
|
||||
case MPMY_FLOAT:
|
||||
rt = MPI_FLOAT;
|
||||
break;
|
||||
case MPMY_DOUBLE:
|
||||
rt = MPI_DOUBLE;
|
||||
break;
|
||||
case MPMY_INT:
|
||||
rt = MPI_INT;
|
||||
break;
|
||||
case MPMY_CHAR:
|
||||
rt = MPI_CHAR;
|
||||
break;
|
||||
case MPMY_SHORT:
|
||||
rt = MPI_SHORT;
|
||||
break;
|
||||
case MPMY_LONG:
|
||||
rt = MPI_LONG;
|
||||
break;
|
||||
default:
|
||||
Error("No type match in alltoallv\n");
|
||||
}
|
||||
MPI_Alltoallv(sendbuf, sendcounts, sendoffsets, st,
|
||||
recvbuf, recvcounts, recvoffsets, rt, MPI_COMM_WORLD);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
Native_MPMY_Allgather(void *sendbuf, int sendcount, MPMY_Datatype type, void *recvbuf)
|
||||
{
|
||||
MPI_Datatype st, rt;
|
||||
int recvcount = sendcount;
|
||||
|
||||
switch (type){
|
||||
case MPMY_FLOAT:
|
||||
st = MPI_FLOAT;
|
||||
break;
|
||||
case MPMY_DOUBLE:
|
||||
st = MPI_DOUBLE;
|
||||
break;
|
||||
case MPMY_INT:
|
||||
st = MPI_INT;
|
||||
break;
|
||||
case MPMY_CHAR:
|
||||
st = MPI_CHAR;
|
||||
break;
|
||||
case MPMY_SHORT:
|
||||
st = MPI_SHORT;
|
||||
break;
|
||||
case MPMY_LONG:
|
||||
st = MPI_LONG;
|
||||
break;
|
||||
default:
|
||||
Error("No type match in allgather\n");
|
||||
}
|
||||
rt = st;
|
||||
MPI_Allgather(sendbuf, sendcount, st,
|
||||
recvbuf, recvcount, rt, MPI_COMM_WORLD);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
Native_MPMY_Allgatherv(void *sendbuf, int sendcount, MPMY_Datatype type, void *recvbuf,
|
||||
int *rcounts, int *roffsets)
|
||||
{
|
||||
MPI_Datatype st, rt;
|
||||
|
||||
switch (type){
|
||||
case MPMY_FLOAT:
|
||||
st = MPI_FLOAT;
|
||||
break;
|
||||
case MPMY_DOUBLE:
|
||||
st = MPI_DOUBLE;
|
||||
break;
|
||||
case MPMY_INT:
|
||||
st = MPI_INT;
|
||||
break;
|
||||
case MPMY_CHAR:
|
||||
st = MPI_CHAR;
|
||||
break;
|
||||
case MPMY_SHORT:
|
||||
st = MPI_SHORT;
|
||||
break;
|
||||
case MPMY_LONG:
|
||||
st = MPI_LONG;
|
||||
break;
|
||||
default:
|
||||
Error("No type match in allgather\n");
|
||||
}
|
||||
rt = st;
|
||||
MPI_Allgatherv(sendbuf, sendcount, st,
|
||||
recvbuf, rcounts, roffsets, rt, MPI_COMM_WORLD);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#define HAVE_MPMY_SYNC
|
||||
int MPMY_Sync(void) {
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_Init(int *argcp, char ***argvp) {
|
||||
ChnInit(&commchn, sizeof(struct comm_s), NCOMM, Realloc_f);
|
||||
ChnMoreMem(&commchn); /* alloc now to prevent heap fragmentation later */
|
||||
if (MPI_Init(argcp, argvp) != MPI_SUCCESS)
|
||||
Error("MPMY_Init MPI_Init failed\n");
|
||||
if (MPI_Comm_size(MPI_COMM_WORLD, &_MPMY_nproc_) != MPI_SUCCESS)
|
||||
Error("MPMY_Init MPI_Comm_size failed\n");
|
||||
if (MPI_Comm_rank(MPI_COMM_WORLD, &_MPMY_procnum_) != MPI_SUCCESS)
|
||||
Error("MPMY_Init MPI_Comm_rank failed\n");
|
||||
#ifdef PROCS_PER_NODE
|
||||
_MPMY_procs_per_node_ = PROCS_PER_NODE;
|
||||
#else
|
||||
_MPMY_procs_per_node_ = 1;
|
||||
#endif
|
||||
_MPMY_setup_absigs();
|
||||
MPMY_OnAbnormal(MPMY_SystemAbort);
|
||||
MPMY_OnAbnormal(MPMY_Abannounce);
|
||||
MPMY_OnAbnormal(PrintMemfile);
|
||||
_MPMY_initialized_ = 1;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
#define HAVE_MPMY_FINALIZE
|
||||
int MPMY_Finalize(void){
|
||||
return (MPI_Finalize() == MPI_SUCCESS) ? MPMY_SUCCESS : MPMY_FAILED ;
|
||||
}
|
||||
|
||||
#define HAVE_MPMY_FLICK
|
||||
int MPMY_Flick(void){
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
#define HAVE_MPMY_JOBREMAINING
|
||||
int
|
||||
MPMY_JobRemaining(void)
|
||||
{
|
||||
/* returns -1 for failure, or if not a slurm job */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_HWCLOCK
|
||||
#include "timers_hwclock.c"
|
||||
#endif
|
||||
|
||||
#ifdef USE_GETTIME
|
||||
#include "timers_gettime.c"
|
||||
#endif
|
||||
|
||||
#if !defined(USE_HWCLOCK) && !defined(USE_GETTIME)
|
||||
#define HAVE_MPMY_TIMERS
|
||||
#include "timers_mpi.c"
|
||||
#endif
|
||||
|
||||
#if defined(__CM5__) || defined(_AIX) || defined(__AP1000__)
|
||||
#define CANT_USE_ALARM
|
||||
#endif
|
||||
#if defined(__CM5__) || defined(__INTEL_SSD__)
|
||||
#include "mpmy_pario.c"
|
||||
#else
|
||||
#if defined(USE_MPIIO)
|
||||
#include "mpmy_mpiio.c"
|
||||
#else
|
||||
#include "mpmy_io.c"
|
||||
#endif
|
||||
#endif
|
||||
#include "mpmy_abnormal.c"
|
||||
#include "mpmy_generic.c"
|
292
external/libsdf/libmpmy/mpmy_mpiio.1.c
vendored
Normal file
292
external/libsdf/libmpmy/mpmy_mpiio.1.c
vendored
Normal file
|
@ -0,0 +1,292 @@
|
|||
/* This file contains the parallel I/O suitable for CMMD and NX.
|
||||
It wouldn't be hard to add cubix-syntax as well. Are there any
|
||||
other options? Would they fit in this structure? The only
|
||||
difference between CMMD and NX is in Fopen, where one
|
||||
system calls gopen() and the other calls CMMD_set_io_mode().
|
||||
We use a pre-processor symbol (__INTEL_SSD__) or (__CM5__) to decide
|
||||
which one to use. __INTEL_SSD__ is set by the ARCH-specific Makefiles,
|
||||
while __CM5__ is set by mpmy_cm5.c, which #includes this file.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mpi.h>
|
||||
#ifndef OPEN_MPI
|
||||
#include <mpio.h>
|
||||
#endif
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
#include "mpmy_io.h"
|
||||
#include "Msgs.h"
|
||||
|
||||
#ifndef EINVAL
|
||||
/* just in case... */
|
||||
#define EINVAL 0
|
||||
#endif
|
||||
|
||||
#define NFILES 4096
|
||||
|
||||
static struct _File{
|
||||
MPI_File fd;
|
||||
int iomode;
|
||||
} _files[NFILES];
|
||||
|
||||
static int files; /* need dynamic storage */
|
||||
|
||||
static int do_nfileio;
|
||||
|
||||
MPMYFile *
|
||||
MPMY_Fopen(const char *path, int flags)
|
||||
{
|
||||
MPI_File fd;
|
||||
MPI_Info info;
|
||||
int iomode = MPMY_SINGL; /* default */
|
||||
int real_flags = MPI_MODE_RDONLY; /* if no flags specified */
|
||||
int ret;
|
||||
|
||||
Msgf(("Fopen %s, flags = 0x%x\n", path, flags));
|
||||
if (flags & MPMY_RDONLY) real_flags = MPI_MODE_RDONLY;
|
||||
if (flags & MPMY_WRONLY) real_flags = MPI_MODE_WRONLY;
|
||||
if (flags & MPMY_RDWR) real_flags = MPI_MODE_RDWR;
|
||||
if (flags & MPMY_APPEND) real_flags |= MPI_MODE_APPEND;
|
||||
if (flags & MPMY_TRUNC && ((flags & MPMY_WRONLY) || (flags & MPMY_RDWR))) {
|
||||
int fd;
|
||||
if (MPMY_Procnum() == 0) {
|
||||
fd = open(path, O_RDWR|O_TRUNC, 0644);
|
||||
if (fd < 0) Msgf(("Fopen fails, errno=%d\n", errno));
|
||||
else close(fd);
|
||||
MPMY_Sync();
|
||||
} else {
|
||||
MPMY_Sync();
|
||||
}
|
||||
}
|
||||
if (flags & MPMY_CREAT) real_flags |= MPI_MODE_CREATE;
|
||||
|
||||
/* Panasas optimizations */
|
||||
real_flags |= MPI_MODE_UNIQUE_OPEN; /* dangerous? */
|
||||
MPI_Info_create(&info);
|
||||
MPI_Info_set(info, "panfs_concurrent_write", "1");
|
||||
|
||||
/* Should we make sure that only one of them is on?? */
|
||||
if (flags & MPMY_MULTI) iomode = MPMY_MULTI;
|
||||
if (flags & MPMY_SINGL) iomode = MPMY_SINGL;
|
||||
|
||||
if (flags & MPMY_NFILE) Error("MPMY_NFILE not supported\n");
|
||||
if (flags & MPMY_IOZERO) Error("MPMY_IOZERO not supported\n");
|
||||
if (flags & MPMY_INDEPENDENT) Error("MPMY_INDEPENDENT not supported\n");
|
||||
|
||||
if (flags & MPMY_SINGL) {
|
||||
Msgf(("Fopen %s in SINGL mode\n", path));
|
||||
} else {
|
||||
Msgf(("Fopen %s in MULTI mode\n", path));
|
||||
}
|
||||
Msgf(("MPI_File_open %s with flags = 0x%x\n", path, real_flags));
|
||||
ret = MPI_File_open(MPI_COMM_WORLD, (char *)path, real_flags, info, &fd);
|
||||
|
||||
if (files >= NFILES) Error("files too large\n");
|
||||
if (ret == 0) {
|
||||
_files[files].iomode = iomode;
|
||||
_files[files].fd = fd;
|
||||
Msgf(("Fopen returns fd %p, iomode=%d, flags=0x%x\n",
|
||||
fd, iomode, flags));
|
||||
return &(_files[files++]);
|
||||
} else {
|
||||
Msgf(("Fopen fails, errno=%d\n", errno));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Nfileio(int val){
|
||||
int oldval = do_nfileio;
|
||||
do_nfileio = val;
|
||||
return oldval;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Fclose(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
int ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
Msgf(("Fclose %p\n", fp->fd));
|
||||
ret = MPI_File_close(&fp->fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Mkdir(const char *path, int mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
ret = mkdir(path, mode);
|
||||
if( ret && errno == EEXIST ){
|
||||
/* Let's just pretend we really made it... */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
MPMY_BcastTag(&ret, 1, MPMY_INT, 0, 0x4579 );
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
MPMY_Fread(void *ptr, size_t size, size_t nitems, MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Status status;
|
||||
int cnt;
|
||||
size_t nread = size*nitems;
|
||||
const char *p = ptr;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
MPI_File_read_all(fp->fd, (void *)p, nread, MPI_CHAR, &status);
|
||||
} else {
|
||||
MPI_File_read_ordered(fp->fd, (void *)p, nread, MPI_CHAR, &status);
|
||||
}
|
||||
MPI_Get_count(&status, MPI_BYTE, &cnt);
|
||||
if (cnt != nread) Error("MPMY_Fread has a problem\n");
|
||||
Msgf(("MPI_File_read from %p returns %d\n", fp->fd, cnt));
|
||||
return nitems;
|
||||
}
|
||||
|
||||
size_t
|
||||
MPMY_Fwrite(const void *ptr, size_t size, size_t nitems, MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Status status;
|
||||
int cnt;
|
||||
size_t nwrite = size*nitems;
|
||||
const char *p = ptr;
|
||||
|
||||
Msgf(("MPMY_Fwrite %ld %ld\n", size, nitems));
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
MPI_File_write_all(fp->fd, (void *)p, nwrite, MPI_CHAR, &status);
|
||||
} else {
|
||||
MPI_File_write_ordered(fp->fd, (void *)p, nwrite, MPI_CHAR, &status);
|
||||
}
|
||||
MPI_Get_count(&status, MPI_BYTE, &cnt);
|
||||
if (cnt != nwrite) Error("MPMY_Fread has a problem\n");
|
||||
Msgf(("MPI_File_write from %p returns %d\n", fp->fd, cnt));
|
||||
return nitems;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Fseek(MPMYFile *Fp, off_t offset, int whence)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
int ret;
|
||||
MPI_Offset mpi_offset;
|
||||
int real_whence = 0;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (whence == MPMY_SEEK_SET) real_whence = MPI_SEEK_SET;
|
||||
if (whence == MPMY_SEEK_CUR) real_whence = MPI_SEEK_CUR;
|
||||
if (whence == MPMY_SEEK_END) real_whence = MPI_SEEK_END;
|
||||
|
||||
mpi_offset = offset; /* potential conversion problem */
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
ret = MPI_File_seek_shared(fp->fd, mpi_offset, real_whence);
|
||||
} else {
|
||||
ret = MPI_File_seek(fp->fd, mpi_offset, real_whence);
|
||||
}
|
||||
if (ret != -1) ret = 0;
|
||||
Msgf(("Fseek to %ld returns %d\n", (long)mpi_offset, ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
off_t
|
||||
MPMY_Ftell(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Offset mpi_offset;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
MPI_File_get_position_shared(fp->fd, &mpi_offset);
|
||||
} else {
|
||||
MPI_File_get_position(fp->fd, &mpi_offset);
|
||||
}
|
||||
Msgf(("Ftell returns %ld\n", (long)mpi_offset));
|
||||
return mpi_offset;
|
||||
}
|
||||
|
||||
off_t
|
||||
MPMY_Flen(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Offset mpi_offset_current, mpi_offset_end;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
MPI_File_get_position_shared(fp->fd, &mpi_offset_current);
|
||||
MPI_File_seek_shared(fp->fd, mpi_offset_current, MPI_SEEK_END);
|
||||
MPI_File_get_position_shared(fp->fd, &mpi_offset_end);
|
||||
MPI_File_seek_shared(fp->fd, mpi_offset_current, MPI_SEEK_SET);
|
||||
} else {
|
||||
MPI_File_get_position(fp->fd, &mpi_offset_current);
|
||||
MPI_File_seek(fp->fd, mpi_offset_current, MPI_SEEK_END);
|
||||
MPI_File_get_position(fp->fd, &mpi_offset_end);
|
||||
MPI_File_seek(fp->fd, mpi_offset_current, MPI_SEEK_SET);
|
||||
}
|
||||
Msgf(("Flen returns %ld\n", (long)mpi_offset_end));
|
||||
return mpi_offset_end;
|
||||
}
|
||||
|
||||
size_t
|
||||
MPMY_Fseekrd(MPMYFile *Fp, off_t offset, int whence, void *buf, size_t reclen,
|
||||
size_t nrecs)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Offset mpi_offset;
|
||||
MPI_Status status;
|
||||
int cnt;
|
||||
size_t nread = reclen*nrecs;
|
||||
const char *p = buf;
|
||||
|
||||
Msgf(("Fseekrd %ld at %ld\n", (size_t)reclen*nrecs, offset));
|
||||
mpi_offset = offset;
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
MPI_File_read_at_all(fp->fd, mpi_offset, (void *)p, nread, MPI_BYTE, &status);
|
||||
} else {
|
||||
MPI_File_read_at(fp->fd, mpi_offset, (void *)p, nread, MPI_BYTE, &status);
|
||||
}
|
||||
MPI_Get_count(&status, MPI_BYTE, &cnt);
|
||||
if (cnt != nread) Error("MPMY_Fseekrd has a problem, got %d expected %ld\n",
|
||||
cnt, nread);
|
||||
return nrecs;
|
||||
}
|
||||
|
||||
#include "io_generic.c"
|
346
external/libsdf/libmpmy/mpmy_mpiio.c
vendored
Normal file
346
external/libsdf/libmpmy/mpmy_mpiio.c
vendored
Normal file
|
@ -0,0 +1,346 @@
|
|||
/* This file contains the parallel I/O suitable for CMMD and NX.
|
||||
It wouldn't be hard to add cubix-syntax as well. Are there any
|
||||
other options? Would they fit in this structure? The only
|
||||
difference between CMMD and NX is in Fopen, where one
|
||||
system calls gopen() and the other calls CMMD_set_io_mode().
|
||||
We use a pre-processor symbol (__INTEL_SSD__) or (__CM5__) to decide
|
||||
which one to use. __INTEL_SSD__ is set by the ARCH-specific Makefiles,
|
||||
while __CM5__ is set by mpmy_cm5.c, which #includes this file.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mpi.h>
|
||||
#ifndef OPEN_MPI
|
||||
#include <mpio.h>
|
||||
#endif
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
#include "mpmy_io.h"
|
||||
#include "Msgs.h"
|
||||
|
||||
#ifndef EINVAL
|
||||
/* just in case... */
|
||||
#define EINVAL 0
|
||||
#endif
|
||||
|
||||
#define NFILES 4096
|
||||
|
||||
/* MPI only allows 2GB buffer sizes, and MPI_Get_Count uses an int */
|
||||
#define MAXIOSIZE (256*1024*1024)
|
||||
|
||||
static struct _File{
|
||||
MPI_File fd;
|
||||
int iomode;
|
||||
} _files[NFILES];
|
||||
|
||||
static int files; /* need dynamic storage */
|
||||
|
||||
static int do_nfileio;
|
||||
|
||||
MPMYFile *
|
||||
MPMY_Fopen(const char *path, int flags)
|
||||
{
|
||||
MPI_File fd;
|
||||
MPI_Info info;
|
||||
int iomode = MPMY_SINGL; /* default */
|
||||
int real_flags = MPI_MODE_RDONLY; /* if no flags specified */
|
||||
int ret;
|
||||
|
||||
Msgf(("Fopen %s, flags = 0x%x\n", path, flags));
|
||||
if (flags & MPMY_RDONLY) real_flags = MPI_MODE_RDONLY;
|
||||
if (flags & MPMY_WRONLY) real_flags = MPI_MODE_WRONLY;
|
||||
if (flags & MPMY_RDWR) real_flags = MPI_MODE_RDWR;
|
||||
if (flags & MPMY_APPEND) real_flags |= MPI_MODE_APPEND;
|
||||
if (flags & MPMY_TRUNC && ((flags & MPMY_WRONLY) || (flags & MPMY_RDWR))) {
|
||||
int fd;
|
||||
if (MPMY_Procnum() == 0) {
|
||||
fd = open(path, O_RDWR|O_TRUNC, 0644);
|
||||
if (fd < 0) Msgf(("Fopen fails, errno=%d\n", errno));
|
||||
else close(fd);
|
||||
MPMY_Sync();
|
||||
} else {
|
||||
MPMY_Sync();
|
||||
}
|
||||
}
|
||||
if (flags & MPMY_CREAT) real_flags |= MPI_MODE_CREATE;
|
||||
|
||||
/* Panasas optimizations */
|
||||
if (!(flags & MPMY_RDONLY))
|
||||
real_flags |= MPI_MODE_UNIQUE_OPEN; /* dangerous? */
|
||||
MPI_Info_create(&info);
|
||||
MPI_Info_set(info, "panfs_concurrent_write", "1");
|
||||
|
||||
/* Should we make sure that only one of them is on?? */
|
||||
if (flags & MPMY_MULTI) iomode = MPMY_MULTI;
|
||||
if (flags & MPMY_SINGL) iomode = MPMY_SINGL;
|
||||
|
||||
if (flags & MPMY_NFILE) Error("MPMY_NFILE not supported\n");
|
||||
if (flags & MPMY_IOZERO) Error("MPMY_IOZERO not supported\n");
|
||||
if (flags & MPMY_INDEPENDENT) Error("MPMY_INDEPENDENT not supported\n");
|
||||
|
||||
if (flags & MPMY_SINGL) {
|
||||
Msgf(("Fopen %s in SINGL mode\n", path));
|
||||
} else {
|
||||
Msgf(("Fopen %s in MULTI mode\n", path));
|
||||
}
|
||||
Msgf(("MPI_File_open %s with flags = 0x%x\n", path, real_flags));
|
||||
ret = MPI_File_open(MPI_COMM_WORLD, (char *)path, real_flags, info, &fd);
|
||||
|
||||
if (files >= NFILES) Error("files too large\n");
|
||||
if (ret == 0) {
|
||||
_files[files].iomode = iomode;
|
||||
_files[files].fd = fd;
|
||||
Msgf(("Fopen returns fd %p, iomode=%d, flags=0x%x\n",
|
||||
fd, iomode, flags));
|
||||
return &(_files[files++]);
|
||||
} else {
|
||||
Msgf(("Fopen fails, errno=%d\n", errno));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Nfileio(int val){
|
||||
int oldval = do_nfileio;
|
||||
do_nfileio = val;
|
||||
return oldval;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Fclose(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
int ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
Msgf(("Fclose %p\n", fp->fd));
|
||||
ret = MPI_File_close(&fp->fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Mkdir(const char *path, int mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
ret = mkdir(path, mode);
|
||||
if( ret && errno == EEXIST ){
|
||||
/* Let's just pretend we really made it... */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
MPMY_BcastTag(&ret, 1, MPMY_INT, 0, 0x4579 );
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
MPMY_Fread(void *ptr, size_t size, size_t nitems, MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Status status;
|
||||
int cnt;
|
||||
size_t nread = size*nitems;
|
||||
const char *p = ptr;
|
||||
|
||||
Msgf(("MPMY_Fread %ld %ld\n", size, nitems));
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
if (nread >= (1 << 31)) Error("MPMY_SINGL does not yet support large reads\n");
|
||||
MPI_File_read_all(fp->fd, (void *)p, nread, MPI_CHAR, &status);
|
||||
MPI_Get_count(&status, MPI_CHAR, &cnt);
|
||||
} else {
|
||||
MPI_Offset mpi_offset;
|
||||
size_t left, *sizes;
|
||||
int i;
|
||||
assert(sizeof(size_t) == MPMY_Datasize[MPMY_LONG]);
|
||||
sizes = Malloc(sizeof(size_t)*MPMY_Nproc());
|
||||
/* Use scan instead? */
|
||||
Native_MPMY_Allgather(&nread, 1, MPMY_LONG, sizes);
|
||||
MPI_File_get_position(fp->fd, &mpi_offset);
|
||||
Msgf(("Starting offset in MPMY_Fread is %lld\n", mpi_offset));
|
||||
for (i = 0; i < MPMY_Procnum(); i++) {
|
||||
mpi_offset += sizes[i];
|
||||
}
|
||||
Msgf(("My offset in MPMY_Fread is %lld\n", mpi_offset));
|
||||
Free(sizes);
|
||||
left = nread;
|
||||
while (left > 0) {
|
||||
nread = (left < MAXIOSIZE) ? left : MAXIOSIZE;
|
||||
Msgf(("read %ld at %lld\n", nread, mpi_offset));
|
||||
Msg_flush();
|
||||
MPI_File_read_at(fp->fd, mpi_offset, (void *)p, nread, MPI_CHAR, &status);
|
||||
left -= nread;
|
||||
p += nread;
|
||||
mpi_offset += nread;
|
||||
MPI_Get_count(&status, MPI_CHAR, &cnt);
|
||||
}
|
||||
}
|
||||
return cnt/size;
|
||||
}
|
||||
|
||||
size_t
|
||||
MPMY_Fwrite(const void *ptr, size_t size, size_t nitems, MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Status status;
|
||||
int cnt;
|
||||
size_t nwrite = size*nitems;
|
||||
const char *p = ptr;
|
||||
|
||||
Msgf(("MPMY_Fwrite %ld %ld\n", size, nitems));
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
if (nwrite >= (1 << 31)) Error("MPMY_SINGL does not yet support large writes\n");
|
||||
MPI_File_write_all(fp->fd, (void *)p, nwrite, MPI_CHAR, &status);
|
||||
MPI_Get_count(&status, MPI_CHAR, &cnt);
|
||||
if (cnt != nwrite) Error("MPMY_Fwrite has a problem, wrote %d of %ld\n",
|
||||
cnt, nwrite);
|
||||
} else {
|
||||
MPI_Offset mpi_offset;
|
||||
size_t left, *sizes;
|
||||
int i;
|
||||
assert(sizeof(size_t) == MPMY_Datasize[MPMY_LONG]);
|
||||
sizes = Malloc(sizeof(size_t)*MPMY_Nproc());
|
||||
Native_MPMY_Allgather(&nwrite, 1, MPMY_LONG, sizes);
|
||||
MPI_File_get_position(fp->fd, &mpi_offset);
|
||||
Msgf(("Starting offset in MPMY_Fwrite is %lld\n", mpi_offset));
|
||||
for (i = 0; i < MPMY_Procnum(); i++) {
|
||||
mpi_offset += sizes[i];
|
||||
}
|
||||
Msgf(("My offset in MPMY_Fwrite is %lld\n", mpi_offset));
|
||||
Free(sizes);
|
||||
left = nwrite;
|
||||
while (left > 0) {
|
||||
nwrite = (left < MAXIOSIZE) ? left : MAXIOSIZE;
|
||||
Msgf(("write %ld at %lld\n", nwrite, mpi_offset));
|
||||
Msg_flush();
|
||||
MPI_File_write_at(fp->fd, mpi_offset, (void *)p, nwrite, MPI_CHAR, &status);
|
||||
left -= nwrite;
|
||||
p += nwrite;
|
||||
mpi_offset += nwrite;
|
||||
MPI_Get_count(&status, MPI_CHAR, &cnt);
|
||||
if (cnt != nwrite) Error("MPMY_Fwrite has a problem, wrote %d of %ld\n",
|
||||
cnt, nwrite);
|
||||
}
|
||||
}
|
||||
return nitems;
|
||||
}
|
||||
|
||||
off_t
|
||||
MPMY_Fseek(MPMYFile *Fp, off_t offset, int whence)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
int ret;
|
||||
MPI_Offset mpi_offset;
|
||||
int real_whence = 0;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (whence == MPMY_SEEK_SET) real_whence = MPI_SEEK_SET;
|
||||
if (whence == MPMY_SEEK_CUR) real_whence = MPI_SEEK_CUR;
|
||||
if (whence == MPMY_SEEK_END) real_whence = MPI_SEEK_END;
|
||||
|
||||
mpi_offset = offset; /* potential conversion problem */
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
ret = MPI_File_seek_shared(fp->fd, mpi_offset, real_whence);
|
||||
} else {
|
||||
ret = MPI_File_seek(fp->fd, mpi_offset, real_whence);
|
||||
}
|
||||
if (ret != -1) ret = 0;
|
||||
Msgf(("Fseek to %ld returns %d\n", (long)mpi_offset, ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
off_t
|
||||
MPMY_Ftell(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Offset mpi_offset;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
MPI_File_get_position_shared(fp->fd, &mpi_offset);
|
||||
} else {
|
||||
MPI_File_get_position(fp->fd, &mpi_offset);
|
||||
}
|
||||
Msgf(("Ftell returns %ld\n", (long)mpi_offset));
|
||||
return mpi_offset;
|
||||
}
|
||||
|
||||
off_t
|
||||
MPMY_Flen(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Offset mpi_offset_current, mpi_offset_end;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
MPI_File_get_position_shared(fp->fd, &mpi_offset_current);
|
||||
MPI_File_seek_shared(fp->fd, mpi_offset_current, MPI_SEEK_END);
|
||||
MPI_File_get_position_shared(fp->fd, &mpi_offset_end);
|
||||
MPI_File_seek_shared(fp->fd, mpi_offset_current, MPI_SEEK_SET);
|
||||
} else {
|
||||
MPI_File_get_position(fp->fd, &mpi_offset_current);
|
||||
MPI_File_seek(fp->fd, mpi_offset_current, MPI_SEEK_END);
|
||||
MPI_File_get_position(fp->fd, &mpi_offset_end);
|
||||
MPI_File_seek(fp->fd, mpi_offset_current, MPI_SEEK_SET);
|
||||
}
|
||||
Msgf(("Flen returns %ld\n", (long)mpi_offset_end));
|
||||
return mpi_offset_end;
|
||||
}
|
||||
|
||||
size_t
|
||||
MPMY_Fseekrd(MPMYFile *Fp, off_t offset, int whence, void *buf, size_t reclen,
|
||||
size_t nrecs)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
MPI_Offset mpi_offset;
|
||||
MPI_Status status;
|
||||
int cnt;
|
||||
size_t nread = reclen*nrecs;
|
||||
const char *p = buf;
|
||||
|
||||
Msgf(("Fseekrd %ld at %ld\n", (size_t)reclen*nrecs, offset));
|
||||
mpi_offset = offset;
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
MPI_File_read_at_all(fp->fd, mpi_offset, (void *)p, nread, MPI_BYTE, &status);
|
||||
} else {
|
||||
MPI_File_read_at(fp->fd, mpi_offset, (void *)p, nread, MPI_BYTE, &status);
|
||||
}
|
||||
MPI_Get_count(&status, MPI_BYTE, &cnt);
|
||||
if (cnt != nread) Error("MPMY_Fseekrd has a problem, got %d expected %ld\n",
|
||||
cnt, nread);
|
||||
return nrecs;
|
||||
}
|
||||
|
||||
#include "io_generic.c"
|
1
external/libsdf/libmpmy/mpmy_mvapich2.c
vendored
Symbolic link
1
external/libsdf/libmpmy/mpmy_mvapich2.c
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
mpmy_mpi.c
|
281
external/libsdf/libmpmy/mpmy_panio.c
vendored
Normal file
281
external/libsdf/libmpmy/mpmy_panio.c
vendored
Normal file
|
@ -0,0 +1,281 @@
|
|||
/* This file contains the parallel I/O suitable for CMMD and NX.
|
||||
It wouldn't be hard to add cubix-syntax as well. Are there any
|
||||
other options? Would they fit in this structure? The only
|
||||
difference between CMMD and NX is in Fopen, where one
|
||||
system calls gopen() and the other calls CMMD_set_io_mode().
|
||||
We use a pre-processor symbol (__INTEL_SSD__) or (__CM5__) to decide
|
||||
which one to use. __INTEL_SSD__ is set by the ARCH-specific Makefiles,
|
||||
while __CM5__ is set by mpmy_cm5.c, which #includes this file.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
#include "mpmy_io.h"
|
||||
#include "Msgs.h"
|
||||
#include "iozero.h"
|
||||
|
||||
#ifndef EINVAL
|
||||
/* just in case... */
|
||||
#define EINVAL 0
|
||||
#endif
|
||||
|
||||
#define NFILES 4096
|
||||
static struct _File{
|
||||
int fd;
|
||||
int iomode;
|
||||
int iotype;
|
||||
int flags;
|
||||
} _files[NFILES];
|
||||
|
||||
static int do_nfileio;
|
||||
|
||||
MPMYFile *
|
||||
MPMY_Fopen(const char *path, int flags)
|
||||
{
|
||||
int fd;
|
||||
int mode = 0644;
|
||||
int iomode = MPMY_SINGL; /* default */
|
||||
int iotype = 0;
|
||||
int real_flags = 0;
|
||||
|
||||
Msgf(("Fopen %s\n", path));
|
||||
if (flags & MPMY_RDONLY) real_flags |= O_RDONLY;
|
||||
if (flags & MPMY_WRONLY) real_flags |= O_WRONLY;
|
||||
if (flags & MPMY_RDWR) real_flags |= O_RDWR;
|
||||
if (flags & MPMY_APPEND) real_flags |= O_APPEND;
|
||||
if (flags & MPMY_TRUNC) real_flags |= O_TRUNC;
|
||||
if (flags & MPMY_CREAT) real_flags |= O_CREAT;
|
||||
|
||||
/* Should we make sure that only one of them is on?? */
|
||||
if (flags & MPMY_MULTI) iomode = MPMY_MULTI;
|
||||
if (flags & MPMY_SINGL) iomode = MPMY_SINGL;
|
||||
|
||||
if (flags & MPMY_NFILE) iotype = MPMY_NFILE;
|
||||
if (flags & MPMY_IOZERO) Error("MPMY_IOZERO not supported\n");
|
||||
if (flags & MPMY_INDEPENDENT) Error("MPMY_INDEPENDENT not supported\n");
|
||||
|
||||
if (iotype == MPMY_NFILE) {
|
||||
char real_path[256];
|
||||
sprintf(real_path, "%s.p%03d", path, MPMY_Procnum());
|
||||
Msgf(("Fopen %s in NFILE mode\n", path));
|
||||
fd = open(real_path, real_flags, mode);
|
||||
} else if (flags & MPMY_SINGL) {
|
||||
Msgf(("Fopen %s in SINGL mode\n", path));
|
||||
fd = open(path, real_flags, mode);
|
||||
} else {
|
||||
Msgf(("Fopen %s in MULTI mode\n", path));
|
||||
fd = open(path, real_flags, mode);
|
||||
}
|
||||
|
||||
if (fd >= NFILES) Error("fd too large (%d)\n", fd);
|
||||
if( fd >= 0 ){
|
||||
_files[fd].iomode = iomode;
|
||||
_files[fd].iotype = iotype;
|
||||
Msgf(("Fopen returns %d, iomode=%d, flags=0x%x\n", fd, iomode, flags));
|
||||
return &(_files[fd]);
|
||||
}else{
|
||||
Msgf(("Fopen fails, errno=%d\n", errno));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Nfileio(int val){
|
||||
int oldval = do_nfileio;
|
||||
do_nfileio = val;
|
||||
return oldval;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Fclose(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
int ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) ret = close0(fp->fd);
|
||||
else ret = close(fp->fd);
|
||||
Msgf(("Fclose of %d returns %d\n", fp->fd, ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Mkdir(const char *path, int mode){
|
||||
return mkdir0(path, mode);
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Fread(void *ptr, int size, int nitems, MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
int ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) ret = read0(fp->fd, ptr, size*nitems);
|
||||
else ret = read(fp->fd, ptr, size*nitems);
|
||||
|
||||
Msgf(("Fread from %d returns %d\n", fp->fd, ret));
|
||||
if (ret % size) Error("MPMY_Fread has a problem\n");
|
||||
return ret/size;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Fwrite(const void *ptr, int size, int nitems, MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
int ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) ret= write0(fp->fd, ptr, size*nitems);
|
||||
else ret = write(fp->fd, ptr, size*nitems);
|
||||
/* Msgf(("Fwrite to %d returns %d.\n", fp->fd, ret)); */
|
||||
if (ret % size) Error("MPMY_Fwrite has a problem\n");
|
||||
return ret/size;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Fseek(MPMYFile *Fp, off_t offset, int whence)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
off_t ret;
|
||||
int real_whence = 0;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (whence == MPMY_SEEK_SET) real_whence = SEEK_SET;
|
||||
if (whence == MPMY_SEEK_CUR) real_whence = SEEK_CUR;
|
||||
if (whence == MPMY_SEEK_END) real_whence = SEEK_END;
|
||||
|
||||
if (fp->iotype == MPMY_SINGL) {
|
||||
ret = lseek0(fp->fd, offset, real_whence);
|
||||
} else {
|
||||
ret = lseek(fp->fd, offset, real_whence);
|
||||
}
|
||||
if (ret != -1) ret = 0;
|
||||
Msgf(("Fseek returns %ld\n", (long)ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Ftell(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
off_t ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iotype == MPMY_SINGL) {
|
||||
ret = tell0(fp->fd);
|
||||
} else {
|
||||
ret = lseek(fp->fd, 0L, SEEK_CUR);
|
||||
}
|
||||
Msgf(("Ftell returns %ld\n", (long)ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
off_t
|
||||
MPMY_Flen(MPMYFile *Fp)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
off_t ret;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iotype & MPMY_NFILE) {
|
||||
ret = flen(fp->fd);
|
||||
Msgf(("flen segment %ld\n", (long)ret));
|
||||
if (sizeof(ret) != sizeof(long)) {
|
||||
Error("Bad types in MPMY_Flen\n");
|
||||
}
|
||||
MPMY_Combine(&ret, &ret, 1, MPMY_LONG, MPMY_SUM);
|
||||
} else if (fp->iotype == MPMY_SINGL) {
|
||||
ret = flen0(fp->fd);
|
||||
} else {
|
||||
ret = flen(fp->fd);
|
||||
}
|
||||
Msgf(("Flen returns %ld\n", (long)ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Fseekrd(MPMYFile *Fp, off_t offset, int whence, void *buf, int reclen,
|
||||
int nrecs)
|
||||
{
|
||||
struct _File *fp = (struct _File *)Fp;
|
||||
int doseek;
|
||||
|
||||
if( fp == NULL ){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (fp->iomode == MPMY_SINGL) {
|
||||
nrecs = fseekrd0(fp->fd, offset, whence, buf, reclen, nrecs);
|
||||
return nrecs;
|
||||
}
|
||||
|
||||
if( whence == MPMY_SEEK_CUR ){
|
||||
doseek = (offset != 0);
|
||||
}else if( whence == MPMY_SEEK_SET ){
|
||||
/* don't worry about errors. If ftell returns -1, */
|
||||
/* doseek will be turned on, and the fseek below will */
|
||||
/* (probably) fail */
|
||||
doseek = (MPMY_Ftell(Fp) != offset);
|
||||
}else{
|
||||
doseek = 1;
|
||||
}
|
||||
|
||||
if( doseek ){
|
||||
if( MPMY_Fseek(Fp, offset, whence) ){
|
||||
if( whence == MPMY_SEEK_CUR && offset > 0 ){
|
||||
/* Make a final heroic effort to seek by reading forward! */
|
||||
char junk[BUFSIZ];
|
||||
int nleft = offset;
|
||||
while( nleft ){
|
||||
int ntry = ( nleft > sizeof(junk) ) ? sizeof(junk) : nleft;
|
||||
if( MPMY_Fread(junk, ntry, 1, Fp) != 1 ){
|
||||
Error("fseekrd: incremental fread(%#lx, %d, 1, %#lx) failed, errno=%d\n",
|
||||
(unsigned long)junk, ntry,
|
||||
(unsigned long)fp, errno);
|
||||
return -1;
|
||||
}
|
||||
nleft -= ntry;
|
||||
}
|
||||
}else{
|
||||
Error("fseekrd: fseek(%#lx, %lld, %d) failed, errno=%d\n",
|
||||
(unsigned long)fp, offset, whence, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( MPMY_Fread(buf, reclen, nrecs, Fp) != nrecs ){
|
||||
Error("fseekrd: fread(%#lx, %d, %d, %#lx) failed, errno=%d\n",
|
||||
(unsigned long)buf, reclen, nrecs, (unsigned long)fp, errno);
|
||||
return -1;
|
||||
}
|
||||
return nrecs;
|
||||
}
|
||||
|
||||
#include "iozero.c"
|
||||
#include "io_generic.c"
|
262
external/libsdf/libmpmy/mpmy_seq.c
vendored
Normal file
262
external/libsdf/libmpmy/mpmy_seq.c
vendored
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
Not-so-trivial implementation of the mpmy interface for a single process(or)
|
||||
that handles messages sent to itself.
|
||||
|
||||
This is not designed for speed. In fact, it's not designed at all. It's
|
||||
just meant to limp along. I think it's a bad idea to be sending a lot
|
||||
of messages to yourself.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "Msgs.h"
|
||||
#include "mpmy.h"
|
||||
#include "Assert.h"
|
||||
#include "mpmy_io.h"
|
||||
#include "mpmy_time.h"
|
||||
#include "mpmy_abnormal.h"
|
||||
|
||||
#define IN 1
|
||||
#define OUT 2
|
||||
|
||||
#ifdef __SUN4__
|
||||
/* ARCH=sun4 code may have been compiled and linked with __CM5VU__, which
|
||||
means that if we're not careful we'll hit some illegal instructions when
|
||||
we try to call do_grav. This variable sidesteps those Vector-Unit
|
||||
calls at run-time. It's twisted, but it's the price we pay for using
|
||||
ARCH=sun4 for the CM5. */
|
||||
int have_vu = 0;
|
||||
void *VUHeap;
|
||||
int VUaux_allocated;
|
||||
|
||||
#if 0
|
||||
void *aux_alloc_heap(int n){
|
||||
Error("aux_alloc_heap: You shouldn't reach this on a non-cm5 processor!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
struct comm_s{
|
||||
int cnt;
|
||||
int tag;
|
||||
void *buf;
|
||||
int inout;
|
||||
int finished;
|
||||
};
|
||||
|
||||
/* These do a little more than mpmy_alloc_generic. It lets us search */
|
||||
/* the list of allocated requests too. Unfortunately, it takes O(Nreq) */
|
||||
/* time to do a Dealloc or a Match. I'm sure there's something simpler than */
|
||||
/* hashing that would do better, but I'm being dense. */
|
||||
|
||||
#define MAXCOMM 200
|
||||
static struct comm_s _comms[MAXCOMM];
|
||||
static int freecomm[MAXCOMM];
|
||||
static int usedcomm[MAXCOMM];
|
||||
static int mpmy_nfree = 0;
|
||||
static int mpmy_nused = 0;
|
||||
|
||||
static void CommInit(void){
|
||||
int i;
|
||||
for(i=0; i<MAXCOMM; i++){
|
||||
freecomm[i] = i;
|
||||
}
|
||||
mpmy_nfree = MAXCOMM;
|
||||
mpmy_nused = 0;
|
||||
}
|
||||
|
||||
static int CommAlloc(void){
|
||||
int ret;
|
||||
if( mpmy_nfree >= 0 ){
|
||||
ret = freecomm[--mpmy_nfree];
|
||||
usedcomm[mpmy_nused++] = ret;
|
||||
return ret;
|
||||
}else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void CommDealloc(int req){
|
||||
int i;
|
||||
assert(mpmy_nfree < MAXCOMM);
|
||||
for(i=0; i<mpmy_nused; i++){
|
||||
if( usedcomm[i] == req ){
|
||||
usedcomm[i] = usedcomm[--mpmy_nused];
|
||||
break;
|
||||
}
|
||||
}
|
||||
freecomm[mpmy_nfree++] = req;
|
||||
}
|
||||
|
||||
static int find_match(int inout, int tag){
|
||||
int i, ui;
|
||||
struct comm_s *comm;
|
||||
|
||||
for(i=0; i<mpmy_nused; i++){
|
||||
ui = usedcomm[i];
|
||||
comm = &_comms[ui];
|
||||
if( !comm->finished
|
||||
&& (comm->tag == tag || tag == MPMY_TAG_ANY || comm->tag == MPMY_TAG_ANY)
|
||||
&& comm->inout == inout )
|
||||
return ui;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int MPMY_Isend(const void *buf, int cnt, int dest, int tag, MPMY_Comm_request *reqp){
|
||||
struct comm_s *comm;
|
||||
int req;
|
||||
|
||||
if( dest != 0 )
|
||||
return MPMY_FAILED;
|
||||
req = CommAlloc();
|
||||
if( req < 0 )
|
||||
return MPMY_FAILED;
|
||||
|
||||
comm = &_comms[req];
|
||||
comm->inout = OUT;
|
||||
comm->cnt = cnt;
|
||||
comm->tag = tag;
|
||||
comm->buf = (void *)buf; /* drop const. modifier */
|
||||
comm->finished = 0;
|
||||
*reqp = comm;
|
||||
IncrCounter(&MPMYSendCnt);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_Irecv(void *buf, int cnt, int src, int tag, MPMY_Comm_request *reqp){
|
||||
struct comm_s *comm;
|
||||
int req;
|
||||
|
||||
if( src != 0 && src != MPMY_SOURCE_ANY )
|
||||
return MPMY_FAILED;
|
||||
req = CommAlloc();
|
||||
if( req < 0 )
|
||||
return MPMY_FAILED;
|
||||
|
||||
comm = &_comms[req];
|
||||
comm->inout = IN;
|
||||
comm->cnt = cnt;
|
||||
comm->tag = tag;
|
||||
comm->buf = buf;
|
||||
comm->finished = 0;
|
||||
*reqp = comm;
|
||||
IncrCounter(&MPMYRecvCnt);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_Test(MPMY_Comm_request req, int *flag, MPMY_Status *stat){
|
||||
struct comm_s *comm = req;
|
||||
struct comm_s *mcomm;
|
||||
int match;
|
||||
int ireq = comm - _comms;
|
||||
|
||||
if( comm->finished ){
|
||||
*flag = 1;
|
||||
if( comm->inout == IN && stat ){
|
||||
stat->count = comm->cnt;
|
||||
stat->tag = comm->tag;
|
||||
stat->src = 0;
|
||||
}
|
||||
CommDealloc(ireq);
|
||||
IncrCounter(&MPMYDoneCnt);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
if( comm->inout == IN ){
|
||||
match = find_match(OUT, comm->tag);
|
||||
if( match >= 0 ){
|
||||
mcomm = &_comms[match];
|
||||
if( mcomm->cnt > comm->cnt ){
|
||||
SeriousWarning("MPMY_Test message too long\n");
|
||||
CommDealloc(ireq);
|
||||
return MPMY_FAILED;
|
||||
}
|
||||
memcpy(comm->buf, mcomm->buf, mcomm->cnt);
|
||||
if( stat ){
|
||||
stat->count = mcomm->cnt;
|
||||
stat->tag = mcomm->tag;
|
||||
stat->src = 0;
|
||||
}
|
||||
mcomm->finished = 1;
|
||||
*flag = 1;
|
||||
IncrCounter(&MPMYDoneCnt);
|
||||
CommDealloc(ireq);
|
||||
return MPMY_SUCCESS;
|
||||
}else{
|
||||
*flag = 0;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
}else{
|
||||
match = find_match(IN, comm->tag);
|
||||
if( match >= 0 ){
|
||||
mcomm = &_comms[match];
|
||||
if( comm->cnt > mcomm->cnt ){
|
||||
SeriousWarning("MPMY_Test message too long\n");
|
||||
CommDealloc(ireq);
|
||||
return MPMY_FAILED;
|
||||
}
|
||||
memcpy(mcomm->buf, comm->buf, comm->cnt);
|
||||
mcomm->cnt = comm->cnt;
|
||||
mcomm->tag = comm->tag;
|
||||
mcomm->finished = 1;
|
||||
*flag = 1;
|
||||
IncrCounter(&MPMYDoneCnt);
|
||||
CommDealloc(ireq);
|
||||
return MPMY_SUCCESS;
|
||||
}else{
|
||||
*flag = 0;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Native_MPMY_Alltoall(void *sendbuf, int sendcount, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int recvcount, MPMY_Datatype recvtype)
|
||||
{
|
||||
memcpy(recvbuf, sendbuf, sendcount*MPMY_Datasize[sendtype]);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
Native_MPMY_Allgather(void *sendbuf, int sendcount, MPMY_Datatype type, void *recvbuf)
|
||||
{
|
||||
memcpy(recvbuf, sendbuf, sendcount*MPMY_Datasize[type]);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
Native_MPMY_Allgatherv(void *sendbuf, int sendcount, MPMY_Datatype type, void *recvbuf,
|
||||
int *rcounts, int *roffsets)
|
||||
{
|
||||
memcpy(recvbuf, sendbuf, sendcount*MPMY_Datasize[type]);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int MPMY_Init(int *argcp, char ***argvp){
|
||||
CommInit();
|
||||
_MPMY_nproc_ = 1;
|
||||
_MPMY_procnum_ = 0;
|
||||
_MPMY_initialized_ = 1;
|
||||
/* There should really be a better way to opt out of MPMY abnormal
|
||||
signal handling. For now, this will work for programs that might
|
||||
use SDF, but which have their own carefully crafted signal handlers,
|
||||
e.g., SM */
|
||||
if( argcp )
|
||||
_MPMY_setup_absigs();
|
||||
MPMY_OnAbnormal(MPMY_SystemAbort);
|
||||
MPMY_OnAbnormal(MPMY_Abannounce);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef USE_GETTIME
|
||||
#include "timers_gettime.c"
|
||||
#endif
|
||||
|
||||
#ifdef USE_HWCLOCK
|
||||
#include "timers_hwclock.c"
|
||||
#endif
|
||||
|
||||
#include "mpmy_io.c"
|
||||
#include "mpmy_abnormal.c"
|
||||
#include "mpmy_generic.c"
|
85
external/libsdf/libmpmy/timers_gettime.c
vendored
Normal file
85
external/libsdf/libmpmy/timers_gettime.c
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include <time.h>
|
||||
#include "mpmy_time.h"
|
||||
#include "Malloc.h"
|
||||
#include "chn.h"
|
||||
|
||||
static Chn timer_chn;
|
||||
static int initialized;
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
struct timespec cpu_start;
|
||||
double cpu_accum;
|
||||
struct timespec wc_start;
|
||||
double wc_accum;
|
||||
} MPMY_Timer;
|
||||
|
||||
void *MPMY_CreateTimer(int type){
|
||||
MPMY_Timer *ret;
|
||||
|
||||
if( initialized == 0 ){
|
||||
ChnInit(&timer_chn, sizeof(MPMY_Timer), 40, Realloc_f);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
ret = ChnAlloc(&timer_chn);
|
||||
ret->type = type;
|
||||
MPMY_ClearTimer(ret);
|
||||
return (void *)ret;
|
||||
}
|
||||
|
||||
int MPMY_DestroyTimer(void *p){
|
||||
ChnFree(&timer_chn, p);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_StartTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
switch(t->type){
|
||||
case MPMY_CPU_TIME:
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t->cpu_start);
|
||||
break;
|
||||
case MPMY_WC_TIME:
|
||||
clock_gettime(CLOCK_REALTIME, &t->wc_start);
|
||||
break;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_StopTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
struct timespec tnow;
|
||||
|
||||
switch(t->type){
|
||||
case MPMY_CPU_TIME:
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tnow);
|
||||
t->cpu_accum += (tnow.tv_sec - t->cpu_start.tv_sec) + (tnow.tv_nsec - t->cpu_start.tv_nsec) * 1e-9;
|
||||
break;
|
||||
case MPMY_WC_TIME:
|
||||
clock_gettime(CLOCK_REALTIME, &tnow);
|
||||
t->wc_accum += (tnow.tv_sec - t->wc_start.tv_sec) + (tnow.tv_nsec - t->wc_start.tv_nsec) * 1e-9;
|
||||
break;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_ClearTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
t->cpu_accum = 0.0;
|
||||
t->wc_accum = 0.0;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
double MPMY_ReadTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
switch(t->type){
|
||||
case MPMY_CPU_TIME:
|
||||
return t->cpu_accum;
|
||||
case MPMY_WC_TIME:
|
||||
return t->wc_accum;
|
||||
}
|
||||
return -1.0;
|
||||
}
|
106
external/libsdf/libmpmy/timers_hwclock.c
vendored
Normal file
106
external/libsdf/libmpmy/timers_hwclock.c
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
#include <time.h>
|
||||
#include "mpmy_time.h"
|
||||
#include "Malloc.h"
|
||||
#include "chn.h"
|
||||
|
||||
static Chn timer_chn;
|
||||
static int initialized;
|
||||
|
||||
typedef struct {
|
||||
unsigned long long start;
|
||||
unsigned long long accum;
|
||||
struct timespec wc_start;
|
||||
double wc_accum;
|
||||
int type;
|
||||
} MPMY_Timer;
|
||||
|
||||
#ifdef AMD6100
|
||||
#define DEFAULT_MHZ 2300.0e6
|
||||
#else
|
||||
#define DEFAULT_MHZ 2668.0e6
|
||||
#endif
|
||||
|
||||
static __inline__ unsigned long long rdtsc(void)
|
||||
{
|
||||
unsigned hi, lo;
|
||||
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
|
||||
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
|
||||
}
|
||||
|
||||
void *MPMY_CreateTimer(int type){
|
||||
MPMY_Timer *ret;
|
||||
|
||||
if( initialized == 0 ){
|
||||
ChnInit(&timer_chn, sizeof(MPMY_Timer), 40, Realloc_f);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
ret = ChnAlloc(&timer_chn);
|
||||
ret->type = type;
|
||||
MPMY_ClearTimer(ret);
|
||||
return (void *)ret;
|
||||
}
|
||||
|
||||
int MPMY_DestroyTimer(void *p){
|
||||
ChnFree(&timer_chn, p);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_CopyTimer(void *p, void *q)
|
||||
{
|
||||
MPMY_Timer *t = p;
|
||||
MPMY_Timer *u = q;
|
||||
|
||||
*u = *t;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_StartTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
switch(t->type){
|
||||
case MPMY_CPU_TIME:
|
||||
t->start = rdtsc();
|
||||
break;
|
||||
case MPMY_WC_TIME:
|
||||
clock_gettime(CLOCK_REALTIME, &t->wc_start);
|
||||
break;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_StopTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
struct timespec tnow;
|
||||
|
||||
switch(t->type){
|
||||
case MPMY_CPU_TIME:
|
||||
t->accum += rdtsc()-t->start;
|
||||
break;
|
||||
case MPMY_WC_TIME:
|
||||
clock_gettime(CLOCK_REALTIME, &tnow);
|
||||
t->wc_accum += (tnow.tv_sec - t->wc_start.tv_sec) + (tnow.tv_nsec - t->wc_start.tv_nsec) * 1e-9;
|
||||
break;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_ClearTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
t->accum = 0;
|
||||
t->wc_accum = 0.0;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
double MPMY_ReadTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
switch(t->type){
|
||||
case MPMY_CPU_TIME:
|
||||
return t->accum/DEFAULT_MHZ;
|
||||
case MPMY_WC_TIME:
|
||||
return t->wc_accum;
|
||||
}
|
||||
return -1.0;
|
||||
}
|
59
external/libsdf/libmpmy/timers_mpi.c
vendored
Normal file
59
external/libsdf/libmpmy/timers_mpi.c
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* This file tries to use only MPI-approved timer constructs. */
|
||||
|
||||
/* time.h should define CLOCKS_PER_SECOND and prototype clock() and time()
|
||||
and it should have typedefs for time_t and clock_t. */
|
||||
#include "mpmy_time.h"
|
||||
#include "chn.h"
|
||||
|
||||
static Chn timer_chn;
|
||||
static int initialized;
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
double wc_start, wc_accum;
|
||||
} MPMY_Timer;
|
||||
|
||||
void *MPMY_CreateTimer(int type){
|
||||
MPMY_Timer *ret;
|
||||
|
||||
if( initialized == 0 ){
|
||||
ChnInit(&timer_chn, sizeof(MPMY_Timer), 40, Realloc_f);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
ret = ChnAlloc(&timer_chn);
|
||||
ret->type = type;
|
||||
return (void *)ret;
|
||||
}
|
||||
|
||||
int MPMY_DestroyTimer(void *p){
|
||||
ChnFree(&timer_chn, p);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_StartTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
t->wc_start = MPI_Wtime();
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_StopTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
t->wc_accum += MPI_Wtime() - t->wc_start;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_ClearTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
t->wc_accum = 0.;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
double MPMY_ReadTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
return (double)t->wc_accum;
|
||||
}
|
139
external/libsdf/libmpmy/timers_posix.c
vendored
Normal file
139
external/libsdf/libmpmy/timers_posix.c
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
/* This file tries to use only ANSI/POSIX-approved timer constructs. */
|
||||
/* It should compile correctly everywhere (Ha!) */
|
||||
|
||||
/* time.h should define CLOCKS_PER_SECOND and prototype clock() and time()
|
||||
and it should have typedefs for time_t and clock_t. */
|
||||
#include <time.h>
|
||||
#include "mpmy_time.h"
|
||||
#include "chn.h"
|
||||
#include "Malloc.h"
|
||||
|
||||
#ifndef CLOCKS_PER_SECOND
|
||||
/* We've got a non-standard time.h. At least we have a time.h...*/
|
||||
#ifdef CLOCKS_PER_SEC /* This works for linux */
|
||||
#define CLOCKS_PER_SECOND CLOCKS_PER_SEC
|
||||
#else
|
||||
#define CLOCKS_PER_SECOND 1000000 /* this is just a wild guess!! */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* POSIX only guarantees 'time', which returns a time_t. The option
|
||||
is available for the 'implementor' to make time_t a double. Does
|
||||
the friendly implementor at Sun do this? Nooooo. If we want more
|
||||
precision we have to use gettimeofday, which is a non-POSIX BSD-ism.
|
||||
|
||||
Better still, gettimeofday has mutually incompatible definitions in
|
||||
SVr4 (one argument) and XSH4.2 (two arguments). Sigh...
|
||||
*/
|
||||
#if defined(sun) || defined(__INTEL_SSD__) || defined(_AIX) || defined(__x86_64__)
|
||||
# define USE_GETTIMEOFDAY
|
||||
# include <sys/time.h>
|
||||
#else /* don't use gettimeofday. use time() instead */
|
||||
extern time_t time(time_t *);
|
||||
#endif
|
||||
|
||||
/* This ought to be in one of the system headers... */
|
||||
extern clock_t clock(void);
|
||||
|
||||
static Chn timer_chn;
|
||||
static int initialized;
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
clock_t cpu_start, cpu_accum;
|
||||
#ifdef USE_GETTIMEOFDAY
|
||||
struct timeval wc_start;
|
||||
struct timeval wc_accum;
|
||||
#else
|
||||
time_t wc_start, wc_accum;
|
||||
#endif
|
||||
} MPMY_Timer;
|
||||
|
||||
void *MPMY_CreateTimer(int type){
|
||||
MPMY_Timer *ret;
|
||||
|
||||
if( initialized == 0 ){
|
||||
ChnInit(&timer_chn, sizeof(MPMY_Timer), 40, Realloc_f);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
ret = ChnAlloc(&timer_chn);
|
||||
ret->type = type;
|
||||
MPMY_ClearTimer(ret);
|
||||
return (void *)ret;
|
||||
}
|
||||
|
||||
int MPMY_DestroyTimer(void *p){
|
||||
ChnFree(&timer_chn, p);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_StartTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
switch(t->type){
|
||||
case MPMY_WC_TIME:
|
||||
#ifdef USE_GETTIMEOFDAY
|
||||
gettimeofday(&t->wc_start, 0);
|
||||
#else
|
||||
t->wc_start = time(0);
|
||||
#endif
|
||||
break;
|
||||
case MPMY_CPU_TIME:
|
||||
t->cpu_start = clock();
|
||||
break;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_StopTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
switch(t->type){
|
||||
case MPMY_WC_TIME:
|
||||
#ifdef USE_GETTIMEOFDAY
|
||||
{
|
||||
struct timeval tnow;
|
||||
gettimeofday(&tnow, 0);
|
||||
t->wc_accum.tv_sec += tnow.tv_sec - t->wc_start.tv_sec;
|
||||
t->wc_accum.tv_usec += tnow.tv_usec - t->wc_start.tv_usec;
|
||||
}
|
||||
#else
|
||||
t->wc_accum += time(0) - t->wc_start;
|
||||
#endif
|
||||
break;
|
||||
case MPMY_CPU_TIME:
|
||||
t->cpu_accum += clock() - t->cpu_start;
|
||||
break;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int MPMY_ClearTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
#ifdef USE_GETTIMEOFDAY
|
||||
t->wc_accum.tv_sec = 0;
|
||||
t->wc_accum.tv_usec = 0;
|
||||
#else
|
||||
t->wc_accum = 0;
|
||||
#endif
|
||||
t->cpu_accum = 0;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
double MPMY_ReadTimer(void *p){
|
||||
MPMY_Timer *t = p;
|
||||
|
||||
switch(t->type){
|
||||
case MPMY_WC_TIME:
|
||||
#ifdef USE_GETTIMEOFDAY
|
||||
return (double)t->wc_accum.tv_sec + (double)t->wc_accum.tv_usec*1.0e-6;
|
||||
#else
|
||||
return (double)t->wc_accum;
|
||||
#endif
|
||||
case MPMY_CPU_TIME:
|
||||
return (double)t->cpu_accum * (1.0/CLOCKS_PER_SECOND);
|
||||
}
|
||||
return -1.0;
|
||||
}
|
|
@ -105,17 +105,15 @@ for sample in dataSampleList:
|
|||
# -------------------------------------------------------------------------
|
||||
if (startCatalogStage <= 3) and (endCatalogStage >= 3) and not sample.isCombo:
|
||||
|
||||
for thisDataPortion in dataPortions:
|
||||
print " Taking data portion:", thisDataPortion, "...",
|
||||
sys.stdout.flush()
|
||||
print " Taking data portions", "...",
|
||||
sys.stdout.flush()
|
||||
|
||||
logFile = logDir+"/pruneVoids_"+sampleName+"_"+\
|
||||
thisDataPortion+".out"
|
||||
logFile = logDir+"/pruneVoids_"+sampleName+".out"
|
||||
|
||||
PRUNE_PATH = CTOOLS_PATH+"/stacking/pruneVoids"
|
||||
PRUNE_PATH = CTOOLS_PATH+"/stacking/pruneVoids"
|
||||
|
||||
launchPrune(sample, PRUNE_PATH, thisDataPortion=thisDataPortion,
|
||||
logFile=logFile, zobovDir=zobovDir, continueRun=continueRun)
|
||||
launchPrune(sample, PRUNE_PATH,
|
||||
logFile=logFile, zobovDir=zobovDir, continueRun=continueRun)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
if (startCatalogStage <= 4) and (endCatalogStage >= 4):
|
||||
|
|
|
@ -76,7 +76,7 @@ from void_python_tools.backend.classes import *
|
|||
|
||||
continueRun = False # set to True to enable restarting aborted jobs
|
||||
startCatalogStage = 1
|
||||
endCatalogStage = 4
|
||||
endCatalogStage = 3
|
||||
|
||||
startAPStage = 1
|
||||
endAPStage = 1
|
||||
|
@ -170,15 +170,21 @@ newSample.addStack(0.0, 5.0, 90, 95, False, False)
|
|||
LIGHT_SPEED*lbox, zVsDX, zVsDY)-zBox
|
||||
dzSafe = 0.03
|
||||
else:
|
||||
boxWidthZ = lbox*100./LIGHT_SPEED
|
||||
boxWidthZ = np.interp(vp.angularDiameter(zBox,Om=Om)+100. / \
|
||||
LIGHT_SPEED*lbox, zVsDX, zVsDY)-zBox
|
||||
#boxWidthZ = lbox*100./LIGHT_SPEED
|
||||
dzSafe = 0.0
|
||||
|
||||
for iSlice in xrange(numSlices):
|
||||
sliceMin = zBox + dzSafe + iSlice*(boxWidthZ-dzSafe)/numSlices
|
||||
sliceMax = zBox + dzSafe + (iSlice+1)*(boxWidthZ-dzSafe)/numSlices
|
||||
sliceMin = zBox + dzSafe + iSlice*(boxWidthZ-2.*dzSafe)/numSlices
|
||||
sliceMax = zBox + dzSafe + (iSlice+1)*(boxWidthZ-2.*dzSafe)/numSlices
|
||||
|
||||
sliceMinMpc = sliceMin*LIGHT_SPEED/100.
|
||||
sliceMaxMpc = sliceMax*LIGHT_SPEED/100.
|
||||
if useLightCone:
|
||||
sliceMinMpc = sliceMin*LIGHT_SPEED/100.
|
||||
sliceMaxMpc = sliceMax*LIGHT_SPEED/100.
|
||||
else:
|
||||
sliceMinMpc = LIGHT_SPEED/100.*vp.angularDiameter(sliceMin, Om=Om)
|
||||
sliceMaxMpc = LIGHT_SPEED/100.*vp.angularDiameter(sliceMax, Om=Om)
|
||||
|
||||
sliceMin = "%0.2f" % sliceMin
|
||||
sliceMax = "%0.2f" % sliceMax
|
||||
|
@ -316,7 +322,7 @@ for thisSubSample in sorted(subSamples, reverse=True):
|
|||
else:
|
||||
outFile.write(line)
|
||||
|
||||
outFile.write("-99 -99 -99 -99 -99\n")
|
||||
outFile.write("-99 -99 -99 -99 -99 -99 -99\n")
|
||||
inFile.close()
|
||||
outFile.close()
|
||||
|
||||
|
@ -337,7 +343,7 @@ for thisSubSample in sorted(subSamples, reverse=True):
|
|||
|
||||
outFile.write("%d %e %e %e 0. 0. 0.\n" % (i, x,y,z))
|
||||
|
||||
outFile.write("-99 -99 -99 -99 -99\n")
|
||||
outFile.write("-99 -99 -99 -99 -99 -99 -99\n")
|
||||
outFile.close()
|
||||
|
||||
prevSubSample = thisSubSample
|
||||
|
@ -427,7 +433,7 @@ if (args.halos or args.all) and haloFileBase != "":
|
|||
# write to output file
|
||||
outFile.write("%d %e %e %e %e %e %e\n" %(iHalo,x,y,z,vz,vy,vx))
|
||||
|
||||
outFile.write("-99 -99 -99 -99 -99\n")
|
||||
outFile.write("-99 -99 -99 -99 -99 -99 -99\n")
|
||||
inFile.close()
|
||||
outFile.close()
|
||||
|
||||
|
@ -528,3 +534,5 @@ if (args.hod or args.all) and haloFileBase != "":
|
|||
outFileName = catalogDir+"/"+sampleName+".dat"
|
||||
os.system("mv %s/hod.mock %s" % (catalogDir, outFileName))
|
||||
os.system("rm %s/hod.*" % catalogDir)
|
||||
|
||||
print " Done!"
|
||||
|
|
|
@ -247,7 +247,7 @@ def launchZobov(sample, binPath, zobovDir=None, logDir=None, continueRun=None,
|
|||
os.unlink(vozScript)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def launchPrune(sample, binPath, thisDataPortion=None,
|
||||
def launchPrune(sample, binPath,
|
||||
summaryFile=None, logFile=None, zobovDir=None,
|
||||
continueRun=None):
|
||||
|
||||
|
@ -274,7 +274,6 @@ def launchPrune(sample, binPath, thisDataPortion=None,
|
|||
sample.boxLen <= 1.e-1:
|
||||
periodicLine += "z"
|
||||
periodicLine += "' "
|
||||
periodicLine = ""
|
||||
|
||||
if not (continueRun and (jobSuccessful(logFile, "NetCDF: Not a valid ID\n") \
|
||||
or jobSuccessful(logFile, "Done!\n"))):
|
||||
|
@ -287,7 +286,6 @@ def launchPrune(sample, binPath, thisDataPortion=None,
|
|||
cmd += " --extraInfo=" + zobovDir+"/zobov_slice_"+str(sampleName)+\
|
||||
".par"
|
||||
cmd += " --tolerance=1.0"
|
||||
cmd += " --dataPortion=" + thisDataPortion
|
||||
cmd += " --mockIndex=" + str(mockIndex)
|
||||
cmd += " --maxCentralDen=" + str(maxDen)
|
||||
cmd += " --zMin=" + str(sample.zRange[0])
|
||||
|
@ -296,27 +294,8 @@ def launchPrune(sample, binPath, thisDataPortion=None,
|
|||
cmd += " --numVoids=" + str(numVoids)
|
||||
cmd += observationLine
|
||||
cmd += periodicLine
|
||||
cmd += " --output=" + zobovDir+"/voidDesc_"+\
|
||||
str(thisDataPortion)+"_"+\
|
||||
str(sampleName)+".out"
|
||||
cmd += " --outCenters=" + zobovDir+"/barycenters_"+\
|
||||
str(thisDataPortion)+"_"+\
|
||||
str(sampleName)+".out"
|
||||
cmd += " --outInfo=" + zobovDir+"/centers_"+\
|
||||
str(thisDataPortion)+"_"+\
|
||||
str(sampleName)+".out"
|
||||
cmd += " --outNoCutInfo=" + zobovDir+"/centers_nocut_"+\
|
||||
str(thisDataPortion)+"_"+\
|
||||
str(sampleName)+".out"
|
||||
cmd += " --outSkyPositions=" + zobovDir+"/sky_positions_"+\
|
||||
str(thisDataPortion)+"_"+\
|
||||
str(sampleName)+".out"
|
||||
cmd += " --outShapes=" + zobovDir+"/shapes_"+\
|
||||
str(thisDataPortion)+"_"+\
|
||||
str(sampleName)+".out"
|
||||
cmd += " --outDistances=" + zobovDir+"/boundaryDistances_"+\
|
||||
str(thisDataPortion)+"_"+\
|
||||
str(sampleName)+".out"
|
||||
cmd += " --outputDir=" + zobovDir
|
||||
cmd += " --sampleName=" + str(sampleName)
|
||||
cmd += " &> " + logFile
|
||||
f=file("run_prune.sh",mode="w")
|
||||
f.write(cmd)
|
||||
|
@ -956,7 +935,7 @@ def launchFit(sample, stack, logFile=None, voidDir=None, figDir=None,
|
|||
return
|
||||
|
||||
numVoids = int(open(voidDir+"/num_voids.txt", "r").readline())
|
||||
if numVoids < 15:
|
||||
if numVoids < 10:
|
||||
print "not enough voids to fit; skipping!"
|
||||
fp = open(voidDir+"/NOFIT", "w")
|
||||
fp.write("not enough voids: %d \n" % numVoids)
|
||||
|
@ -1334,8 +1313,9 @@ def launchHubble(dataPortions=None, dataSampleList=None, logDir=None,
|
|||
plotTitle = "all samples, incoherent "+\
|
||||
thisDataPortion+" voids (systematics corrected)"
|
||||
else:
|
||||
plotTitle = "all samples, "+thisDataPortion+\
|
||||
" voids (systematics corrected)"
|
||||
#plotTitle = "all samples, "+thisDataPortion+\
|
||||
# " voids (systematics corrected)"
|
||||
plotTitle = setName + "(sysematics corrected)"
|
||||
vp.do_all_obs(zbase, allExpList, aveDistList,
|
||||
rlist, plotTitle=plotTitle, sampleNames=shortSampleNames,
|
||||
plotAve=True, mulfac = 1.16,
|
||||
|
@ -1429,7 +1409,9 @@ def launchLikelihood(dataPortions=None, logDir=None, workDir=None,
|
|||
OmStart = 0.0,
|
||||
OmEnd = 1.0,
|
||||
biasStart = 1.0,
|
||||
biasEnd = 1.2,
|
||||
biasEnd = 1.32,
|
||||
#biasStart = 1.15,
|
||||
#biasEnd = 1.17,
|
||||
outputBase = workDir+"/1dlikelihoods_"+thisDataPortion+"_",
|
||||
useBinAve = False)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue