void bounds_reduced_extents (array_t *a, array_t *b, int which, const char *a_name, const char *intrinsic) { index_type i, n, a_size, b_size; assert (GFC_DESCRIPTOR_RANK(a) == GFC_DESCRIPTOR_RANK(b) - 1); a_size = size0 (a); b_size = size0 (b); if (b_size == 0) { if (a_size != 0) runtime_error ("Incorrect size in %s of %s" " intrinsic: should not be zero-sized", a_name, intrinsic); } else { if (a_size == 0) runtime_error ("Incorrect size of %s of %s" " intrinsic: should be zero-sized", a_name, intrinsic); i = 0; for (n = 0; n < GFC_DESCRIPTOR_RANK (b); n++) { index_type a_extent, b_extent; if (n != which) { a_extent = GFC_DESCRIPTOR_EXTENT(a, i); b_extent = GFC_DESCRIPTOR_EXTENT(b, n); if (a_extent != b_extent) runtime_error("Incorrect extent in %s of %s" " intrinsic in dimension %ld: is %ld," " should be %ld", a_name, intrinsic, (long int) i + 1, (long int) a_extent, (long int) b_extent); i++; } } } }
void bounds_equal_extents (array_t *a, array_t *b, const char *a_name, const char *intrinsic) { index_type a_size, b_size, n; assert (GFC_DESCRIPTOR_RANK(a) == GFC_DESCRIPTOR_RANK(b)); a_size = size0 (a); b_size = size0 (b); if (b_size == 0) { if (a_size != 0) runtime_error ("Incorrect size of %s in %s" " intrinsic: should be zero-sized", a_name, intrinsic); } else { if (a_size == 0) runtime_error ("Incorrect size of %s of %s" " intrinsic: Should not be zero-sized", a_name, intrinsic); for (n = 0; n < GFC_DESCRIPTOR_RANK (b); n++) { index_type a_extent, b_extent; a_extent = GFC_DESCRIPTOR_EXTENT(a, n); b_extent = GFC_DESCRIPTOR_EXTENT(b, n); if (a_extent != b_extent) runtime_error("Incorrect extent in %s of %s" " intrinsic in dimension %ld: is %ld," " should be %ld", a_name, intrinsic, (long int) n + 1, (long int) a_extent, (long int) b_extent); } } }
dgVector dgCollisionBox::SupportVertexSpecial(const dgVector& dir, dgInt32* const vertexIndex) const { dgAssert(dgAbsf(dir.DotProduct3(dir) - dgFloat32(1.0f)) < dgFloat32(1.0e-3f)); dgAssert(dir.m_w == dgFloat32(0.0f)); dgVector mask(dir < dgVector(dgFloat32(0.0f))); if (vertexIndex) { dgVector index(m_indexMark.CompProduct4(mask & dgVector::m_one)); index = (index.AddHorizontal()).GetInt(); *vertexIndex = dgInt32 (index.m_ix); } dgVector padd (D_BOX_SKIN_THINCKNESS); padd = padd & dgVector::m_triplexMask; dgVector size0 (m_size[0] - padd); dgVector size1 (m_size[1] + padd); return (size1 & mask) + size0.AndNot(mask); }
void bounds_ifunction_return (array_t * a, const index_type * extent, const char * a_name, const char * intrinsic) { int empty; int n; int rank; index_type a_size; rank = GFC_DESCRIPTOR_RANK (a); a_size = size0 (a); empty = 0; for (n = 0; n < rank; n++) { if (extent[n] == 0) empty = 1; } if (empty) { if (a_size != 0) runtime_error ("Incorrect size in %s of %s" " intrinsic: should be zero-sized", a_name, intrinsic); } else { if (a_size == 0) runtime_error ("Incorrect size of %s in %s" " intrinsic: should not be zero-sized", a_name, intrinsic); for (n = 0; n < rank; n++) { index_type a_extent; a_extent = GFC_DESCRIPTOR_EXTENT(a, n); if (a_extent != extent[n]) runtime_error("Incorrect extent in %s of %s" " intrinsic in dimension %ld: is %ld," " should be %ld", a_name, intrinsic, (long int) n + 1, (long int) a_extent, (long int) extent[n]); } } }
static void unpack_bounds (gfc_array_char *ret, const gfc_array_char *vector, const gfc_array_l1 *mask, const gfc_array_char *field) { index_type vec_size, mask_count; vec_size = size0 ((array_t *) vector); mask_count = count_0 (mask); if (vec_size < mask_count) runtime_error ("Incorrect size of return value in UNPACK" " intrinsic: should be at least %ld, is" " %ld", (long int) mask_count, (long int) vec_size); if (field != NULL) bounds_equal_extents ((array_t *) field, (array_t *) mask, "FIELD", "UNPACK"); if (ret->base_addr != NULL) bounds_equal_extents ((array_t *) ret, (array_t *) mask, "return value", "UNPACK"); }
void NonUniformScaledCollision(DemoEntityManager* const scene) { // load the skybox scene->CreateSkyBox(); // load the scene from a ngd file format CreateLevelMesh(scene, "flatPlane.ngd", 1); // CreateLevelMesh (scene, "sponza.ngd", 1); // CreateLevelMesh (scene, "cattle.ngd", fileName); // CreateLevelMesh (scene, "playground.ngd", 1); dMatrix camMatrix(dRollMatrix(-20.0f * 3.1416f / 180.0f) * dYawMatrix(-45.0f * 3.1416f / 180.0f)); dQuaternion rot(camMatrix); // dVector origin (-30.0f, 40.0f, -15.0f, 0.0f); dVector origin(-10.0f, 5.0f, -15.0f, 0.0f); scene->SetCameraMatrix(rot, origin); NewtonWorld* const world = scene->GetNewton(); int defaultMaterialID = NewtonMaterialGetDefaultGroupID(world); dVector location(0.0f, 0.0f, 0.0f, 0.0f); dVector size0(0.5f, 0.5f, 1.0f, 0.0f); dVector size1(0.5f, 0.5f, 0.5f, 0.0f); int count = 5; dMatrix shapeOffsetMatrix(dRollMatrix(3.141592f / 2.0f)); shapeOffsetMatrix.m_posit.m_y = 0.0f; AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size1, count, count, 4.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size1, count, count, 4.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 4.0f, _COMPOUND_CONVEX_CRUZ_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); }
static void eoshift0 (gfc_array_char * ret, const gfc_array_char * array, int shift, const char * pbound, int which, index_type size, char filler) { /* r.* indicates the return array. */ index_type rstride[GFC_MAX_DIMENSIONS]; index_type rstride0; index_type roffset; char *rptr; char *dest; /* s.* indicates the source array. */ index_type sstride[GFC_MAX_DIMENSIONS]; index_type sstride0; index_type soffset; const char *sptr; const char *src; index_type count[GFC_MAX_DIMENSIONS]; index_type extent[GFC_MAX_DIMENSIONS]; index_type dim; index_type len; index_type n; /* The compiler cannot figure out that these are set, initialize them to avoid warnings. */ len = 0; soffset = 0; roffset = 0; if (ret->data == NULL) { int i; ret->data = internal_malloc_size (size * size0 ((array_t *)array)); ret->offset = 0; ret->dtype = array->dtype; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) { ret->dim[i].lbound = 0; ret->dim[i].ubound = array->dim[i].ubound - array->dim[i].lbound; if (i == 0) ret->dim[i].stride = 1; else ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride; } } which = which - 1; extent[0] = 1; count[0] = 0; sstride[0] = -1; rstride[0] = -1; n = 0; for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++) { if (dim == which) { roffset = ret->dim[dim].stride * size; if (roffset == 0) roffset = size; soffset = array->dim[dim].stride * size; if (soffset == 0) soffset = size; len = array->dim[dim].ubound + 1 - array->dim[dim].lbound; } else { count[n] = 0; extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound; rstride[n] = ret->dim[dim].stride * size; sstride[n] = array->dim[dim].stride * size; n++; } } if (sstride[0] == 0) sstride[0] = size; if (rstride[0] == 0) rstride[0] = size; dim = GFC_DESCRIPTOR_RANK (array); rstride0 = rstride[0]; sstride0 = sstride[0]; rptr = ret->data; sptr = array->data; if ((shift >= 0 ? shift : -shift) > len) { shift = len; len = 0; } else { if (shift > 0) len = len - shift; else len = len + shift; } while (rptr) { /* Do the shift for this dimension. */ if (shift > 0) { src = &sptr[shift * soffset]; dest = rptr; } else { src = sptr; dest = &rptr[-shift * roffset]; } for (n = 0; n < len; n++) { memcpy (dest, src, size); dest += roffset; src += soffset; } if (shift >= 0) { n = shift; } else { dest = rptr; n = -shift; } if (pbound) while (n--) { memcpy (dest, pbound, size); dest += roffset; } else while (n--) { memset (dest, filler, size); dest += roffset; } /* Advance to the next section. */ rptr += rstride0; sptr += sstride0; count[0]++; n = 0; while (count[n] == extent[n]) { /* When we get to the end of a dimension, reset it and increment the next dimension. */ count[n] = 0; /* We could precalculate these products, but this is a less frequently used path so probably not worth it. */ rptr -= rstride[n] * extent[n]; sptr -= sstride[n] * extent[n]; n++; if (n >= dim - 1) { /* Break out of the loop. */ rptr = NULL; break; } else { count[n]++; rptr += rstride[n]; sptr += sstride[n]; } } } }
static void transpose_internal (gfc_array_char *ret, gfc_array_char *source, index_type size) { /* r.* indicates the return array. */ index_type rxstride, rystride; char *rptr; /* s.* indicates the source array. */ index_type sxstride, systride; const char *sptr; index_type xcount, ycount; index_type x, y; assert (GFC_DESCRIPTOR_RANK (source) == 2 && GFC_DESCRIPTOR_RANK (ret) == 2); if (ret->data == NULL) { assert (ret->dtype == source->dtype); ret->dim[0].lbound = 0; ret->dim[0].ubound = source->dim[1].ubound - source->dim[1].lbound; ret->dim[0].stride = 1; ret->dim[1].lbound = 0; ret->dim[1].ubound = source->dim[0].ubound - source->dim[0].lbound; ret->dim[1].stride = ret->dim[0].ubound+1; ret->data = internal_malloc_size (size * size0 ((array_t*)ret)); ret->offset = 0; } else if (unlikely (compile_options.bounds_check)) { index_type ret_extent, src_extent; ret_extent = ret->dim[0].ubound + 1 - ret->dim[0].lbound; src_extent = source->dim[1].ubound + 1 - source->dim[1].lbound; if (src_extent != ret_extent) runtime_error ("Incorrect extent in return value of TRANSPOSE" " intrinsic in dimension 1: is %ld," " should be %ld", (long int) src_extent, (long int) ret_extent); ret_extent = ret->dim[1].ubound + 1 - ret->dim[1].lbound; src_extent = source->dim[0].ubound + 1 - source->dim[0].lbound; if (src_extent != ret_extent) runtime_error ("Incorrect extent in return value of TRANSPOSE" " intrinsic in dimension 2: is %ld," " should be %ld", (long int) src_extent, (long int) ret_extent); } sxstride = source->dim[0].stride * size; systride = source->dim[1].stride * size; xcount = source->dim[0].ubound + 1 - source->dim[0].lbound; ycount = source->dim[1].ubound + 1 - source->dim[1].lbound; rxstride = ret->dim[0].stride * size; rystride = ret->dim[1].stride * size; rptr = ret->data; sptr = source->data; for (y = 0; y < ycount; y++) { for (x = 0; x < xcount; x++) { memcpy (rptr, sptr, size); sptr += sxstride; rptr += rystride; } sptr += systride - (sxstride * xcount); rptr += rxstride - (rystride * xcount); } }
static void cshift0 (gfc_array_char * ret, const gfc_array_char * array, ptrdiff_t shift, int which, index_type size) { /* r.* indicates the return array. */ index_type rstride[GFC_MAX_DIMENSIONS]; index_type rstride0; index_type roffset; char *rptr; /* s.* indicates the source array. */ index_type sstride[GFC_MAX_DIMENSIONS]; index_type sstride0; index_type soffset; const char *sptr; index_type count[GFC_MAX_DIMENSIONS]; index_type extent[GFC_MAX_DIMENSIONS]; index_type dim; index_type len; index_type n; index_type arraysize; index_type type_size; if (which < 1 || which > GFC_DESCRIPTOR_RANK (array)) runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'"); arraysize = size0 ((array_t *) array); if (ret->base_addr == NULL) { int i; ret->offset = 0; GFC_DTYPE_COPY(ret,array); for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) { index_type ub, str; ub = GFC_DESCRIPTOR_EXTENT(array,i) - 1; if (i == 0) str = 1; else str = GFC_DESCRIPTOR_EXTENT(ret,i-1) * GFC_DESCRIPTOR_STRIDE(ret,i-1); GFC_DIMENSION_SET(ret->dim[i], 0, ub, str); } /* xmallocarray allocates a single byte for zero size. */ ret->base_addr = xmallocarray (arraysize, size); } else if (unlikely (compile_options.bounds_check)) { bounds_equal_extents ((array_t *) ret, (array_t *) array, "return value", "CSHIFT"); } if (arraysize == 0) return; type_size = GFC_DTYPE_TYPE_SIZE (array); switch(type_size) { case GFC_DTYPE_LOGICAL_1: case GFC_DTYPE_INTEGER_1: cshift0_i1 ((gfc_array_i1 *)ret, (gfc_array_i1 *) array, shift, which); return; case GFC_DTYPE_LOGICAL_2: case GFC_DTYPE_INTEGER_2: cshift0_i2 ((gfc_array_i2 *)ret, (gfc_array_i2 *) array, shift, which); return; case GFC_DTYPE_LOGICAL_4: case GFC_DTYPE_INTEGER_4: cshift0_i4 ((gfc_array_i4 *)ret, (gfc_array_i4 *) array, shift, which); return; case GFC_DTYPE_LOGICAL_8: case GFC_DTYPE_INTEGER_8: cshift0_i8 ((gfc_array_i8 *)ret, (gfc_array_i8 *) array, shift, which); return; #ifdef HAVE_GFC_INTEGER_16 case GFC_DTYPE_LOGICAL_16: case GFC_DTYPE_INTEGER_16: cshift0_i16 ((gfc_array_i16 *)ret, (gfc_array_i16 *) array, shift, which); return; #endif case GFC_DTYPE_REAL_4: cshift0_r4 ((gfc_array_r4 *)ret, (gfc_array_r4 *) array, shift, which); return; case GFC_DTYPE_REAL_8: cshift0_r8 ((gfc_array_r8 *)ret, (gfc_array_r8 *) array, shift, which); return; /* FIXME: This here is a hack, which will have to be removed when the array descriptor is reworked. Currently, we don't store the kind value for the type, but only the size. Because on targets with __float128, we have sizeof(logn double) == sizeof(__float128), we cannot discriminate here and have to fall back to the generic handling (which is suboptimal). */ #if !defined(GFC_REAL_16_IS_FLOAT128) # ifdef HAVE_GFC_REAL_10 case GFC_DTYPE_REAL_10: cshift0_r10 ((gfc_array_r10 *)ret, (gfc_array_r10 *) array, shift, which); return; # endif # ifdef HAVE_GFC_REAL_16 case GFC_DTYPE_REAL_16: cshift0_r16 ((gfc_array_r16 *)ret, (gfc_array_r16 *) array, shift, which); return; # endif #endif case GFC_DTYPE_COMPLEX_4: cshift0_c4 ((gfc_array_c4 *)ret, (gfc_array_c4 *) array, shift, which); return; case GFC_DTYPE_COMPLEX_8: cshift0_c8 ((gfc_array_c8 *)ret, (gfc_array_c8 *) array, shift, which); return; /* FIXME: This here is a hack, which will have to be removed when the array descriptor is reworked. Currently, we don't store the kind value for the type, but only the size. Because on targets with __float128, we have sizeof(logn double) == sizeof(__float128), we cannot discriminate here and have to fall back to the generic handling (which is suboptimal). */ #if !defined(GFC_REAL_16_IS_FLOAT128) # ifdef HAVE_GFC_COMPLEX_10 case GFC_DTYPE_COMPLEX_10: cshift0_c10 ((gfc_array_c10 *)ret, (gfc_array_c10 *) array, shift, which); return; # endif # ifdef HAVE_GFC_COMPLEX_16 case GFC_DTYPE_COMPLEX_16: cshift0_c16 ((gfc_array_c16 *)ret, (gfc_array_c16 *) array, shift, which); return; # endif #endif default: break; } switch (size) { /* Let's check the actual alignment of the data pointers. If they are suitably aligned, we can safely call the unpack functions. */ case sizeof (GFC_INTEGER_1): cshift0_i1 ((gfc_array_i1 *) ret, (gfc_array_i1 *) array, shift, which); break; case sizeof (GFC_INTEGER_2): if (GFC_UNALIGNED_2(ret->base_addr) || GFC_UNALIGNED_2(array->base_addr)) break; else { cshift0_i2 ((gfc_array_i2 *) ret, (gfc_array_i2 *) array, shift, which); return; } case sizeof (GFC_INTEGER_4): if (GFC_UNALIGNED_4(ret->base_addr) || GFC_UNALIGNED_4(array->base_addr)) break; else { cshift0_i4 ((gfc_array_i4 *)ret, (gfc_array_i4 *) array, shift, which); return; } case sizeof (GFC_INTEGER_8): if (GFC_UNALIGNED_8(ret->base_addr) || GFC_UNALIGNED_8(array->base_addr)) { /* Let's try to use the complex routines. First, a sanity check that the sizes match; this should be optimized to a no-op. */ if (sizeof(GFC_INTEGER_8) != sizeof(GFC_COMPLEX_4)) break; if (GFC_UNALIGNED_C4(ret->base_addr) || GFC_UNALIGNED_C4(array->base_addr)) break; cshift0_c4 ((gfc_array_c4 *) ret, (gfc_array_c4 *) array, shift, which); return; } else { cshift0_i8 ((gfc_array_i8 *)ret, (gfc_array_i8 *) array, shift, which); return; } #ifdef HAVE_GFC_INTEGER_16 case sizeof (GFC_INTEGER_16): if (GFC_UNALIGNED_16(ret->base_addr) || GFC_UNALIGNED_16(array->base_addr)) { /* Let's try to use the complex routines. First, a sanity check that the sizes match; this should be optimized to a no-op. */ if (sizeof(GFC_INTEGER_16) != sizeof(GFC_COMPLEX_8)) break; if (GFC_UNALIGNED_C8(ret->base_addr) || GFC_UNALIGNED_C8(array->base_addr)) break; cshift0_c8 ((gfc_array_c8 *) ret, (gfc_array_c8 *) array, shift, which); return; } else { cshift0_i16 ((gfc_array_i16 *) ret, (gfc_array_i16 *) array, shift, which); return; } #else case sizeof (GFC_COMPLEX_8): if (GFC_UNALIGNED_C8(ret->base_addr) || GFC_UNALIGNED_C8(array->base_addr)) break; else { cshift0_c8 ((gfc_array_c8 *) ret, (gfc_array_c8 *) array, shift, which); return; } #endif default: break; } which = which - 1; sstride[0] = 0; rstride[0] = 0; extent[0] = 1; count[0] = 0; n = 0; /* Initialized for avoiding compiler warnings. */ roffset = size; soffset = size; len = 0; for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++) { if (dim == which) { roffset = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim); if (roffset == 0) roffset = size; soffset = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim); if (soffset == 0) soffset = size; len = GFC_DESCRIPTOR_EXTENT(array,dim); } else { count[n] = 0; extent[n] = GFC_DESCRIPTOR_EXTENT(array,dim); rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim); sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim); n++; } } if (sstride[0] == 0) sstride[0] = size; if (rstride[0] == 0) rstride[0] = size; dim = GFC_DESCRIPTOR_RANK (array); rstride0 = rstride[0]; sstride0 = sstride[0]; rptr = ret->base_addr; sptr = array->base_addr; shift = len == 0 ? 0 : shift % (ptrdiff_t)len; if (shift < 0) shift += len; while (rptr) { /* Do the shift for this dimension. */ /* If elements are contiguous, perform the operation in two block moves. */ if (soffset == size && roffset == size) { size_t len1 = shift * size; size_t len2 = (len - shift) * size; memcpy (rptr, sptr + len1, len2); memcpy (rptr + len2, sptr, len1); } else { /* Otherwise, we'll have to perform the copy one element at a time. */ char *dest = rptr; const char *src = &sptr[shift * soffset]; for (n = 0; n < len - shift; n++) { memcpy (dest, src, size); dest += roffset; src += soffset; } for (src = sptr, n = 0; n < shift; n++) { memcpy (dest, src, size); dest += roffset; src += soffset; } } /* Advance to the next section. */ rptr += rstride0; sptr += sstride0; count[0]++; n = 0; while (count[n] == extent[n]) { /* When we get to the end of a dimension, reset it and increment the next dimension. */ count[n] = 0; /* We could precalculate these products, but this is a less frequently used path so probably not worth it. */ rptr -= rstride[n] * extent[n]; sptr -= sstride[n] * extent[n]; n++; if (n >= dim - 1) { /* Break out of the loop. */ rptr = NULL; break; } else { count[n]++; rptr += rstride[n]; sptr += sstride[n]; } } } }
index_type dim; index_type len; index_type n; index_type size; index_type arraysize; int which; GFC_INTEGER_16 sh; GFC_INTEGER_16 delta; /* The compiler cannot figure out that these are set, initialize them to avoid warnings. */ len = 0; soffset = 0; roffset = 0; arraysize = size0 ((array_t *) array); size = GFC_DESCRIPTOR_SIZE(array); if (pwhich) which = *pwhich - 1; else which = 0; if (ret->base_addr == NULL) { int i; ret->base_addr = xmallocarray (arraysize, size); ret->offset = 0; ret->dtype = array->dtype; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
static void cshift1 (gfc_array_char * ret, const gfc_array_char * array, const gfc_array_i4 * h, const GFC_INTEGER_4 * pwhich, index_type size) { /* r.* indicates the return array. */ index_type rstride[GFC_MAX_DIMENSIONS]; index_type rstride0; index_type roffset; char *rptr; char *dest; /* s.* indicates the source array. */ index_type sstride[GFC_MAX_DIMENSIONS]; index_type sstride0; index_type soffset; const char *sptr; const char *src; /* h.* indicates the array. */ index_type hstride[GFC_MAX_DIMENSIONS]; index_type hstride0; const GFC_INTEGER_4 *hptr; index_type count[GFC_MAX_DIMENSIONS]; index_type extent[GFC_MAX_DIMENSIONS]; index_type dim; index_type len; index_type n; int which; GFC_INTEGER_4 sh; if (pwhich) which = *pwhich - 1; else which = 0; if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array)) runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'"); if (ret->data == NULL) { int i; ret->data = internal_malloc_size (size * size0 ((array_t *)array)); ret->offset = 0; ret->dtype = array->dtype; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) { ret->dim[i].lbound = 0; ret->dim[i].ubound = array->dim[i].ubound - array->dim[i].lbound; if (i == 0) ret->dim[i].stride = 1; else ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride; } } extent[0] = 1; count[0] = 0; n = 0; /* Initialized for avoiding compiler warnings. */ roffset = size; soffset = size; len = 0; for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++) { if (dim == which) { roffset = ret->dim[dim].stride * size; if (roffset == 0) roffset = size; soffset = array->dim[dim].stride * size; if (soffset == 0) soffset = size; len = array->dim[dim].ubound + 1 - array->dim[dim].lbound; } else { count[n] = 0; extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound; rstride[n] = ret->dim[dim].stride * size; sstride[n] = array->dim[dim].stride * size; hstride[n] = h->dim[n].stride; n++; } } if (sstride[0] == 0) sstride[0] = size; if (rstride[0] == 0) rstride[0] = size; if (hstride[0] == 0) hstride[0] = 1; dim = GFC_DESCRIPTOR_RANK (array); rstride0 = rstride[0]; sstride0 = sstride[0]; hstride0 = hstride[0]; rptr = ret->data; sptr = array->data; hptr = h->data; while (rptr) { /* Do the for this dimension. */ sh = *hptr; sh = (div (sh, len)).rem; if (sh < 0) sh += len; src = &sptr[sh * soffset]; dest = rptr; for (n = 0; n < len; n++) { memcpy (dest, src, size); dest += roffset; if (n == len - sh - 1) src = sptr; else src += soffset; } /* Advance to the next section. */ rptr += rstride0; sptr += sstride0; hptr += hstride0; count[0]++; n = 0; while (count[n] == extent[n]) { /* When we get to the end of a dimension, reset it and increment the next dimension. */ count[n] = 0; /* We could precalculate these products, but this is a less frequently used path so proabably not worth it. */ rptr -= rstride[n] * extent[n]; sptr -= sstride[n] * extent[n]; hptr -= hstride[n] * extent[n]; n++; if (n >= dim - 1) { /* Break out of the loop. */ rptr = NULL; break; } else { count[n]++; rptr += rstride[n]; sptr += sstride[n]; hptr += hstride[n]; } } } }
void matmul_l8 (gfc_array_l8 * retarray, gfc_array_l4 * a, gfc_array_l4 * b) { GFC_INTEGER_4 *abase; GFC_INTEGER_4 *bbase; GFC_LOGICAL_8 *dest; index_type rxstride; index_type rystride; index_type xcount; index_type ycount; index_type xstride; index_type ystride; index_type x; index_type y; GFC_INTEGER_4 *pa; GFC_INTEGER_4 *pb; index_type astride; index_type bstride; index_type count; index_type n; assert (GFC_DESCRIPTOR_RANK (a) == 2 || GFC_DESCRIPTOR_RANK (b) == 2); if (retarray->data == NULL) { if (GFC_DESCRIPTOR_RANK (a) == 1) { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = b->dim[1].ubound - b->dim[1].lbound; retarray->dim[0].stride = 1; } else if (GFC_DESCRIPTOR_RANK (b) == 1) { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = a->dim[0].ubound - a->dim[0].lbound; retarray->dim[0].stride = 1; } else { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = a->dim[0].ubound - a->dim[0].lbound; retarray->dim[0].stride = 1; retarray->dim[1].lbound = 0; retarray->dim[1].ubound = b->dim[1].ubound - b->dim[1].lbound; retarray->dim[1].stride = retarray->dim[0].ubound+1; } retarray->data = internal_malloc_size (sizeof (GFC_LOGICAL_8) * size0 ((array_t *) retarray)); retarray->base = 0; } abase = a->data; if (GFC_DESCRIPTOR_SIZE (a) != 4) { assert (GFC_DESCRIPTOR_SIZE (a) == 8); abase = GFOR_POINTER_L8_TO_L4 (abase); } bbase = b->data; if (GFC_DESCRIPTOR_SIZE (b) != 4) { assert (GFC_DESCRIPTOR_SIZE (b) == 8); bbase = GFOR_POINTER_L8_TO_L4 (bbase); } dest = retarray->data; if (retarray->dim[0].stride == 0) retarray->dim[0].stride = 1; if (a->dim[0].stride == 0) a->dim[0].stride = 1; if (b->dim[0].stride == 0) b->dim[0].stride = 1; if (GFC_DESCRIPTOR_RANK (retarray) == 1) { rxstride = retarray->dim[0].stride; rystride = rxstride; } else { rxstride = retarray->dim[0].stride; rystride = retarray->dim[1].stride; } /* If we have rank 1 parameters, zero the absent stride, and set the size to one. */ if (GFC_DESCRIPTOR_RANK (a) == 1) { astride = a->dim[0].stride; count = a->dim[0].ubound + 1 - a->dim[0].lbound; xstride = 0; rxstride = 0; xcount = 1; } else { astride = a->dim[1].stride; count = a->dim[1].ubound + 1 - a->dim[1].lbound; xstride = a->dim[0].stride; xcount = a->dim[0].ubound + 1 - a->dim[0].lbound; } if (GFC_DESCRIPTOR_RANK (b) == 1) { bstride = b->dim[0].stride; assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound); ystride = 0; rystride = 0; ycount = 1; } else { bstride = b->dim[0].stride; assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound); ystride = b->dim[1].stride; ycount = b->dim[1].ubound + 1 - b->dim[1].lbound; } for (y = 0; y < ycount; y++) { for (x = 0; x < xcount; x++) { /* Do the summation for this element. For real and integer types this is the same as DOT_PRODUCT. For complex types we use do a*b, not conjg(a)*b. */ pa = abase; pb = bbase; *dest = 0; for (n = 0; n < count; n++) { if (*pa && *pb) { *dest = 1; break; } pa += astride; pb += bstride; } dest += rxstride; abase += xstride; } abase -= xstride * xcount; bbase += ystride; dest += rystride - (rxstride * xcount); } }
/* Dimensions: retarray(x,y) a(x, count) b(count,y). Either a or b can be rank 1. In this case x or y is 1. */ void __matmul_c8 (gfc_array_c8 * retarray, gfc_array_c8 * a, gfc_array_c8 * b) { GFC_COMPLEX_8 *abase; GFC_COMPLEX_8 *bbase; GFC_COMPLEX_8 *dest; GFC_COMPLEX_8 res; index_type rxstride; index_type rystride; index_type xcount; index_type ycount; index_type xstride; index_type ystride; index_type x; index_type y; GFC_COMPLEX_8 *pa; GFC_COMPLEX_8 *pb; index_type astride; index_type bstride; index_type count; index_type n; assert (GFC_DESCRIPTOR_RANK (a) == 2 || GFC_DESCRIPTOR_RANK (b) == 2); if (retarray->data == NULL) { if (GFC_DESCRIPTOR_RANK (a) == 1) { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = b->dim[1].ubound - b->dim[1].lbound; retarray->dim[0].stride = 1; } else if (GFC_DESCRIPTOR_RANK (b) == 1) { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = a->dim[0].ubound - a->dim[0].lbound; retarray->dim[0].stride = 1; } else { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = a->dim[0].ubound - a->dim[0].lbound; retarray->dim[0].stride = 1; retarray->dim[1].lbound = 0; retarray->dim[1].ubound = b->dim[1].ubound - b->dim[1].lbound; retarray->dim[1].stride = retarray->dim[0].ubound+1; } retarray->data = internal_malloc (sizeof (GFC_COMPLEX_8) * size0 (retarray)); retarray->base = 0; } abase = a->data; bbase = b->data; dest = retarray->data; if (retarray->dim[0].stride == 0) retarray->dim[0].stride = 1; if (a->dim[0].stride == 0) a->dim[0].stride = 1; if (b->dim[0].stride == 0) b->dim[0].stride = 1; if (GFC_DESCRIPTOR_RANK (retarray) == 1) { rxstride = retarray->dim[0].stride; rystride = rxstride; } else { rxstride = retarray->dim[0].stride; rystride = retarray->dim[1].stride; } /* If we have rank 1 parameters, zero the absent stride, and set the size to one. */ if (GFC_DESCRIPTOR_RANK (a) == 1) { astride = a->dim[0].stride; count = a->dim[0].ubound + 1 - a->dim[0].lbound; xstride = 0; rxstride = 0; xcount = 1; } else { astride = a->dim[1].stride; count = a->dim[1].ubound + 1 - a->dim[1].lbound; xstride = a->dim[0].stride; xcount = a->dim[0].ubound + 1 - a->dim[0].lbound; } if (GFC_DESCRIPTOR_RANK (b) == 1) { bstride = b->dim[0].stride; assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound); ystride = 0; rystride = 0; ycount = 1; } else { bstride = b->dim[0].stride; assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound); ystride = b->dim[1].stride; ycount = b->dim[1].ubound + 1 - b->dim[1].lbound; } for (y = 0; y < ycount; y++) { for (x = 0; x < xcount; x++) { /* Do the summation for this element. For real and integer types this is the same as DOT_PRODUCT. For complex types we use do a*b, not conjg(a)*b. */ pa = abase; pb = bbase; res = 0; for (n = 0; n < count; n++) { res += *pa * *pb; pa += astride; pb += bstride; } *dest = res; dest += rxstride; abase += xstride; } abase -= xstride * xcount; bbase += ystride; dest += rystride - (rxstride * xcount); } }
void eoshift3_4 (gfc_array_char *ret, gfc_array_char *array, gfc_array_i4 *h, const gfc_array_char *bound, GFC_INTEGER_4 *pwhich) { /* r.* indicates the return array. */ index_type rstride[GFC_MAX_DIMENSIONS]; index_type rstride0; index_type roffset; char *rptr; char *dest; /* s.* indicates the source array. */ index_type sstride[GFC_MAX_DIMENSIONS]; index_type sstride0; index_type soffset; const char *sptr; const char *src; /* h.* indicates the shift array. */ index_type hstride[GFC_MAX_DIMENSIONS]; index_type hstride0; const GFC_INTEGER_4 *hptr; /* b.* indicates the bound array. */ index_type bstride[GFC_MAX_DIMENSIONS]; index_type bstride0; const char *bptr; index_type count[GFC_MAX_DIMENSIONS]; index_type extent[GFC_MAX_DIMENSIONS]; index_type dim; index_type size; index_type len; index_type n; int which; GFC_INTEGER_4 sh; GFC_INTEGER_4 delta; if (pwhich) which = *pwhich - 1; else which = 0; size = GFC_DESCRIPTOR_SIZE (ret); if (ret->data == NULL) { int i; ret->data = internal_malloc_size (size * size0 ((array_t *)array)); ret->base = 0; ret->dtype = array->dtype; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) { ret->dim[i].lbound = 0; ret->dim[i].ubound = array->dim[i].ubound - array->dim[i].lbound; if (i == 0) ret->dim[i].stride = 1; else ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride; } } extent[0] = 1; count[0] = 0; size = GFC_DESCRIPTOR_SIZE (array); n = 0; for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++) { if (dim == which) { roffset = ret->dim[dim].stride * size; if (roffset == 0) roffset = size; soffset = array->dim[dim].stride * size; if (soffset == 0) soffset = size; len = array->dim[dim].ubound + 1 - array->dim[dim].lbound; } else { count[n] = 0; extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound; rstride[n] = ret->dim[dim].stride * size; sstride[n] = array->dim[dim].stride * size; hstride[n] = h->dim[n].stride; if (bound) bstride[n] = bound->dim[n].stride * size; else bstride[n] = 0; n++; } } if (sstride[0] == 0) sstride[0] = size; if (rstride[0] == 0) rstride[0] = size; if (hstride[0] == 0) hstride[0] = 1; if (bound && bstride[0] == 0) bstride[0] = size; dim = GFC_DESCRIPTOR_RANK (array); rstride0 = rstride[0]; sstride0 = sstride[0]; hstride0 = hstride[0]; bstride0 = bstride[0]; rptr = ret->data; sptr = array->data; hptr = h->data; if (bound) bptr = bound->data; else bptr = zeros; while (rptr) { /* Do the shift for this dimension. */ sh = *hptr; if (( sh >= 0 ? sh : -sh ) > len) { delta = len; sh = len; } else delta = (sh >= 0) ? sh: -sh; if (sh > 0) { src = &sptr[delta * soffset]; dest = rptr; } else { src = sptr; dest = &rptr[delta * roffset]; } for (n = 0; n < len - delta; n++) { memcpy (dest, src, size); dest += roffset; src += soffset; } if (sh < 0) dest = rptr; n = delta; while (n--) { memcpy (dest, bptr, size); dest += roffset; } /* Advance to the next section. */ rptr += rstride0; sptr += sstride0; hptr += hstride0; bptr += bstride0; count[0]++; n = 0; while (count[n] == extent[n]) { /* When we get to the end of a dimension, reset it and increment the next dimension. */ count[n] = 0; /* We could precalculate these products, but this is a less frequently used path so proabably not worth it. */ rptr -= rstride[n] * extent[n]; sptr -= sstride[n] * extent[n]; hptr -= hstride[n] * extent[n]; bptr -= bstride[n] * extent[n]; n++; if (n >= dim - 1) { /* Break out of the loop. */ rptr = NULL; break; } else { count[n]++; rptr += rstride[n]; sptr += sstride[n]; hptr += hstride[n]; bptr += bstride[n]; } } } }
static void transpose_internal (gfc_array_char *ret, gfc_array_char *source) { /* r.* indicates the return array. */ index_type rxstride, rystride; char *rptr; /* s.* indicates the source array. */ index_type sxstride, systride; const char *sptr; index_type xcount, ycount; index_type x, y; index_type size; assert (GFC_DESCRIPTOR_RANK (source) == 2 && GFC_DESCRIPTOR_RANK (ret) == 2); size = GFC_DESCRIPTOR_SIZE(ret); if (ret->base_addr == NULL) { assert (ret->dtype == source->dtype); GFC_DIMENSION_SET(ret->dim[0], 0, GFC_DESCRIPTOR_EXTENT(source,1) - 1, 1); GFC_DIMENSION_SET(ret->dim[1], 0, GFC_DESCRIPTOR_EXTENT(source,0) - 1, GFC_DESCRIPTOR_EXTENT(source, 1)); ret->base_addr = xmallocarray (size0 ((array_t*)ret), size); ret->offset = 0; } else if (unlikely (compile_options.bounds_check)) { index_type ret_extent, src_extent; ret_extent = GFC_DESCRIPTOR_EXTENT(ret,0); src_extent = GFC_DESCRIPTOR_EXTENT(source,1); if (src_extent != ret_extent) runtime_error ("Incorrect extent in return value of TRANSPOSE" " intrinsic in dimension 1: is %ld," " should be %ld", (long int) src_extent, (long int) ret_extent); ret_extent = GFC_DESCRIPTOR_EXTENT(ret,1); src_extent = GFC_DESCRIPTOR_EXTENT(source,0); if (src_extent != ret_extent) runtime_error ("Incorrect extent in return value of TRANSPOSE" " intrinsic in dimension 2: is %ld," " should be %ld", (long int) src_extent, (long int) ret_extent); } sxstride = GFC_DESCRIPTOR_STRIDE_BYTES(source,0); systride = GFC_DESCRIPTOR_STRIDE_BYTES(source,1); xcount = GFC_DESCRIPTOR_EXTENT(source,0); ycount = GFC_DESCRIPTOR_EXTENT(source,1); rxstride = GFC_DESCRIPTOR_STRIDE_BYTES(ret,0); rystride = GFC_DESCRIPTOR_STRIDE_BYTES(ret,1); rptr = ret->base_addr; sptr = source->base_addr; for (y = 0; y < ycount; y++) { for (x = 0; x < xcount; x++) { memcpy (rptr, sptr, size); sptr += sxstride; rptr += rystride; } sptr += systride - (sxstride * xcount); rptr += rxstride - (rystride * xcount); } }
void matmul_i8 (gfc_array_i8 * retarray, gfc_array_i8 * a, gfc_array_i8 * b) { GFC_INTEGER_8 *abase; GFC_INTEGER_8 *bbase; GFC_INTEGER_8 *dest; index_type rxstride, rystride, axstride, aystride, bxstride, bystride; index_type x, y, n, count, xcount, ycount; assert (GFC_DESCRIPTOR_RANK (a) == 2 || GFC_DESCRIPTOR_RANK (b) == 2); /* C[xcount,ycount] = A[xcount, count] * B[count,ycount] Either A or B (but not both) can be rank 1: o One-dimensional argument A is implicitly treated as a row matrix dimensioned [1,count], so xcount=1. o One-dimensional argument B is implicitly treated as a column matrix dimensioned [count, 1], so ycount=1. */ if (retarray->data == NULL) { if (GFC_DESCRIPTOR_RANK (a) == 1) { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = b->dim[1].ubound - b->dim[1].lbound; retarray->dim[0].stride = 1; } else if (GFC_DESCRIPTOR_RANK (b) == 1) { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = a->dim[0].ubound - a->dim[0].lbound; retarray->dim[0].stride = 1; } else { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = a->dim[0].ubound - a->dim[0].lbound; retarray->dim[0].stride = 1; retarray->dim[1].lbound = 0; retarray->dim[1].ubound = b->dim[1].ubound - b->dim[1].lbound; retarray->dim[1].stride = retarray->dim[0].ubound+1; } retarray->data = internal_malloc_size (sizeof (GFC_INTEGER_8) * size0 (retarray)); retarray->base = 0; } abase = a->data; bbase = b->data; dest = retarray->data; if (retarray->dim[0].stride == 0) retarray->dim[0].stride = 1; if (a->dim[0].stride == 0) a->dim[0].stride = 1; if (b->dim[0].stride == 0) b->dim[0].stride = 1; if (GFC_DESCRIPTOR_RANK (retarray) == 1) { /* One-dimensional result may be addressed in the code below either as a row or a column matrix. We want both cases to work. */ rxstride = rystride = retarray->dim[0].stride; } else { rxstride = retarray->dim[0].stride; rystride = retarray->dim[1].stride; } if (GFC_DESCRIPTOR_RANK (a) == 1) { /* Treat it as a a row matrix A[1,count]. */ axstride = a->dim[0].stride; aystride = 1; xcount = 1; count = a->dim[0].ubound + 1 - a->dim[0].lbound; } else { axstride = a->dim[0].stride; aystride = a->dim[1].stride; count = a->dim[1].ubound + 1 - a->dim[1].lbound; xcount = a->dim[0].ubound + 1 - a->dim[0].lbound; } assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound); if (GFC_DESCRIPTOR_RANK (b) == 1) { /* Treat it as a column matrix B[count,1] */ bxstride = b->dim[0].stride; /* bystride should never be used for 1-dimensional b. in case it is we want it to cause a segfault, rather than an incorrect result. */ bystride = 0xDEADBEEF; ycount = 1; } else { bxstride = b->dim[0].stride; bystride = b->dim[1].stride; ycount = b->dim[1].ubound + 1 - b->dim[1].lbound; } abase = a->data; bbase = b->data; dest = retarray->data; if (rxstride == 1 && axstride == 1 && bxstride == 1) { GFC_INTEGER_8 *bbase_y; GFC_INTEGER_8 *dest_y; GFC_INTEGER_8 *abase_n; GFC_INTEGER_8 bbase_yn; if (rystride == ycount) memset (dest, 0, (sizeof (GFC_INTEGER_8) * size0((array_t *) retarray))); else { for (y = 0; y < ycount; y++) for (x = 0; x < xcount; x++) dest[x + y*rystride] = (GFC_INTEGER_8)0; } for (y = 0; y < ycount; y++) { bbase_y = bbase + y*bystride; dest_y = dest + y*rystride; for (n = 0; n < count; n++) { abase_n = abase + n*aystride; bbase_yn = bbase_y[n]; for (x = 0; x < xcount; x++) { dest_y[x] += abase_n[x] * bbase_yn; } } } } else { for (y = 0; y < ycount; y++) for (x = 0; x < xcount; x++) dest[x*rxstride + y*rystride] = (GFC_INTEGER_8)0; for (y = 0; y < ycount; y++) for (n = 0; n < count; n++) for (x = 0; x < xcount; x++) /* dest[x,y] += a[x,n] * b[n,y] */ dest[x*rxstride + y*rystride] += abase[x*axstride + n*aystride] * bbase[n*bxstride + y*bystride]; } }
static void eoshift0 (gfc_array_char * ret, const gfc_array_char * array, int shift, const char * pbound, int which, index_type size, const char *filler, index_type filler_len) { /* r.* indicates the return array. */ index_type rstride[GFC_MAX_DIMENSIONS]; index_type rstride0; index_type roffset; char * restrict rptr; char *dest; /* s.* indicates the source array. */ index_type sstride[GFC_MAX_DIMENSIONS]; index_type sstride0; index_type soffset; const char *sptr; const char *src; index_type count[GFC_MAX_DIMENSIONS]; index_type extent[GFC_MAX_DIMENSIONS]; index_type dim; index_type len; index_type n; index_type arraysize; /* The compiler cannot figure out that these are set, initialize them to avoid warnings. */ len = 0; soffset = 0; roffset = 0; arraysize = size0 ((array_t *) array); if (ret->base_addr == NULL) { int i; ret->offset = 0; ret->dtype = array->dtype; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) { index_type ub, str; ub = GFC_DESCRIPTOR_EXTENT(array,i) - 1; if (i == 0) str = 1; else str = GFC_DESCRIPTOR_EXTENT(ret,i-1) * GFC_DESCRIPTOR_STRIDE(ret,i-1); GFC_DIMENSION_SET(ret->dim[i], 0, ub, str); } /* xmalloc allocates a single byte for zero size. */ ret->base_addr = xmalloc (size * arraysize); } else if (unlikely (compile_options.bounds_check)) { bounds_equal_extents ((array_t *) ret, (array_t *) array, "return value", "EOSHIFT"); } if (arraysize == 0) return; which = which - 1; extent[0] = 1; count[0] = 0; sstride[0] = -1; rstride[0] = -1; n = 0; for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++) { if (dim == which) { roffset = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim); if (roffset == 0) roffset = size; soffset = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim); if (soffset == 0) soffset = size; len = GFC_DESCRIPTOR_EXTENT(array,dim); } else { count[n] = 0; extent[n] = GFC_DESCRIPTOR_EXTENT(array,dim); rstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(ret,dim); sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,dim); n++; } } if (sstride[0] == 0) sstride[0] = size; if (rstride[0] == 0) rstride[0] = size; dim = GFC_DESCRIPTOR_RANK (array); rstride0 = rstride[0]; sstride0 = sstride[0]; rptr = ret->base_addr; sptr = array->base_addr; if ((shift >= 0 ? shift : -shift) > len) { shift = len; len = 0; } else { if (shift > 0) len = len - shift; else len = len + shift; } while (rptr) { /* Do the shift for this dimension. */ if (shift > 0) { src = &sptr[shift * soffset]; dest = rptr; } else { src = sptr; dest = &rptr[-shift * roffset]; } for (n = 0; n < len; n++) { memcpy (dest, src, size); dest += roffset; src += soffset; } if (shift >= 0) { n = shift; } else { dest = rptr; n = -shift; } if (pbound) while (n--) { memcpy (dest, pbound, size); dest += roffset; } else while (n--) { index_type i; if (filler_len == 1) memset (dest, filler[0], size); else for (i = 0; i < size ; i += filler_len) memcpy (&dest[i], filler, filler_len); dest += roffset; } /* Advance to the next section. */ rptr += rstride0; sptr += sstride0; count[0]++; n = 0; while (count[n] == extent[n]) { /* When we get to the end of a dimension, reset it and increment the next dimension. */ count[n] = 0; /* We could precalculate these products, but this is a less frequently used path so probably not worth it. */ rptr -= rstride[n] * extent[n]; sptr -= sstride[n] * extent[n]; n++; if (n >= dim - 1) { /* Break out of the loop. */ rptr = NULL; break; } else { count[n]++; rptr += rstride[n]; sptr += sstride[n]; } } } }
void ScaledMeshCollision (DemoEntityManager* const scene) { // load the skybox scene->CreateSkyBox(); // load the scene from a ngd file format CreateLevelMesh (scene, "flatPlane.ngd", 1); //CreateLevelMesh (scene, "flatPlaneDoubleFace.ngd", 1); //CreateLevelMesh (scene, "sponza.ngd", 0); //CreateLevelMesh (scene, "cattle.ngd", fileName); //CreateLevelMesh (scene, "playground.ngd", 0); //dMatrix camMatrix (dRollMatrix(-20.0f * 3.1416f /180.0f) * dYawMatrix(-45.0f * 3.1416f /180.0f)); dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); dVector origin (-15.0f, 5.0f, 0.0f, 0.0f); //origin = origin.Scale (0.25f); scene->SetCameraMatrix(rot, origin); NewtonWorld* const world = scene->GetNewton(); int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world); dVector location (0.0f, 0.0f, 0.0f, 0.0f); dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit = location; matrix.m_posit.m_x = 0.0f; matrix.m_posit.m_y = 0.0f; matrix.m_posit.m_z = 0.0f; matrix.m_posit.m_w = 1.0f; DemoEntity teaPot (dGetIdentityMatrix(), NULL); teaPot.LoadNGD_mesh("teapot.ngd", world); //teaPot.LoadNGD_mesh("box.ngd", world); NewtonCollision* const staticCollision = CreateCollisionTree (world, &teaPot, 0, true); CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (1.0f, 1.0f, 1.0f, 0.0f)); // CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (0.5f, 0.5f, 2.0f, 0.0f)); matrix.m_posit.m_z = -5.0f; CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (0.5f, 0.5f, 2.0f, 0.0f)); matrix.m_posit.m_z = 5.0f; CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (3.0f, 3.0f, 1.5f, 0.0f)); matrix.m_posit.m_z = 0.0f; matrix.m_posit.m_x = -5.0f; CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (0.5f, 0.5f, 0.5f, 0.0f)); matrix.m_posit.m_x = 5.0f; CreateScaleStaticMesh (&teaPot, staticCollision, scene, matrix, dVector (2.0f, 2.0f, 2.0f, 0.0f)); // do not forget to destroy the collision mesh helper NewtonDestroyCollision(staticCollision); dVector size0 (1.0f, 1.0f, 1.0f, 0.0f); dVector size1 (0.5f, 1.0f, 1.0f, 0.0f); dMatrix shapeOffsetMatrix (dRollMatrix(3.141592f/2.0f)); int count = 3; AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _SPHERE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _BOX_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size1, count, count, 5.0f, _CAPSULE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size1, count, count, 5.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _CHAMFER_CYLINDER_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _CONE_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); AddNonUniformScaledPrimitives(scene, 10.0f, location, size0, count, count, 5.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, defaultMaterialID, shapeOffsetMatrix); origin.m_x -= 4.0f; origin.m_y += 1.0f; scene->SetCameraMatrix(rot, origin); }
void transpose_i4 (gfc_array_i4 * ret, gfc_array_i4 * source) { /* r.* indicates the return array. */ index_type rxstride, rystride; GFC_INTEGER_4 *rptr; /* s.* indicates the source array. */ index_type sxstride, systride; const GFC_INTEGER_4 *sptr; index_type xcount, ycount; index_type x, y; assert (GFC_DESCRIPTOR_RANK (source) == 2); if (ret->data == NULL) { assert (GFC_DESCRIPTOR_RANK (ret) == 2); assert (ret->dtype == source->dtype); ret->dim[0].lbound = 0; ret->dim[0].ubound = source->dim[1].ubound - source->dim[1].lbound; ret->dim[0].stride = 1; ret->dim[1].lbound = 0; ret->dim[1].ubound = source->dim[0].ubound - source->dim[0].lbound; ret->dim[1].stride = ret->dim[0].ubound+1; ret->data = internal_malloc_size (sizeof (GFC_INTEGER_4) * size0 ((array_t *) ret)); ret->offset = 0; } if (ret->dim[0].stride == 0) ret->dim[0].stride = 1; if (source->dim[0].stride == 0) source->dim[0].stride = 1; sxstride = source->dim[0].stride; systride = source->dim[1].stride; xcount = source->dim[0].ubound + 1 - source->dim[0].lbound; ycount = source->dim[1].ubound + 1 - source->dim[1].lbound; rxstride = ret->dim[0].stride; rystride = ret->dim[1].stride; rptr = ret->data; sptr = source->data; for (y=0; y < ycount; y++) { for (x=0; x < xcount; x++) { *rptr = *sptr; sptr += sxstride; rptr += rystride; } sptr += systride - (sxstride * xcount); rptr += rxstride - (rystride * xcount); } }
void transpose (gfc_array_char *ret, gfc_array_char *source) { /* r.* indicates the return array. */ index_type rxstride, rystride; char *rptr; /* s.* indicates the source array. */ index_type sxstride, systride; const char *sptr; index_type xcount, ycount; index_type x, y; index_type size; assert (GFC_DESCRIPTOR_RANK (source) == 2 && GFC_DESCRIPTOR_RANK (ret) == 2); size = GFC_DESCRIPTOR_SIZE (source); if (ret->data == NULL) { assert (ret->dtype == source->dtype); ret->dim[0].lbound = 0; ret->dim[0].ubound = source->dim[1].ubound - source->dim[1].lbound; ret->dim[0].stride = 1; ret->dim[1].lbound = 0; ret->dim[1].ubound = source->dim[0].ubound - source->dim[0].lbound; ret->dim[1].stride = ret->dim[0].ubound+1; ret->data = internal_malloc_size (size * size0 ((array_t*)ret)); ret->base = 0; } sxstride = source->dim[0].stride * size; if (sxstride == 0) sxstride = size; systride = source->dim[1].stride * size; xcount = source->dim[0].ubound + 1 - source->dim[0].lbound; ycount = source->dim[1].ubound + 1 - source->dim[1].lbound; rxstride = ret->dim[0].stride * size; if (rxstride == 0) rxstride = size; rystride = ret->dim[1].stride * size; rptr = ret->data; sptr = source->data; for (y = 0; y < ycount; y++) { for (x = 0; x < xcount; x++) { memcpy (rptr, sptr, size); sptr += sxstride; rptr += rystride; } sptr += systride - (sxstride * xcount); rptr += rxstride - (rystride * xcount); } }
static void cshift0 (gfc_array_char * ret, const gfc_array_char * array, ssize_t shift, int which, index_type size) { /* r.* indicates the return array. */ index_type rstride[GFC_MAX_DIMENSIONS]; index_type rstride0; index_type roffset; char *rptr; /* s.* indicates the source array. */ index_type sstride[GFC_MAX_DIMENSIONS]; index_type sstride0; index_type soffset; const char *sptr; index_type count[GFC_MAX_DIMENSIONS]; index_type extent[GFC_MAX_DIMENSIONS]; index_type dim; index_type len; index_type n; int whichloop; if (which < 1 || which > GFC_DESCRIPTOR_RANK (array)) runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'"); which = which - 1; extent[0] = 1; count[0] = 0; n = 0; /* The values assigned here must match the cases in the inner loop. */ whichloop = 0; switch (GFC_DESCRIPTOR_TYPE (array)) { case GFC_DTYPE_LOGICAL: case GFC_DTYPE_INTEGER: case GFC_DTYPE_REAL: if (size == sizeof (int)) whichloop = 1; else if (size == sizeof (long)) whichloop = 2; else if (size == sizeof (double)) whichloop = 3; else if (size == sizeof (long double)) whichloop = 4; break; case GFC_DTYPE_COMPLEX: if (size == sizeof (_Complex float)) whichloop = 5; else if (size == sizeof (_Complex double)) whichloop = 6; break; default: break; } /* Initialized for avoiding compiler warnings. */ roffset = size; soffset = size; len = 0; if (ret->data == NULL) { int i; index_type arraysize = size0 ((array_t *)array); ret->offset = 0; ret->dtype = array->dtype; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) { ret->dim[i].lbound = 0; ret->dim[i].ubound = array->dim[i].ubound - array->dim[i].lbound; if (i == 0) ret->dim[i].stride = 1; else ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride; } if (arraysize > 0) ret->data = internal_malloc_size (size * arraysize); else { ret->data = internal_malloc_size (1); return; } } for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++) { if (dim == which) { roffset = ret->dim[dim].stride * size; if (roffset == 0) roffset = size; soffset = array->dim[dim].stride * size; if (soffset == 0) soffset = size; len = array->dim[dim].ubound + 1 - array->dim[dim].lbound; } else { count[n] = 0; extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound; rstride[n] = ret->dim[dim].stride * size; sstride[n] = array->dim[dim].stride * size; n++; } } if (sstride[0] == 0) sstride[0] = size; if (rstride[0] == 0) rstride[0] = size; dim = GFC_DESCRIPTOR_RANK (array); rstride0 = rstride[0]; sstride0 = sstride[0]; rptr = ret->data; sptr = array->data; shift = shift % (ssize_t)len; if (shift < 0) shift += len; while (rptr) { /* Do the shift for this dimension. */ /* If elements are contiguous, perform the operation in two block moves. */ if (soffset == size && roffset == size) { size_t len1 = shift * size; size_t len2 = (len - shift) * size; memcpy (rptr, sptr + len1, len2); memcpy (rptr + len2, sptr, len1); } else { /* Otherwise, we'll have to perform the copy one element at a time. We can speed this up a tad for common cases of fundamental types. */ switch (whichloop) { case 0: { char *dest = rptr; const char *src = &sptr[shift * soffset]; for (n = 0; n < len - shift; n++) { memcpy (dest, src, size); dest += roffset; src += soffset; } for (src = sptr, n = 0; n < shift; n++) { memcpy (dest, src, size); dest += roffset; src += soffset; } } break; case 1: copy_loop_int (rptr, sptr, roffset, soffset, len, shift); break; case 2: copy_loop_long (rptr, sptr, roffset, soffset, len, shift); break; case 3: copy_loop_double (rptr, sptr, roffset, soffset, len, shift); break; case 4: copy_loop_ldouble (rptr, sptr, roffset, soffset, len, shift); break; case 5: copy_loop_cfloat (rptr, sptr, roffset, soffset, len, shift); break; case 6: copy_loop_cdouble (rptr, sptr, roffset, soffset, len, shift); break; default: abort (); } } /* Advance to the next section. */ rptr += rstride0; sptr += sstride0; count[0]++; n = 0; while (count[n] == extent[n]) { /* When we get to the end of a dimension, reset it and increment the next dimension. */ count[n] = 0; /* We could precalculate these products, but this is a less frequently used path so probably not worth it. */ rptr -= rstride[n] * extent[n]; sptr -= sstride[n] * extent[n]; n++; if (n >= dim - 1) { /* Break out of the loop. */ rptr = NULL; break; } else { count[n]++; rptr += rstride[n]; sptr += sstride[n]; } } } }
int avaliablebytestacks() { return size0(); }