Commit 6d137345 by liyinqiao

Optimize the ScaleAndShift function and add more unit tests.

1. Call the Scale or Shift functions when the parameter shift is 0.0F or scale is 1.0F.
2. Add the unit test for ScaleAndShift for the cases which parameter shift is 0.0F or scale is 1.0F.
parent 13db2e92
......@@ -23,6 +23,7 @@
#include "../../XName.h"
#include "../../XUtility.h"
#include "../shape/IsSameShaped.h"
#include "../math/Binary.h"
#include "ScaleAndShift.h"
#include "ScaleAndShift.cuh"
......@@ -132,7 +133,15 @@ a = a * scale + shift
*/
void ScaleAndShiftMe(XTensor& a, DTYPE scale, DTYPE shift)
{
_ScaleAndShift(&a, &a, scale, shift);
if (scale == 1.0F)
/* call Shift function */
_Shift(&a, &a, shift);
else if (shift == 0.0F)
/* call Scale function */
_Scale(&a, &a, scale);
else
/* call _ScaleAndShift function */
_ScaleAndShift(&a, &a, scale, shift);
}
/*
......@@ -150,15 +159,23 @@ XTensor ScaleAndShift(const XTensor &a, DTYPE scale, DTYPE shift)
{
XTensor b(&a);
b.SetTMPFlag();
/* call _ScaleAndShift function */
_ScaleAndShift(&a, &b, scale, shift);
/* tensor connections */
if (a.enableGrad) {
XLink::MakeLink(&a, NULL, &b, MATH_SCALEANDSHIFT);
XLink::AddParamToHead(&b, scale);
XLink::AddParamToHead(&b, shift);
if (scale == 1.0F)
/* call Shift function */
Shift(a, b, shift);
else if (shift == 0.0F)
/* call Scale function */
Scale(a, b, scale);
else {
/* call _ScaleAndShift function */
_ScaleAndShift(&a, &b, scale, shift);
/* tensor connections */
if (a.enableGrad) {
XLink::MakeLink(&a, NULL, &b, MATH_SCALEANDSHIFT);
XLink::AddParamToHead(&b, scale);
XLink::AddParamToHead(&b, shift);
}
}
return b;
......@@ -180,14 +197,22 @@ void ScaleAndShift(const XTensor & a, XTensor & b, DTYPE scale, DTYPE shift)
InitTensorV2(&b, &a);
}
/* call _ScaleAndShift function */
_ScaleAndShift(&a, &b, scale, shift);
if (a.enableGrad) {
/* tensor connections */
XLink::MakeLink(&a, NULL, &b, MATH_SCALEANDSHIFT);
XLink::AddParamToHead(&b, scale);
XLink::AddParamToHead(&b, shift);
if (scale == 1.0F)
/* call Shift function */
Shift(a, b, shift);
else if (shift == 0.0F)
/* call Scale function */
Scale(a, b, scale);
else {
/* call _ScaleAndShift function */
_ScaleAndShift(&a, &b, scale, shift);
if (a.enableGrad) {
/* tensor connections */
XLink::MakeLink(&a, NULL, &b, MATH_SCALEANDSHIFT);
XLink::AddParamToHead(&b, scale);
XLink::AddParamToHead(&b, shift);
}
}
}
......
......@@ -116,6 +116,190 @@ bool TestScaleAndShift1()
#endif // USE_CUDA
}
/*
case 2: scale all tensor entires.
p = p * scale + 0
*/
bool TestScaleAndShift2()
{
/* a input tensor of size (2, 4) */
int sOrder = 2;
int * sDimSize = new int[sOrder];
sDimSize[0] = 2;
sDimSize[1] = 4;
int sUnitNum = 1;
for (int i = 0; i < sOrder; i++)
sUnitNum *= sDimSize[i];
DTYPE sData[2][4] = { {0.0F, 1.0F, 2.0F, 3.0F},
{4.0F, 5.0F, 6.0F, 7.0F} };
DTYPE answer[2][4] = { {0.0F, 2.0F, 4.0F, 6.0F},
{8.0F, 10.0F, 12.0F, 14.0F} };
DTYPE scaleFactor = 2.0F;
DTYPE shiftFactor = 0.0F;
/* CPU test */
bool cpuTest = true;
/* create tensors */
XTensor * s = NewTensorV2(sOrder, sDimSize);
XTensor * t = NewTensorV2(sOrder, sDimSize);
XTensor * tMe = NewTensorV2(sOrder, sDimSize);
XTensor tUser;
/* initialize variables */
s->SetData(sData, sUnitNum);
tMe->SetData(sData, sUnitNum);
/* call ScaleAndShift function */
_ScaleAndShift(s, t, scaleFactor, shiftFactor);
_ScaleAndShiftMe(tMe, scaleFactor, shiftFactor);
tUser = ScaleAndShift(*s, scaleFactor, shiftFactor);
/* check results */
cpuTest = _CheckData(t, answer, sUnitNum, 1e-4F) &&
_CheckData(tMe, answer, sUnitNum, 1e-4F) &&
_CheckData(&tUser, answer, sUnitNum, 1e-4F);
#ifdef USE_CUDA
/* GPU test */
bool gpuTest = true;
/* create tensors */
XTensor * sGPU = NewTensorV2(sOrder, sDimSize, X_FLOAT, 1.0F, 0);
XTensor * tGPU = NewTensorV2(sOrder, sDimSize, X_FLOAT, 1.0F, 0);
XTensor * tMeGPU = NewTensorV2(sOrder, sDimSize, X_FLOAT, 1.0F, 0);
XTensor tUserGPU;
/* initialize variables */
sGPU->SetData(sData, sUnitNum);
tMeGPU->SetData(sData, sUnitNum);
/* call ScaleAndShift function */
_ScaleAndShift(sGPU, tGPU, scaleFactor, shiftFactor);
_ScaleAndShiftMe(tMeGPU, scaleFactor, shiftFactor);
tUserGPU = ScaleAndShift(*sGPU, scaleFactor, shiftFactor);
/* check results */
gpuTest = _CheckData(tGPU, answer, sUnitNum, 1e-4F) &&
_CheckData(tMeGPU, answer, sUnitNum, 1e-4F) &&
_CheckData(&tUserGPU, answer, sUnitNum, 1e-4F);
/* destroy variables */
delete s;
delete t;
delete tMe;
delete sGPU;
delete tGPU;
delete tMeGPU;
delete[] sDimSize;
return cpuTest && gpuTest;
#else
/* destroy variables */
delete s;
delete t;
delete tMe;
delete[] sDimSize;
return cpuTest;
#endif // USE_CUDA
}
/*
case 3: shift all tensor entires.
p = p * 1.0 + shift
*/
bool TestScaleAndShift3()
{
/* a input tensor of size (2, 4) */
int sOrder = 2;
int * sDimSize = new int[sOrder];
sDimSize[0] = 2;
sDimSize[1] = 4;
int sUnitNum = 1;
for (int i = 0; i < sOrder; i++)
sUnitNum *= sDimSize[i];
DTYPE sData[2][4] = { {0.0F, 1.0F, 2.0F, 3.0F},
{4.0F, 5.0F, 6.0F, 7.0F} };
DTYPE answer[2][4] = { {0.5F, 1.5F, 2.5F, 3.5F},
{4.5F, 5.5F, 6.5F, 7.5F} };
DTYPE scaleFactor = 1.0F;
DTYPE shiftFactor = 0.5F;
/* CPU test */
bool cpuTest = true;
/* create tensors */
XTensor * s = NewTensorV2(sOrder, sDimSize);
XTensor * t = NewTensorV2(sOrder, sDimSize);
XTensor * tMe = NewTensorV2(sOrder, sDimSize);
XTensor tUser;
/* initialize variables */
s->SetData(sData, sUnitNum);
tMe->SetData(sData, sUnitNum);
/* call ScaleAndShift function */
_ScaleAndShift(s, t, scaleFactor, shiftFactor);
_ScaleAndShiftMe(tMe, scaleFactor, shiftFactor);
tUser = ScaleAndShift(*s, scaleFactor, shiftFactor);
/* check results */
cpuTest = _CheckData(t, answer, sUnitNum, 1e-4F) &&
_CheckData(tMe, answer, sUnitNum, 1e-4F) &&
_CheckData(&tUser, answer, sUnitNum, 1e-4F);
#ifdef USE_CUDA
/* GPU test */
bool gpuTest = true;
/* create tensors */
XTensor * sGPU = NewTensorV2(sOrder, sDimSize, X_FLOAT, 1.0F, 0);
XTensor * tGPU = NewTensorV2(sOrder, sDimSize, X_FLOAT, 1.0F, 0);
XTensor * tMeGPU = NewTensorV2(sOrder, sDimSize, X_FLOAT, 1.0F, 0);
XTensor tUserGPU;
/* initialize variables */
sGPU->SetData(sData, sUnitNum);
tMeGPU->SetData(sData, sUnitNum);
/* call ScaleAndShift function */
_ScaleAndShift(sGPU, tGPU, scaleFactor, shiftFactor);
_ScaleAndShiftMe(tMeGPU, scaleFactor, shiftFactor);
tUserGPU = ScaleAndShift(*sGPU, scaleFactor, shiftFactor);
/* check results */
gpuTest = _CheckData(tGPU, answer, sUnitNum, 1e-4F) &&
_CheckData(tMeGPU, answer, sUnitNum, 1e-4F) &&
_CheckData(&tUserGPU, answer, sUnitNum, 1e-4F);
/* destroy variables */
delete s;
delete t;
delete tMe;
delete sGPU;
delete tGPU;
delete tMeGPU;
delete[] sDimSize;
return cpuTest && gpuTest;
#else
/* destroy variables */
delete s;
delete t;
delete tMe;
delete[] sDimSize;
return cpuTest;
#endif // USE_CUDA
}
/* other cases */
/*
TODO!!
......@@ -136,6 +320,24 @@ bool TestScaleAndShift()
else
XPRINT(0, stdout, ">> case 1 passed!\n");
/* case 2 test */
caseFlag = TestScaleAndShift2();
if (!caseFlag) {
returnFlag = false;
XPRINT(0, stdout, ">> case 2 failed!\n");
}
else
XPRINT(0, stdout, ">> case 2 passed!\n");
/* case 3 test */
caseFlag = TestScaleAndShift3();
if (!caseFlag) {
returnFlag = false;
XPRINT(0, stdout, ">> case 3 failed!\n");
}
else
XPRINT(0, stdout, ">> case 3 passed!\n");
/* other cases test */
/*
TODO!!
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论