Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
aidge_backend_cpu_ll
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Lucas Lopez
aidge_backend_cpu_ll
Commits
dd72b454
Commit
dd72b454
authored
4 months ago
by
Lucas Lopez
Browse files
Options
Downloads
Plain Diff
merge
parents
ab8dd8d8
30d2af82
No related branches found
No related tags found
No related merge requests found
Pipeline
#66070
canceled
4 months ago
Stage: static_analysis
Stage: build
Stage: test
Stage: coverage
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
unit_tests/operator/Test_MulImpl.cpp
+689
-0
689 additions, 0 deletions
unit_tests/operator/Test_MulImpl.cpp
with
689 additions
and
0 deletions
unit_tests/operator/Test_MulImpl.cpp
+
689
−
0
View file @
dd72b454
...
...
@@ -9,6 +9,7 @@
*
********************************************************************************/
<<<<<<<
HEAD
#include
<chrono>
#include
<cstddef>
// std::size_t
#include
<cstdint>
// std::uint16_t
...
...
@@ -22,6 +23,36 @@
#include
"aidge/backend/cpu/data/TensorImpl.hpp"
#include
"aidge/backend/cpu/operator/MulImpl.hpp"
#include
"aidge/data/DataType.hpp"
=======
<<<<<<<
HEAD
#include
<chrono>
// std::micro, std::chrono::time_point,
// std::chrono::system_clock,
#include
<cstddef>
// std::size_t
#include
<cstdint>
// std::uint16_t
#include
<functional>
// std::multiplies
#include
<memory>
#include
<numeric>
// std::accumulate
#include
<random>
// std::random_device, std::mt19937
// std::uniform_int_distribution, std::uniform_real_distribution
#include
<vector>
#include
<catch2/catch_test_macros.hpp>
#include
<fmt/core.h>
=======
#include
<catch2/catch_test_macros.hpp>
#include
<chrono>
#include
<cstddef>
// std::size_t
#include
<cstdint>
// std::uint16_t
#include
<iostream>
#include
<memory>
#include
<numeric>
// std::accumulate
#include
<random>
// std::random_device, std::mt19937, std::uniform_real_distribution
>>>>>>>
9
d427c111c3c37ad141cd12a30c851f7fdf6a8fe
#include
"aidge/backend/cpu/data/TensorImpl.hpp"
#include
"aidge/backend/cpu/operator/MulImpl.hpp"
#include
"aidge/data/Data.hpp"
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
#include
"aidge/data/Tensor.hpp"
#include
"aidge/operator/Mul.hpp"
#include
"aidge/utils/ArrayHelpers.hpp"
...
...
@@ -30,11 +61,19 @@
namespace
Aidge
{
<<<<<<<
HEAD
TEST_CASE
(
"[CPU/Operator] Mul(Backward)"
,
"[Mul][CPU][Backward]"
)
{
=======
<<<<<<<
HEAD
TEST_CASE
(
"[CPU/Operator] Mul Backward"
,
"[Mul][CPU][Backward]"
)
{
using
aif32
=
cpptype_t
<
DataType
::
Float32
>
;
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
std
::
shared_ptr
<
Mul_Op
>
op
=
std
::
make_shared
<
Mul_Op
>
();
op
->
setDataType
(
DataType
::
Float32
);
op
->
setBackend
(
"cpu"
);
<<<<<<<
HEAD
// NOTE: The first four tests use fixed values, the last one uses random values but static dimensions.
SECTION
(
"Case 1: 1D and 2D Tensors"
)
{
...
...
@@ -120,6 +159,88 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
{
70.0
,
74.0
,
78.0
},
{
82.0
,
86.0
,
90.0
}}});
=======
SECTION
(
"Case 1: 2D and 1D tensors"
)
{
const
auto
T0
=
std
::
make_shared
<
Tensor
>
(
Array2D
<
aif32
,
2
,
3
>
(
{
{
{
1
,
2
,
3
},{
4
,
5
,
6
}
}
}
));
const
auto
T1
=
std
::
make_shared
<
Tensor
>
(
Array1D
<
aif32
,
3
>
(
{
0.1
,
0.2
,
0.3
}
));
op
->
getOutput
(
0
)
->
setGrad
(
std
::
make_shared
<
Tensor
>
(
Array2D
<
aif32
,
2
,
3
>
({{{
1.0
,
1.0
,
1.0
},{
1.0
,
1.0
,
1.0
}}})));
op
->
associateInput
(
0
,
T0
);
op
->
associateInput
(
1
,
T1
);
op
->
forwardDims
();
op
->
forward
();
op
->
backward
();
const
Tensor
T0Grad
=
Array2D
<
aif32
,
2
,
3
>
({{{
0.1
,
0.2
,
0.3
},{
0.1
,
0.2
,
0.3
}}});
const
Tensor
T1Grad
=
Array1D
<
aif32
,
3
>
({
5
,
7
,
9
});
REQUIRE
(
approxEq
<
aif32
>
(
*
(
op
->
getInput
(
0
)
->
grad
()),
T0Grad
));
REQUIRE
(
approxEq
<
aif32
>
(
*
(
op
->
getInput
(
1
)
->
grad
()),
T1Grad
));
}
SECTION
(
"Case 2: 3D and 1D tensors"
)
{
const
auto
T0
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
aif32
,
2
,
2
,
3
>
(
{
{
{
{
1.0
,
2.0
,
3.0
},
{
4.0
,
5.0
,
6.0
}
},
{
{
7.0
,
8.0
,
9.0
},
{
10.0
,
11.0
,
12.0
}
}
}
}
));
const
auto
T1
=
std
::
make_shared
<
Tensor
>
(
Array1D
<
aif32
,
3
>
({
0.3
,
0.2
,
0.1
}));
const
auto
newGrad
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
aif32
,
2
,
2
,
3
>
(
{
{
{
{
1
,
1
,
1
},
{
1
,
1
,
1
}
},
{
{
1
,
1
,
1
},
{
1
,
1
,
1
}
}
}
}
));
const
Tensor
expectedGrad0
=
Array3D
<
aif32
,
2
,
2
,
3
>
(
{
{
{
{
0.3
,
0.2
,
0.1
},
{
0.3
,
0.2
,
0.1
}
},
{
{
0.3
,
0.2
,
0.1
},
{
0.3
,
0.2
,
0.1
}
}
}
}
);
const
Tensor
expectedGrad1
=
Array1D
<
aif32
,
3
>
(
{
22.0
,
26.0
,
30.0
}
);
op
->
associateInput
(
0
,
T0
);
op
->
associateInput
(
1
,
T1
);
op
->
getOutput
(
0
)
->
setGrad
(
newGrad
);
...
...
@@ -127,6 +248,133 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
op
->
backward
();
REQUIRE
(
approxEq
<
aif32
>
(
*
(
op
->
getInput
(
0
)
->
grad
()),
expectedGrad0
));
REQUIRE
(
approxEq
<
aif32
>
(
*
(
op
->
getInput
(
1
)
->
grad
()),
expectedGrad1
));
}
SECTION
(
"Case 3: 4D and 2D tensors"
)
{
const
auto
T0
=
std
::
make_shared
<
Tensor
>
(
Array4D
<
aif32
,
2
,
2
,
3
,
3
>
(
{
{
{
{
{
1.0
,
2.0
,
3.0
},
{
4.0
,
5.0
,
6.0
},
{
7.0
,
8.0
,
9.0
}
},
{
{
10.0
,
11.0
,
12.0
},
{
13.0
,
14.0
,
15.0
},
{
16.0
,
17.0
,
18.0
}
}
},
{
{
{
19.0
,
20.0
,
21.0
},
{
22.0
,
23.0
,
24.0
},
{
25.0
,
26.0
,
27.0
}
},
{
{
28.0
,
29.0
,
30.0
},
{
31.0
,
32.0
,
33.0
},
{
34.0
,
35.0
,
36.0
}
}
}
}
}
));
const
auto
T1
=
std
::
make_shared
<
Tensor
>
(
Array2D
<
aif32
,
3
,
3
>
(
{
{
{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}
}
}
));
const
auto
newGrad
=
std
::
make_shared
<
Tensor
>
(
Array4D
<
aif32
,
2
,
2
,
3
,
3
>
(
{
{
{
{
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
}
},
{
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
}
}
},
{
{
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
}
},
{
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
}
}
}
}
}
));
const
Tensor
expectedGrad0
=
Array4D
<
aif32
,
2
,
2
,
3
,
3
>
(
{
{
{
{
{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}
},
{
{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}
}
},
{
{
{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}
},
{
{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}
}
}
}
}
);
const
Tensor
expectedGrad1
=
Array2D
<
aif32
,
3
,
3
>
(
{
{
{
58.0
,
62.0
,
66.0
},
{
70.0
,
74.0
,
78.0
},
{
82.0
,
86.0
,
90.0
}
}
}
);
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
op
->
associateInput
(
0
,
T0
);
op
->
associateInput
(
1
,
T1
);
op
->
getOutput
(
0
)
->
setGrad
(
newGrad
);
op
->
forwardDims
();
<<<<<<<
HEAD
op
->
backward
();
REQUIRE
(
approxEq
<
cpptype_t
<
DataType
::
Float32
>>
(
*
(
op
->
getInput
(
0
)
->
grad
()),
expectedGrad0
));
REQUIRE
(
approxEq
<
cpptype_t
<
DataType
::
Float32
>>
(
*
(
op
->
getInput
(
1
)
->
grad
()),
expectedGrad1
));
}
...
...
@@ -281,6 +529,392 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
// Perform backward pass
op
->
backward
();
=======
op
->
backward
();
REQUIRE
(
approxEq
<
aif32
>
(
*
(
op
->
getInput
(
0
)
->
grad
()),
expectedGrad0
));
REQUIRE
(
approxEq
<
aif32
>
(
*
(
op
->
getInput
(
1
)
->
grad
()),
expectedGrad1
));
}
SECTION
(
"Case 4: 3D and 2D tensors"
)
{
const
auto
T0
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
aif32
,
2
,
3
,
4
>
(
{
{
{
{
1.0
,
2.0
,
3.0
,
4.0
},
{
5.0
,
6.0
,
7.0
,
8.0
},
{
9.0
,
10.0
,
11.0
,
12.0
},
},
{
{
13.0
,
14.0
,
15.0
,
16.0
},
{
17.0
,
18.0
,
19.0
,
20.0
},
{
21.0
,
22.0
,
23.0
,
24.0
},
}
}
}
));
const
auto
T1
=
std
::
make_shared
<
Tensor
>
(
Array2D
<
aif32
,
3
,
4
>
(
{
{
{
0.1
,
0.2
,
0.3
,
0.4
},
{
0.5
,
0.6
,
0.7
,
0.8
},
{
0.9
,
1.0
,
1.1
,
1.2
}
}
}
));
const
auto
newGrad
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
aif32
,
2
,
3
,
4
>
(
{
{
{
{
1.0
,
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
,
1.0
},
},
{
{
1.0
,
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
,
1.0
},
}
}
}
));
const
Tensor
expectedGrad0
=
Array3D
<
aif32
,
2
,
3
,
4
>
(
{
{
{
{
0.1
,
0.2
,
0.3
,
0.4
},
{
0.5
,
0.6
,
0.7
,
0.8
},
{
0.9
,
1.0
,
1.1
,
1.2
}
},
{
{
0.1
,
0.2
,
0.3
,
0.4
},
{
0.5
,
0.6
,
0.7
,
0.8
},
{
0.9
,
1.0
,
1.1
,
1.2
}
}
}
}
);
const
Tensor
expectedGrad1
=
Array2D
<
aif32
,
3
,
4
>
(
{
{
{
14.0
,
16.0
,
18.0
,
20.0
},
{
22.0
,
24.0
,
26.0
,
28.0
},
{
30.0
,
32.0
,
34.0
,
36.0
}
}
}
);
op
->
associateInput
(
0
,
T0
);
op
->
associateInput
(
1
,
T1
);
op
->
getOutput
(
0
)
->
setGrad
(
newGrad
);
op
->
forwardDims
();
op
->
backward
();
REQUIRE
(
approxEq
<
aif32
>
(
*
(
op
->
getInput
(
0
)
->
grad
()),
expectedGrad0
));
REQUIRE
(
approxEq
<
aif32
>
(
*
(
op
->
getInput
(
1
)
->
grad
()),
expectedGrad1
));
=======
TEST_CASE
(
"[CPU/Operator] Mul(Backward)"
,
"[Mul][CPU][Backward]"
)
{
std
::
shared_ptr
<
Node
>
myMul
=
Mul
();
auto
op
=
std
::
static_pointer_cast
<
OperatorTensor
>
(
myMul
->
getOperator
());
op
->
setDataType
(
DataType
::
Float32
);
op
->
setBackend
(
"cpu"
);
// NOTE: The first four tests use fixed values, the last one uses random values but static dimensions.
SECTION
(
"Case 1: 1D and 2D Tensors"
)
{
const
auto
T0
=
std
::
make_shared
<
Tensor
>
(
Array2D
<
float
,
2
,
3
>
({{{
1
,
2
,
3
},
{
4
,
5
,
6
}}}));
const
auto
T1
=
std
::
make_shared
<
Tensor
>
(
Array1D
<
float
,
3
>
({
0.1
,
0.2
,
0.3
}));
float
*
input0
=
static_cast
<
float
*>
(
T0
->
getImpl
()
->
rawPtr
());
float
*
input1
=
static_cast
<
float
*>
(
T1
->
getImpl
()
->
rawPtr
());
// TODO Use
T0
->
setDataType
(
DataType
::
Float32
);
T0
->
setBackend
(
"cpu"
);
T1
->
setDataType
(
DataType
::
Float32
);
T1
->
setBackend
(
"cpu"
);
op
->
associateInput
(
0
,
T0
);
op
->
associateInput
(
1
,
T1
);
op
->
getOutput
(
0
)
->
setGrad
(
std
::
make_shared
<
Tensor
>
(
Array2D
<
float
,
2
,
3
>
({{{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
}}})));
op
->
forwardDims
();
myMul
->
backward
();
const
auto
expectedGrad0
=
std
::
make_shared
<
Tensor
>
(
Array2D
<
float
,
2
,
3
>
({{{
0.1
,
0.2
,
0.3
},
{
0.1
,
0.2
,
0.3
}}}));
const
auto
expectedGrad1
=
std
::
make_shared
<
Tensor
>
(
Array1D
<
float
,
3
>
({
5
,
7
,
9
}));
REQUIRE
(
approxEq
<
float
>
(
*
(
op
->
getInput
(
0
)
->
grad
()),
*
expectedGrad0
));
REQUIRE
(
approxEq
<
float
>
(
*
(
op
->
getInput
(
1
)
->
grad
()),
*
expectedGrad1
));
}
SECTION
(
"Case 2: 3D and 1D tensors"
)
{
const
auto
T0
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
float
,
2
,
2
,
3
>
(
{{{{
1.0
,
2.0
,
3.0
},
{
4.0
,
5.0
,
6.0
}},
{{
7.0
,
8.0
,
9.0
},
{
10.0
,
11.0
,
12.0
}}}}));
const
auto
T1
=
std
::
make_shared
<
Tensor
>
(
Array1D
<
float
,
3
>
({
0.3
,
0.2
,
0.1
}));
const
auto
newGrad
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
float
,
2
,
2
,
3
>
(
{{{{
1
,
1
,
1
},
{
1
,
1
,
1
}},
{{
1
,
1
,
1
},
{
1
,
1
,
1
}}}}));
const
auto
expectedGrad0
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
float
,
2
,
2
,
3
>
({{{{
0.3
,
0.2
,
0.1
},
{
0.3
,
0.2
,
0.1
}},
{{
0.3
,
0.2
,
0.1
},
{
0.3
,
0.2
,
0.1
}}}}));
const
auto
expectedGrad1
=
std
::
make_shared
<
Tensor
>
(
Array1D
<
float
,
3
>
({
22.0
,
26.0
,
30.0
}));
for
(
auto
T
:
{
T0
,
T1
,
newGrad
,
expectedGrad0
,
expectedGrad1
})
{
T
->
setBackend
(
"cpu"
);
T
->
setDataType
(
DataType
::
Float32
);
}
op
->
associateInput
(
0
,
T0
);
op
->
associateInput
(
1
,
T1
);
op
->
getOutput
(
0
)
->
setGrad
(
newGrad
);
op
->
forwardDims
();
myMul
->
backward
();
REQUIRE
(
approxEq
<
float
>
(
*
(
op
->
getInput
(
0
)
->
grad
()),
*
expectedGrad0
));
REQUIRE
(
approxEq
<
float
>
(
*
(
op
->
getInput
(
1
)
->
grad
()),
*
expectedGrad1
));
}
SECTION
(
"Case 3: 4D and 2D tensors"
)
{
const
auto
T0
=
std
::
make_shared
<
Tensor
>
(
Array4D
<
float
,
2
,
2
,
3
,
3
>
(
{{{{{
1.0
,
2.0
,
3.0
},
{
4.0
,
5.0
,
6.0
},
{
7.0
,
8.0
,
9.0
}},
{{
10.0
,
11.0
,
12.0
},
{
13.0
,
14.0
,
15.0
},
{
16.0
,
17.0
,
18.0
}}},
{{{
19.0
,
20.0
,
21.0
},
{
22.0
,
23.0
,
24.0
},
{
25.0
,
26.0
,
27.0
}},
{{
28.0
,
29.0
,
30.0
},
{
31.0
,
32.0
,
33.0
},
{
34.0
,
35.0
,
36.0
}}}}}));
const
auto
T1
=
std
::
make_shared
<
Tensor
>
(
Array2D
<
float
,
3
,
3
>
(
{{{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}}}));
const
auto
newGrad
=
std
::
make_shared
<
Tensor
>
(
Array4D
<
float
,
2
,
2
,
3
,
3
>
(
{{{{{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
}},
{{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
}}},
{{{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
}},
{{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
}}}}}));
const
auto
expectedGrad0
=
std
::
make_shared
<
Tensor
>
(
Array4D
<
float
,
2
,
2
,
3
,
3
>
(
{{{{{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}},
{{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}}},
{{{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}},
{{
0.5
,
0.3
,
0.1
},
{
0.4
,
0.2
,
0.6
},
{
0.7
,
0.8
,
0.9
}}}}}));
const
auto
expectedGrad1
=
std
::
make_shared
<
Tensor
>
(
Array2D
<
float
,
3
,
3
>
({{{
58.0
,
62.0
,
66.0
},
{
70.0
,
74.0
,
78.0
},
{
82.0
,
86.0
,
90.0
}}}));
for
(
const
auto
T
:
{
T0
,
T1
,
newGrad
,
expectedGrad0
,
expectedGrad1
})
{
T
->
setBackend
(
"cpu"
);
T
->
setDataType
(
DataType
::
Float32
);
}
op
->
associateInput
(
0
,
T0
);
op
->
associateInput
(
1
,
T1
);
op
->
getOutput
(
0
)
->
setGrad
(
newGrad
);
op
->
forwardDims
();
myMul
->
backward
();
REQUIRE
(
approxEq
<
float
>
(
*
(
op
->
getInput
(
0
)
->
grad
()),
*
expectedGrad0
));
REQUIRE
(
approxEq
<
float
>
(
*
(
op
->
getInput
(
1
)
->
grad
()),
*
expectedGrad1
));
}
SECTION
(
"Case 4: 3D and 2D tensors"
)
{
const
auto
T0
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
float
,
2
,
3
,
4
>
({{{
{
1.0
,
2.0
,
3.0
,
4.0
},
{
5.0
,
6.0
,
7.0
,
8.0
},
{
9.0
,
10.0
,
11.0
,
12.0
},
},
{
{
13.0
,
14.0
,
15.0
,
16.0
},
{
17.0
,
18.0
,
19.0
,
20.0
},
{
21.0
,
22.0
,
23.0
,
24.0
},
}}}));
const
auto
T1
=
std
::
make_shared
<
Tensor
>
(
Array2D
<
float
,
3
,
4
>
({{{
0.1
,
0.2
,
0.3
,
0.4
},
{
0.5
,
0.6
,
0.7
,
0.8
},
{
0.9
,
1.0
,
1.1
,
1.2
}}}));
const
auto
newGrad
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
float
,
2
,
3
,
4
>
({{{
{
1.0
,
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
,
1.0
},
},
{
{
1.0
,
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
,
1.0
},
{
1.0
,
1.0
,
1.0
,
1.0
},
}}}));
const
auto
expectedGrad0
=
std
::
make_shared
<
Tensor
>
(
Array3D
<
float
,
2
,
3
,
4
>
({{{{
0.1
,
0.2
,
0.3
,
0.4
},
{
0.5
,
0.6
,
0.7
,
0.8
},
{
0.9
,
1.0
,
1.1
,
1.2
}},
{{
0.1
,
0.2
,
0.3
,
0.4
},
{
0.5
,
0.6
,
0.7
,
0.8
},
{
0.9
,
1.0
,
1.1
,
1.2
}}}}));
const
auto
expectedGrad1
=
std
::
make_shared
<
Tensor
>
(
Array2D
<
float
,
3
,
4
>
({{{
14.0
,
16.0
,
18.0
,
20.0
},
{
22.0
,
24.0
,
26.0
,
28.0
},
{
30.0
,
32.0
,
34.0
,
36.0
}}}));
for
(
const
auto
T
:
{
T0
,
T1
,
newGrad
,
expectedGrad0
,
expectedGrad1
})
{
T
->
setBackend
(
"cpu"
);
T
->
setDataType
(
DataType
::
Float32
);
}
op
->
associateInput
(
0
,
T0
);
op
->
associateInput
(
1
,
T1
);
op
->
getOutput
(
0
)
->
setGrad
(
newGrad
);
op
->
forwardDims
();
myMul
->
backward
();
REQUIRE
(
approxEq
<
float
>
(
*
(
op
->
getInput
(
0
)
->
grad
()),
*
expectedGrad0
));
REQUIRE
(
approxEq
<
float
>
(
*
(
op
->
getInput
(
1
)
->
grad
()),
*
expectedGrad1
));
}
SECTION
(
"Case 5: Tensors with random values"
)
{
// Use random values
std
::
vector
<
std
::
size_t
>
dims0
=
{
5
,
2
,
1
,
7
};
// First tensor
std
::
vector
<
std
::
size_t
>
dims1
=
{
2
,
6
,
7
};
// Second tensor
std
::
vector
<
std
::
size_t
>
outputDims
=
{
5
,
2
,
6
,
7
};
const
auto
input0Size
=
5
*
2
*
1
*
7
;
const
auto
input1Size
=
2
*
6
*
7
;
const
auto
outputSize
=
5
*
2
*
6
*
7
;
std
::
random_device
rd
;
std
::
mt19937
gen
(
rd
());
std
::
uniform_real_distribution
<
float
>
dist
(
0.1
f
,
1.0
f
);
std
::
vector
<
float
>
input0Data
(
input0Size
);
std
::
vector
<
float
>
input1Data
(
input1Size
);
// Fill with random values
for
(
auto
&
val
:
input0Data
)
{
val
=
dist
(
gen
);
}
for
(
auto
&
val
:
input1Data
)
{
val
=
dist
(
gen
);
}
auto
T0
=
std
::
make_shared
<
Tensor
>
();
auto
T1
=
std
::
make_shared
<
Tensor
>
();
T0
->
setDataType
(
DataType
::
Float32
);
T0
->
setBackend
(
"cpu"
);
T0
->
resize
(
dims0
);
T0
->
getImpl
()
->
setRawPtr
(
input0Data
.
data
(),
input0Size
);
T1
->
setDataType
(
DataType
::
Float32
);
T1
->
setBackend
(
"cpu"
);
T1
->
resize
(
dims1
);
T1
->
getImpl
()
->
setRawPtr
(
input1Data
.
data
(),
input1Size
);
op
->
associateInput
(
0
,
T0
);
op
->
associateInput
(
1
,
T1
);
op
->
forwardDims
();
myMul
->
forward
();
std
::
vector
<
float
>
expectedOutput
(
outputSize
);
for
(
std
::
size_t
n
=
0
;
n
<
5
;
++
n
)
{
for
(
std
::
size_t
c
=
0
;
c
<
2
;
++
c
)
{
for
(
std
::
size_t
h
=
0
;
h
<
6
;
++
h
)
{
for
(
std
::
size_t
w
=
0
;
w
<
7
;
++
w
)
{
std
::
size_t
outIdx
=
w
+
7
*
(
h
+
6
*
(
c
+
2
*
n
));
std
::
size_t
in0Idx
=
w
+
7
*
(
0
+
1
*
(
c
+
2
*
n
));
// middle dim is 1
std
::
size_t
in1Idx
=
w
+
7
*
(
h
+
6
*
c
);
// no n dimension
expectedOutput
[
outIdx
]
=
input0Data
[
in0Idx
]
*
input1Data
[
in1Idx
];
}
}
}
}
auto
outputTensor
=
op
->
getOutput
(
0
);
// Verify forward pass
auto
expectedOutputTensor
=
std
::
make_shared
<
Tensor
>
();
expectedOutputTensor
->
resize
(
outputDims
);
expectedOutputTensor
->
setBackend
(
"cpu"
);
expectedOutputTensor
->
setDataType
(
DataType
::
Float32
);
expectedOutputTensor
->
getImpl
()
->
setRawPtr
(
expectedOutput
.
data
(),
expectedOutput
.
size
());
REQUIRE
(
approxEq
<
float
>
(
*
outputTensor
,
*
expectedOutputTensor
));
// Backward pass
std
::
vector
<
float
>
gradOutputData
(
outputSize
);
for
(
auto
&
val
:
gradOutputData
)
{
val
=
dist
(
gen
);
}
op
->
getOutput
(
0
)
->
setGrad
(
std
::
make_shared
<
Tensor
>
());
op
->
getOutput
(
0
)
->
grad
()
->
resize
(
outputDims
);
op
->
getOutput
(
0
)
->
grad
()
->
getImpl
()
->
setRawPtr
(
gradOutputData
.
data
(),
outputSize
);
// Compute reference gradients
std
::
vector
<
float
>
expectedGrad0
(
input0Size
,
0.0
f
);
std
::
vector
<
float
>
expectedGrad1
(
input1Size
,
0.0
f
);
for
(
std
::
size_t
n
=
0
;
n
<
5
;
++
n
)
{
for
(
std
::
size_t
c
=
0
;
c
<
2
;
++
c
)
{
for
(
std
::
size_t
h
=
0
;
h
<
6
;
++
h
)
{
for
(
std
::
size_t
w
=
0
;
w
<
7
;
++
w
)
{
std
::
size_t
outIdx
=
w
+
7
*
(
h
+
6
*
(
c
+
2
*
n
));
std
::
size_t
in0Idx
=
w
+
7
*
(
0
+
1
*
(
c
+
2
*
n
));
std
::
size_t
in1Idx
=
w
+
7
*
(
h
+
6
*
c
);
// Gradient for input0: grad_output * input1
expectedGrad0
[
in0Idx
]
+=
gradOutputData
[
outIdx
]
*
input1Data
[
in1Idx
];
// Gradient for input1: grad_output * input0
expectedGrad1
[
in1Idx
]
+=
gradOutputData
[
outIdx
]
*
input0Data
[
in0Idx
];
}
}
}
}
// Perform backward pass
myMul
->
backward
();
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
auto
expectedGrad0Tensor
=
std
::
make_shared
<
Tensor
>
();
expectedGrad0Tensor
->
resize
(
T0
->
dims
());
...
...
@@ -289,7 +923,12 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
expectedGrad0Tensor
->
getImpl
()
->
setRawPtr
(
expectedGrad0
.
data
(),
expectedGrad0
.
size
());
<<<<<<<
HEAD
auto
expectedGrad1Tensor
=
std
::
make_shared
<
Tensor
>
(
T1
->
dims
());
=======
auto
expectedGrad1Tensor
=
std
::
make_shared
<
Tensor
>
();
expectedGrad1Tensor
->
resize
(
T1
->
dims
());
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
expectedGrad1Tensor
->
setBackend
(
"cpu"
);
expectedGrad1Tensor
->
setDataType
(
DataType
::
Float32
);
expectedGrad1Tensor
->
getImpl
()
->
setRawPtr
(
expectedGrad1
.
data
(),
...
...
@@ -309,6 +948,10 @@ TEST_CASE("[CPU/Operator] Mul(Backward)", "[Mul][CPU][Backward]") {
// ")\n";
// std::cout << "Input sizes: " << input0_size << " * " <<
// input1_size << " -> " << output_size << "\n";
<<<<<<<
HEAD
=======
>>>>>>>
9
d427c111c3c37ad141cd12a30c851f7fdf6a8fe
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
}
}
...
...
@@ -326,7 +969,17 @@ TEST_CASE("[cpu/operator] Mul(forward)", "[Mul][CPU]") {
std
::
size_t
(
3
));
std
::
uniform_int_distribution
<
int
>
boolDist
(
0
,
1
);
<<<<<<<
HEAD
std
::
shared_ptr
<
Mul_Op
>
op
=
std
::
make_shared
<
Mul_Op
>
();
=======
<<<<<<<
HEAD
// Create MatMul Operator
std
::
shared_ptr
<
Mul_Op
>
op
=
std
::
make_shared
<
Mul_Op
>
();
=======
std
::
shared_ptr
<
Node
>
myMul
=
Mul
();
auto
op
=
std
::
static_pointer_cast
<
OperatorTensor
>
(
myMul
->
getOperator
());
>>>>>>>
9
d427c111c3c37ad141cd12a30c851f7fdf6a8fe
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
op
->
setDataType
(
DataType
::
Float32
);
op
->
setBackend
(
"cpu"
);
...
...
@@ -409,8 +1062,20 @@ TEST_CASE("[cpu/operator] Mul(forward)", "[Mul][CPU]") {
delete
[]
array1
;
delete
[]
result
;
}
<<<<<<<
HEAD
Log
::
info
(
"number of elements over time spent: {}
\n
"
,
(
number_of_operation
/
duration
.
count
()));
Log
::
info
(
"total time: {}μs
\n
"
,
duration
.
count
());
=======
<<<<<<<
HEAD
Log
::
info
(
"number of elements over time spent: {}
\n
"
,
(
number_of_operation
/
duration
.
count
()));
Log
::
info
(
"total time: {} μs
\n
"
,
duration
.
count
());
=======
std
::
cout
<<
"number of elements over time spent: "
<<
(
number_of_operation
/
duration
.
count
())
<<
std
::
endl
;
std
::
cout
<<
"total time: "
<<
duration
.
count
()
<<
"μs"
<<
std
::
endl
;
>>>>>>>
9
d427c111c3c37ad141cd12a30c851f7fdf6a8fe
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
}
SECTION
(
"+1-D Tensor / +1-D Tensor - broadcasting"
)
{
...
...
@@ -564,8 +1229,20 @@ TEST_CASE("[cpu/operator] Mul(forward)", "[Mul][CPU]") {
std
::
multiplies
<
std
::
size_t
>
());
number_of_operation
+=
nb_elements
;
}
<<<<<<<
HEAD
Log
::
info
(
"number of elements over time spent: {}
\n
"
,
(
number_of_operation
/
duration
.
count
()));
Log
::
info
(
"total time: {}μs
\n
"
,
duration
.
count
());
=======
<<<<<<<
HEAD
Log
::
info
(
"number of elements over time spent: {}
\n
"
,
(
number_of_operation
/
duration
.
count
()));
Log
::
info
(
"total time: {} μs
\n
"
,
duration
.
count
());
=======
std
::
cout
<<
"number of elements over time spent: "
<<
(
number_of_operation
/
duration
.
count
())
<<
std
::
endl
;
std
::
cout
<<
"total time: "
<<
duration
.
count
()
<<
"μs"
<<
std
::
endl
;
>>>>>>>
9
d427c111c3c37ad141cd12a30c851f7fdf6a8fe
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
}
SECTION
(
"+1-D Tensor / 1-D Tensor"
)
{
std
::
size_t
number_of_operation
=
0
;
...
...
@@ -702,8 +1379,20 @@ TEST_CASE("[cpu/operator] Mul(forward)", "[Mul][CPU]") {
number_of_operation
+=
nb_elements
;
}
<<<<<<<
HEAD
Log
::
info
(
"number of elements over time spent: {}
\n
"
,
(
number_of_operation
/
duration
.
count
()));
Log
::
info
(
"total time: {}μs
\n
"
,
duration
.
count
());
=======
<<<<<<<
HEAD
Log
::
info
(
"number of elements over time spent: {}
\n
"
,
(
number_of_operation
/
duration
.
count
()));
Log
::
info
(
"total time: {} μs
\n
"
,
duration
.
count
());
=======
std
::
cout
<<
"number of elements over time spent: "
<<
(
number_of_operation
/
duration
.
count
())
<<
std
::
endl
;
std
::
cout
<<
"total time: "
<<
duration
.
count
()
<<
"μs"
<<
std
::
endl
;
>>>>>>>
9
d427c111c3c37ad141cd12a30c851f7fdf6a8fe
>>>>>>>
30
d2af827763a1f1b36c3fe7b152cd4566b3540c
}
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment