#include "cacheinfo.hh" #include #include #include #include template vect pad_shape(bbox const& extent) { assert(all(extent.shape() >= 0)); return pad_shape(extent.shape() / extent.stride()); } namespace { struct cache_info_t { int type; int linesize; int stride; }; bool have_cache_info = false; vector cache_info; } template vect pad_shape(vect const& shape) { DECLARE_CCTK_PARAMETERS; assert(all(shape>=0)); // Don't pad empty arrays; we don't want to handle all the special // cases for this below if (any(shape==0)) return shape; if (CCTK_BUILTIN_EXPECT(not have_cache_info, false)) { #pragma omp barrier #pragma omp master { if (CCTK_IsFunctionAliased("GetCacheInfo1")) { int const num_levels = GetCacheInfo1(NULL, NULL, NULL, NULL, NULL, NULL, 0); vector types (num_levels); vector linesizes(num_levels); vector strides (num_levels); GetCacheInfo1(NULL, &types[0], NULL, &linesizes[0], &strides[0], NULL, num_levels); cache_info.resize(num_levels); for (int level=0; level padded_shape; int accumulated_npoints = 1; for (int d=0; d 0) { assert(cache_stride % sizeof(CCTK_REAL) == 0); int const stride = cache_stride / sizeof(CCTK_REAL); if (npoints * accumulated_npoints % stride == 0) { assert(stride > linesize); int total_npoints = npoints * accumulated_npoints; total_npoints += max(linesize, accumulated_npoints); assert(total_npoints % accumulated_npoints == 0); npoints = total_npoints / accumulated_npoints; } } } // if is cache } // for cache_level } // if pad_to_cachelines #endif padded_shape[d] = npoints; accumulated_npoints *= npoints; } assert(prod(padded_shape) == accumulated_npoints); // self-check for (int d=0; d= shape[d]); #if VECTORISE && VECTORISE_ALIGNED_ARRAYS if (d == 0) { assert(padded_shape[d] % CCTK_REAL_VEC_SIZE == 0); } #endif } // Safety check if (not (prod(padded_shape) <= 2 * prod(shape) + 1000)) { cerr << "shape=" << shape << " prod(shape)=" << prod(shape) << "\n" << "padded_shape=" << padded_shape << " prod(padded_shape)=" << prod(padded_shape) << "\n"; } assert(prod(padded_shape) <= 2 * prod(shape) + 1000); if (verbose) { ostringstream buf; buf << "padding " << shape << " to " << padded_shape; CCTK_INFO(buf.str().c_str()); } return padded_shape; } template vect pad_shape(bbox const& extent); template vect pad_shape(vect const& shape); template vect pad_shape(bbox const& extent); template vect pad_shape(vect const& shape);