diff --git a/src/aiori-PMDK.c b/src/aiori-PMDK.c index b14978d..225b427 100644 --- a/src/aiori-PMDK.c +++ b/src/aiori-PMDK.c @@ -99,10 +99,11 @@ static void *PMDK_Create(char * testFileName, IOR_param_t * param){ MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); } - if(!is_pmem){ + /* if(!is_pmem){ + fprintf(stdout, "\n is_pmem is %d\n",is_pmem); fprintf(stdout, "\npmem_map_file thinks the hardware being used is not pmem\n"); MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); - } + }*/ return((void *)pmemaddr); @@ -137,10 +138,11 @@ static void *PMDK_Open(char * testFileName, IOR_param_t * param){ MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); } + /* if(!is_pmem){ fprintf(stdout, "pmem_map_file thinks the hardware being used is not pmem\n"); MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); - } + }*/ return((void *)pmemaddr); } /* PMDK_Open() */ @@ -174,7 +176,7 @@ static IOR_offset_t PMDK_Xfer(int access, void *file, IOR_size_t * buffer, pmem_persist(&file[offset_size],length*sizeof(char));*/ }else{ memcpy(ptr, &file[offset_size], length); - /*for(i=0; itestFileName); + if(test->dualMount){ + GetProcessorAndCore(&socket, &core); + sprintf(tmpString, "%s%d/%s",initialTestFileName, + socket, "data"); + strcpy(initialTestFileName, tmpString); + } fileNames = ParseFileName(initialTestFileName, &count); if (count > 1 && test->uniqueDir == TRUE) ERR("cannot use multiple file names with unique directories"); diff --git a/src/ior.h b/src/ior.h index ccf47fa..3e9e260 100755 --- a/src/ior.h +++ b/src/ior.h @@ -97,6 +97,7 @@ typedef struct char * options; /* options string */ // intermediate options int dryRun; /* do not perform any I/Os just run evtl. inputs print dummy output */ + int dualMount; /* dual mount points */ int numTasks; /* number of tasks for test */ int numNodes; /* number of nodes for test */ int numTasksOnNode0; /* number of tasks on node 0 (usually all the same, but don't have to be, use with caution) */ diff --git a/src/parse_options.c b/src/parse_options.c index 74a7b54..3f20ba1 100755 --- a/src/parse_options.c +++ b/src/parse_options.c @@ -80,6 +80,10 @@ static void CheckRunSettings(IOR_test_t *tests) else params->openFlags |= IOR_WRONLY; } + + if(params->dualMount && !params->filePerProc) { + MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "Dual Mount can only be used with File Per Process"); + } } } @@ -137,6 +141,8 @@ void DecodeDirective(char *line, IOR_param_t *params, options_all_t * module_opt params->platform = strdup(value); } else if (strcasecmp(option, "testfile") == 0) { params->testFileName = strdup(value); + } else if (strcasecmp(option, "dualmount") == 0){ + params->dualMount = atoi(value); } else if (strcasecmp(option, "hintsfilename") == 0) { params->hintsFileName = strdup(value); } else if (strcasecmp(option, "deadlineforstonewalling") == 0) { @@ -521,6 +527,7 @@ option_help * createGlobalOptions(IOR_param_t * params){ {'W', NULL, "checkWrite -- check read after write", OPTION_FLAG, 'd', & params->checkWrite}, {'x', NULL, "singleXferAttempt -- do not retry transfer if incomplete", OPTION_FLAG, 'd', & params->singleXferAttempt}, {'X', NULL, "reorderTasksRandomSeed -- random seed for -Z option", OPTION_OPTIONAL_ARGUMENT, 'd', & params->reorderTasksRandomSeed}, + {'y', NULL, "dualMount -- use dual mount points for a filesystem", OPTION_FLAG, 'd', & params->dualMount}, {'Y', NULL, "fsyncPerWrite -- perform sync operation after every write operation", OPTION_FLAG, 'd', & params->fsyncPerWrite}, {'z', NULL, "randomOffset -- access is to random, not sequential, offsets within a file", OPTION_FLAG, 'd', & params->randomOffset}, {'Z', NULL, "reorderTasksRandom -- changes task ordering to random ordering for readback", OPTION_FLAG, 'd', & params->reorderTasksRandom}, diff --git a/src/utilities.c b/src/utilities.c index a657d9f..e06bfdc 100755 --- a/src/utilities.c +++ b/src/utilities.c @@ -880,3 +880,25 @@ char *HumanReadable(IOR_offset_t value, int base) } return valueStr; } + +#if defined(__aarch64__) +// TODO: This might be general enough to provide the functionality for any system +// regardless of processor type given we aren't worried about thread/process migration. +// Test on Intel systems and see if we can get rid of the architecture specificity +// of the code. +unsigned long GetProcessorAndCore(int *chip, int *core){ + return syscall(SYS_getcpu, core, chip, NULL); +} +// TODO: Add in AMD function +#else +// If we're not on an ARM processor assume we're on an intel processor and use the +// rdtscp instruction. +unsigned long GetProcessorAndCore(int *chip, int *core){ + unsigned long a,d,c; + __asm__ volatile("rdtscp" : "=a" (a), "=d" (d), "=c" (c)); + *chip = (c & 0xFFF000)>>12; + *core = c & 0xFFF; + return ((unsigned long)a) | (((unsigned long)d) << 32);; +} +#endif + diff --git a/src/utilities.h b/src/utilities.h index 2a9abe3..600da18 100755 --- a/src/utilities.h +++ b/src/utilities.h @@ -68,6 +68,7 @@ void StoreStoneWallingIterations(char * const filename, int64_t count); void init_clock(void); double GetTimeStamp(void); char * PrintTimestamp(); // TODO remove this function +unsigned long GetProcessorAndCore(int *chip, int *core); extern double wall_clock_deviation; extern double wall_clock_delta;