Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
7829bdbd
P
Paddle
项目概览
PaddlePaddle
/
Paddle
1 年多 前同步成功
通知
2302
Star
20931
Fork
5422
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
7829bdbd
编写于
7月 27, 2017
作者:
L
liaogang
浏览文件
操作
浏览文件
下载
差异文件
Fix conflicts
上级
d951e9c7
2200ff5e
变更
51
隐藏空白更改
内联
并排
Showing
51 changed file
with
863 addition
and
675 deletion
+863
-675
.pre-commit-config.yaml
.pre-commit-config.yaml
+7
-5
go/master/c/client.go
go/master/c/client.go
+13
-4
go/master/client.go
go/master/client.go
+39
-31
go/master/client_internal_test.go
go/master/client_internal_test.go
+32
-28
go/master/client_test.go
go/master/client_test.go
+57
-26
go/master/service.go
go/master/service.go
+60
-38
go/master/service_internal_test.go
go/master/service_internal_test.go
+2
-1
go/pserver/client/c/test/test_train.py
go/pserver/client/c/test/test_train.py
+12
-6
paddle/framework/CMakeLists.txt
paddle/framework/CMakeLists.txt
+2
-4
paddle/framework/detail/tensor-inl.h
paddle/framework/detail/tensor-inl.h
+160
-0
paddle/framework/net.cc
paddle/framework/net.cc
+4
-12
paddle/framework/net.h
paddle/framework/net.h
+5
-19
paddle/framework/net_op_test.cc
paddle/framework/net_op_test.cc
+15
-22
paddle/framework/net_proto.proto
paddle/framework/net_proto.proto
+0
-15
paddle/framework/op_registry.h
paddle/framework/op_registry.h
+4
-3
paddle/framework/operator.h
paddle/framework/operator.h
+11
-7
paddle/framework/tensor.cc
paddle/framework/tensor.cc
+1
-1
paddle/framework/tensor.h
paddle/framework/tensor.h
+88
-102
paddle/framework/tensor_test.cc
paddle/framework/tensor_test.cc
+70
-20
paddle/memory/detail/buddy_allocator.cc
paddle/memory/detail/buddy_allocator.cc
+27
-29
paddle/memory/memory.h
paddle/memory/memory.h
+3
-3
paddle/operators/add_op.cc
paddle/operators/add_op.cc
+12
-17
paddle/operators/add_op.cu
paddle/operators/add_op.cu
+2
-3
paddle/operators/add_op.h
paddle/operators/add_op.h
+8
-11
paddle/operators/cross_entropy_op.cc
paddle/operators/cross_entropy_op.cc
+11
-17
paddle/operators/cross_entropy_op.cu
paddle/operators/cross_entropy_op.cu
+1
-3
paddle/operators/cross_entropy_op.h
paddle/operators/cross_entropy_op.h
+6
-8
paddle/operators/fc_op.cc
paddle/operators/fc_op.cc
+17
-22
paddle/operators/mul_op.cc
paddle/operators/mul_op.cc
+12
-17
paddle/operators/mul_op.cu
paddle/operators/mul_op.cu
+1
-4
paddle/operators/mul_op.h
paddle/operators/mul_op.h
+9
-12
paddle/operators/rowwise_add_op.cc
paddle/operators/rowwise_add_op.cc
+9
-15
paddle/operators/rowwise_add_op.cu
paddle/operators/rowwise_add_op.cu
+2
-4
paddle/operators/rowwise_add_op.h
paddle/operators/rowwise_add_op.h
+9
-11
paddle/operators/sgd_op.cc
paddle/operators/sgd_op.cc
+8
-13
paddle/operators/sgd_op.cu
paddle/operators/sgd_op.cu
+1
-3
paddle/operators/sgd_op.h
paddle/operators/sgd_op.h
+8
-12
paddle/operators/sigmoid_op.cc
paddle/operators/sigmoid_op.cc
+12
-20
paddle/operators/sigmoid_op.cu
paddle/operators/sigmoid_op.cu
+1
-3
paddle/operators/sigmoid_op.h
paddle/operators/sigmoid_op.h
+7
-9
paddle/operators/softmax_op.cc
paddle/operators/softmax_op.cc
+10
-17
paddle/operators/softmax_op.cu
paddle/operators/softmax_op.cu
+1
-2
paddle/operators/softmax_op.h
paddle/operators/softmax_op.h
+7
-9
paddle/operators/type_alias.h
paddle/operators/type_alias.h
+51
-0
paddle/platform/enforce.h
paddle/platform/enforce.h
+5
-5
paddle/pybind/pybind.cc
paddle/pybind/pybind.cc
+9
-9
python/paddle/trainer_config_helpers/attrs.py
python/paddle/trainer_config_helpers/attrs.py
+1
-1
python/paddle/trainer_config_helpers/layers.py
python/paddle/trainer_config_helpers/layers.py
+11
-20
python/paddle/v2/dataset/common.py
python/paddle/v2/dataset/common.py
+13
-31
python/paddle/v2/inference.py
python/paddle/v2/inference.py
+7
-0
python/paddle/v2/master/client.py
python/paddle/v2/master/client.py
+0
-1
未找到文件。
.pre-commit-config.yaml
浏览文件 @
7829bdbd
...
...
@@ -22,9 +22,11 @@
hooks
:
-
id
:
clang-formater
-
repo
:
https://github.com/PaddlePaddle/pre-commit-golang
sha
:
16398aeccf263adaf53b2495eed0406347d76281
sha
:
8337620115c25ff8333f1b1a493bd031049bd7c0
hooks
:
-
id
:
go-fmt
types
:
[
go
]
-
id
:
gometalinter
types
:
[
go
]
-
id
:
go-fmt
types
:
-
go
-
id
:
gometalinter
types
:
-
go
go/master/c/client.go
浏览文件 @
7829bdbd
...
...
@@ -18,7 +18,6 @@ package main
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define PADDLE_MASTER_OK 0
#define PADDLE_MASTER_ERROR -1
...
...
@@ -101,6 +100,12 @@ func paddle_release_master_client(client C.paddle_master_client) {
remove
(
client
)
}
//export paddle_start_get_records
func
paddle_start_get_records
(
client
C
.
paddle_master_client
,
pass
C
.
int
)
{
c
:=
get
(
client
)
c
.
StartGetRecords
(
int
(
pass
))
}
//export paddle_set_dataset
func
paddle_set_dataset
(
client
C
.
paddle_master_client
,
path
**
C
.
char
,
size
C
.
int
)
C
.
int
{
c
:=
get
(
client
)
...
...
@@ -121,15 +126,19 @@ func paddle_set_dataset(client C.paddle_master_client, path **C.char, size C.int
// paddle_next_record gets the nexts training record.
//
// returns number of bytes of the records if success, -1 if failed.
// returns number of bytes of the records if success, -1 if failed
, -2 if pass end
.
//
//export paddle_next_record
func
paddle_next_record
(
client
C
.
paddle_master_client
,
record
**
C
.
uchar
)
C
.
int
{
c
:=
get
(
client
)
r
,
err
:=
c
.
NextRecord
()
if
err
!=
nil
{
// Error
// TODO: return the type of error?
// NOTE: use errors to indicate pass ends
if
err
.
Error
()
==
master
.
ErrAllTaskFailed
.
Error
()
||
err
.
Error
()
==
master
.
ErrNoMoreAvailable
.
Error
()
||
err
.
Error
()
==
master
.
ErrPassBefore
.
Error
()
{
return
-
2
}
*
record
=
(
*
C
.
uchar
)(
nil
)
return
-
1
}
...
...
go/master/client.go
浏览文件 @
7829bdbd
...
...
@@ -16,7 +16,6 @@ package master
import
(
"os"
"sync"
"time"
"github.com/PaddlePaddle/Paddle/go/connection"
...
...
@@ -27,9 +26,9 @@ import (
// Client is the client of the master server.
type
Client
struct
{
conn
*
connection
.
Conn
ch
chan
record
initChOnce
sync
.
Once
conn
*
connection
.
Conn
ch
chan
record
bufSize
int
}
type
record
struct
{
...
...
@@ -46,11 +45,7 @@ func WithBuffer(bufSize int) func(*Client) error {
if
bufSize
<=
0
{
return
nil
}
c
.
initChOnce
.
Do
(
func
()
{
c
.
ch
=
make
(
chan
record
,
bufSize
)
go
c
.
getRecords
()
})
c
.
bufSize
=
bufSize
return
nil
}
}
...
...
@@ -104,25 +99,41 @@ func NewClient(opts ...func(*Client) error) (*Client, error) {
if
err
!=
nil
{
return
nil
,
err
}
}
c
.
ch
=
make
(
chan
record
,
c
.
bufSize
)
// FIXME: connection is created asyncrosly in monitorMaster go routine,
// ensure the connection is ready for use before calling c.addClient.
time
.
Sleep
(
time
.
Second
)
return
c
,
nil
}
func
(
c
*
Client
)
getRecords
()
{
// StartGetRecords must be called at beginning of each pass
func
(
c
*
Client
)
StartGetRecords
(
passID
int
)
{
go
c
.
getRecords
(
passID
)
}
func
(
c
*
Client
)
getRecords
(
passID
int
)
{
for
{
t
,
err
:=
c
.
getTask
()
t
,
err
:=
c
.
getTask
(
passID
)
if
err
!=
nil
{
log
.
Errorf
(
"Get task failed, sleep 3 seconds and continue, %s"
,
err
)
time
.
Sleep
(
3
*
time
.
Second
)
continue
if
err
.
Error
()
==
ErrPassBefore
.
Error
()
||
err
.
Error
()
==
ErrNoMoreAvailable
.
Error
()
||
err
.
Error
()
==
ErrAllTaskFailed
.
Error
()
{
c
.
ch
<-
record
{
nil
,
err
}
break
}
if
err
.
Error
()
==
ErrPassAfter
.
Error
()
{
// wait util last pass finishes
time
.
Sleep
(
time
.
Second
*
3
)
continue
}
log
.
Errorf
(
"getTask error: %s"
,
err
)
}
for
_
,
chunk
:=
range
t
.
Chunks
{
f
,
e
rr
:=
os
.
Open
(
chunk
.
Path
)
if
e
rr
!=
nil
{
log
.
Errorln
(
e
rr
)
f
,
e
:=
os
.
Open
(
chunk
.
Path
)
if
e
!=
nil
{
log
.
Errorln
(
e
)
continue
}
...
...
@@ -178,18 +189,21 @@ func (c *Client) monitorMaster(addrCh <-chan string) {
}
}
// SetDataset set dataset for the master server to dispatch.
// SetDataset sets dataset to dispatch for the master server.
//
// SetDataset can be call multiple times at one pass. But only the first call
// will be honored.
//
// SetDataset can be call multiple times from different nodes. But
// only the first call will be honored.
// After all tasks are done, another call of SetDataset will start another pass.
func
(
c
*
Client
)
SetDataset
(
globPaths
[]
string
)
error
{
return
c
.
conn
.
Call
(
"Service.SetDataset"
,
globPaths
,
nil
)
err
:=
c
.
conn
.
Call
(
"Service.SetDataset"
,
globPaths
,
nil
)
return
err
}
// getTask gets a new task from the master server.
func
(
c
*
Client
)
getTask
()
(
Task
,
error
)
{
func
(
c
*
Client
)
getTask
(
passID
int
)
(
Task
,
error
)
{
var
t
Task
err
:=
c
.
conn
.
Call
(
"Service.GetTask"
,
0
,
&
t
)
err
:=
c
.
conn
.
Call
(
"Service.GetTask"
,
passID
,
&
t
)
return
t
,
err
}
...
...
@@ -208,12 +222,6 @@ func (c *Client) taskFailed(meta TaskMeta) error {
// NextRecord will block until the next record is available. It is
// thread-safe.
func
(
c
*
Client
)
NextRecord
()
([]
byte
,
error
)
{
c
.
initChOnce
.
Do
(
func
()
{
// initialize with in case WithBuffer is not used.
c
.
ch
=
make
(
chan
record
,
0
)
go
c
.
getRecords
()
})
r
:=
<-
c
.
ch
return
r
.
r
,
r
.
err
}
...
...
go/master/client_internal_test.go
浏览文件 @
7829bdbd
...
...
@@ -54,22 +54,22 @@ func TestGetFinishTask(t *testing.T) {
panic
(
err
)
}
go
func
(
l
net
.
Listener
)
{
s
,
e
rr
:=
NewService
(
&
InMemStore
{},
chunkPerTask
,
time
.
Second
,
1
)
if
e
rr
!=
nil
{
panic
(
e
rr
)
s
,
sE
rr
:=
NewService
(
&
InMemStore
{},
chunkPerTask
,
time
.
Second
,
1
)
if
sE
rr
!=
nil
{
panic
(
sE
rr
)
}
server
:=
rpc
.
NewServer
()
e
rr
=
server
.
Register
(
s
)
if
e
rr
!=
nil
{
panic
(
e
rr
)
sE
rr
=
server
.
Register
(
s
)
if
sE
rr
!=
nil
{
panic
(
sE
rr
)
}
mux
:=
http
.
NewServeMux
()
mux
.
Handle
(
rpc
.
DefaultRPCPath
,
server
)
e
rr
=
http
.
Serve
(
l
,
mux
)
if
e
rr
!=
nil
{
panic
(
e
rr
)
sE
rr
=
http
.
Serve
(
l
,
mux
)
if
sE
rr
!=
nil
{
panic
(
sE
rr
)
}
}(
l
)
...
...
@@ -103,6 +103,7 @@ func TestGetFinishTask(t *testing.T) {
ch
:=
make
(
chan
string
,
1
)
ch
<-
addr
go
c
.
monitorMaster
(
ch
)
err
=
c
.
SetDataset
([]
string
{
path
})
if
err
!=
nil
{
panic
(
err
)
...
...
@@ -111,44 +112,47 @@ func TestGetFinishTask(t *testing.T) {
checkOnePass
:=
func
(
i
int
)
{
var
tasks
[]
Task
for
idx
:=
0
;
idx
<
totalTask
;
idx
++
{
task
,
err
:=
c
.
getTask
(
)
if
err
!=
nil
{
t
.
Fatalf
(
"
Error: %v, pass: %d
\n
"
,
e
rr
,
i
)
task
,
cErr
:=
c
.
getTask
(
i
)
if
cErr
!=
nil
&&
cErr
.
Error
()
!=
ErrNoMoreAvailable
.
Error
()
&&
cErr
.
Error
()
!=
ErrPassAfter
.
Error
()
{
t
.
Fatalf
(
"
error: %v, pass: %d
\n
"
,
cE
rr
,
i
)
}
tasks
=
append
(
tasks
,
task
)
}
_
,
err
=
c
.
getTask
()
if
err
==
nil
{
// getting task before task finishes should return error
_
,
cErr
:=
c
.
getTask
(
i
)
if
cErr
==
nil
{
t
.
Fatalf
(
"Should get error, pass: %d
\n
"
,
i
)
}
e
rr
=
c
.
taskFinished
(
tasks
[
0
]
.
Meta
.
ID
)
if
e
rr
!=
nil
{
t
.
Fatalf
(
"Error: %v, pass: %d
\n
"
,
e
rr
,
i
)
cE
rr
=
c
.
taskFinished
(
tasks
[
0
]
.
Meta
.
ID
)
if
cE
rr
!=
nil
{
t
.
Fatalf
(
"Error: %v, pass: %d
\n
"
,
cE
rr
,
i
)
}
err
=
c
.
taskFailed
(
tasks
[
0
]
.
Meta
)
if
err
!=
nil
{
t
.
Fatalf
(
"Error: %v, pass: %d
\n
"
,
err
,
i
)
// call taskFailed once won't put the task to failed queue, just ensure
// the call
cErr
=
c
.
taskFailed
(
tasks
[
0
]
.
Meta
)
if
cErr
!=
nil
{
t
.
Fatalf
(
"Error: %v, pass: %d
\n
"
,
cErr
,
i
)
}
tasks
=
tasks
[
1
:
]
task
,
err
:=
c
.
getTask
(
)
if
err
!=
nil
{
t
.
Fatal
(
e
rr
)
_
,
cErr
=
c
.
getTask
(
i
)
if
cErr
!=
nil
&&
cErr
.
Error
()
!=
ErrNoMoreAvailable
.
Error
()
&&
cErr
.
Error
()
!=
ErrPassAfter
.
Error
()
{
t
.
Fatal
f
(
"Should be ErrNoMoreAvailable or ErrPassAfter: %s"
,
cE
rr
)
}
tasks
=
append
(
tasks
,
task
)
for
_
,
task
:=
range
tasks
{
e
rr
=
c
.
taskFinished
(
task
.
Meta
.
ID
)
if
e
rr
!=
nil
{
t
.
Fatal
f
(
"Error: %v, pass: %d
\n
"
,
err
,
i
)
cE
rr
=
c
.
taskFinished
(
task
.
Meta
.
ID
)
if
cE
rr
!=
nil
{
t
.
Fatal
(
cErr
)
}
}
}
for
i
:=
0
;
i
<
10
;
i
++
{
// init pass data
c
.
StartGetRecords
(
i
)
checkOnePass
(
i
)
}
}
go/master/client_test.go
浏览文件 @
7829bdbd
...
...
@@ -20,8 +20,10 @@ import (
"net/http"
"net/rpc"
"os"
"runtime"
"strconv"
"strings"
"sync"
"testing"
"time"
...
...
@@ -29,6 +31,18 @@ import (
"github.com/PaddlePaddle/recordio"
)
// tool function for testing output goroutine ids
func
goid
()
int
{
var
buf
[
64
]
byte
n
:=
runtime
.
Stack
(
buf
[
:
],
false
)
idField
:=
strings
.
Fields
(
strings
.
TrimPrefix
(
string
(
buf
[
:
n
]),
"goroutine "
))[
0
]
id
,
err
:=
strconv
.
Atoi
(
idField
)
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"cannot get goroutine id: %v"
,
err
))
}
return
id
}
func
TestNextRecord
(
t
*
testing
.
T
)
{
const
(
path
=
"/tmp/master_client_TestFull"
...
...
@@ -45,7 +59,7 @@ func TestNextRecord(t *testing.T) {
panic
(
err
)
}
go
func
(
l
net
.
Listener
)
{
s
,
err
:=
master
.
NewService
(
&
master
.
InMemStore
{},
1
0
,
time
.
Second
,
1
)
s
,
err
:=
master
.
NewService
(
&
master
.
InMemStore
{},
1
,
time
.
Second
*
60
,
1
)
if
err
!=
nil
{
panic
(
err
)
}
...
...
@@ -69,7 +83,7 @@ func TestNextRecord(t *testing.T) {
panic
(
err
)
}
w
:=
recordio
.
NewWriter
(
f
,
-
1
,
-
1
)
w
:=
recordio
.
NewWriter
(
f
,
1
,
-
1
)
for
i
:=
0
;
i
<
total
;
i
++
{
_
,
err
=
w
.
Write
([]
byte
{
byte
(
i
)})
if
err
!=
nil
{
...
...
@@ -87,32 +101,49 @@ func TestNextRecord(t *testing.T) {
panic
(
err
)
}
c
,
err
:=
master
.
NewClient
(
master
.
WithAddr
(
fmt
.
Sprintf
(
":%d"
,
p
)),
master
.
WithBuffer
(
10
))
if
err
!=
nil
{
panic
(
err
)
}
err
=
c
.
SetDataset
([]
string
{
path
})
if
err
!=
nil
{
panic
(
err
)
}
for
pass
:=
0
;
pass
<
50
;
pass
++
{
received
:=
make
(
map
[
byte
]
bool
)
for
i
:=
0
;
i
<
total
;
i
++
{
r
,
err
:=
c
.
NextRecord
()
if
err
!=
nil
{
t
.
Fatal
(
pass
,
i
,
"Read error:"
,
err
)
// start several client to test task fetching
var
wg
sync
.
WaitGroup
for
i
:=
0
;
i
<
4
;
i
++
{
wg
.
Add
(
1
)
// test for multiple concurrent clients
go
func
()
{
defer
wg
.
Done
()
// each go-routine needs a single client connection instance
c
,
e
:=
master
.
NewClient
(
master
.
WithAddr
(
fmt
.
Sprintf
(
":%d"
,
p
)),
master
.
WithBuffer
(
1
))
if
e
!=
nil
{
t
.
Fatal
(
e
)
}
if
len
(
r
)
!=
1
{
t
.
Fatal
(
pass
,
i
,
"Length should be 1."
,
r
)
e
=
c
.
SetDataset
([]
string
{
path
})
if
e
!=
nil
{
panic
(
e
)
}
if
received
[
r
[
0
]]
{
t
.
Fatal
(
pass
,
i
,
"Received duplicate."
,
received
,
r
)
// test for n passes
for
pass
:=
0
;
pass
<
10
;
pass
++
{
c
.
StartGetRecords
(
pass
)
received
:=
make
(
map
[
byte
]
bool
)
taskid
:=
0
for
{
r
,
e
:=
c
.
NextRecord
()
if
e
!=
nil
{
// ErrorPassAfter will wait, else break for next pass
if
e
.
Error
()
==
master
.
ErrPassBefore
.
Error
()
||
e
.
Error
()
==
master
.
ErrNoMoreAvailable
.
Error
()
{
break
}
t
.
Fatal
(
pass
,
taskid
,
"Read error:"
,
e
)
}
if
len
(
r
)
!=
1
{
t
.
Fatal
(
pass
,
taskid
,
"Length should be 1."
,
r
)
}
if
received
[
r
[
0
]]
{
t
.
Fatal
(
pass
,
taskid
,
"Received duplicate."
,
received
,
r
)
}
taskid
++
received
[
r
[
0
]]
=
true
}
}
received
[
r
[
0
]]
=
true
}
}()
}
wg
.
Wait
()
}
go/master/service.go
浏览文件 @
7829bdbd
...
...
@@ -19,6 +19,7 @@ import (
"compress/gzip"
"encoding/gob"
"errors"
"math/rand"
"os"
"path/filepath"
"sync"
...
...
@@ -33,6 +34,18 @@ const (
dialTimeout
=
5
*
time
.
Second
)
// ErrAllTaskFailed occur when tasks are in done or failed state.
var
ErrAllTaskFailed
=
errors
.
New
(
"all task finished"
)
// ErrNoMoreAvailable occur when no task in todo and yet not all done or fail.
var
ErrNoMoreAvailable
=
errors
.
New
(
"no more available task"
)
// ErrPassBefore client side pass number does not match with master counter.
var
ErrPassBefore
=
errors
.
New
(
"pass number smaller than master"
)
// ErrPassAfter client side pass number does not match with master counter.
var
ErrPassAfter
=
errors
.
New
(
"pass number larger than master"
)
// Store is the interface for save and load the master state.
type
Store
interface
{
Save
([]
byte
)
error
...
...
@@ -75,17 +88,26 @@ type Service struct {
chunksPerTask
int
timeoutDur
time
.
Duration
failureMax
int
ready
chan
struct
{}
store
Store
mu
sync
.
Mutex
initDone
bool
taskQueues
taskQueues
ready
chan
struct
{}
initDone
bool
mu
sync
.
Mutex
taskQueues
taskQueues
currPass
int
jobTasks
[]
taskEntry
savingTrainer
string
}
func
partition
(
chunks
[]
Chunk
,
chunksPerTask
int
)
[]
taskEntry
{
id
:=
0
// generate uniq id across job using nanosecond + randint + counter
// FIXME(typhoonzero): this is a workaround, use uuid
randStart
:=
rand
.
Int
()
counter
:=
0
timestamp
:=
time
.
Now
()
.
Nanosecond
()
id
:=
timestamp
+
randStart
+
counter
if
chunksPerTask
<=
0
{
chunksPerTask
=
1
}
...
...
@@ -95,7 +117,8 @@ func partition(chunks []Chunk, chunksPerTask int) []taskEntry {
for
i
,
c
:=
range
chunks
{
if
i
%
chunksPerTask
==
0
&&
len
(
cur
.
Task
.
Chunks
)
>
0
{
cur
.
Task
.
Meta
.
ID
=
id
id
++
counter
++
id
=
timestamp
+
randStart
+
counter
result
=
append
(
result
,
cur
)
cur
.
Task
.
Chunks
=
nil
}
...
...
@@ -266,19 +289,21 @@ func (s *Service) SetDataset(globPaths []string, _ *int) error {
return
err
}
s
.
taskQueues
.
Todo
=
partition
(
chunks
,
s
.
chunksPerTask
)
s
.
jobTasks
=
partition
(
chunks
,
s
.
chunksPerTask
)
s
.
taskQueues
.
Todo
=
s
.
jobTasks
err
=
s
.
snapshot
()
if
err
!=
nil
{
log
.
Errorln
(
err
)
return
err
}
close
(
s
.
ready
)
s
.
initDone
=
true
return
nil
}
// processFailedTask retry s.failureMax times for failed task.
// return true if all task are done or failed.
func
(
s
*
Service
)
processFailedTask
(
t
taskEntry
,
epoch
int
)
{
if
t
.
Task
.
Meta
.
Epoch
!=
epoch
{
// new epoch, task launched after the
...
...
@@ -302,8 +327,9 @@ func (s *Service) processFailedTask(t taskEntry, epoch int) {
return
}
log
.
Warningf
(
"Task %v failed %d times,
discard
."
,
t
.
Task
,
t
.
NumFailure
)
log
.
Warningf
(
"Task %v failed %d times,
re-dispatch
."
,
t
.
Task
,
t
.
NumFailure
)
s
.
taskQueues
.
Todo
=
append
(
s
.
taskQueues
.
Todo
,
t
)
return
}
func
(
s
*
Service
)
checkTimeoutFunc
(
taskID
int
,
epoch
int
)
func
()
{
...
...
@@ -331,37 +357,30 @@ func (s *Service) logFields() log.Fields {
}
// GetTask gets a new task from the service.
func
(
s
*
Service
)
GetTask
(
_
int
,
task
*
Task
)
error
{
// passID is the client side pass count
func
(
s
*
Service
)
GetTask
(
passID
int
,
task
*
Task
)
error
{
select
{
case
<-
s
.
ready
:
}
s
.
mu
.
Lock
()
defer
s
.
mu
.
Unlock
()
if
passID
<
s
.
currPass
{
return
ErrPassBefore
}
if
passID
>
s
.
currPass
{
// Client may get run to pass after master when one client faster than the
// other
return
ErrPassAfter
}
if
len
(
s
.
taskQueues
.
Todo
)
==
0
{
if
len
(
s
.
taskQueues
.
Done
)
==
0
{
if
len
(
s
.
taskQueues
.
Pending
)
==
0
{
err
:=
errors
.
New
(
"all task failed"
)
log
.
WithFields
(
s
.
logFields
())
.
Warningln
(
"All tasks failed."
)
return
err
}
// TODO(helin): client need to retry in this
// error case. Gotcha: RPC client can't
// compare returned error with predefined
// errors like io.EOF, because the error
// instance deserialized from RPC is a
// different instance than the error defined
// in package. So we need to figure out a way
// for client to check this error correctly.
err
:=
errors
.
New
(
"no more available task"
)
log
.
WithFields
(
s
.
logFields
())
.
Warningln
(
"No more available task."
)
return
err
if
len
(
s
.
taskQueues
.
Done
)
==
0
&&
len
(
s
.
taskQueues
.
Pending
)
==
0
{
log
.
WithFields
(
s
.
logFields
())
.
Warningln
(
"All tasks failed, may start next pass"
)
return
ErrAllTaskFailed
}
s
.
taskQueues
.
Todo
=
s
.
taskQueues
.
Done
s
.
taskQueues
.
Done
=
nil
log
.
WithFields
(
s
.
logFields
())
.
Infoln
(
"No more todo task, but trainer is requesting task to do. Move all done task to todo."
)
log
.
WithFields
(
s
.
logFields
())
.
Warningln
(
"No more available task."
)
return
ErrNoMoreAvailable
}
t
:=
s
.
taskQueues
.
Todo
[
0
]
...
...
@@ -381,7 +400,7 @@ func (s *Service) GetTask(_ int, task *Task) error {
}
// TaskFinished tell the service that a task is finished.
func
(
s
*
Service
)
TaskFinished
(
taskID
int
,
_
*
int
)
error
{
func
(
s
*
Service
)
TaskFinished
(
taskID
int
,
dummy
*
int
)
error
{
select
{
case
<-
s
.
ready
:
}
...
...
@@ -401,11 +420,14 @@ func (s *Service) TaskFinished(taskID int, _ *int) error {
delete
(
s
.
taskQueues
.
Pending
,
taskID
)
log
.
WithFields
(
s
.
logFields
())
.
Infof
(
"Task #%d finished."
,
taskID
)
if
len
(
s
.
taskQueues
.
Pending
)
==
0
&&
len
(
s
.
taskQueues
.
Todo
)
==
0
{
log
.
WithFields
(
s
.
logFields
())
.
Infoln
(
"No more todo and pending task, start a new pass."
)
s
.
taskQueues
.
Todo
=
append
(
s
.
taskQueues
.
Todo
,
s
.
taskQueues
.
Done
...
)
s
.
taskQueues
.
Done
=
nil
if
len
(
s
.
taskQueues
.
Todo
)
==
0
&&
len
(
s
.
taskQueues
.
Pending
)
==
0
{
// increase master side pass count if all tasks finished
s
.
currPass
++
s
.
taskQueues
.
Todo
=
s
.
jobTasks
s
.
taskQueues
.
Done
=
[]
taskEntry
{}
// TODO(typhoonzero): deal with failed tasks
s
.
taskQueues
.
Failed
=
[]
taskEntry
{}
log
.
WithFields
(
s
.
logFields
())
.
Warningf
(
"all task finished, add new pass data, newpass: %d."
,
s
.
currPass
)
}
err
:=
s
.
snapshot
()
...
...
@@ -416,7 +438,7 @@ func (s *Service) TaskFinished(taskID int, _ *int) error {
}
// TaskFailed tells the service that a task is failed.
func
(
s
*
Service
)
TaskFailed
(
meta
TaskMeta
,
_
*
int
)
error
{
func
(
s
*
Service
)
TaskFailed
(
meta
TaskMeta
,
dummy
*
int
)
error
{
select
{
case
<-
s
.
ready
:
}
...
...
go/master/service_internal_test.go
浏览文件 @
7829bdbd
...
...
@@ -44,7 +44,8 @@ func TestPartionIndex(t *testing.T) {
cs
:=
make
([]
Chunk
,
100
)
ts
:=
partition
(
cs
,
20
)
for
i
:=
range
ts
{
if
ts
[
i
]
.
Task
.
Meta
.
ID
!=
i
{
// test auto increament ids
if
i
>
0
&&
ts
[
i
]
.
Task
.
Meta
.
ID
!=
ts
[
i
-
1
]
.
Task
.
Meta
.
ID
+
1
{
t
.
Error
(
ts
[
i
],
i
)
}
}
...
...
go/pserver/client/c/test/test_train.py
浏览文件 @
7829bdbd
...
...
@@ -6,16 +6,19 @@ import cPickle as pickle
etcd_ip
=
os
.
getenv
(
"MASTER_IP"
,
"127.0.0.1"
)
etcd_endpoint
=
"http://"
+
etcd_ip
+
":2379"
print
"connecting to master, etcd endpoints: "
,
etcd_endpoint
master_client
=
master
.
client
(
etcd_endpoint
,
5
,
64
)
def
cloud_reader
():
print
"connecting to master, etcd endpoints: "
,
etcd_endpoint
master_client
=
master
.
client
(
etcd_endpoint
,
5
,
64
)
global
master_client
master_client
.
set_dataset
(
[
"/pfs/dlnel/public/dataset/uci_housing/uci_housing-*
-of-*"
]
)
[
"/pfs/dlnel/public/dataset/uci_housing/uci_housing-*
"
],
passes
=
30
)
while
1
:
r
,
e
=
master_client
.
next_record
()
if
not
r
:
if
e
!=
-
2
:
# other errors
print
"get record error:"
,
e
break
yield
pickle
.
loads
(
r
)
...
...
@@ -27,10 +30,12 @@ def main():
# network config
x
=
paddle
.
layer
.
data
(
name
=
'x'
,
type
=
paddle
.
data_type
.
dense_vector
(
13
))
y_predict
=
paddle
.
layer
.
fc
(
input
=
x
,
param_attr
=
paddle
.
attr
.
Param
(
name
=
'w'
),
param_attr
=
paddle
.
attr
.
Param
(
name
=
'w'
,
learning_rate
=
1e-3
),
size
=
1
,
act
=
paddle
.
activation
.
Linear
(),
bias_attr
=
paddle
.
attr
.
Param
(
name
=
'b'
))
bias_attr
=
paddle
.
attr
.
Param
(
name
=
'b'
,
learning_rate
=
1e-3
))
y
=
paddle
.
layer
.
data
(
name
=
'y'
,
type
=
paddle
.
data_type
.
dense_vector
(
1
))
cost
=
paddle
.
layer
.
mse_cost
(
input
=
y_predict
,
label
=
y
)
...
...
@@ -40,7 +45,6 @@ def main():
# create optimizer of new remote updater to pserver
optimizer
=
paddle
.
optimizer
.
Momentum
(
momentum
=
0
,
learning_rate
=
1e-3
)
print
"etcd endoint: "
,
etcd_endpoint
trainer
=
paddle
.
trainer
.
SGD
(
cost
=
cost
,
parameters
=
parameters
,
update_equation
=
optimizer
,
...
...
@@ -51,6 +55,8 @@ def main():
# event_handler to print training and testing info
def
event_handler
(
event
):
if
isinstance
(
event
,
paddle
.
event
.
EndIteration
):
# FIXME: for cloud data reader, pass number is managed by master
# should print the server side pass number
if
event
.
batch_id
%
100
==
0
:
print
"Pass %d, Batch %d, Cost %f"
%
(
event
.
pass_id
,
event
.
batch_id
,
event
.
cost
)
...
...
paddle/framework/CMakeLists.txt
浏览文件 @
7829bdbd
...
...
@@ -3,7 +3,7 @@ cc_library(ddim SRCS ddim.cc DEPS eigen3)
cc_test
(
ddim_test SRCS ddim_test.cc DEPS ddim
)
nv_test
(
dim_test SRCS dim_test.cu DEPS ddim
)
cc_library
(
tensor SRCS tensor.cc DEPS ddim place paddle_memory
)
cc_library
(
tensor SRCS tensor.cc DEPS ddim place paddle_memory
device_context
)
cc_test
(
tensor_test SRCS tensor_test.cc DEPS tensor
)
cc_test
(
eigen_test SRCS eigen_test.cc DEPS tensor
)
...
...
@@ -29,7 +29,5 @@ py_proto_compile(framework_py_proto SRCS attr_type.proto op_proto.proto op_desc.
add_custom_target
(
framework_py_proto_init ALL COMMAND
${
CMAKE_COMMAND
}
-E touch __init__.py
)
add_dependencies
(
framework_py_proto framework_py_proto_init
)
proto_library
(
net_proto SRCS net_proto.proto DEPS op_proto
)
# cc_library(net SRCS net.cc DEPS operator net_proto op_registry fc_op)
cc_library
(
net SRCS net.cc DEPS operator net_proto op_registry
)
cc_library
(
net SRCS net.cc DEPS op_registry
)
cc_test
(
net_op_test SRCS net_op_test.cc DEPS net add_op mul_op sigmoid_op softmax_op fc_op
)
paddle/framework/detail/tensor-inl.h
0 → 100644
浏览文件 @
7829bdbd
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
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. */
#pragma once
#include "paddle/memory/memcpy.h"
namespace
paddle
{
namespace
framework
{
template
<
typename
T
>
inline
void
Tensor
::
check_memory_size
()
const
{
PADDLE_ENFORCE
(
holder_
!=
nullptr
,
"Tenosr holds no memory. Call Tensor::mutable_data first."
);
PADDLE_ENFORCE
(
holder_
->
size
()
>=
product
(
dims_
)
*
sizeof
(
T
)
+
offset_
,
"Tensor's dims_ is out of bound. Call Tensor::mutable_data "
"first to re-allocate memory."
);
}
template
<
typename
T
>
inline
const
T
*
Tensor
::
data
()
const
{
check_memory_size
<
T
>
();
return
reinterpret_cast
<
const
T
*>
(
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
}
template
<
typename
T
>
inline
T
*
Tensor
::
data
()
{
check_memory_size
<
T
>
();
return
reinterpret_cast
<
T
*>
(
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
}
template
<
typename
T
>
inline
T
*
Tensor
::
mutable_data
(
DDim
dims
,
platform
::
Place
place
)
{
static_assert
(
std
::
is_pod
<
T
>::
value
,
"T must be POD"
);
Resize
(
dims
);
return
mutable_data
<
T
>
(
place
);
}
template
<
typename
T
>
inline
T
*
Tensor
::
mutable_data
(
platform
::
Place
place
)
{
static_assert
(
std
::
is_pod
<
T
>::
value
,
"T must be POD"
);
PADDLE_ENFORCE
(
product
(
dims_
)
>
0
,
"Tensor's numel must be larger than zero to call "
"Tensor::mutable_data. Call Tensor::set_dim first."
);
/* some versions of boost::variant don't have operator!= */
size_t
size
=
product
(
dims_
)
*
sizeof
(
T
);
if
(
holder_
==
nullptr
||
!
(
holder_
->
place
()
==
place
)
||
holder_
->
size
()
<
size
+
offset_
)
{
if
(
platform
::
is_cpu_place
(
place
))
{
holder_
.
reset
(
new
PlaceholderImpl
<
T
,
platform
::
CPUPlace
>
(
boost
::
get
<
platform
::
CPUPlace
>
(
place
),
size
));
}
#ifndef PADDLE_ONLY_CPU
else
if
(
platform
::
is_gpu_place
(
place
))
{
holder_
.
reset
(
new
PlaceholderImpl
<
T
,
platform
::
GPUPlace
>
(
boost
::
get
<
platform
::
GPUPlace
>
(
place
),
size
));
}
#endif
offset_
=
0
;
}
return
reinterpret_cast
<
T
*>
(
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
}
template
<
typename
T
>
inline
void
Tensor
::
ShareDataWith
(
const
Tensor
&
src
)
{
src
.
check_memory_size
<
T
>
();
*
this
=
src
;
}
template
<
typename
T
>
inline
void
Tensor
::
CopyFrom
(
const
Tensor
&
src
,
const
platform
::
CPUDeviceContext
&
ctx
)
{
src
.
check_memory_size
<
T
>
();
Resize
(
src
.
dims
());
auto
src_place
=
src
.
holder_
->
place
();
auto
src_ptr
=
static_cast
<
const
void
*>
(
src
.
data
<
T
>
());
auto
dst_place
=
ctx
.
GetPlace
();
auto
dst_ptr
=
static_cast
<
void
*>
(
mutable_data
<
T
>
(
dst_place
));
auto
size
=
product
(
src
.
dims_
)
*
sizeof
(
T
);
if
(
platform
::
is_cpu_place
(
src_place
))
{
memory
::
Copy
(
boost
::
get
<
platform
::
CPUPlace
>
(
dst_place
),
dst_ptr
,
boost
::
get
<
platform
::
CPUPlace
>
(
src_place
),
src_ptr
,
size
);
}
#ifndef PADDLE_ONLY_CPU
else
if
(
platform
::
is_gpu_place
(
src_place
))
{
memory
::
Copy
(
boost
::
get
<
platform
::
CPUPlace
>
(
dst_place
),
dst_ptr
,
boost
::
get
<
platform
::
GPUPlace
>
(
src_place
),
src_ptr
,
size
,
0
);
}
#endif
}
#ifndef PADDLE_ONLY_CPU
template
<
typename
T
>
inline
void
Tensor
::
CopyFrom
(
const
Tensor
&
src
,
const
platform
::
CUDADeviceContext
&
ctx
)
{
src
.
check_memory_size
<
T
>
();
Resize
(
src
.
dims
());
auto
src_place
=
src
.
holder_
->
place
();
auto
src_ptr
=
static_cast
<
const
void
*>
(
src
.
data
<
T
>
());
auto
dst_place
=
ctx
.
GetPlace
();
auto
dst_ptr
=
static_cast
<
void
*>
(
mutable_data
<
T
>
(
dst_place
));
auto
size
=
product
(
src
.
dims_
)
*
sizeof
(
T
);
if
(
platform
::
is_cpu_place
(
src_place
))
{
memory
::
Copy
(
boost
::
get
<
platform
::
GPUPlace
>
(
dst_place
),
dst_ptr
,
boost
::
get
<
platform
::
CPUPlace
>
(
src_place
),
src_ptr
,
size
,
ctx
.
stream
());
}
else
if
(
platform
::
is_gpu_place
(
src_place
))
{
memory
::
Copy
(
boost
::
get
<
platform
::
GPUPlace
>
(
dst_place
),
dst_ptr
,
boost
::
get
<
platform
::
GPUPlace
>
(
src_place
),
src_ptr
,
size
,
ctx
.
stream
());
}
}
#endif
template
<
typename
T
>
inline
Tensor
Tensor
::
Slice
(
const
int
&
begin_idx
,
const
int
&
end_idx
)
const
{
check_memory_size
<
T
>
();
PADDLE_ENFORCE
(
begin_idx
>=
0
,
"Slice begin index is less than zero."
);
PADDLE_ENFORCE
(
end_idx
<=
dims_
[
0
],
"Slice end index is out of bound."
);
PADDLE_ENFORCE
(
begin_idx
<
end_idx
,
"Begin index must be less than end index."
);
PADDLE_ENFORCE
(
dims_
[
0
]
!=
1
,
"Can not slice a tensor with dims_[0] = 1."
);
int
base
=
product
(
dims_
)
/
dims_
[
0
];
Tensor
dst
;
dst
.
holder_
=
holder_
;
DDim
dst_dims
=
dims_
;
dst_dims
[
0
]
=
end_idx
-
begin_idx
;
dst
.
Resize
(
dst_dims
);
dst
.
offset_
=
offset_
+
begin_idx
*
base
*
sizeof
(
T
);
return
dst
;
}
inline
void
Tensor
::
Resize
(
const
DDim
&
dims
)
{
dims_
=
dims
;
}
inline
const
DDim
&
Tensor
::
dims
()
const
{
return
dims_
;
}
}
// namespace framework
}
// namespace paddle
paddle/framework/net.cc
浏览文件 @
7829bdbd
...
...
@@ -20,17 +20,7 @@
namespace
paddle
{
namespace
framework
{
std
::
shared_ptr
<
PlainNet
>
AddBackwardOp
(
std
::
shared_ptr
<
PlainNet
>
ForwardOps
)
{
auto
grad_ops
=
std
::
make_shared
<
PlainNet
>
();
for
(
auto
&
op
:
ForwardOps
->
ops_
)
{
auto
op_grad
=
OpRegistry
::
CreateGradOp
(
op
);
grad_ops
->
AddOp
(
op_grad
);
}
grad_ops
->
CompleteAddOp
();
return
grad_ops
;
}
void
PlainNet
::
CompleteAddOp
(
bool
calc
)
{
void
NetOp
::
CompleteAddOp
(
bool
calc
)
{
add_op_done_
=
true
;
if
(
!
calc
)
return
;
std
::
unordered_set
<
std
::
string
>
input_set
;
...
...
@@ -70,7 +60,7 @@ void PlainNet::CompleteAddOp(bool calc) {
attrs_
[
"temporary_index"
]
=
tmp_index
;
}
std
::
string
PlainNet
::
DebugString
()
const
{
std
::
string
NetOp
::
DebugString
()
const
{
std
::
ostringstream
os
;
os
<<
OperatorBase
::
DebugString
()
<<
std
::
endl
;
for
(
auto
&
op
:
ops_
)
{
...
...
@@ -82,5 +72,7 @@ std::string PlainNet::DebugString() const {
return
os
.
str
();
}
bool
NetOp
::
IsNetOp
()
const
{
return
true
;
}
}
// namespace framework
}
// namespace paddle
paddle/framework/net.h
浏览文件 @
7829bdbd
...
...
@@ -37,21 +37,7 @@ namespace framework {
* This is the base class of network, all the networks should implement the APIs
* it defines.
*/
class
Net
:
public
OperatorBase
{
public:
virtual
void
AddOp
(
const
std
::
shared_ptr
<
OperatorBase
>&
op
)
=
0
;
virtual
void
CompleteAddOp
(
bool
calc
)
=
0
;
};
using
NetPtr
=
std
::
shared_ptr
<
Net
>
;
/**
* @brief a basic implementation of Net.
*
* PlainNet is a very simple Net, it create a list of operators, and run them
* sequentially following the order they added.
*/
class
PlainNet
:
public
Net
{
class
NetOp
:
public
OperatorBase
{
public:
/**
* Infer all the operators' input and output variables' shapes, will be called
...
...
@@ -80,15 +66,17 @@ class PlainNet : public Net {
/**
* @brief Add an operator by ptr
*/
void
AddOp
(
const
std
::
shared_ptr
<
OperatorBase
>&
op
)
override
{
void
AddOp
(
const
std
::
shared_ptr
<
OperatorBase
>&
op
)
{
PADDLE_ENFORCE
(
!
add_op_done_
,
"Cannot AddOp when this network is sealed"
);
ops_
.
push_back
(
op
);
}
void
CompleteAddOp
(
bool
calculate
=
true
)
override
;
void
CompleteAddOp
(
bool
calculate
=
true
);
std
::
string
DebugString
()
const
override
;
bool
IsNetOp
()
const
override
;
std
::
vector
<
std
::
shared_ptr
<
OperatorBase
>>
ops_
;
private:
...
...
@@ -100,7 +88,5 @@ class PlainNet : public Net {
}
};
std
::
shared_ptr
<
PlainNet
>
AddBackwardOp
(
std
::
shared_ptr
<
PlainNet
>
ForwardOps
);
}
// namespace framework
}
// namespace paddle
paddle/framework/net_op_test.cc
浏览文件 @
7829bdbd
...
...
@@ -40,7 +40,7 @@ void AssertSameVectorWithoutOrder(const std::vector<T>& expected,
}
TEST
(
OpKernel
,
all
)
{
auto
net
=
std
::
make_shared
<
PlainNet
>
();
auto
net
=
std
::
make_shared
<
NetOp
>
();
ASSERT_NE
(
net
,
nullptr
);
auto
op1
=
std
::
make_shared
<
TestOp
>
();
...
...
@@ -71,28 +71,21 @@ TEST(OpKernel, all) {
ASSERT_EQ
(
2
,
run_cnt
);
ASSERT_THROW
(
net
->
AddOp
(
op2
),
paddle
::
platform
::
EnforceNotMet
);
}
TEST
(
AddBackwardOp
,
TestGradOp
)
{
auto
net
=
std
::
make_shared
<
PlainNet
>
();
ASSERT_NE
(
net
,
nullptr
);
net
->
AddOp
(
framework
::
OpRegistry
::
CreateOp
(
"mul"
,
{
"X"
,
"Y"
},
{
"Out"
},
{}));
net
->
AddOp
(
framework
::
OpRegistry
::
CreateOp
(
"add_two"
,
{
"X"
,
"Y"
},
{
"Out"
},
{}));
net
->
AddOp
(
framework
::
OpRegistry
::
CreateOp
(
"add_two"
,
{
"X"
,
"Y"
},
{
""
},
{}));
auto
grad_ops
=
AddBackwardOp
(
net
);
for
(
auto
&
op
:
grad_ops
->
ops_
)
{
op
->
DebugString
();
}
}
// TODO(zhihong): add fc grad without registering.
// TEST(AddBackwardOp, TestNoGradOp) {
// auto net = std::make_shared<PlainNet>();
// ASSERT_NE(net, nullptr);
// net->AddOp(framework::OpRegistry::CreateOp("fc", {"X", "W", "b"}, {"Y"},
// {})); auto grad_ops = AddBackwardOp(net); for (auto& op : grad_ops->ops_) {
// op->DebugString();
// }
// }
//! TODO(yuyang18): Refine Backward Op.
// TEST(AddBackwardOp, TestGradOp) {
// auto net = std::make_shared<NetOp>();
// ASSERT_NE(net, nullptr);
// net->AddOp(framework::OpRegistry::CreateOp("mul", {"X", "Y"}, {"Out"}, {}));
// net->AddOp(
// framework::OpRegistry::CreateOp("add_two", {"X", "Y"}, {"Out"}, {}));
// net->AddOp(framework::OpRegistry::CreateOp("add_two", {"X", "Y"}, {""},
// {}));
// auto grad_ops = AddBackwardOp(net);
// for (auto& op : grad_ops->ops_) {
// op->DebugString();
// }
//}
}
// namespace framework
}
// namespace paddle
paddle/framework/net_proto.proto
已删除
100644 → 0
浏览文件 @
d951e9c7
syntax
=
"proto2"
;
package
paddle
.
framework
;
import
"op_proto.proto"
;
message
NetDesc
{
// network identification
optional
string
name
=
1
;
// operator contains in network
repeated
OpProto
operators
=
2
;
// network type to run with. e.g "plainNet", "DAG"
optional
string
net_type
=
3
;
// num worker always
optional
int32
num_workers
=
4
;
}
paddle/framework/op_registry.h
浏览文件 @
7829bdbd
...
...
@@ -403,15 +403,16 @@ class GradOpRegisterHelper {
STATIC_ASSERT_GLOBAL_NAMESPACE( \
__reg_op_kernel_##type##_##DEVICE_TYPE##__, \
"REGISTER_OP_KERNEL must be in global namespace"); \
struct __op_kernel_register__##type##__
{
\
__op_kernel_register__##type##__
() {
\
struct __op_kernel_register__##type##__
##DEVICE_TYPE##__ {
\
__op_kernel_register__##type##__
##DEVICE_TYPE##__() {
\
::paddle::framework::OperatorWithKernel::OpKernelKey key; \
key.place_ = PlaceType(); \
::paddle::framework::OperatorWithKernel::AllOpKernels()[#type][key] \
.reset(new __VA_ARGS__()); \
} \
}; \
static __op_kernel_register__##type##__ __reg_kernel_##type##__; \
static __op_kernel_register__##type##__##DEVICE_TYPE##__ \
__reg_kernel_##type##__##DEVICE_TYPE##__; \
int __op_kernel_register_##type##_handle_##DEVICE_TYPE##__() { return 0; }
// (type, KernelType)
...
...
paddle/framework/operator.h
浏览文件 @
7829bdbd
...
...
@@ -90,15 +90,17 @@ class OperatorBase {
virtual
void
Run
(
const
std
::
shared_ptr
<
Scope
>&
scope
,
const
platform
::
DeviceContext
&
dev_ctx
)
const
=
0
;
// Get a input with argument's name described in `op_proto`
virtual
bool
IsNetOp
()
const
{
return
false
;
}
//! Get a input with argument's name described in `op_proto`
const
std
::
string
&
Input
(
const
std
::
string
&
name
)
const
;
// Get a input which has multiple variables.
// TODO add a vector_view to prevent memory copy.
//
!
Get a input which has multiple variables.
//
!
TODO add a vector_view to prevent memory copy.
std
::
vector
<
std
::
string
>
Inputs
(
const
std
::
string
&
name
)
const
;
// Get a output with argument's name described in `op_proto`
//
!
Get a output with argument's name described in `op_proto`
const
std
::
string
&
Output
(
const
std
::
string
&
name
)
const
;
// Get an output which has multiple variables.
// TODO add a vector_view to prevent memory copy.
//
!
Get an output which has multiple variables.
//
!
TODO add a vector_view to prevent memory copy.
std
::
vector
<
std
::
string
>
Outputs
(
const
std
::
string
&
name
)
const
;
public:
...
...
@@ -199,7 +201,9 @@ class OperatorWithKernel : public OperatorBase {
place_
=
dev_ctx
.
GetPlace
();
}
bool
operator
==
(
const
OpKernelKey
&
o
)
const
{
return
place_
==
o
.
place_
;
}
bool
operator
==
(
const
OpKernelKey
&
o
)
const
{
return
platform
::
places_are_same_class
(
place_
,
o
.
place_
);
}
};
struct
OpKernelHash
{
...
...
paddle/framework/tensor.cc
浏览文件 @
7829bdbd
...
...
@@ -12,7 +12,7 @@
See the License for the specific language governing permissions and
limitations under the License. */
#include
<paddle/framework/tensor.h>
#include
"paddle/framework/tensor.h"
namespace
paddle
{
namespace
framework
{}
...
...
paddle/framework/tensor.h
浏览文件 @
7829bdbd
...
...
@@ -20,6 +20,7 @@ limitations under the License. */
#include <typeindex>
#include "paddle/framework/ddim.h"
#include "paddle/memory/memory.h"
#include "paddle/platform/device_context.h"
#include "paddle/platform/enforce.h"
#include "paddle/platform/place.h"
#include "unsupported/Eigen/CXX11/Tensor"
...
...
@@ -31,9 +32,11 @@ template <bool less, size_t i, typename... args>
struct
CastToPyBufferImpl
;
}
// namespace details
}
// namespace pybind
namespace
framework
{
class
Tensor
{
public:
template
<
bool
less
,
size_t
i
,
typename
...
args
>
friend
struct
paddle
::
pybind
::
details
::
CastToPyBufferImpl
;
...
...
@@ -46,106 +49,84 @@ class Tensor {
public:
Tensor
()
:
offset_
(
0
)
{}
/*! Return a pointer to mutable memory block. */
template
<
typename
T
>
const
T
*
data
()
const
{
EnforceSufficientMemory
<
T
>
();
return
reinterpret_cast
<
const
T
*>
(
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
}
inline
T
*
data
();
/*! Return a pointer to constant memory block. */
template
<
typename
T
>
T
*
data
()
{
EnforceSufficientMemory
<
T
>
();
return
reinterpret_cast
<
T
*>
(
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
}
template
<
typename
T
,
// must be POD types
typename
std
::
enable_if
<
std
::
is_pod
<
T
>
::
value
>::
type
*
=
nullptr
>
T
*
mutable_data
(
DDim
dims
,
platform
::
Place
place
)
{
Resize
(
dims
);
return
mutable_data
<
T
>
(
place
);
}
template
<
typename
T
,
// must be POD types
typename
std
::
enable_if
<
std
::
is_pod
<
T
>
::
value
>::
type
*
=
nullptr
>
T
*
mutable_data
(
platform
::
Place
place
)
{
PADDLE_ENFORCE
(
product
(
dims_
)
>
0
,
"Tensor's numel must be larger than zero to call "
"Tensor::mutable_data. Call Tensor::set_dim first."
);
if
(
holder_
==
nullptr
||
!
(
holder_
->
place
()
==
place
)
/* some versions of boost::variant don't have operator!= */
||
holder_
->
size
()
<
product
(
dims_
)
*
sizeof
(
T
)
+
offset_
)
{
if
(
platform
::
is_cpu_place
(
place
))
{
holder_
.
reset
(
new
PlaceholderImpl
<
T
,
platform
::
CPUPlace
>
(
boost
::
get
<
platform
::
CPUPlace
>
(
place
),
product
(
dims_
)
*
sizeof
(
T
)));
}
else
if
(
platform
::
is_gpu_place
(
place
))
{
#ifdef PADDLE_ONLY_CPU
PADDLE_THROW
(
"'GPUPlace' is not supported in CPU only device."
);
#else
holder_
.
reset
(
new
PlaceholderImpl
<
T
,
platform
::
GPUPlace
>
(
boost
::
get
<
platform
::
GPUPlace
>
(
place
),
product
(
dims_
)
*
sizeof
(
T
)));
#endif
}
else
{
PADDLE_THROW
(
"Unknown 'place'."
);
}
offset_
=
0
;
}
return
reinterpret_cast
<
T
*>
(
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
}
inline
const
T
*
data
()
const
;
/**
* @brief Return a pointer to mutable memory block.
* @note If not exist, then allocation.
*/
template
<
typename
T
>
inline
T
*
mutable_data
(
platform
::
Place
place
);
/**
* @brief Return a pointer to mutable memory block.
*
* @param[in] dims The dimensions of the memory block.
* @param[in] place The place of the memory block.
*
* @note If not exist, then allocation.
*/
template
<
typename
T
>
inline
T
*
mutable_data
(
DDim
dims
,
platform
::
Place
place
);
/*! Return the dimensions of the memory block. */
inline
const
DDim
&
dims
()
const
;
/*! Resize the dimensions of the memory block. */
inline
void
Resize
(
const
DDim
&
dims
);
/*! The internal of two tensors share the same memory block. */
template
<
typename
T
>
inline
void
ShareDataWith
(
const
Tensor
&
src
);
/**
* @brief Copy the content of external tensor to a new place.
*
* @param[in] src The external tensor.
* @param[in] ctx The device context contains place where to store.
*
* @note CopyFrom supports CPU <-> GPU, GPU <-> GPU.
*/
template
<
typename
T
>
void
ShareDataWith
(
const
Tensor
&
src
)
{
src
.
EnforceSufficientMemory
<
T
>
();
*
this
=
src
;
}
inline
void
CopyFrom
(
const
Tensor
&
src
,
const
platform
::
CPUDeviceContext
&
ctx
);
#ifndef PADDLE_ONLY_CPU
template
<
typename
T
>
void
CopyFrom
(
const
Tensor
&
src
,
platform
::
Place
dst_place
)
{
PADDLE_ENFORCE
(
platform
::
is_cpu_place
(
src
.
holder_
->
place
())
&&
platform
::
is_cpu_place
(
dst_place
),
"Tensor::CopyFrom only support CPU now."
);
src
.
EnforceSufficientMemory
<
T
>
();
size_t
size
=
product
(
src
.
dims_
)
*
sizeof
(
T
);
Resize
(
src
.
dims
());
const
void
*
src_ptr
=
static_cast
<
const
void
*>
(
src
.
data
<
T
>
());
void
*
dst_ptr
=
static_cast
<
void
*>
(
mutable_data
<
T
>
(
dst_place
));
memcpy
(
dst_ptr
,
src_ptr
,
size
);
}
inline
void
CopyFrom
(
const
Tensor
&
src
,
const
platform
::
CUDADeviceContext
&
ctx
);
#endif
/**
* @brief Return the slice of the tensor.
*
* @param[in] begin_idx The begin index of the slice.
* @param[in] end_idx The end index of the slice.
*/
template
<
typename
T
>
Tensor
Slice
(
const
int
&
begin_idx
,
const
int
&
end_idx
)
const
{
EnforceSufficientMemory
<
T
>
();
PADDLE_ENFORCE
(
begin_idx
>=
0
,
"Slice begin index is less than zero."
);
PADDLE_ENFORCE
(
end_idx
<=
dims_
[
0
],
"Slice end index is out of bound."
);
PADDLE_ENFORCE
(
begin_idx
<
end_idx
,
"Begin index must be less than end index."
);
PADDLE_ENFORCE
(
dims_
[
0
]
!=
1
,
"Can not slice a tensor with dims_[0] = 1."
);
int
base
=
product
(
dims_
)
/
dims_
[
0
];
Tensor
dst
;
dst
.
holder_
=
holder_
;
DDim
dst_dims
=
dims_
;
dst_dims
[
0
]
=
end_idx
-
begin_idx
;
dst
.
Resize
(
dst_dims
);
dst
.
offset_
=
offset_
+
begin_idx
*
base
*
sizeof
(
T
);
return
dst
;
}
void
Resize
(
const
DDim
&
dims
)
{
dims_
=
dims
;
}
const
DDim
&
dims
()
const
{
return
dims_
;
}
inline
Tensor
Slice
(
const
int
&
begin_idx
,
const
int
&
end_idx
)
const
;
private:
// Placeholder hides type T, so it doesn't appear as a template
// parameter of Variable.
template
<
typename
T
>
inline
void
check_memory_size
()
const
;
private:
/**
* @note Placeholder hides type T, so it doesn't appear as a template
* parameter of Variable.
*/
struct
Placeholder
{
virtual
~
Placeholder
()
{}
virtual
void
*
ptr
()
const
=
0
;
virtual
platform
::
Place
place
()
const
=
0
;
virtual
size_t
size
()
const
=
0
;
virtual
std
::
type_index
type
()
const
=
0
;
virtual
platform
::
Place
place
()
const
=
0
;
};
template
<
typename
T
,
typename
PlaceType
>
...
...
@@ -156,33 +137,38 @@ class Tensor {
place_
(
place
),
size_
(
size
)
{}
virtual
void
*
ptr
()
const
{
return
static_cast
<
void
*>
(
ptr_
.
get
());
}
virtual
size_t
size
()
const
{
return
size_
;
}
virtual
paddle
::
platform
::
Place
place
()
const
{
return
place_
;
}
virtual
platform
::
Place
place
()
const
{
return
place_
;
}
virtual
void
*
ptr
()
const
{
return
static_cast
<
void
*>
(
ptr_
.
get
());
}
virtual
std
::
type_index
type
()
const
{
return
std
::
type_index
(
typeid
(
T
));
}
/*! the pointer of memory block. */
std
::
unique_ptr
<
T
,
memory
::
PODDeleter
<
T
,
PlaceType
>>
ptr_
;
platform
::
Place
place_
;
// record the place of ptr_.
size_t
size_
;
// size of the memory block.
/*! the place of memory block. */
platform
::
Place
place_
;
/*! the size of memory block. */
size_t
size_
;
};
template
<
typename
T
>
inline
void
EnforceSufficientMemory
()
const
{
PADDLE_ENFORCE
(
holder_
!=
nullptr
,
"Tenosr holds no memory. Call Tensor::mutable_data first."
);
PADDLE_ENFORCE
(
holder_
->
size
()
>=
product
(
dims_
)
*
sizeof
(
T
)
+
offset_
,
"Tensor's dims_ is out of bound. Call Tensor::mutable_data "
"first to re-allocate memory."
);
}
std
::
shared_ptr
<
Placeholder
>
holder_
;
// holds the memory block if allocated.
/*! holds the memory block if allocated. */
std
::
shared_ptr
<
Placeholder
>
holder_
;
/*! points to dimensions of memory block. */
DDim
dims_
;
// A PlaceHolder may be shared by more than one tensor. Some of them may be
// slices of the others. So the offset_ is introduced here to indicate the
// byte offset between PlaceHolder::ptr_ and where tensor's data really
// begins.
/**
* @brief A PlaceHolder may be shared by more than one tensor.
*
* @note Some of them may be slices of the others. So the offset_
* is introduced here to indicate the byte offset between
* PlaceHolder::ptr_ and where the tensor data really begins.
*/
size_t
offset_
;
};
}
// namespace framework
}
// namespace paddle
#include "paddle/framework/detail/tensor-inl.h"
paddle/framework/tensor_test.cc
浏览文件 @
7829bdbd
...
...
@@ -72,7 +72,8 @@ TEST(Tensor, MutableData) {
p2
=
src_tensor
.
mutable_data
<
float
>
(
make_ddim
({
2
,
2
}),
CPUPlace
());
EXPECT_EQ
(
p1
,
p2
);
}
#ifdef __CUDACC__
#ifndef PADDLE_ONLY_CPU
{
Tensor
src_tensor
;
float
*
p1
=
nullptr
;
...
...
@@ -123,7 +124,7 @@ TEST(Tensor, ShareDataWith) {
ASSERT_EQ
(
src_tensor
.
data
<
int
>
(),
dst_tensor
.
data
<
int
>
());
}
#if
def __CUDACC__
#if
ndef PADDLE_ONLY_CPU
{
Tensor
src_tensor
;
Tensor
dst_tensor
;
...
...
@@ -160,7 +161,7 @@ TEST(Tensor, Slice) {
EXPECT_EQ
(
src_data_address
+
3
*
4
*
1
*
sizeof
(
int
),
slice_data_address
);
}
#if
def __CUDACC__
#if
ndef PADDLE_ONLY_CPU
{
Tensor
src_tensor
;
src_tensor
.
mutable_data
<
double
>
(
make_ddim
({
6
,
9
}),
GPUPlace
());
...
...
@@ -188,25 +189,74 @@ TEST(Tensor, Slice) {
TEST
(
Tensor
,
CopyFrom
)
{
using
namespace
paddle
::
framework
;
using
namespace
paddle
::
platform
;
{
Tensor
src_tensor
;
Tensor
dst_tensor
;
int
*
src_ptr
=
src_tensor
.
mutable_data
<
int
>
(
make_ddim
({
3
,
3
}),
CPUPlace
());
int
arr
[
9
]
=
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
};
memcpy
(
src_ptr
,
arr
,
9
*
sizeof
(
int
));
Tensor
src_tensor
;
int
*
src_ptr
=
src_tensor
.
mutable_data
<
int
>
(
make_ddim
({
3
,
3
}),
CPUPlace
());
int
arr
[
9
]
=
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
};
memcpy
(
src_ptr
,
arr
,
9
*
sizeof
(
int
));
Tensor
dst_tensor
;
dst_tensor
.
CopyFrom
<
int
>
(
src_tensor
,
CPUPlace
());
const
int
*
dst_ptr
=
dst_tensor
.
data
<
int
>
();
ASSERT_NE
(
src_ptr
,
dst_ptr
);
for
(
size_t
i
=
0
;
i
<
9
;
++
i
)
{
EXPECT_EQ
(
src_ptr
[
i
],
dst_ptr
[
i
]);
auto
*
cpu_ctx
=
new
paddle
::
platform
::
CPUDeviceContext
();
dst_tensor
.
CopyFrom
<
int
>
(
src_tensor
,
*
cpu_ctx
);
const
int
*
dst_ptr
=
dst_tensor
.
data
<
int
>
();
ASSERT_NE
(
src_ptr
,
dst_ptr
);
for
(
size_t
i
=
0
;
i
<
9
;
++
i
)
{
EXPECT_EQ
(
src_ptr
[
i
],
dst_ptr
[
i
]);
}
Tensor
slice_tensor
=
src_tensor
.
Slice
<
int
>
(
1
,
2
);
dst_tensor
.
CopyFrom
<
int
>
(
slice_tensor
,
*
cpu_ctx
);
const
int
*
slice_ptr
=
slice_tensor
.
data
<
int
>
();
dst_ptr
=
dst_tensor
.
data
<
int
>
();
ASSERT_NE
(
dst_ptr
,
slice_ptr
);
for
(
size_t
i
=
0
;
i
<
3
;
++
i
)
{
EXPECT_EQ
(
dst_ptr
[
i
],
slice_ptr
[
i
]);
}
}
#ifndef PADDLE_ONLY_CPU
{
Tensor
src_tensor
;
Tensor
gpu_tensor
;
Tensor
dst_tensor
;
int
*
src_ptr
=
src_tensor
.
mutable_data
<
int
>
(
make_ddim
({
3
,
3
}),
CPUPlace
());
int
arr
[
9
]
=
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
};
memcpy
(
src_ptr
,
arr
,
9
*
sizeof
(
int
));
// CPU Tensor to GPU Tensor
auto
gpu_ctx
=
new
paddle
::
platform
::
CUDADeviceContext
(
0
);
gpu_tensor
.
CopyFrom
<
int
>
(
src_tensor
,
*
gpu_ctx
);
// GPU Tensor to CPU Tensor
auto
cpu_ctx
=
new
paddle
::
platform
::
CPUDeviceContext
();
dst_tensor
.
CopyFrom
<
int
>
(
gpu_tensor
,
*
cpu_ctx
);
// Compare Tensors
const
int
*
dst_ptr
=
dst_tensor
.
data
<
int
>
();
ASSERT_NE
(
src_ptr
,
dst_ptr
);
for
(
size_t
i
=
0
;
i
<
9
;
++
i
)
{
EXPECT_EQ
(
src_ptr
[
i
],
dst_ptr
[
i
]);
}
Tensor
slice_tensor
=
src_tensor
.
Slice
<
int
>
(
1
,
2
);
// CPU Slice Tensor to GPU Tensor
gpu_tensor
.
CopyFrom
<
int
>
(
slice_tensor
,
*
gpu_ctx
);
Tensor
slice_tensor
=
src_tensor
.
Slice
<
int
>
(
1
,
2
);
dst_tensor
.
CopyFrom
<
int
>
(
slice_tensor
,
CPUPlace
());
const
int
*
slice_ptr
=
slice_tensor
.
data
<
int
>
();
dst_ptr
=
dst_tensor
.
data
<
int
>
();
ASSERT_NE
(
dst_ptr
,
slice_ptr
);
for
(
size_t
i
=
0
;
i
<
3
;
++
i
)
{
EXPECT_EQ
(
dst_ptr
[
i
],
slice_ptr
[
i
]);
// GPU Tensor to CPU Tensor
dst_tensor
.
CopyFrom
<
int
>
(
gpu_tensor
,
*
cpu_ctx
);
// Compare Slice Tensors
const
int
*
slice_ptr
=
slice_tensor
.
data
<
int
>
();
dst_ptr
=
dst_tensor
.
data
<
int
>
();
ASSERT_NE
(
dst_ptr
,
slice_ptr
);
for
(
size_t
i
=
0
;
i
<
3
;
++
i
)
{
EXPECT_EQ
(
dst_ptr
[
i
],
slice_ptr
[
i
]);
}
}
#endif
}
paddle/memory/detail/buddy_allocator.cc
浏览文件 @
7829bdbd
...
...
@@ -27,12 +27,11 @@ BuddyAllocator::BuddyAllocator(SystemAllocator* system_allocator,
system_allocator_
(
std
::
move
(
system_allocator
))
{}
BuddyAllocator
::~
BuddyAllocator
()
{
DLOG
(
INFO
)
<<
"BuddyAllocator Disconstructor makes sure that all of these "
"have actually been freed"
;
VLOG
(
3
)
<<
"BuddyAllocator Disconstructor makes sure that all of these "
"have actually been freed"
;
while
(
!
pool_
.
empty
())
{
auto
block
=
static_cast
<
MemoryBlock
*>
(
std
::
get
<
2
>
(
*
pool_
.
begin
()));
DLOG
(
INFO
)
<<
"Free from block ("
<<
block
<<
", "
<<
max_chunk_size_
<<
")"
;
VLOG
(
3
)
<<
"Free from block ("
<<
block
<<
", "
<<
max_chunk_size_
<<
")"
;
system_allocator_
->
Free
(
block
,
max_chunk_size_
,
block
->
index
(
cache_
));
cache_
.
invalidate
(
block
);
...
...
@@ -52,12 +51,11 @@ void* BuddyAllocator::Alloc(size_t unaligned_size) {
// acquire the allocator lock
std
::
lock_guard
<
std
::
mutex
>
lock
(
mutex_
);
DLOG
(
INFO
)
<<
"Allocate "
<<
unaligned_size
<<
" bytes from chunk size "
<<
size
;
VLOG
(
3
)
<<
"Allocate "
<<
unaligned_size
<<
" bytes from chunk size "
<<
size
;
// if the allocation is huge, send directly to the system allocator
if
(
size
>
max_chunk_size_
)
{
DLOG
(
INFO
)
<<
"Allocate from system allocator."
;
VLOG
(
3
)
<<
"Allocate from system allocator."
;
return
SystemAlloc
(
size
);
}
...
...
@@ -72,9 +70,9 @@ void* BuddyAllocator::Alloc(size_t unaligned_size) {
return
nullptr
;
}
}
else
{
DLOG
(
INFO
)
<<
"Allocation from existing memory block "
<<
std
::
get
<
2
>
(
*
it
)
<<
" at address "
<<
reinterpret_cast
<
MemoryBlock
*>
(
std
::
get
<
2
>
(
*
it
))
->
data
();
VLOG
(
3
)
<<
"Allocation from existing memory block "
<<
std
::
get
<
2
>
(
*
it
)
<<
" at address "
<<
reinterpret_cast
<
MemoryBlock
*>
(
std
::
get
<
2
>
(
*
it
))
->
data
();
}
total_used_
+=
size
;
...
...
@@ -91,10 +89,10 @@ void BuddyAllocator::Free(void* p) {
// Acquire the allocator lock
std
::
lock_guard
<
std
::
mutex
>
lock
(
mutex_
);
DLOG
(
INFO
)
<<
"Free from address "
<<
block
;
VLOG
(
3
)
<<
"Free from address "
<<
block
;
if
(
block
->
type
(
cache_
)
==
MemoryBlock
::
HUGE_CHUNK
)
{
DLOG
(
INFO
)
<<
"Free directly from system allocator"
;
VLOG
(
3
)
<<
"Free directly from system allocator"
;
system_allocator_
->
Free
(
block
,
block
->
total_size
(
cache_
),
block
->
index
(
cache_
));
...
...
@@ -111,8 +109,8 @@ void BuddyAllocator::Free(void* p) {
// Trying to merge the right buddy
if
(
block
->
has_right_buddy
(
cache_
))
{
DLOG
(
INFO
)
<<
"Merging this block "
<<
block
<<
" with its right buddy "
<<
block
->
right_buddy
(
cache_
);
VLOG
(
3
)
<<
"Merging this block "
<<
block
<<
" with its right buddy "
<<
block
->
right_buddy
(
cache_
);
auto
right_buddy
=
block
->
right_buddy
(
cache_
);
...
...
@@ -129,8 +127,8 @@ void BuddyAllocator::Free(void* p) {
// Trying to merge the left buddy
if
(
block
->
has_left_buddy
(
cache_
))
{
DLOG
(
INFO
)
<<
"Merging this block "
<<
block
<<
" with its left buddy "
<<
block
->
left_buddy
(
cache_
);
VLOG
(
3
)
<<
"Merging this block "
<<
block
<<
" with its left buddy "
<<
block
->
left_buddy
(
cache_
);
auto
left_buddy
=
block
->
left_buddy
(
cache_
);
...
...
@@ -146,8 +144,8 @@ void BuddyAllocator::Free(void* p) {
}
// Dumping this block into pool
DLOG
(
INFO
)
<<
"Inserting free block ("
<<
block
<<
", "
<<
block
->
total_size
(
cache_
)
<<
")"
;
VLOG
(
3
)
<<
"Inserting free block ("
<<
block
<<
", "
<<
block
->
total_size
(
cache_
)
<<
")"
;
pool_
.
insert
(
IndexSizeAddress
(
block
->
index
(
cache_
),
block
->
total_size
(
cache_
),
block
));
...
...
@@ -166,7 +164,7 @@ void* BuddyAllocator::SystemAlloc(size_t size) {
size_t
index
=
0
;
void
*
p
=
system_allocator_
->
Alloc
(
index
,
size
);
DLOG
(
INFO
)
<<
"Allocated "
<<
p
<<
" from system allocator."
;
VLOG
(
3
)
<<
"Allocated "
<<
p
<<
" from system allocator."
;
if
(
p
==
nullptr
)
return
nullptr
;
...
...
@@ -192,8 +190,8 @@ BuddyAllocator::PoolSet::iterator BuddyAllocator::RefillPool() {
if
(
p
==
nullptr
)
return
pool_
.
end
();
DLOG
(
INFO
)
<<
"Creating and inserting new block "
<<
p
<<
" from system allocator"
;
VLOG
(
3
)
<<
"Creating and inserting new block "
<<
p
<<
" from system allocator"
;
static_cast
<
MemoryBlock
*>
(
p
)
->
init
(
cache_
,
MemoryBlock
::
FREE_CHUNK
,
index
,
max_chunk_size_
,
nullptr
,
nullptr
);
...
...
@@ -237,19 +235,19 @@ void* BuddyAllocator::SplitToAlloc(BuddyAllocator::PoolSet::iterator it,
auto
block
=
static_cast
<
MemoryBlock
*>
(
std
::
get
<
2
>
(
*
it
));
pool_
.
erase
(
it
);
DLOG
(
INFO
)
<<
"Split block ("
<<
block
<<
", "
<<
block
->
total_size
(
cache_
)
<<
") into"
;
VLOG
(
3
)
<<
"Split block ("
<<
block
<<
", "
<<
block
->
total_size
(
cache_
)
<<
") into"
;
block
->
split
(
cache_
,
size
);
DLOG
(
INFO
)
<<
"Left block ("
<<
block
<<
", "
<<
block
->
total_size
(
cache_
)
<<
")"
;
VLOG
(
3
)
<<
"Left block ("
<<
block
<<
", "
<<
block
->
total_size
(
cache_
)
<<
")"
;
block
->
set_type
(
cache_
,
MemoryBlock
::
ARENA_CHUNK
);
// the rest of memory if exist
if
(
block
->
has_right_buddy
(
cache_
))
{
if
(
block
->
right_buddy
(
cache_
)
->
type
(
cache_
)
==
MemoryBlock
::
FREE_CHUNK
)
{
DLOG
(
INFO
)
<<
"Insert right block ("
<<
block
->
right_buddy
(
cache_
)
<<
", "
<<
block
->
right_buddy
(
cache_
)
->
total_size
(
cache_
)
<<
")"
;
VLOG
(
3
)
<<
"Insert right block ("
<<
block
->
right_buddy
(
cache_
)
<<
", "
<<
block
->
right_buddy
(
cache_
)
->
total_size
(
cache_
)
<<
")"
;
pool_
.
insert
(
IndexSizeAddress
(
block
->
right_buddy
(
cache_
)
->
index
(
cache_
),
...
...
@@ -276,7 +274,7 @@ void BuddyAllocator::CleanIdleFallBackAlloc() {
return
;
}
DLOG
(
INFO
)
<<
"Return block "
<<
block
<<
" to fallback allocator."
;
VLOG
(
3
)
<<
"Return block "
<<
block
<<
" to fallback allocator."
;
system_allocator_
->
Free
(
block
,
max_chunk_size_
,
block
->
index
(
cache_
));
cache_
.
invalidate
(
block
);
...
...
@@ -312,7 +310,7 @@ void BuddyAllocator::CleanIdleNormalAlloc() {
MemoryBlock
*
block
=
static_cast
<
MemoryBlock
*>
(
std
::
get
<
2
>
(
*
pool
));
DLOG
(
INFO
)
<<
"Return block "
<<
block
<<
" to base allocator."
;
VLOG
(
3
)
<<
"Return block "
<<
block
<<
" to base allocator."
;
system_allocator_
->
Free
(
block
,
max_chunk_size_
,
block
->
index
(
cache_
));
cache_
.
invalidate
(
block
);
...
...
paddle/memory/memory.h
浏览文件 @
7829bdbd
...
...
@@ -29,10 +29,10 @@ void Free(Place, void*);
template
<
typename
Place
>
size_t
Used
(
Place
);
template
<
typename
T
,
/* must be POD types */
typename
Place
/* platform::GPUPlace or platform::CPUPlace */
,
typename
std
::
enable_if
<
std
::
is_pod
<
T
>
::
value
>::
type
*
=
nullptr
>
template
<
typename
T
,
typename
Place
>
class
PODDeleter
{
static_assert
(
std
::
is_pod
<
T
>::
value
,
"T must be POD"
);
public:
PODDeleter
(
Place
place
)
:
place_
(
place
)
{}
void
operator
()(
T
*
ptr
)
{
Free
(
place_
,
static_cast
<
void
*>
(
ptr
));
}
...
...
paddle/operators/add_op.cc
浏览文件 @
7829bdbd
...
...
@@ -13,17 +13,14 @@ See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/operators/add_op.h"
#include "paddle/framework/op_registry.h"
#include "paddle/framework/tensor.h"
namespace
paddle
{
namespace
operators
{
class
AddOp
:
public
framework
::
OperatorWithKernel
{
class
AddOp
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{
PADDLE_ENFORCE
(
inputs
.
size
()
==
2
,
"Input size of AddOp must be two"
);
PADDLE_ENFORCE
(
outputs
.
size
()
==
1
,
"Output size of AddOp must be one"
);
PADDLE_ENFORCE
(
...
...
@@ -35,10 +32,10 @@ protected:
}
};
class
AddOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
class
AddOpMaker
:
public
OpProtoAndCheckerMaker
{
public:
AddOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
:
framework
::
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"X"
,
"The first input of add op"
);
AddInput
(
"Y"
,
"The second input of add op"
);
AddOutput
(
"Out"
,
"The output of add op"
);
...
...
@@ -50,11 +47,10 @@ The equation is: Out = X + Y
}
};
class
AddOpGrad
:
public
framework
::
OperatorWithKernel
{
class
AddOpGrad
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{}
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{}
std
::
string
DebugString
()
const
override
{
LOG
(
INFO
)
<<
"AddOpGrad"
;
return
""
;
...
...
@@ -64,7 +60,6 @@ protected:
}
// namespace operators
}
// namespace paddle
REGISTER_OP
(
add_two
,
paddle
::
operators
::
AddOp
,
paddle
::
operators
::
AddOpMaker
);
REGISTER_GRADIENT_OP
(
add_two
,
add_two_grad
,
paddle
::
operators
::
AddOpGrad
);
REGISTER_OP_CPU_KERNEL
(
add_two
,
paddle
::
operators
::
AddKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_OP
(
add_two
,
ops
::
AddOp
,
ops
::
AddOpMaker
);
REGISTER_GRADIENT_OP
(
add_two
,
add_two_grad
,
ops
::
AddOpGrad
);
REGISTER_OP_CPU_KERNEL
(
add_two
,
ops
::
AddKernel
<
ops
::
CPUPlace
,
float
>
);
paddle/operators/add_op.cu
浏览文件 @
7829bdbd
#include "paddle/operators/add_op.h"
#include "paddle/framework/op_registry.h"
#include "paddle/operators/add_op.h"
REGISTER_OP_GPU_KERNEL
(
add_two
,
paddle
::
operators
::
AddKernel
<
paddle
::
platform
::
GPUPlace
,
float
>
);
\ No newline at end of file
REGISTER_OP_GPU_KERNEL
(
add_two
,
ops
::
AddKernel
<
ops
::
GPUPlace
,
float
>
);
paddle/operators/add_op.h
浏览文件 @
7829bdbd
...
...
@@ -13,27 +13,24 @@ See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include "glog/logging.h"
#include "paddle/framework/eigen.h"
#include "paddle/framework/operator.h"
#include "paddle/operators/type_alias.h"
namespace
paddle
{
namespace
operators
{
template
<
typename
Place
,
typename
T
>
class
AddKernel
:
public
framework
::
OpKernel
{
class
AddKernel
:
public
OpKernel
{
public:
void
Compute
(
const
framework
::
KernelContext
&
context
)
const
override
{
auto
input0
=
context
.
Input
(
0
)
->
Get
<
framework
::
Tensor
>
();
auto
input1
=
context
.
Input
(
1
)
->
Get
<
framework
::
Tensor
>
();
auto
*
output
=
context
.
Output
(
0
)
->
GetMutable
<
framework
::
Tensor
>
();
void
Compute
(
const
KernelContext
&
context
)
const
override
{
auto
input0
=
context
.
Input
(
0
)
->
Get
<
Tensor
>
();
auto
input1
=
context
.
Input
(
1
)
->
Get
<
Tensor
>
();
auto
output
=
context
.
Output
(
0
)
->
GetMutable
<
Tensor
>
();
output
->
mutable_data
<
T
>
(
context
.
GetPlace
());
framework
::
EigenVector
<
T
>::
Flatten
(
*
output
).
device
(
EigenVector
<
T
>::
Flatten
(
*
output
).
device
(
*
(
context
.
GetEigenDevice
<
Place
>
()))
=
framework
::
EigenVector
<
T
>::
Flatten
(
input0
)
+
framework
::
EigenVector
<
T
>::
Flatten
(
input1
);
EigenVector
<
T
>::
Flatten
(
input0
)
+
EigenVector
<
T
>::
Flatten
(
input1
);
}
};
...
...
paddle/operators/cross_entropy_op.cc
浏览文件 @
7829bdbd
...
...
@@ -13,17 +13,14 @@ See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/operators/cross_entropy_op.h"
#include "paddle/framework/op_registry.h"
#include "paddle/framework/tensor.h"
namespace
paddle
{
namespace
operators
{
class
OnehotCrossEntropyOp
:
public
framework
::
OperatorWithKernel
{
class
OnehotCrossEntropyOp
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{
PADDLE_ENFORCE
(
inputs
.
size
()
==
2
,
"Input size of OnehotCrossEntropyOp must be two"
);
PADDLE_ENFORCE
(
outputs
.
size
()
==
1
,
...
...
@@ -35,15 +32,14 @@ protected:
PADDLE_ENFORCE
(
inputs
[
0
]
->
dims
().
size
()
==
2
,
"X's dimension must be 2."
);
PADDLE_ENFORCE
(
outputs
[
0
]
->
dims
().
size
()
==
1
,
"label's dimension must be 1."
);
outputs
[
0
]
->
Resize
(
framework
::
make_ddim
({
inputs
[
0
]
->
dims
()[
0
]})
);
outputs
[
0
]
->
Resize
(
{
inputs
[
0
]
->
dims
()[
0
]}
);
}
};
class
OnehotCrossEntropyOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
class
OnehotCrossEntropyOpMaker
:
public
OpProtoAndCheckerMaker
{
public:
OnehotCrossEntropyOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
:
framework
::
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
OnehotCrossEntropyOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"X"
,
"The first input of OnehotCrossEntropyOp"
);
AddInput
(
"label"
,
"The second input of OnehotCrossEntropyOp"
);
AddOutput
(
"Y"
,
"The output of OnehotCrossEntropyOp"
);
...
...
@@ -59,9 +55,7 @@ OnehotCrossEntropy Operator.
}
// namespace paddle
REGISTER_OP
(
onehot_cross_entropy
,
paddle
::
operators
::
OnehotCrossEntropyOp
,
paddle
::
operators
::
OnehotCrossEntropyOpMaker
);
REGISTER_OP_CPU_KERNEL
(
onehot_cross_entropy
,
paddle
::
operators
::
OnehotCrossEntropyOpKernel
<::
paddle
::
platform
::
CPUPlace
,
float
>
);
ops
::
OnehotCrossEntropyOp
,
ops
::
OnehotCrossEntropyOpMaker
);
REGISTER_OP_CPU_KERNEL
(
onehot_cross_entropy
,
ops
::
OnehotCrossEntropyOpKernel
<
ops
::
CPUPlace
,
float
>
);
paddle/operators/cross_entropy_op.cu
浏览文件 @
7829bdbd
#include "paddle/operators/cross_entropy_op.h"
#include "paddle/framework/op_registry.h"
REGISTER_OP_GPU_KERNEL
(
onehot_cross_entropy
,
paddle
::
operators
::
OnehotCrossEntropyOpKernel
<
::
paddle
::
platform
::
GPUPlace
,
float
>
);
\ No newline at end of file
ops
::
OnehotCrossEntropyOpKernel
<
ops
::
GPUPlace
,
float
>
);
\ No newline at end of file
paddle/operators/cross_entropy_op.h
浏览文件 @
7829bdbd
...
...
@@ -13,23 +13,21 @@ See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include "glog/logging.h"
#include "paddle/framework/operator.h"
#include "paddle/operators/type_alias.h"
namespace
paddle
{
namespace
operators
{
template
<
typename
Place
,
typename
T
>
class
OnehotCrossEntropyOpKernel
:
public
framework
::
OpKernel
{
class
OnehotCrossEntropyOpKernel
:
public
OpKernel
{
public:
constexpr
T
LOG_THRESHOLD
()
const
{
return
static_cast
<
T
>
(
1e-20
);
}
void
Compute
(
const
framework
::
KernelContext
&
context
)
const
override
{
auto
X
=
context
.
Input
(
0
)
->
Get
<
framework
::
Tensor
>
();
void
Compute
(
const
KernelContext
&
context
)
const
override
{
auto
X
=
context
.
Input
(
0
)
->
Get
<
Tensor
>
();
const
T
*
X_data
=
X
.
data
<
T
>
();
const
int
*
label_data
=
context
.
Input
(
1
)
->
Get
<
framework
::
Tensor
>
().
data
<
int
>
();
auto
*
Y
=
context
.
Output
(
0
)
->
GetMutable
<
framework
::
Tensor
>
();
const
int
*
label_data
=
context
.
Input
(
1
)
->
Get
<
Tensor
>
().
data
<
int
>
();
auto
*
Y
=
context
.
Output
(
0
)
->
GetMutable
<
Tensor
>
();
Y
->
mutable_data
<
T
>
(
context
.
GetPlace
());
...
...
paddle/operators/fc_op.cc
浏览文件 @
7829bdbd
...
...
@@ -12,41 +12,38 @@
See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/framework/net.h"
#include "paddle/framework/op_registry.h"
#include "paddle/framework/operator.h"
#include "type_alias.h"
namespace
paddle
{
namespace
operators
{
class
FullyConnectedOp
:
public
framework
::
PlainNet
{
class
FullyConnectedOp
:
public
NetOp
{
public:
void
Init
()
override
{
AddOp
(
framework
::
OpRegistry
::
CreateOp
(
"mul"
,
{
Input
(
"X"
),
Input
(
"W"
),
},
{
Output
(
"before_act"
)},
{}));
AddOp
(
OpRegistry
::
CreateOp
(
"mul"
,
{
Input
(
"X"
),
Input
(
"W"
),
},
{
Output
(
"before_act"
)},
{}));
auto
b
=
Input
(
"b"
);
if
(
b
!=
framework
::
OperatorBase
::
EMPTY_VAR_NAME
())
{
AddOp
(
framework
::
OpRegistry
::
CreateOp
(
"rowwise_add"
,
{
Output
(
"before_act"
),
Input
(
"b"
)},
{
Output
(
"before_act"
)},
{}));
if
(
b
!=
EMPTY_VAR_NAME
())
{
AddOp
(
OpRegistry
::
CreateOp
(
"rowwise_add"
,
{
Output
(
"before_act"
),
Input
(
"b"
)},
{
Output
(
"before_act"
)},
{}));
}
auto
activation
=
GetAttr
<
std
::
string
>
(
"activation"
);
AddOp
(
framework
::
OpRegistry
::
CreateOp
(
AddOp
(
OpRegistry
::
CreateOp
(
activation
,
{
Output
(
"before_act"
)},
{
Output
(
"Y"
)},
{}));
CompleteAddOp
(
false
);
}
};
class
FullyConnectedOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
class
FullyConnectedOpMaker
:
public
OpProtoAndCheckerMaker
{
public:
FullyConnectedOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
FullyConnectedOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"X"
,
"the input of fc operator"
);
AddInput
(
"W"
,
"the weight of fc operator"
);
...
...
@@ -71,6 +68,4 @@ USE_OP(rowwise_add);
USE_OP
(
sigmoid
);
USE_OP
(
softmax
);
REGISTER_OP
(
fc
,
paddle
::
operators
::
FullyConnectedOp
,
paddle
::
operators
::
FullyConnectedOpMaker
);
REGISTER_OP
(
fc
,
ops
::
FullyConnectedOp
,
ops
::
FullyConnectedOpMaker
);
paddle/operators/mul_op.cc
浏览文件 @
7829bdbd
...
...
@@ -13,17 +13,14 @@
limitations under the License. */
#include "paddle/operators/mul_op.h"
#include "paddle/framework/op_registry.h"
#include "paddle/framework/tensor.h"
namespace
paddle
{
namespace
operators
{
class
MulOp
:
public
framework
::
OperatorWithKernel
{
class
MulOp
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{
PADDLE_ENFORCE
(
inputs
.
size
()
==
2
,
"The mul op must take two inputs"
);
auto
dim0
=
inputs
[
0
]
->
dims
();
auto
dim1
=
inputs
[
1
]
->
dims
();
...
...
@@ -37,10 +34,10 @@ protected:
}
};
class
MulOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
class
MulOpMaker
:
public
OpProtoAndCheckerMaker
{
public:
MulOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
:
framework
::
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
MulOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"X"
,
"The first input of mul op"
);
AddInput
(
"Y"
,
"The second input of mul op"
);
AddOutput
(
"Out"
,
"The output of mul op"
);
...
...
@@ -52,11 +49,10 @@ The equation is: Out = X * Y
}
};
class
MulOpGrad
:
public
framework
::
OperatorWithKernel
{
class
MulOpGrad
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{}
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{}
std
::
string
DebugString
()
const
override
{
LOG
(
INFO
)
<<
"MulGrad"
;
return
""
;
...
...
@@ -66,8 +62,7 @@ protected:
}
// namespace operators
}
// namespace paddle
REGISTER_OP
(
mul
,
paddle
::
operators
::
MulOp
,
paddle
::
operator
s
::
MulOpMaker
);
REGISTER_GRADIENT_OP
(
mul
,
mul_grad
,
paddle
::
operator
s
::
MulOpGrad
);
REGISTER_OP
(
mul
,
ops
::
MulOp
,
op
s
::
MulOpMaker
);
REGISTER_GRADIENT_OP
(
mul
,
mul_grad
,
op
s
::
MulOpGrad
);
REGISTER_OP_CPU_KERNEL
(
mul
,
paddle
::
operators
::
MulKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_OP_CPU_KERNEL
(
mul
,
ops
::
MulKernel
<
ops
::
CPUPlace
,
float
>
);
paddle/operators/mul_op.cu
浏览文件 @
7829bdbd
...
...
@@ -13,8 +13,5 @@
limitations under the License. */
#include "paddle/operators/mul_op.h"
#include "paddle/framework/op_registry.h"
REGISTER_OP_GPU_KERNEL
(
mul
,
paddle
::
operators
::
MulKernel
<
paddle
::
platform
::
GPUPlace
,
float
>
);
\ No newline at end of file
REGISTER_OP_GPU_KERNEL
(
mul
,
ops
::
MulKernel
<
ops
::
GPUPlace
,
float
>
);
\ No newline at end of file
paddle/operators/mul_op.h
浏览文件 @
7829bdbd
...
...
@@ -14,30 +14,27 @@
#pragma once
#include "glog/logging.h"
#include "paddle/framework/eigen.h"
#include "paddle/framework/operator.h"
#include "paddle/operators/type_alias.h"
namespace
paddle
{
namespace
operators
{
template
<
typename
Place
,
typename
T
>
class
MulKernel
:
public
framework
::
OpKernel
{
class
MulKernel
:
public
OpKernel
{
public:
void
Compute
(
const
framework
::
KernelContext
&
context
)
const
override
{
void
Compute
(
const
KernelContext
&
context
)
const
override
{
Eigen
::
array
<
Eigen
::
IndexPair
<
Eigen
::
DenseIndex
>
,
1
>
dim_pair
=
{
{
Eigen
::
IndexPair
<
Eigen
::
DenseIndex
>
(
1
,
0
)}};
auto
input0
=
context
.
Input
(
0
)
->
Get
<
framework
::
Tensor
>
();
auto
input1
=
context
.
Input
(
1
)
->
Get
<
framework
::
Tensor
>
();
auto
*
output
=
context
.
Output
(
0
)
->
GetMutable
<
framework
::
Tensor
>
();
auto
input0
=
context
.
Input
(
0
)
->
Get
<
Tensor
>
();
auto
input1
=
context
.
Input
(
1
)
->
Get
<
Tensor
>
();
auto
*
output
=
context
.
Output
(
0
)
->
GetMutable
<
Tensor
>
();
output
->
mutable_data
<
T
>
(
context
.
GetPlace
());
framework
::
EigenMatrix
<
T
>::
From
(
*
output
).
device
(
*
(
context
.
GetEigenDevice
<
Place
>
()))
=
framework
::
EigenMatrix
<
T
>::
From
(
input0
).
contract
(
framework
::
EigenMatrix
<
T
>::
From
(
input1
),
dim_pair
);
EigenMatrix
<
T
>::
From
(
*
output
).
device
(
*
(
context
.
GetEigenDevice
<
Place
>
()))
=
EigenMatrix
<
T
>::
From
(
input0
).
contract
(
EigenMatrix
<
T
>::
From
(
input1
),
dim_pair
);
}
};
}
// namespace operators
...
...
paddle/operators/rowwise_add_op.cc
浏览文件 @
7829bdbd
...
...
@@ -13,15 +13,13 @@
limitations under the License. */
#include "paddle/operators/rowwise_add_op.h"
#include "paddle/framework/op_registry.h"
namespace
paddle
{
namespace
operators
{
class
RowWiseAddOp
:
public
framework
::
OperatorWithKernel
{
class
RowWiseAddOp
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{
PADDLE_ENFORCE
(
inputs
.
size
()
==
2UL
,
"Two inputs is needed by rowwise add"
);
auto
dim0
=
inputs
[
0
]
->
dims
();
auto
dim1
=
inputs
[
1
]
->
dims
();
...
...
@@ -34,11 +32,10 @@ protected:
}
};
class
RowWiseAddOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
class
RowWiseAddOpMaker
:
public
OpProtoAndCheckerMaker
{
public:
RowWiseAddOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
:
framework
::
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
RowWiseAddOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"X"
,
"The left input of row-wise add op, must be matrix"
);
AddInput
(
"b"
,
"The right input of row-wise add op, must be vector"
);
AddOutput
(
"Out"
,
"The output of row-wise add op"
);
...
...
@@ -53,9 +50,6 @@ for i in xrange(X.shape[0]):
}
// namespace operators
}
// namespace paddle
REGISTER_OP
(
rowwise_add
,
paddle
::
operators
::
RowWiseAddOp
,
paddle
::
operators
::
RowWiseAddOpMaker
);
REGISTER_OP_CPU_KERNEL
(
rowwise_add
,
paddle
::
operators
::
RowWiseAddKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_OP
(
rowwise_add
,
ops
::
RowWiseAddOp
,
ops
::
RowWiseAddOpMaker
);
REGISTER_OP_CPU_KERNEL
(
rowwise_add
,
ops
::
RowWiseAddKernel
<
ops
::
CPUPlace
,
float
>
);
paddle/operators/rowwise_add_op.cu
浏览文件 @
7829bdbd
#include "paddle/framework/op_registry.h"
#include "paddle/operators/rowwise_add_op.h"
REGISTER_OP_GPU_KERNEL
(
rowwise_add
,
paddle
::
operators
::
RowWiseAddKernel
<
paddle
::
platform
::
GPUPlace
,
float
>
);
REGISTER_OP_GPU_KERNEL
(
rowwise_add
,
ops
::
RowWiseAddKernel
<
ops
::
GPUPlace
,
float
>
);
paddle/operators/rowwise_add_op.h
浏览文件 @
7829bdbd
...
...
@@ -13,25 +13,23 @@
limitations under the License. */
#pragma once
#include "glog/logging.h"
#include "paddle/framework/eigen.h"
#include "paddle/framework/operator.h"
#include "paddle/operators/type_alias.h"
namespace
paddle
{
namespace
operators
{
template
<
typename
Place
,
typename
T
>
class
RowWiseAddKernel
:
public
framework
::
OpKernel
{
class
RowWiseAddKernel
:
public
OpKernel
{
public:
void
Compute
(
const
framework
::
KernelContext
&
context
)
const
override
{
auto
in0
=
context
.
Input
(
0
)
->
Get
<
framework
::
Tensor
>
();
auto
in1
=
context
.
Input
(
1
)
->
Get
<
framework
::
Tensor
>
();
auto
*
out
=
context
.
Output
(
0
)
->
GetMutable
<
framework
::
Tensor
>
();
void
Compute
(
const
KernelContext
&
context
)
const
override
{
auto
in0
=
context
.
Input
(
0
)
->
Get
<
Tensor
>
();
auto
in1
=
context
.
Input
(
1
)
->
Get
<
Tensor
>
();
auto
*
out
=
context
.
Output
(
0
)
->
GetMutable
<
Tensor
>
();
out
->
mutable_data
<
T
>
(
context
.
GetPlace
());
auto
input
=
framework
::
EigenMatrix
<
T
>::
From
(
in0
);
auto
bias
=
framework
::
EigenVector
<
T
>::
From
(
in1
);
auto
output
=
framework
::
EigenMatrix
<
T
>::
From
(
*
out
);
auto
input
=
EigenMatrix
<
T
>::
From
(
in0
);
auto
bias
=
EigenVector
<
T
>::
From
(
in1
);
auto
output
=
EigenMatrix
<
T
>::
From
(
*
out
);
const
int
bias_size
=
bias
.
dimension
(
0
);
const
int
rest_size
=
input
.
size
()
/
bias_size
;
...
...
paddle/operators/sgd_op.cc
浏览文件 @
7829bdbd
...
...
@@ -13,17 +13,14 @@ See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/operators/sgd_op.h"
#include "paddle/framework/op_registry.h"
#include "paddle/framework/tensor.h"
namespace
paddle
{
namespace
operators
{
class
SGDOp
:
public
framework
::
OperatorWithKernel
{
class
SGDOp
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{
PADDLE_ENFORCE
(
inputs
.
size
()
==
2
,
"Input size of SGDOp must be two"
);
PADDLE_ENFORCE
(
outputs
.
size
()
==
1
,
"Output size of SGDOp must be one"
);
PADDLE_ENFORCE
(
inputs
[
0
]
!=
nullptr
,
"inputs[0] mast be set"
);
...
...
@@ -35,10 +32,10 @@ protected:
}
};
class
SGDOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
class
SGDOpMaker
:
public
OpProtoAndCheckerMaker
{
public:
SGDOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
:
framework
::
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
SGDOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"param"
,
"input parameter"
);
AddInput
(
"grad"
,
"input gradient"
);
AddOutput
(
"param_out"
,
"output parameter"
);
...
...
@@ -55,7 +52,5 @@ param_out = param - learning_rate * grad;
}
// namespace operators
}
// namespace paddle
REGISTER_OP
(
sgd
,
paddle
::
operators
::
SGDOp
,
paddle
::
operators
::
SGDOpMaker
);
typedef
paddle
::
operators
::
SGDOpKernel
<::
paddle
::
platform
::
CPUPlace
,
float
>
SGDOpKernel_CPU_float
;
REGISTER_OP_CPU_KERNEL
(
sgd
,
SGDOpKernel_CPU_float
);
REGISTER_OP
(
sgd
,
ops
::
SGDOp
,
ops
::
SGDOpMaker
);
REGISTER_OP_CPU_KERNEL
(
sgd
,
ops
::
SGDOpKernel
<
ops
::
CPUPlace
,
float
>
);
paddle/operators/sgd_op.cu
浏览文件 @
7829bdbd
#include "paddle/operators/sgd_op.h"
#include "paddle/framework/op_registry.h"
typedef
paddle
::
operators
::
SGDOpKernel
<::
paddle
::
platform
::
GPUPlace
,
float
>
SGDOpKernel_GPU_float
;
REGISTER_OP_GPU_KERNEL
(
sgd
,
SGDOpKernel_GPU_float
);
\ No newline at end of file
REGISTER_OP_GPU_KERNEL
(
sgd
,
ops
::
SGDOpKernel
<
ops
::
GPUPlace
,
float
>
);
\ No newline at end of file
paddle/operators/sgd_op.h
浏览文件 @
7829bdbd
...
...
@@ -13,28 +13,24 @@ See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include "glog/logging.h"
#include "paddle/framework/eigen.h"
#include "paddle/framework/operator.h"
#include "paddle/operators/type_alias.h"
namespace
paddle
{
namespace
operators
{
template
<
typename
Place
,
typename
T
>
class
SGDOpKernel
:
public
framework
::
OpKernel
{
class
SGDOpKernel
:
public
OpKernel
{
public:
void
Compute
(
const
framework
::
KernelContext
&
ctx
)
const
override
{
auto
param
=
ctx
.
Input
(
"param"
)
->
Get
<
framework
::
Tensor
>
();
auto
grad
=
ctx
.
Input
(
"grad"
)
->
Get
<
framework
::
Tensor
>
();
auto
*
param_out
=
ctx
.
Output
(
0
)
->
GetMutable
<
framework
::
Tensor
>
();
void
Compute
(
const
KernelContext
&
ctx
)
const
override
{
auto
param
=
ctx
.
Input
(
"param"
)
->
Get
<
Tensor
>
();
auto
grad
=
ctx
.
Input
(
"grad"
)
->
Get
<
Tensor
>
();
auto
*
param_out
=
ctx
.
Output
(
0
)
->
GetMutable
<
Tensor
>
();
float
lr
=
ctx
.
op_
.
GetAttr
<
float
>
(
"learning_rate"
);
param_out
->
mutable_data
<
T
>
(
ctx
.
GetPlace
());
framework
::
EigenVector
<
T
>::
Flatten
(
*
param_out
)
.
device
(
*
(
ctx
.
GetEigenDevice
<
Place
>
()))
=
framework
::
EigenVector
<
T
>::
Flatten
(
param
)
-
lr
*
framework
::
EigenVector
<
T
>::
Flatten
(
grad
);
EigenVector
<
T
>::
Flatten
(
*
param_out
).
device
(
*
(
ctx
.
GetEigenDevice
<
Place
>
()))
=
EigenVector
<
T
>::
Flatten
(
param
)
-
lr
*
EigenVector
<
T
>::
Flatten
(
grad
);
}
};
...
...
paddle/operators/sigmoid_op.cc
浏览文件 @
7829bdbd
...
...
@@ -13,37 +13,33 @@
limitations under the License. */
#include "paddle/operators/sigmoid_op.h"
#include "paddle/framework/op_registry.h"
namespace
paddle
{
namespace
operators
{
class
SigmoidOp
:
public
framework
::
OperatorWithKernel
{
class
SigmoidOp
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{
PADDLE_ENFORCE
(
inputs
.
size
()
==
1
,
"Sigmoid Op only have one input"
);
PADDLE_ENFORCE
(
outputs
.
size
()
==
1
,
"Sigmoid Op only have one output"
);
outputs
[
0
]
->
Resize
(
inputs
[
0
]
->
dims
());
}
};
class
SigmoidOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
class
SigmoidOpMaker
:
public
OpProtoAndCheckerMaker
{
public:
SigmoidOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
:
framework
::
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
SigmoidOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"X"
,
"sigmoid input"
);
AddOutput
(
"Y"
,
"sigmoid output"
);
AddComment
(
"Sigmoid function"
);
}
};
class
SigmoidOpGrad
:
public
framework
::
OperatorWithKernel
{
class
SigmoidOpGrad
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{}
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{}
std
::
string
DebugString
()
const
override
{
LOG
(
INFO
)
<<
"SigmoidGrad"
;
return
""
;
...
...
@@ -53,11 +49,7 @@ protected:
}
// namespace operators
}
// namespace paddle
REGISTER_OP
(
sigmoid
,
paddle
::
operators
::
SigmoidOp
,
paddle
::
operators
::
SigmoidOpMaker
);
REGISTER_GRADIENT_OP
(
sigmoid
,
sigmoid_grad
,
paddle
::
operators
::
SigmoidOpGrad
);
REGISTER_OP
(
sigmoid
,
ops
::
SigmoidOp
,
ops
::
SigmoidOpMaker
);
REGISTER_GRADIENT_OP
(
sigmoid
,
sigmoid_grad
,
ops
::
SigmoidOpGrad
);
REGISTER_OP_CPU_KERNEL
(
sigmoid
,
paddle
::
operators
::
SigmoidKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_OP_CPU_KERNEL
(
sigmoid
,
ops
::
SigmoidKernel
<
ops
::
CPUPlace
,
float
>
);
paddle/operators/sigmoid_op.cu
浏览文件 @
7829bdbd
#include "paddle/operators/sigmoid_op.h"
#include "paddle/framework/op_registry.h"
REGISTER_OP_GPU_KERNEL
(
sigmoid
,
paddle
::
operators
::
SigmoidKernel
<
paddle
::
platform
::
GPUPlace
,
float
>
);
REGISTER_OP_GPU_KERNEL
(
sigmoid
,
ops
::
SigmoidKernel
<
ops
::
GPUPlace
,
float
>
);
paddle/operators/sigmoid_op.h
浏览文件 @
7829bdbd
...
...
@@ -14,25 +14,23 @@
#pragma once
#include "glog/logging.h"
#include "paddle/framework/eigen.h"
#include "paddle/framework/operator.h"
#include "paddle/operators/type_alias.h"
namespace
paddle
{
namespace
operators
{
template
<
typename
Place
,
typename
T
>
class
SigmoidKernel
:
public
framework
::
OpKernel
{
class
SigmoidKernel
:
public
OpKernel
{
public:
void
Compute
(
const
framework
::
KernelContext
&
context
)
const
override
{
auto
input
=
context
.
Input
(
0
)
->
Get
<
framework
::
Tensor
>
();
auto
*
output
=
context
.
Output
(
0
)
->
GetMutable
<
framework
::
Tensor
>
();
void
Compute
(
const
KernelContext
&
context
)
const
override
{
auto
input
=
context
.
Input
(
0
)
->
Get
<
Tensor
>
();
auto
*
output
=
context
.
Output
(
0
)
->
GetMutable
<
Tensor
>
();
output
->
mutable_data
<
T
>
(
context
.
GetPlace
());
framework
::
EigenVector
<
T
>::
Flatten
(
*
output
).
device
(
EigenVector
<
T
>::
Flatten
(
*
output
).
device
(
*
(
context
.
GetEigenDevice
<
Place
>
()))
=
1.0
/
(
1.0
+
(
-
1.0
*
framework
::
EigenVector
<
T
>::
Flatten
(
input
)).
exp
());
1.0
/
(
1.0
+
(
-
1.0
*
EigenVector
<
T
>::
Flatten
(
input
)).
exp
());
}
};
}
// namespace operators
...
...
paddle/operators/softmax_op.cc
浏览文件 @
7829bdbd
...
...
@@ -12,16 +12,14 @@
See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/operators/softmax_op.h"
#include "paddle/framework/op_registry.h"
namespace
paddle
{
namespace
operators
{
class
SoftmaxOp
:
public
framework
::
OperatorWithKernel
{
class
SoftmaxOp
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{
PADDLE_ENFORCE
(
inputs
.
size
()
==
1
,
"Only one input is need for softmax"
);
PADDLE_ENFORCE
(
inputs
[
0
]
->
dims
().
size
()
==
2
,
"The input of softmax op must be matrix"
);
...
...
@@ -31,10 +29,9 @@ protected:
}
};
class
SoftmaxOpMaker
:
public
framework
::
OpProtoAndCheckerMaker
{
class
SoftmaxOpMaker
:
public
OpProtoAndCheckerMaker
{
public:
SoftmaxOpMaker
(
framework
::
OpProto
*
proto
,
framework
::
OpAttrChecker
*
op_checker
)
SoftmaxOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"X"
,
"input of softmax"
);
AddOutput
(
"Y"
,
"output of softmax"
);
...
...
@@ -42,11 +39,10 @@ public:
}
};
class
SoftmaxOpGrad
:
public
framework
::
OperatorWithKernel
{
class
SoftmaxOpGrad
:
public
OperatorWithKernel
{
protected:
void
InferShape
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
)
const
override
{}
void
InferShape
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
)
const
override
{}
std
::
string
DebugString
()
const
override
{
LOG
(
INFO
)
<<
"SoftmaxOpGrad"
;
return
""
;
...
...
@@ -56,9 +52,6 @@ protected:
}
// namespace operators
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
REGISTER_OP
(
softmax
,
ops
::
SoftmaxOp
,
ops
::
SoftmaxOpMaker
);
REGISTER_GRADIENT_OP
(
softmax
,
softmax_grad
,
paddle
::
operators
::
SoftmaxOpGrad
);
REGISTER_OP_CPU_KERNEL
(
softmax
,
ops
::
SoftmaxKernel
<
paddle
::
platform
::
CPUPlace
,
float
>
);
REGISTER_GRADIENT_OP
(
softmax
,
softmax_grad
,
ops
::
SoftmaxOpGrad
);
REGISTER_OP_CPU_KERNEL
(
softmax
,
ops
::
SoftmaxKernel
<
ops
::
CPUPlace
,
float
>
);
paddle/operators/softmax_op.cu
浏览文件 @
7829bdbd
#include "paddle/framework/op_registry.h"
#include "paddle/operators/softmax_op.h"
REGISTER_OP_GPU_KERNEL
(
softmax
,
paddle
::
operators
::
SoftmaxKernel
<
paddle
::
platform
::
GPUPlace
,
float
>
);
REGISTER_OP_GPU_KERNEL
(
softmax
,
ops
::
SoftmaxKernel
<
ops
::
GPUPlace
,
float
>
);
paddle/operators/softmax_op.h
浏览文件 @
7829bdbd
...
...
@@ -14,23 +14,21 @@
#pragma once
#include "glog/logging.h"
#include "paddle/framework/eigen.h"
#include "paddle/framework/operator.h"
#include "paddle/operators/type_alias.h"
namespace
paddle
{
namespace
operators
{
template
<
typename
Place
,
typename
T
>
class
SoftmaxKernel
:
public
framework
::
OpKernel
{
class
SoftmaxKernel
:
public
OpKernel
{
public:
void
Compute
(
const
framework
::
KernelContext
&
context
)
const
override
{
auto
input
=
context
.
Input
(
0
)
->
Get
<
framework
::
Tensor
>
();
auto
*
output
=
context
.
Output
(
0
)
->
GetMutable
<
framework
::
Tensor
>
();
void
Compute
(
const
KernelContext
&
context
)
const
override
{
auto
input
=
context
.
Input
(
0
)
->
Get
<
Tensor
>
();
auto
*
output
=
context
.
Output
(
0
)
->
GetMutable
<
Tensor
>
();
output
->
mutable_data
<
T
>
(
context
.
GetPlace
());
auto
logits
=
framework
::
EigenMatrix
<
T
>::
From
(
input
);
auto
softmax
=
framework
::
EigenMatrix
<
T
>::
From
(
*
output
);
auto
logits
=
EigenMatrix
<
T
>::
From
(
input
);
auto
softmax
=
EigenMatrix
<
T
>::
From
(
*
output
);
const
int
kBatchDim
=
0
;
const
int
kClassDim
=
1
;
...
...
paddle/operators/type_alias.h
0 → 100644
浏览文件 @
7829bdbd
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
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. */
#pragma once
#include "paddle/framework/eigen.h"
#include "paddle/framework/net.h"
#include "paddle/framework/op_registry.h"
namespace
paddle
{
namespace
operators
{
using
OpKernel
=
framework
::
OpKernel
;
using
KernelContext
=
framework
::
KernelContext
;
template
<
typename
T
,
int
MajorType
=
Eigen
::
RowMajor
,
typename
IndexType
=
Eigen
::
DenseIndex
>
using
EigenVector
=
framework
::
EigenVector
<
T
,
MajorType
,
IndexType
>
;
template
<
typename
T
,
int
MajorType
=
Eigen
::
RowMajor
,
typename
IndexType
=
Eigen
::
DenseIndex
>
using
EigenMatrix
=
framework
::
EigenMatrix
<
T
,
MajorType
,
IndexType
>
;
template
<
typename
T
,
size_t
D
,
int
MajorType
=
Eigen
::
RowMajor
,
typename
IndexType
=
Eigen
::
DenseIndex
>
using
EigenTensor
=
framework
::
EigenTensor
<
T
,
D
,
MajorType
,
IndexType
>
;
using
Tensor
=
framework
::
Tensor
;
using
OperatorWithKernel
=
framework
::
OperatorWithKernel
;
using
OpProtoAndCheckerMaker
=
framework
::
OpProtoAndCheckerMaker
;
using
OpProto
=
framework
::
OpProto
;
using
OpAttrChecker
=
framework
::
OpAttrChecker
;
using
CPUPlace
=
platform
::
CPUPlace
;
using
GPUPlace
=
platform
::
GPUPlace
;
using
NetOp
=
framework
::
NetOp
;
using
OpRegistry
=
framework
::
OpRegistry
;
}
// namespace operators
}
// namespace paddle
namespace
ops
=
paddle
::
operators
;
paddle/platform/enforce.h
浏览文件 @
7829bdbd
...
...
@@ -58,11 +58,6 @@ struct EnforceNotMet : public std::exception {
// For more details, please check https://stackoverflow.com/a/43870188/724872.
#define UNLIKELY(condition) __builtin_expect(static_cast<bool>(condition), 0)
template
<
typename
T
>
inline
void
throw_on_error
(
T
e
)
{
throw_on_error
(
e
,
""
);
}
template
<
typename
...
Args
>
inline
typename
std
::
enable_if
<
sizeof
...(
Args
)
!=
0
,
void
>::
type
throw_on_error
(
int
stat
,
const
Args
&
...
args
)
{
...
...
@@ -132,6 +127,11 @@ inline typename std::enable_if<sizeof...(Args) != 0, void>::type throw_on_error(
#endif // PADDLE_ONLY_CPU
template
<
typename
T
>
inline
void
throw_on_error
(
T
e
)
{
throw_on_error
(
e
,
""
);
}
#define PADDLE_THROW(...) \
do { \
throw ::paddle::platform::EnforceNotMet( \
...
...
paddle/pybind/pybind.cc
浏览文件 @
7829bdbd
...
...
@@ -146,22 +146,22 @@ All parameter, weight, gradient are variables in Paddle.
});
ExposeOperator
(
operator_base
);
using
PlainNetPtr
=
std
::
shared_ptr
<
pd
::
PlainNet
>
;
py
::
class_
<
pd
::
PlainNet
,
PlainNetPtr
>
net
(
m
,
"Net"
);
py
::
class_
<
pd
::
NetOp
,
std
::
shared_ptr
<
pd
::
NetOp
>>
net
(
m
,
"Net"
);
net
.
def_static
(
"create"
,
[]()
->
std
::
shared_ptr
<
pd
::
PlainNet
>
{
auto
retv
=
std
::
make_shared
<
pd
::
PlainNet
>
();
[]()
->
std
::
shared_ptr
<
pd
::
NetOp
>
{
auto
retv
=
std
::
make_shared
<
pd
::
NetOp
>
();
retv
->
type_
=
"plain_net"
;
return
retv
;
})
.
def
(
"add_op"
,
&
pd
::
PlainNet
::
AddOp
)
.
def
(
"add_op"
,
&
pd
::
NetOp
::
AddOp
)
.
def
(
"add_op"
,
[](
PlainNetPtr
&
self
,
const
PlainNetPtr
&
net
)
->
void
{
self
->
AddOp
(
std
::
static_pointer_cast
<
pd
::
OperatorBase
>
(
net
));
[](
pd
::
NetOp
&
self
,
const
std
::
shared_ptr
<
pd
::
NetOp
>
&
net
)
->
void
{
self
.
AddOp
(
std
::
static_pointer_cast
<
pd
::
OperatorBase
>
(
net
));
})
.
def
(
"complete_add_op"
,
&
pd
::
PlainNet
::
CompleteAddOp
)
.
def
(
"complete_add_op"
,
[](
PlainNetPtr
&
self
)
{
self
->
CompleteAddOp
();
});
.
def
(
"complete_add_op"
,
&
pd
::
NetOp
::
CompleteAddOp
)
.
def
(
"complete_add_op"
,
[](
std
::
shared_ptr
<
pd
::
NetOp
>&
self
)
{
self
->
CompleteAddOp
();
});
ExposeOperator
(
net
);
m
.
def
(
"unique_integer"
,
UniqueIntegerGenerator
);
...
...
python/paddle/trainer_config_helpers/attrs.py
浏览文件 @
7829bdbd
...
...
@@ -272,7 +272,7 @@ class ExtraLayerAttribute(object):
for
key
in
self
.
attr
:
if
not
hasattr
(
self
,
'can_%s'
%
key
)
or
\
not
getattr
(
self
,
'can_%s'
%
key
):
raise
NotImplementedError
(
"Layer %s
can
not support %s"
%
raise
NotImplementedError
(
"Layer %s
does
not support %s"
%
(
layer_name
,
key
))
@
staticmethod
...
...
python/paddle/trainer_config_helpers/layers.py
浏览文件 @
7829bdbd
...
...
@@ -865,7 +865,7 @@ def data_layer(name, size, height=None, width=None, layer_attr=None):
@
wrap_name_default
(
"embedding"
)
@
wrap_param_attr_default
()
@
layer_support
(
ERROR_CLIPPING
)
@
layer_support
(
ERROR_CLIPPING
,
DROPOUT
)
def
embedding_layer
(
input
,
size
,
name
=
None
,
param_attr
=
None
,
layer_attr
=
None
):
"""
Define a embedding Layer.
...
...
@@ -1320,7 +1320,7 @@ def pooling_layer(input,
@
wrap_act_default
(
param_names
=
[
'gate_act'
],
act
=
SigmoidActivation
())
@
wrap_act_default
(
param_names
=
[
"act"
,
'state_act'
],
act
=
TanhActivation
())
@
wrap_name_default
(
"lstmemory"
)
@
layer_support
(
DROPOUT
)
@
layer_support
()
def
lstmemory
(
input
,
name
=
None
,
size
=
None
,
...
...
@@ -1429,7 +1429,7 @@ def lstmemory(input,
@
wrap_act_default
(
param_names
=
[
'gate_act'
],
act
=
SigmoidActivation
())
@
wrap_act_default
(
param_names
=
[
"act"
],
act
=
TanhActivation
())
@
wrap_name_default
(
"gru"
)
@
layer_support
(
DROPOUT
)
@
layer_support
()
def
grumemory
(
input
,
size
=
None
,
name
=
None
,
...
...
@@ -1793,7 +1793,7 @@ def repeat_layer(input,
@
wrap_name_default
(
"seqreshape"
)
@
wrap_act_default
(
act
=
IdentityActivation
())
@
wrap_bias_attr_default
(
has_bias
=
False
)
@
layer_support
()
@
layer_support
(
ERROR_CLIPPING
,
DROPOUT
)
def
seq_reshape_layer
(
input
,
reshape_size
,
act
=
None
,
...
...
@@ -2703,7 +2703,7 @@ def img_cmrnorm_layer(input,
default_factory
=
lambda
_
:
ParamAttr
(
initial_mean
=
1.0
,
initial_std
=
0.
))
@
wrap_act_default
(
act
=
ReluActivation
())
@
wrap_name_default
(
"batch_norm"
)
@
layer_support
(
DROPOUT
)
@
layer_support
(
DROPOUT
,
ERROR_CLIPPING
)
def
batch_norm_layer
(
input
,
act
=
None
,
name
=
None
,
...
...
@@ -2783,15 +2783,6 @@ def batch_norm_layer(input,
:return: LayerOutput object.
:rtype: LayerOutput
"""
if
not
isinstance
(
act
,
ReluActivation
):
logger
.
log
(
logging
.
WARN
,
"%s is not recommend for batch normalization's activation, "
"maybe the relu is better"
%
act
.
name
)
if
not
isinstance
(
input
.
activation
,
LinearActivation
):
logger
.
log
(
logging
.
WARN
,
"The activation should be inside batch normalization, the "
"previous layer's activation may be Linear"
)
if
num_channels
is
None
:
if
input
.
num_filters
is
not
None
:
...
...
@@ -2861,7 +2852,7 @@ def sum_to_one_norm_layer(input, name=None, layer_attr=None):
@
wrap_name_default
(
"addto"
)
@
wrap_act_default
(
act
=
LinearActivation
())
@
wrap_bias_attr_default
(
has_bias
=
False
)
@
layer_support
(
DROPOUT
)
@
layer_support
(
DROPOUT
,
ERROR_CLIPPING
)
def
addto_layer
(
input
,
act
=
None
,
name
=
None
,
bias_attr
=
None
,
layer_attr
=
None
):
"""
AddtoLayer.
...
...
@@ -2940,7 +2931,7 @@ def addto_layer(input, act=None, name=None, bias_attr=None, layer_attr=None):
@
wrap_act_default
(
act
=
IdentityActivation
())
@
wrap_name_default
(
"concat"
)
@
layer_support
()
@
layer_support
(
DROPOUT
,
ERROR_CLIPPING
)
def
concat_layer
(
input
,
act
=
None
,
name
=
None
,
layer_attr
=
None
,
bias_attr
=
None
):
"""
Concat all input vector into one huge vector.
...
...
@@ -3024,7 +3015,7 @@ def concat_layer(input, act=None, name=None, layer_attr=None, bias_attr=None):
@
wrap_name_default
(
"seqconcat"
)
@
wrap_act_default
(
act
=
IdentityActivation
())
@
wrap_bias_attr_default
(
has_bias
=
False
)
@
layer_support
()
@
layer_support
(
DROPOUT
,
ERROR_CLIPPING
)
def
seq_concat_layer
(
a
,
b
,
act
=
None
,
name
=
None
,
layer_attr
=
None
,
bias_attr
=
None
):
"""
...
...
@@ -3177,7 +3168,7 @@ def memory(name,
@
wrap_act_default
(
param_names
=
[
'state_act'
],
act
=
TanhActivation
())
@
wrap_act_default
(
act
=
TanhActivation
())
@
wrap_name_default
(
'lstm_step'
)
@
layer_support
(
ERROR_CLIPPING
,
DROPOUT
)
@
layer_support
()
def
lstm_step_layer
(
input
,
state
,
size
=
None
,
...
...
@@ -4480,7 +4471,7 @@ def tensor_layer(a,
@
wrap_param_attr_default
()
@
wrap_bias_attr_default
()
@
wrap_act_default
()
@
layer_support
()
@
layer_support
(
DROPOUT
,
ERROR_CLIPPING
)
def
selective_fc_layer
(
input
,
size
,
select
=
None
,
...
...
@@ -5974,7 +5965,7 @@ def crop_layer(input, offset, axis=2, shape=None, name=None, layer_attr=None):
"""
The crop layer crops images by offset and shape. User can set crop shape by
args 'shape' explicitly or by reference input layer.
The example usage is:
.. code-block:: python
...
...
python/paddle/v2/dataset/common.py
浏览文件 @
7829bdbd
...
...
@@ -166,55 +166,37 @@ def cluster_files_reader(files_pattern,
return
reader
def
convert
(
output_path
,
reader
,
num_shards
,
name_prefix
,
max_lines_to_shuffle
=
1000
):
def
convert
(
output_path
,
reader
,
line_count
,
name_prefix
):
import
recordio
"""
Convert data from reader to recordio format files.
:param output_path: directory in which output files will be saved.
:param reader: a data reader, from which the convert program will read data instances.
:param num_shards: the number of shards that the dataset will be partitioned into.
:param name_prefix: the name prefix of generated files.
:param max_lines_to_shuffle: the max lines numbers to shuffle before writing.
"""
assert
num_shards
>=
1
assert
max_lines_to_shuffle
>=
1
def
open_writers
():
w
=
[]
for
i
in
range
(
0
,
num_shards
):
n
=
"%s/%s-%05d-of-%05d"
%
(
output_path
,
name_prefix
,
i
,
num_shards
-
1
)
w
.
append
(
recordio
.
writer
(
n
))
return
w
def
close_writers
(
w
):
for
i
in
range
(
0
,
num_shards
):
w
[
i
].
close
()
assert
line_count
>=
1
indx_f
=
0
def
write_data
(
w
,
lines
):
def
write_data
(
indx_f
,
lines
):
random
.
shuffle
(
lines
)
for
i
,
d
in
enumerate
(
lines
):
filename
=
"%s/%s-%05d"
%
(
output_path
,
name_prefix
,
indx_f
)
writer
=
recordio
.
writer
(
filename
)
for
l
in
lines
:
# FIXME(Yancey1989):
# dumps with protocol: pickle.HIGHEST_PROTOCOL
o
=
pickle
.
dumps
(
d
)
w
[
i
%
num_shards
].
write
(
o
)
writer
.
write
(
cPickle
.
dumps
(
l
)
)
writer
.
close
(
)
w
=
open_writers
()
lines
=
[]
for
i
,
d
in
enumerate
(
reader
()):
lines
.
append
(
d
)
if
i
%
max_lines_to_shuffle
==
0
and
i
>=
max_lines_to_shuffle
:
write_data
(
w
,
lines
)
if
i
%
line_count
==
0
and
i
>=
line_count
:
write_data
(
indx_f
,
lines
)
lines
=
[]
indx_f
+=
1
continue
write_data
(
w
,
lines
)
close_writers
(
w
)
write_data
(
indx_f
,
lines
)
python/paddle/v2/inference.py
浏览文件 @
7829bdbd
...
...
@@ -35,6 +35,13 @@ class Inference(object):
name
=
param
.
getName
()
assert
isinstance
(
val
,
api
.
Vector
)
val
.
copyFromNumpyArray
(
parameters
.
get
(
name
).
flatten
())
# the setValueUpdated function is called in randomize, zeroMem,
# load function in paddle/parameter/Parameter.cpp. But in the
# inference mode, the setValueUpdated is never called, it will
# cause the parameter will not be dispatched
# in MultiGradientMachine for multi-GPU. So setValueUpdated is
# called here, but it's better to call this function in one place.
param
.
setValueUpdated
()
self
.
__gradient_machine__
=
gm
self
.
__data_types__
=
topo
.
data_type
()
...
...
python/paddle/v2/master/client.py
浏览文件 @
7829bdbd
...
...
@@ -49,7 +49,6 @@ class client(object):
def
set_dataset
(
self
,
paths
):
holder_type
=
ctypes
.
c_char_p
*
len
(
paths
)
holder
=
holder_type
()
print
paths
for
idx
,
path
in
enumerate
(
paths
):
c_ptr
=
ctypes
.
c_char_p
(
path
)
holder
[
idx
]
=
c_ptr
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录