HINLINE void operator()( ThreadParams* params, FrameType& frame, const std::string subGroup, const uint64_t particlesOffset, const uint64_t elements) { typedef T_Identifier Identifier; typedef typename PMacc::traits::Resolve<Identifier>::type::type ValueType; const uint32_t components = GetNComponents<ValueType>::value; typedef typename GetComponentsType<ValueType>::type ComponentType; typedef typename PICToSplash<ComponentType>::type SplashType; log<picLog::INPUT_OUTPUT > ("HDF5: ( begin ) load species attribute: %1%") % Identifier::getName(); const std::string name_lookup[] = {"x", "y", "z"}; ComponentType* tmpArray = nullptr; if( elements > 0 ) tmpArray = new ComponentType[elements]; ParallelDomainCollector* dataCollector = params->dataCollector; for (uint32_t d = 0; d < components; d++) { OpenPMDName<T_Identifier> openPMDName; std::stringstream datasetName; datasetName << subGroup << "/" << openPMDName(); if (components > 1) datasetName << "/" << name_lookup[d]; ValueType* dataPtr = frame.getIdentifier(Identifier()).getPointer(); Dimensions sizeRead(0, 0, 0); // read one component from file to temporary array dataCollector->read(params->currentStep, Dimensions(elements, 1, 1), Dimensions(particlesOffset, 0, 0), datasetName.str().c_str(), sizeRead, tmpArray ); PMACC_ASSERT(sizeRead[0] == elements); /* copy component from temporary array to array of structs */ #pragma omp parallel for for (size_t i = 0; i < elements; ++i) { ComponentType& ref = ((ComponentType*) dataPtr)[i * components + d]; ref = tmpArray[i]; } } __deleteArray(tmpArray); log<picLog::INPUT_OUTPUT > ("HDF5: ( end ) load species attribute: %1%") % Identifier::getName(); }
HINLINE void operator()( ThreadParams* params, FrameType& frame, const std::string particlePath, const uint64_t particlesOffset, const uint64_t elements) { typedef T_Identifier Identifier; typedef typename PMacc::traits::Resolve<Identifier>::type::type ValueType; const uint32_t components = GetNComponents<ValueType>::value; typedef typename GetComponentsType<ValueType>::type ComponentType; log<picLog::INPUT_OUTPUT > ("ADIOS: ( begin ) load species attribute: %1%") % Identifier::getName(); const std::string name_lookup[] = {"x", "y", "z"}; ComponentType* tmpArray = NULL; if( elements > 0 ) tmpArray = new ComponentType[elements]; // dev assert! if( elements > 0 ) assert(tmpArray); for (uint32_t n = 0; n < components; ++n) { OpenPMDName<T_Identifier> openPMDName; std::stringstream datasetName; datasetName << particlePath << openPMDName(); if (components > 1) datasetName << "/" << name_lookup[n]; ValueType* dataPtr = frame.getIdentifier(Identifier()).getPointer(); ADIOS_VARINFO* varInfo = adios_inq_var( params->fp, datasetName.str().c_str() ); // it's possible to aquire the local block with that call again and // the local elements to-be-read, but the block-ID must be known (MPI rank?) //ADIOS_CMD(adios_inq_var_blockinfo( params->fp, varInfo )); ADIOS_SELECTION* sel = adios_selection_boundingbox( 1, &particlesOffset, &elements ); /** Note: adios_schedule_read is not a collective call in any * ADIOS method and can therefore be skipped for empty reads */ if( elements > 0 ) { ADIOS_CMD(adios_schedule_read( params->fp, sel, datasetName.str().c_str(), 0, /* from_step (not used in streams) */ 1, /* nsteps to read (must be 1 for stream) */ (void*)tmpArray )); } /** start a blocking read of all scheduled variables * (this is collective call in many ADIOS methods) */ ADIOS_CMD(adios_perform_reads( params->fp, 1 )); log<picLog::INPUT_OUTPUT > ("ADIOS: Did read %1% local of %2% global elements for %3%") % elements % varInfo->dims[0] % datasetName.str(); /* copy component from temporary array to array of structs */ #pragma omp parallel for for (size_t i = 0; i < elements; ++i) { ComponentType& ref = ((ComponentType*) dataPtr)[i * components + n]; ref = tmpArray[i]; } adios_selection_delete( sel ); adios_free_varinfo( varInfo ); } __deleteArray(tmpArray); log<picLog::INPUT_OUTPUT > ("ADIOS: ( end ) load species attribute: %1%") % Identifier::getName(); }