#include "petscmat.h"
#include "private/vecimpl.h" /*I "petscvec.h" I*/
#include "veccomp_private.h"
#include "veccomp.h"
#include "../src/vec/vec/impls/dvecimpl.h"
#include "../src/mat/impls/aij/seq/aij.h"
#include "../src/mat/impls/aij/mpi/mpiaij.h"
typedef struct {
PetscInt n, /* number of active subvectors */
N, /* virtual global size */
lN, /* virtual local size */
friends; /* number of vectors sharing this structure */
} Vec_Comp_N;
typedef struct {
Vec *x; /* the vectors */
PetscInt nx; /* number of available subvectors */
Vec_Comp_N *n; /* structure shared by friend vectors */
} Vec_Comp;
#if defined(PETSC_USE_DEBUG)
#define PetscValidVecComp(x) \
if (((Vec_Comp*)(x)->data)->nx < ((Vec_Comp*)(x)->data)->n->n) { \
return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,1,0,"Invalid number of subvectors required!");}
#else
#define PetscValidVecComp(x)
#endif
static PetscErrorCode VecCreate_Comp_Private(Vec v, Vec *x, PetscInt nx,
PetscTruth x_to_me, Vec_Comp_N* n);
#include "veccomp0.h"
#define __WITH_MPI__
#include "veccomp0.h"
#undef __FUNCT__
#define __FUNCT__ "VecRegistre_Comp"
PetscErrorCode PETSCVEC_DLLEXPORT VecRegister_Comp(const char path[])
{
PetscErrorCode ierr;
PetscFunctionBegin;
ierr = VecRegisterDynamic(VECCOMP, path, "VecCreate_Comp", VecCreate_Comp);
CHKERRQ(ierr);
PetscFunctionReturn(0);
}
#undef __FUNCT__
#define __FUNCT__ "VecDestroy_Comp"
PetscErrorCode VecDestroy_Comp(Vec v)
{
Vec_Comp *vs = (Vec_Comp*)v->data;
PetscInt i;
PetscErrorCode ierr;
PetscFunctionBegin;
/* if memory was published with AMS then destroy it */
ierr = PetscObjectDepublish(v);CHKERRQ(ierr);
#if defined(PETSC_USE_LOG)
PetscLogObjectState((PetscObject)v,"Length=%D",v->map->n);
#endif
for(i=0; i<vs->nx; i++) {
ierr = VecDestroy(vs->x[i]); CHKERRQ(ierr);
}
if(--vs->n->friends <= 0) {
ierr = PetscFree(vs->n); CHKERRQ(ierr);
}
ierr = PetscFree(vs->x); CHKERRQ(ierr);
ierr = PetscFree(vs); CHKERRQ(ierr);
PetscFunctionReturn(0);
}
static struct _VecOps DvOps = {VecDuplicate_Comp, /* 1 */
VecDuplicateVecs_Default,
VecDestroyVecs_Default,
VecDot_Comp_MPI,
VecMDot_Comp_MPI,
VecNorm_Comp_MPI,
0,
0,
VecScale_Comp,
VecCopy_Comp, /* 10 */
VecSet_Comp,
VecSwap_Comp,
VecAXPY_Comp,
VecAXPBY_Comp,
VecMAXPY_Comp,
VecAXPY_Comp/*VecAYPX_Comp*/,
VecWAXPY_Comp,
VecAXPBYPCZ_Comp,
VecPointwiseMult_Comp,
VecPointwiseDivide_Comp,
0, /* 20 */
0,0,
0 /*VecGetArray_Seq*/,
VecGetSize_Comp,
VecGetLocalSize_Comp,
0/*VecRestoreArray_Seq*/,
VecMax_Comp,
VecMin_Comp,
VecSetRandom_Comp,
0, /* 30 */
0,
VecDestroy_Comp,
VecView_Comp,
0/*VecPlaceArray_Seq*/,
0/*VecReplaceArray_Seq*/,
VecDot_Comp_Seq,
0,
VecNorm_Comp_Seq,
VecMDot_Comp_Seq,
0, /* 40 */
0,
0, /* VecLoadIntoVectorNative */
VecReciprocal_Comp,
0, /* VecViewNative */
VecConjugate_Comp,
0,0,
0/*VecResetArray_Seq*/,
0,
VecMaxPointwiseDivide_Comp,
0/*VecLoad_Binary*/, /* 50 */
VecPointwiseMax_Comp,
VecPointwiseMaxAbs_Comp,
VecPointwiseMin_Comp,
0,
VecSqrt_Comp,
VecAbs_Comp,
VecExp_Comp,
VecLog_Comp,
0/*VecShift_Comp*/,
0,
VecDotNorm2_Comp_MPI
};
#undef __FUNCT__
#define __FUNCT__ "VecCreate_Comp_Private"
static PetscErrorCode VecCreate_Comp_Private(Vec v, Vec *x, PetscInt nx,
PetscTruth x_to_me, Vec_Comp_N *n)
{
Vec_Comp *s;
PetscErrorCode ierr;
PetscInt N=0, lN=0, i, k;
PetscFunctionBegin;
/* Allocate a new Vec_Comp */
if (v->data) { ierr = PetscFree(v->data); CHKERRQ(ierr); }
ierr = PetscNewLog(v, Vec_Comp, &s); CHKERRQ(ierr);
ierr = PetscMemcpy(v->ops, &DvOps, sizeof(DvOps)); CHKERRQ(ierr);
v->data = (void*)s;
v->petscnative = PETSC_FALSE;
/* Allocate the array of Vec, if it is needed to be done */
if (x_to_me != PETSC_TRUE) {
ierr = PetscMalloc(sizeof(Vec)*nx, &s->x); CHKERRQ(ierr);
ierr = PetscMemcpy(s->x, x, sizeof(Vec)*nx); CHKERRQ(ierr);
} else
s->x = x;
s->nx = nx;
for(i=0; i<nx; i++) {
ierr = VecGetSize(x[i], &k); CHKERRQ(ierr); N+= k;
ierr = VecGetLocalSize(x[i], &k); CHKERRQ(ierr); lN+= k;
}
/* Allocate the shared structure, if it is not given */
if (!n) {
ierr = PetscNewLog(v, Vec_Comp_N, &n); CHKERRQ(ierr);
s->n = n;
n->n = nx;
n->N = N;
n->lN = lN;
n->friends = 1;
}
/* If not, check in the vector in the shared structure */
else {
s->n = n;
s->n->friends++;
s->n->n = nx;
}
/* Set the virtual sizes as the real sizes of the vector */
ierr = VecSetSizes(v, s->n->lN, s->n->N); CHKERRQ(ierr);
ierr = PetscObjectChangeTypeName((PetscObject)v,VECCOMP); CHKERRQ(ierr);
ierr = PetscPublishAll(v); CHKERRQ(ierr);
PetscFunctionReturn(0);
}
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecCreate_Comp"
PetscErrorCode PETSCVEC_DLLEXPORT VecCreate_Comp(Vec V)
{
PetscErrorCode ierr;
PetscFunctionBegin;
ierr = VecCreate_Comp_Private(V, PETSC_NULL, 0, PETSC_FALSE, PETSC_NULL);
CHKERRQ(ierr);
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecCreateComp"
PetscErrorCode PETSCVEC_DLLEXPORT VecCreateComp(MPI_Comm comm, PetscInt *Nx,
PetscInt n, const VecType t,
Vec Vparent, Vec *V)
{
PetscErrorCode ierr;
Vec *x;
PetscInt i;
PetscFunctionBegin;
ierr = VecCreate(comm, V); CHKERRQ(ierr);
ierr = PetscMalloc(sizeof(Vec)*n, &x); CHKERRQ(ierr);
for(i=0; i<n; i++) {
ierr = VecCreate(comm, &x[i]); CHKERRQ(ierr);
ierr = VecSetSizes(x[i], PETSC_DECIDE, Nx[i]); CHKERRQ(ierr);
ierr = VecSetType(x[i], t); CHKERRQ(ierr);
}
ierr = VecCreate_Comp_Private(*V, x, n, PETSC_TRUE,
Vparent?((Vec_Comp*)Vparent->data)->n:PETSC_NULL);
CHKERRQ(ierr);
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecCreateCompWithVec"
PetscErrorCode PETSCVEC_DLLEXPORT VecCreateCompWithVecs(Vec *x, PetscInt n,
Vec Vparent, Vec *V)
{
PetscErrorCode ierr;
PetscInt i;
PetscFunctionBegin;
ierr = VecCreate(((PetscObject)x[0])->comm, V); CHKERRQ(ierr);
for(i=0; i<n; i++) {
ierr = PetscObjectReference((PetscObject)x[i]); CHKERRQ(ierr);
}
ierr = VecCreate_Comp_Private(*V, x, n, PETSC_FALSE,
Vparent?((Vec_Comp*)Vparent->data)->n:PETSC_NULL);
CHKERRQ(ierr);
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecDuplicate_Comp"
PetscErrorCode VecDuplicate_Comp(Vec win, Vec *V)
{
PetscErrorCode ierr;
Vec *x;
PetscInt i;
Vec_Comp *s = (Vec_Comp*)win->data;
PetscFunctionBegin;
PetscValidVecComp(win);
ierr = VecCreate(((PetscObject)win)->comm, V); CHKERRQ(ierr);
ierr = PetscMalloc(sizeof(Vec)*s->nx, &x); CHKERRQ(ierr);
for(i=0; i<s->nx; i++) {
ierr = VecDuplicate(s->x[i], &x[i]); CHKERRQ(ierr);
}
ierr = VecCreate_Comp_Private(*V, x, s->nx, PETSC_TRUE, s->n); CHKERRQ(ierr);
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecCompGetVecs"
PetscErrorCode VecCompGetVecs(Vec win, const Vec **x, PetscInt *n)
{
Vec_Comp *s = (Vec_Comp*)win->data;
PetscFunctionBegin;
PetscValidVecComp(win);
if(x) *x = s->x;
if(n) *n = s->nx;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecCompSetVecs"
PetscErrorCode VecCompSetVecs(Vec win, Vec *x, PetscInt n)
{
Vec_Comp *s = (Vec_Comp*)win->data;
PetscErrorCode ierr;
PetscFunctionBegin;
PetscValidVecComp(win);
if(x) {
if (n > s->nx) {
ierr = PetscFree(s->x); CHKERRQ(ierr);
ierr = PetscMalloc(sizeof(Vec)*n, &s->x); CHKERRQ(ierr);
}
ierr = PetscMemcpy(s->x, x, sizeof(Vec)*n); CHKERRQ(ierr);
s->nx = n;
}
s->n->n = n;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecAXPY_Comp"
PetscErrorCode VecAXPY_Comp(Vec v, PetscScalar alpha, Vec w)
{
PetscErrorCode ierr;
Vec_Comp *vs = (Vec_Comp*)v->data,
*ws = (Vec_Comp*)w->data;
PetscInt i;
PetscFunctionBegin;
PetscValidVecComp(v);
PetscValidVecComp(w);
for(i=0; i<vs->n->n; i++) {
ierr = VecAXPY(vs->x[i], alpha, ws->x[i]); CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecAXPBY_Comp"
PetscErrorCode VecAXPBY_Comp(Vec v, PetscScalar alpha, PetscScalar beta, Vec w)
{
PetscErrorCode ierr;
Vec_Comp *vs = (Vec_Comp*)v->data,
*ws = (Vec_Comp*)w->data;
PetscInt i;
PetscFunctionBegin;
PetscValidVecComp(v);
PetscValidVecComp(w);
for(i=0; i<vs->n->n; i++) {
ierr = VecAXPBY(vs->x[i], alpha, beta, ws->x[i]); CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecMAXPY_Comp"
PetscErrorCode VecMAXPY_Comp(Vec v, PetscInt n, const PetscScalar *alpha,
Vec *w)
{
PetscErrorCode ierr;
Vec_Comp *vs = (Vec_Comp*)v->data;
Vec *wx;
PetscInt i, j;
PetscFunctionBegin;
PetscValidVecComp(v);
for(i=0; i<n; i++) PetscValidVecComp(w[i]);
ierr = PetscMalloc(sizeof(Vec)*n, &wx); CHKERRQ(ierr);
for(j=0; j<vs->n->n; j++) {
for(i=0; i<n; i++) wx[i] = ((Vec_Comp*)w[i]->data)->x[j];
ierr = VecMAXPY(vs->x[j], n, alpha, wx); CHKERRQ(ierr);
}
ierr = PetscFree(wx); CHKERRQ(ierr);
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecWAXPY_Comp"
PetscErrorCode VecWAXPY_Comp(Vec v, PetscScalar alpha, Vec w, Vec z)
{
PetscErrorCode ierr;
Vec_Comp *vs = (Vec_Comp*)v->data,
*ws = (Vec_Comp*)w->data,
*zs = (Vec_Comp*)z->data;
PetscInt i;
PetscFunctionBegin;
PetscValidVecComp(v);
PetscValidVecComp(w);
PetscValidVecComp(z);
for(i=0; i<vs->n->n; i++) {
ierr = VecWAXPY(vs->x[i], alpha, ws->x[i], zs->x[i]); CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecAXPBYPCZ_Comp"
PetscErrorCode VecAXPBYPCZ_Comp(Vec v, PetscScalar alpha, PetscScalar beta,
PetscScalar gamma, Vec w, Vec z)
{
PetscErrorCode ierr;
Vec_Comp *vs = (Vec_Comp*)v->data,
*ws = (Vec_Comp*)w->data,
*zs = (Vec_Comp*)z->data;
PetscInt i;
PetscFunctionBegin;
PetscValidVecComp(v);
PetscValidVecComp(w);
PetscValidVecComp(z);
for(i=0; i<vs->n->n; i++) {
ierr = VecAXPBYPCZ(vs->x[i], alpha, beta, gamma, ws->x[i], zs->x[i]);
CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecGetSize_Comp"
PetscErrorCode VecGetSize_Comp(Vec v, PetscInt *size)
{
Vec_Comp *vs = (Vec_Comp*)v->data;
PetscFunctionBegin;
PetscValidVecComp(v);
if (size) *size = vs->n->N;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecGetLocalSize_Comp"
PetscErrorCode VecGetLocalSize_Comp(Vec v, PetscInt *size)
{
Vec_Comp *vs = (Vec_Comp*)v->data;
PetscFunctionBegin;
PetscValidVecComp(v);
if (size) *size = vs->n->lN;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecMax_Comp"
PetscErrorCode VecMax_Comp(Vec v, PetscInt *idx, PetscReal *z)
{
PetscErrorCode ierr;
Vec_Comp *vs = (Vec_Comp*)v->data;
PetscInt idxp, s=0, s0;
PetscReal zp, z0;
PetscInt i;
PetscFunctionBegin;
PetscValidVecComp(v);
if(!idx && !z)
PetscFunctionReturn(0);
if (vs->n->n > 0) {
ierr = VecMax(vs->x[0], idx?&idxp:PETSC_NULL, &zp); CHKERRQ(ierr);
}
for (i=1; i<vs->n->n; i++) {
ierr = VecGetSize(vs->x[i-1], &s0); CHKERRQ(ierr); s+= s0;
ierr = VecMax(vs->x[i], idx?&idxp:PETSC_NULL, &z0); CHKERRQ(ierr);
if(zp < z0) {
if(idx) *idx = s+idxp;
zp = z0;
}
}
if (z) *z = zp;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecMin_Comp"
PetscErrorCode VecMin_Comp(Vec v, PetscInt *idx, PetscReal *z)
{
PetscErrorCode ierr;
Vec_Comp *vs = (Vec_Comp*)v->data;
PetscInt idxp, s=0, s0;
PetscReal zp, z0;
PetscInt i;
PetscFunctionBegin;
PetscValidVecComp(v);
if(!idx && !z)
PetscFunctionReturn(0);
if (vs->n->n > 0) {
ierr = VecMin(vs->x[0], idx?&idxp:PETSC_NULL, &zp); CHKERRQ(ierr);
}
for (i=1; i<vs->n->n; i++) {
ierr = VecGetSize(vs->x[i-1], &s0); CHKERRQ(ierr); s+= s0;
ierr = VecMin(vs->x[i], idx?&idxp:PETSC_NULL, &z0); CHKERRQ(ierr);
if(zp > z0) {
if(idx) *idx = s+idxp;
zp = z0;
}
}
if (z) *z = zp;
PetscFunctionReturn(0);
}
EXTERN_C_END
EXTERN_C_BEGIN
#undef __FUNCT__
#define __FUNCT__ "VecMaxPointwiseDivide_Comp"
PetscErrorCode VecMaxPointwiseDivide_Comp(Vec v, Vec w, PetscReal *m)
{
PetscErrorCode ierr;
Vec_Comp *vs = (Vec_Comp*)v->data,
*ws = (Vec_Comp*)w->data;
PetscReal work;
PetscInt i;
PetscFunctionBegin;
PetscValidVecComp(v);
PetscValidVecComp(w);
if(!m || vs->n->n == 0)
PetscFunctionReturn(0);
ierr = VecMaxPointwiseDivide(vs->x[0], ws->x[0], m); CHKERRQ(ierr);
for (i=1; i<vs->n->n; i++) {
ierr = VecMaxPointwiseDivide(vs->x[i], ws->x[i], &work); CHKERRQ(ierr);
*m = PetscMax(*m, work);
}
PetscFunctionReturn(0);
}
EXTERN_C_END
#define __QUOTEME__(x) #x
#define __COMPOSE2__(A,B) A##B
#define __COMPOSE3__(A,B,C) A##B##C
#define __FUNC_TEMPLATE1__(NAME) \
EXTERN_C_BEGIN \
PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v) \
{ \
PetscErrorCode ierr; \
Vec_Comp *vs = (Vec_Comp*)v->data; \
PetscInt i; \
\
PetscFunctionBegin; \
\
PetscValidVecComp(v); \
\
for(i=0; i<vs->n->n; i++) { \
ierr = __COMPOSE2__(Vec,NAME)(vs->x[i]); CHKERRQ(ierr); \
} \
\
PetscFunctionReturn(0);\
} \
EXTERN_C_END \
#undef __FUNCT__
#define __FUNCT__ "VecConjugate_Comp"
__FUNC_TEMPLATE1__(Conjugate)
#undef __FUNCT__
#define __FUNCT__ "VecReciprocal_Comp"
__FUNC_TEMPLATE1__(Reciprocal)
#undef __FUNCT__
#define __FUNCT__ "VecSqrt_Comp"
__FUNC_TEMPLATE1__(Sqrt)
#undef __FUNCT__
#define __FUNCT__ "VecAbs_Comp"
__FUNC_TEMPLATE1__(Abs)
#undef __FUNCT__
#define __FUNCT__ "VecExp_Comp"
__FUNC_TEMPLATE1__(Exp)
#undef __FUNCT__
#define __FUNCT__ "VecLog_Comp"
__FUNC_TEMPLATE1__(Log)
#define __FUNC_TEMPLATE2__(NAME,T0) \
EXTERN_C_BEGIN \
PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v, T0 __a) \
{ \
PetscErrorCode ierr; \
Vec_Comp *vs = (Vec_Comp*)v->data; \
PetscInt i; \
\
PetscFunctionBegin; \
\
PetscValidVecComp(v); \
\
for(i=0; i<vs->n->n; i++) { \
ierr = __COMPOSE2__(Vec,NAME)(vs->x[i], __a); CHKERRQ(ierr); \
} \
\
PetscFunctionReturn(0);\
} \
EXTERN_C_END \
#undef __FUNCT__
#define __FUNCT__ "VecSet_Comp"
__FUNC_TEMPLATE2__(Set, PetscScalar)
#undef __FUNCT__
#define __FUNCT__ "VecView_Comp"
__FUNC_TEMPLATE2__(View, PetscViewer)
#undef __FUNCT__
#define __FUNCT__ "VecScale_Comp"
__FUNC_TEMPLATE2__(Scale, PetscScalar)
#undef __FUNCT__
#define __FUNCT__ "VecSetRandom_Comp"
__FUNC_TEMPLATE2__(SetRandom, PetscRandom)
#undef __FUNCT__
#define __FUNCT__ "VecShift_Comp"
__FUNC_TEMPLATE2__(Shift, PetscScalar)
#define __FUNC_TEMPLATE3__(NAME) \
EXTERN_C_BEGIN \
PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v, Vec w) \
{ \
PetscErrorCode ierr; \
Vec_Comp *vs = (Vec_Comp*)v->data, \
*ws = (Vec_Comp*)w->data; \
PetscInt i; \
\
PetscFunctionBegin; \
\
PetscValidVecComp(v); \
PetscValidVecComp(w); \
\
for(i=0; i<vs->n->n; i++) { \
ierr = __COMPOSE2__(Vec,NAME)(vs->x[i], ws->x[i]); CHKERRQ(ierr); \
} \
\
PetscFunctionReturn(0);\
} \
EXTERN_C_END \
#undef __FUNCT__
#define __FUNCT__ "VecCopy_Comp"
__FUNC_TEMPLATE3__(Copy)
#undef __FUNCT__
#define __FUNCT__ "VecSwap_Comp"
__FUNC_TEMPLATE3__(Swap)
#define __FUNC_TEMPLATE4__(NAME) \
EXTERN_C_BEGIN \
PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v, Vec w, Vec z) \
{ \
PetscErrorCode ierr; \
Vec_Comp *vs = (Vec_Comp*)v->data, \
*ws = (Vec_Comp*)w->data, \
*zs = (Vec_Comp*)z->data; \
PetscInt i; \
\
PetscFunctionBegin; \
\
PetscValidVecComp(v); \
PetscValidVecComp(w); \
PetscValidVecComp(z); \
\
for(i=0; i<vs->n->n; i++) { \
ierr = __COMPOSE2__(Vec,NAME)(vs->x[i], ws->x[i], zs->x[i]); \
CHKERRQ(ierr); \
} \
\
PetscFunctionReturn(0);\
} \
EXTERN_C_END \
#undef __FUNCT__
#define __FUNCT__ "VecPointwiseMax_Comp"
__FUNC_TEMPLATE4__(PointwiseMax)
#undef __FUNCT__
#define __FUNCT__ "VecPointwiseMaxAbs_Comp"
__FUNC_TEMPLATE4__(PointwiseMaxAbs)
#undef __FUNCT__
#define __FUNCT__ "VecPointwiseMin_Comp"
__FUNC_TEMPLATE4__(PointwiseMin)
#undef __FUNCT__
#define __FUNCT__ "VecPointwiseMult_Comp"
__FUNC_TEMPLATE4__(PointwiseMult)
#undef __FUNCT__
#define __FUNCT__ "VecPointwiseDivide_Comp"
__FUNC_TEMPLATE4__(PointwiseDivide)