TConcatenate.cpp 14.1 KB
Newer Older
xiaotong committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northestern University.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* $Created by: Lin Ye (email: linye2015@outlook.com) 2018-06-14
*/

22
#include "../core/utilities/CheckData.h"
liyinqiao committed
23
#include "TConcatenate.h"
xiaotong committed
24 25

namespace nts { // namespace nts(NiuTrans.Tensor)
liyinqiao committed
26 27 28 29

/* 
case 1: concatenate a list of tensors along a given dimension.
In this case, 2 * (2, 1) -> (2, 2), dim=1.
xiaotong committed
30 31 32
*/
bool TestConcatenate1()
{
33
    /* create list */
34
    TensorList * sList = new TensorList();
xiaotong committed
35

liyinqiao committed
36
    /* a source tensor of size (2, 1) */
xiaotong committed
37 38 39 40 41 42 43 44 45
    int sOrder1 = 2;
    int * sDimSize1 = new int[sOrder1];
    sDimSize1[0] = 2;
    sDimSize1[1] = 1;

    int sUnitNum1 = 1;
    for (int i = 0; i < sOrder1; i++)
        sUnitNum1 *= sDimSize1[i];

liyinqiao committed
46
    /* a source tensor of size (2, 1) */
xiaotong committed
47 48 49 50 51 52 53 54 55
    int sOrder2 = 2;
    int * sDimSize2 = new int[sOrder2];
    sDimSize2[0] = 2;
    sDimSize2[1] = 1;

    int sUnitNum2 = 1;
    for (int i = 0; i < sOrder2; i++)
        sUnitNum2 *= sDimSize2[i];

liyinqiao committed
56
    /* a target tensor of size (2, 2) */
xiaotong committed
57 58 59 60 61 62 63 64 65
    int tOrder = 2;
    int * tDimSize = new int[tOrder];
    tDimSize[0] = 2;
    tDimSize[1] = 2;

    int tUnitNum = 1;
    for (int i = 0; i < tOrder; i++)
        tUnitNum *= tDimSize[i];

liyinqiao committed
66 67 68 69 70 71
    DTYPE sData1[2][1] = { {0.0F},
                           {1.0F} };
    DTYPE sData2[2][1] = { {2.0F},
                           {3.0F} };
    DTYPE answer[2][2] = { {0.0F, 2.0F},
                           {1.0F, 3.0F} };
xiaotong committed
72 73 74 75 76

    /* CPU test */
    bool cpuTest = true;

    /* create tensors */
77 78 79
    XTensor * s1 = NewTensorV2(sOrder1, sDimSize1);
    XTensor * s2 = NewTensorV2(sOrder2, sDimSize2);
    XTensor * t = NewTensorV2(tOrder, tDimSize);
80
    XTensor tUser;
xiaotong committed
81 82 83 84 85 86

    /* initialize variables */
    s1->SetData(sData1, sUnitNum1);
    s2->SetData(sData2, sUnitNum2);
    t->SetZeroAll();

87
    /* add tensors to list */
liyinqiao committed
88 89
    sList->Add(s1);
    sList->Add(s2);
xiaotong committed
90

liyinqiao committed
91
    /* call Concatenate function */
92
    _Concatenate(sList, t, 1);
93 94
    tUser = Concatenate(*sList, 1);

xiaotong committed
95
    /* check results */
96
    cpuTest = _CheckData(t, answer, tUnitNum) && _CheckData(&tUser, answer, tUnitNum);
xiaotong committed
97 98 99 100 101 102

#ifdef USE_CUDA
    /* GPU test */
    bool gpuTest = true;

    /* create tensor */
103 104 105
    XTensor * sGPU1 = NewTensorV2(sOrder1, sDimSize1, X_FLOAT, 1.0F, 0);
    XTensor * sGPU2 = NewTensorV2(sOrder2, sDimSize2, X_FLOAT, 1.0F, 0);
    XTensor * tGPU = NewTensorV2(tOrder, tDimSize, X_FLOAT, 1.0F, 0);
106
    XTensor tUserGPU;
xiaotong committed
107 108

    /* Initialize variables */
109 110 111
    sGPU1->SetData(sData1, sUnitNum1);
    sGPU2->SetData(sData2, sUnitNum2);
    tGPU->SetZeroAll();
xiaotong committed
112

113 114
    /* clear list */
    sList->Clear();
liyinqiao committed
115

116 117 118
    /* add tensors to list*/
    sList->Add(sGPU1);
    sList->Add(sGPU2);
xiaotong committed
119

120 121
    /* call Concatenate function */
    _Concatenate(sList, tGPU, 1);
122
    tUserGPU = Concatenate(*sList, 1);
xiaotong committed
123

124 125
    /* check results */
    gpuTest = _CheckData(tGPU, answer, tUnitNum) && _CheckData(&tUserGPU, answer, tUnitNum);
xiaotong committed
126 127

    /* destroy variables */
liyinqiao committed
128 129 130 131 132 133 134 135 136 137
    delete sList;
    delete s1;
    delete s2;
    delete t;
    delete sGPU1;
    delete sGPU2;
    delete tGPU;
    delete[] sDimSize1;
    delete[] sDimSize2;
    delete[] tDimSize;
xiaotong committed
138

139
    return cpuTest && gpuTest;
xiaotong committed
140 141
#else
    /* destroy variables */
liyinqiao committed
142 143 144 145 146 147 148
    delete sList;
    delete s1;
    delete s2;
    delete t;
    delete[] sDimSize1;
    delete[] sDimSize2;
    delete[] tDimSize;
xiaotong committed
149 150 151 152 153

    return cpuTest;
#endif // USE_CUDA
}

liyinqiao committed
154 155 156
/* 
case 2: concatenate a list of tensors along a given dimension.
In this case, 2 * (2, 1) -> (4, 1), dim=0.
xiaotong committed
157 158 159
*/
bool TestConcatenate2()
{
160
    /* create list */
161
    TensorList * sList = new TensorList();
xiaotong committed
162

liyinqiao committed
163
    /* a source tensor of size (2, 1) */
xiaotong committed
164 165 166 167 168 169 170 171 172
    int sOrder1 = 2;
    int * sDimSize1 = new int[sOrder1];
    sDimSize1[0] = 2;
    sDimSize1[1] = 1;

    int sUnitNum1 = 1;
    for (int i = 0; i < sOrder1; i++)
        sUnitNum1 *= sDimSize1[i];

liyinqiao committed
173
    /* a source tensor of size (2, 1) */
xiaotong committed
174 175 176 177 178 179 180 181 182
    int sOrder2 = 2;
    int * sDimSize2 = new int[sOrder2];
    sDimSize2[0] = 2;
    sDimSize2[1] = 1;

    int sUnitNum2 = 1;
    for (int i = 0; i < sOrder2; i++)
        sUnitNum2 *= sDimSize2[i];

liyinqiao committed
183
    /* a target tensor of size (4, 1) */
xiaotong committed
184 185 186 187 188 189 190 191 192
    int tOrder = 2;
    int * tDimSize = new int[tOrder];
    tDimSize[0] = 4;
    tDimSize[1] = 1;

    int tUnitNum = 1;
    for (int i = 0; i < tOrder; i++)
        tUnitNum *= tDimSize[i];

liyinqiao committed
193 194 195 196 197 198 199 200
    DTYPE sData1[2][1] = { {0.0F},
                           {1.0F} };
    DTYPE sData2[2][1] = { {2.0F},
                           {3.0F} };
    DTYPE answer[4][1] = { {0.0F},
                           {1.0F},
                           {2.0F},
                           {3.0F} };
xiaotong committed
201 202 203 204 205

    /* CPU test */
    bool cpuTest = true;

    /* create tensors */
206 207 208
    XTensor * s1 = NewTensorV2(sOrder1, sDimSize1);
    XTensor * s2 = NewTensorV2(sOrder2, sDimSize2);
    XTensor * t = NewTensorV2(tOrder, tDimSize);
209
    XTensor tUser;
xiaotong committed
210 211 212 213 214 215

    /* initialize variables */
    s1->SetData(sData1, sUnitNum1);
    s2->SetData(sData2, sUnitNum2);
    t->SetZeroAll();

216
    /* add tensors to list */
liyinqiao committed
217 218
    sList->Add(s1);
    sList->Add(s2);
xiaotong committed
219

liyinqiao committed
220
    /* call Concatenate function */
221
    _Concatenate(sList, t, 0);
222
    tUser = Concatenate(*sList, 0);
xiaotong committed
223 224

    /* check results */
225
    cpuTest = _CheckData(t, answer, tUnitNum) && _CheckData(&tUser, answer, tUnitNum);
xiaotong committed
226 227

#ifdef USE_CUDA
228 229
    /* GPU test */
    bool gpuTest = true;
xiaotong committed
230

231 232 233 234
    /* create tensor */
    XTensor * sGPU1 = NewTensorV2(sOrder1, sDimSize1, X_FLOAT, 1.0F, 0);
    XTensor * sGPU2 = NewTensorV2(sOrder2, sDimSize2, X_FLOAT, 1.0F, 0);
    XTensor * tGPU = NewTensorV2(tOrder, tDimSize, X_FLOAT, 1.0F, 0);
235
    XTensor tUserGPU;
xiaotong committed
236

237 238 239 240
    /* Initialize variables */
    sGPU1->SetData(sData1, sUnitNum1);
    sGPU2->SetData(sData2, sUnitNum2);
    tGPU->SetZeroAll();
liyinqiao committed
241
    
242 243
    /* clear list */
    sList->Clear();
xiaotong committed
244

245 246 247
    /* add tensors to list*/
    sList->Add(sGPU1);
    sList->Add(sGPU2);
xiaotong committed
248

249 250
    /* call Concatenate function */
    _Concatenate(sList, tGPU, 0);
251
    tUserGPU = Concatenate(*sList, 0);
xiaotong committed
252

253 254
    /* check results */
    gpuTest = _CheckData(tGPU, answer, tUnitNum) && _CheckData(&tUserGPU, answer, tUnitNum);
xiaotong committed
255

256
    /* destroy variables */
liyinqiao committed
257 258 259 260 261 262 263 264 265 266
    delete sList;
    delete s1;
    delete s2;
    delete t;
    delete sGPU1;
    delete sGPU2;
    delete tGPU;
    delete[] sDimSize1;
    delete[] sDimSize2;
    delete[] tDimSize;
xiaotong committed
267

268
    return cpuTest && gpuTest;
xiaotong committed
269 270
#else
    /* destroy variables */
liyinqiao committed
271 272 273 274 275 276 277
    delete sList;
    delete s1;
    delete s2;
    delete t;
    delete[] sDimSize1;
    delete[] sDimSize2;
    delete[] tDimSize;
xiaotong committed
278 279 280 281 282

    return cpuTest;
#endif // USE_CUDA
}

liyinqiao committed
283 284 285
/* 
case 3: concatenate a list of tensors along a given dimension.
In this case, (2, 1) + (2, 2) -> (2, 3), dim=1.
xiaotong committed
286 287 288
*/
bool TestConcatenate3()
{
289
    /* create list */
290
    TensorList * sList = new TensorList();
liyinqiao committed
291 292

    /* a source tensor of size (2, 1) */
xiaotong committed
293 294 295 296 297 298 299 300 301
    int sOrder1 = 2;
    int * sDimSize1 = new int[sOrder1];
    sDimSize1[0] = 2;
    sDimSize1[1] = 1;

    int sUnitNum1 = 1;
    for (int i = 0; i < sOrder1; i++)
        sUnitNum1 *= sDimSize1[i];

liyinqiao committed
302
    /* a source tensor of size (2, 2) */
xiaotong committed
303 304 305 306 307 308 309 310 311
    int sOrder2 = 2;
    int * sDimSize2 = new int[sOrder2];
    sDimSize2[0] = 2;
    sDimSize2[1] = 2;

    int sUnitNum2 = 1;
    for (int i = 0; i < sOrder2; i++)
        sUnitNum2 *= sDimSize2[i];

liyinqiao committed
312
    /* a target tensor of size (2, 3) */
xiaotong committed
313 314 315 316 317 318 319 320 321
    int tOrder = 2;
    int * tDimSize = new int[tOrder];
    tDimSize[0] = 2;
    tDimSize[1] = 3;

    int tUnitNum = 1;
    for (int i = 0; i < tOrder; i++)
        tUnitNum *= tDimSize[i];

liyinqiao committed
322 323 324 325 326 327
    DTYPE sData1[2][1] = { {0.0F},
                           {1.0F} };
    DTYPE sData2[2][2] = { {2.0F, 3.0F},
                           {4.0F, 5.0F} };
    DTYPE answer[2][3] = { {0.0F, 2.0F, 3.0F},
                           {1.0F, 4.0F, 5.0F} };
xiaotong committed
328 329 330 331 332

    /* CPU test */
    bool cpuTest = true;

    /* create tensors */
333 334 335
    XTensor * s1 = NewTensorV2(sOrder1, sDimSize1);
    XTensor * s2 = NewTensorV2(sOrder2, sDimSize2);
    XTensor * t = NewTensorV2(tOrder, tDimSize);
336
    XTensor tUser;
xiaotong committed
337 338 339 340 341 342

    /* initialize variables */
    s1->SetData(sData1, sUnitNum1);
    s2->SetData(sData2, sUnitNum2);
    t->SetZeroAll();

343
    /* add tensors to list */
liyinqiao committed
344 345
    sList->Add(s1);
    sList->Add(s2);
xiaotong committed
346

liyinqiao committed
347
    /* call Concatenate function */
348
    _Concatenate(sList, t, 1);
349
    tUser = Concatenate(*sList, 1);
xiaotong committed
350 351

    /* check results */
352
    cpuTest = _CheckData(t, answer, tUnitNum) && _CheckData(&tUser, answer, tUnitNum);
xiaotong committed
353 354

#ifdef USE_CUDA
355 356
    /* GPU test */
    bool gpuTest = true;
xiaotong committed
357

358 359 360 361
    /* create tensor */
    XTensor * sGPU1 = NewTensorV2(sOrder1, sDimSize1, X_FLOAT, 1.0F, 0);
    XTensor * sGPU2 = NewTensorV2(sOrder2, sDimSize2, X_FLOAT, 1.0F, 0);
    XTensor * tGPU = NewTensorV2(tOrder, tDimSize, X_FLOAT, 1.0F, 0);
362
    XTensor tUserGPU;
xiaotong committed
363

364 365 366 367
    /* Initialize variables */
    sGPU1->SetData(sData1, sUnitNum1);
    sGPU2->SetData(sData2, sUnitNum2);
    tGPU->SetZeroAll();
liyinqiao committed
368
    
369 370
    /* clear list */
    sList->Clear();
xiaotong committed
371

372 373 374
    /* add tensors to list*/
    sList->Add(sGPU1);
    sList->Add(sGPU2);
xiaotong committed
375

376 377
    /* call Concatenate function */
    _Concatenate(sList, tGPU, 1);
378
    tUserGPU = Concatenate(*sList, 1);
xiaotong committed
379

380 381
    /* check results */
    gpuTest = _CheckData(tGPU, answer, tUnitNum) && _CheckData(&tUserGPU, answer, tUnitNum);
xiaotong committed
382

383
    /* destroy variables */
liyinqiao committed
384 385 386 387 388 389 390 391 392 393
    delete sList;
    delete s1;
    delete s2;
    delete t;
    delete sGPU1;
    delete sGPU2;
    delete tGPU;
    delete[] sDimSize1;
    delete[] sDimSize2;
    delete[] tDimSize;
xiaotong committed
394

395
    return cpuTest && gpuTest;
xiaotong committed
396
#else
liyinqiao committed
397 398 399 400 401 402 403 404
    /* destroy variables */
    delete sList;
    delete s1;
    delete s2;
    delete t;
    delete[] sDimSize1;
    delete[] sDimSize2;
    delete[] tDimSize;
xiaotong committed
405

406
    return cpuTest;
xiaotong committed
407 408 409
#endif // USE_CUDA
}

liyinqiao committed
410 411 412
/* 
case 4: concatenate two tensors along a given dimension.
In this case, (2, 1), (2, 2) -> (2, 3), dim=1.
xiaotong committed
413 414 415
*/
bool TestConcatenate4()
{
liyinqiao committed
416
    /* a source tensor of size (2, 1) */
xiaotong committed
417 418 419 420 421 422 423 424 425
    int sOrder1 = 2;
    int * sDimSize1 = new int[sOrder1];
    sDimSize1[0] = 2;
    sDimSize1[1] = 1;

    int sUnitNum1 = 1;
    for (int i = 0; i < sOrder1; i++)
        sUnitNum1 *= sDimSize1[i];

liyinqiao committed
426
    /* a source tensor of size (2, 2) */
xiaotong committed
427 428 429 430 431 432 433 434 435
    int sOrder2 = 2;
    int * sDimSize2 = new int[sOrder2];
    sDimSize2[0] = 2;
    sDimSize2[1] = 2;

    int sUnitNum2 = 1;
    for (int i = 0; i < sOrder2; i++)
        sUnitNum2 *= sDimSize2[i];

liyinqiao committed
436
    /* a target tensor of size (2, 3) */
xiaotong committed
437 438 439 440 441 442 443 444 445
    int tOrder = 2;
    int * tDimSize = new int[tOrder];
    tDimSize[0] = 2;
    tDimSize[1] = 3;

    int tUnitNum = 1;
    for (int i = 0; i < tOrder; i++)
        tUnitNum *= tDimSize[i];

liyinqiao committed
446 447 448 449 450 451
    DTYPE sData1[2][1] = { {0.0F},
                           {1.0F} };
    DTYPE sData2[2][2] = { {2.0F, 3.0F},
                           {4.0F, 5.0F} };
    DTYPE answer[2][3] = { {0.0F, 2.0F, 3.0F},
                           {1.0F, 4.0F, 5.0F} };
xiaotong committed
452 453 454 455 456

    /* CPU test */
    bool cpuTest = true;

    /* create tensors */
457 458 459
    XTensor * s1 = NewTensorV2(sOrder1, sDimSize1);
    XTensor * s2 = NewTensorV2(sOrder2, sDimSize2);
    XTensor * t = NewTensorV2(tOrder, tDimSize);
460
    XTensor tUser;
xiaotong committed
461 462 463 464 465 466

    /* initialize variables */
    s1->SetData(sData1, sUnitNum1);
    s2->SetData(sData2, sUnitNum2);
    t->SetZeroAll();

liyinqiao committed
467
    /* call Concatenate function */
468
    _Concatenate(s1, s2, t, 1);
469
    tUser = Concatenate(*s1, *s2, 1);
xiaotong committed
470 471

    /* check results */
472
    cpuTest = _CheckData(t, answer, tUnitNum) && _CheckData(&tUser, answer, tUnitNum);
xiaotong committed
473 474

#ifdef USE_CUDA
475 476
    /* GPU test */
    bool gpuTest = true;
xiaotong committed
477

478 479 480 481
    /* create tensor */
    XTensor * sGPU1 = NewTensorV2(sOrder1, sDimSize1, X_FLOAT, 1.0F, 0);
    XTensor * sGPU2 = NewTensorV2(sOrder2, sDimSize2, X_FLOAT, 1.0F, 0);
    XTensor * tGPU = NewTensorV2(tOrder, tDimSize, X_FLOAT, 1.0F, 0);
482
    XTensor tUserGPU;
xiaotong committed
483

484 485 486 487
    /* Initialize variables */
    sGPU1->SetData(sData1, sUnitNum1);
    sGPU2->SetData(sData2, sUnitNum2);
    tGPU->SetZeroAll();
xiaotong committed
488

489 490
    /* call Concatenate function */
    _Concatenate(sGPU1, sGPU2, tGPU, 1);
491
    tUserGPU = Concatenate(*sGPU1, *sGPU2, 1);
xiaotong committed
492

493 494
    /* check results */
    gpuTest = _CheckData(tGPU, answer, tUnitNum) && _CheckData(&tUserGPU, answer, tUnitNum);
xiaotong committed
495

496
    /* destroy variables */
liyinqiao committed
497 498 499 500 501 502
    delete s1;
    delete s2;
    delete t;
    delete sGPU1;
    delete sGPU2;
    delete tGPU;
503 504 505
    //delete[] sDimSize1;
    //delete[] sDimSize2;
    //delete[] tDimSize;
xiaotong committed
506

507
    return cpuTest && gpuTest;
xiaotong committed
508
#else
liyinqiao committed
509 510 511 512 513 514 515
    /* destroy variables */
    delete s1;
    delete s2;
    delete t;
    delete[] sDimSize1;
    delete[] sDimSize2;
    delete[] tDimSize;
xiaotong committed
516

517
    return cpuTest;
xiaotong committed
518 519 520 521 522 523 524 525 526 527 528
#endif // USE_CUDA
}

/* other cases */
/*
TODO!!
*/

/* test for Concatenate Function */
bool TestConcatenate()
{
liyinqiao committed
529
    XPRINT(0, stdout, "[TEST CONCATENATE] concatenate a list of tensors or two tensors along a given dimension \n");
xiaotong committed
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
    bool returnFlag = true, caseFlag = true;

    /* case 1 test */
    caseFlag = TestConcatenate1();

    if (!caseFlag) {
        returnFlag = false;
        XPRINT(0, stdout, ">> case 1 failed!\n");
    }
    else
        XPRINT(0, stdout, ">> case 1 passed!\n");

    /* case 2 test */
    caseFlag = TestConcatenate2();

    if (!caseFlag) {
        returnFlag = false;
        XPRINT(0, stdout, ">> case 2 failed!\n");
    }
    else
        XPRINT(0, stdout, ">> case 2 passed!\n");

    /* case 3 test */
    caseFlag = TestConcatenate3();

    if (!caseFlag) {
        returnFlag = false;
        XPRINT(0, stdout, ">> case 3 failed!\n");
    }
    else
        XPRINT(0, stdout, ">> case 3 passed!\n");

    /* case 4 test */
    caseFlag = TestConcatenate4();

    if (!caseFlag) {
        returnFlag = false;
        XPRINT(0, stdout, ">> case 4 failed!\n");
    }
    else
        XPRINT(0, stdout, ">> case 4 passed!\n");

    /* other cases test */
    /*
    TODO!!
    */

    if (returnFlag) {
        XPRINT(0, stdout, ">> All Passed!\n");
    }
    else
        XPRINT(0, stdout, ">> Failed!\n");

    XPRINT(0, stdout, "\n");

    return returnFlag;
}

} // namespace nts(NiuTrans.Tensor)