提交 bb97dc25 编写于 作者: G guosheng

Merge branch 'develop' of https://github.com/PaddlePaddle/paddle into add-python-layernorm

...@@ -179,20 +179,24 @@ function(cc_library TARGET_NAME) ...@@ -179,20 +179,24 @@ function(cc_library TARGET_NAME)
set(oneValueArgs "") set(oneValueArgs "")
set(multiValueArgs SRCS DEPS) set(multiValueArgs SRCS DEPS)
cmake_parse_arguments(cc_library "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(cc_library "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (cc_library_SRCS) if(cc_library_SRCS)
if (cc_library_SHARED OR cc_library_shared) # build *.so if(cc_library_SHARED OR cc_library_shared) # build *.so
add_library(${TARGET_NAME} SHARED ${cc_library_SRCS}) add_library(${TARGET_NAME} SHARED ${cc_library_SRCS})
else() else()
add_library(${TARGET_NAME} STATIC ${cc_library_SRCS}) add_library(${TARGET_NAME} STATIC ${cc_library_SRCS})
endif() endif()
if (cc_library_DEPS) if(cc_library_DEPS)
# Don't need link libwarpctc.so # Don't need link libwarpctc.so
if ("${cc_library_DEPS};" MATCHES "warpctc;") if("${cc_library_DEPS};" MATCHES "warpctc;")
list(REMOVE_ITEM cc_library_DEPS warpctc) list(REMOVE_ITEM cc_library_DEPS warpctc)
add_dependencies(${TARGET_NAME} warpctc) add_dependencies(${TARGET_NAME} warpctc)
endif() endif()
# Support linking flags: --whole-archive (Linux) / -force_load (MacOS)
target_circle_link_libraries(${TARGET_NAME} ${cc_library_DEPS})
if("${cc_library_DEPS}" MATCHES "ARCHIVE_START")
list(REMOVE_ITEM cc_library_DEPS ARCHIVE_START ARCHIVE_END)
endif()
add_dependencies(${TARGET_NAME} ${cc_library_DEPS}) add_dependencies(${TARGET_NAME} ${cc_library_DEPS})
target_link_libraries(${TARGET_NAME} ${cc_library_DEPS})
endif() endif()
# cpplint code style # cpplint code style
......
...@@ -176,7 +176,7 @@ TEST(Channel, ConcurrentSendNonConcurrentReceiveWithSufficientBufferSize) { ...@@ -176,7 +176,7 @@ TEST(Channel, ConcurrentSendNonConcurrentReceiveWithSufficientBufferSize) {
sum += i; sum += i;
} }
}); });
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // wait 0.5 sec std::this_thread::sleep_for(std::chrono::milliseconds(100)); // wait 0.1 sec
EXPECT_EQ(sum, 45U); EXPECT_EQ(sum, 45U);
CloseChannel(ch); CloseChannel(ch);
...@@ -194,10 +194,7 @@ TEST(Channel, RecevingOrderEqualToSendingOrderWithBufferedChannel) { ...@@ -194,10 +194,7 @@ TEST(Channel, RecevingOrderEqualToSendingOrderWithBufferedChannel) {
RecevingOrderEqualToSendingOrder(ch); RecevingOrderEqualToSendingOrder(ch);
} }
// This tests that closing a buffered channel also unblocks void ChannelCloseUnblocksReceiversTest(Channel<int> *ch) {
// any receivers waiting on the channel
TEST(Channel, BufferedChannelCloseUnblocksReceiversTest) {
auto ch = MakeChannel<int>(1);
size_t num_threads = 5; size_t num_threads = 5;
std::thread t[num_threads]; std::thread t[num_threads];
bool thread_ended[num_threads]; bool thread_ended[num_threads];
...@@ -208,15 +205,14 @@ TEST(Channel, BufferedChannelCloseUnblocksReceiversTest) { ...@@ -208,15 +205,14 @@ TEST(Channel, BufferedChannelCloseUnblocksReceiversTest) {
t[i] = std::thread( t[i] = std::thread(
[&](bool *p) { [&](bool *p) {
int data; int data;
// All reads should return false
EXPECT_EQ(ch->Receive(&data), false); EXPECT_EQ(ch->Receive(&data), false);
*p = true; *p = true;
}, },
&thread_ended[i]); &thread_ended[i]);
} }
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // wait std::this_thread::sleep_for(std::chrono::milliseconds(100)); // wait 0.1 sec
// Verify that all threads are blocked // Verify that all the threads are blocked
for (size_t i = 0; i < num_threads; i++) { for (size_t i = 0; i < num_threads; i++) {
EXPECT_EQ(thread_ended[i], false); EXPECT_EQ(thread_ended[i], false);
} }
...@@ -225,7 +221,7 @@ TEST(Channel, BufferedChannelCloseUnblocksReceiversTest) { ...@@ -225,7 +221,7 @@ TEST(Channel, BufferedChannelCloseUnblocksReceiversTest) {
// This should unblock all receivers // This should unblock all receivers
CloseChannel(ch); CloseChannel(ch);
std::this_thread::sleep_for(std::chrono::milliseconds(200)); // wait std::this_thread::sleep_for(std::chrono::milliseconds(100)); // wait 0.1 sec
// Verify that all threads got unblocked // Verify that all threads got unblocked
for (size_t i = 0; i < num_threads; i++) { for (size_t i = 0; i < num_threads; i++) {
...@@ -233,13 +229,12 @@ TEST(Channel, BufferedChannelCloseUnblocksReceiversTest) { ...@@ -233,13 +229,12 @@ TEST(Channel, BufferedChannelCloseUnblocksReceiversTest) {
} }
for (size_t i = 0; i < num_threads; i++) t[i].join(); for (size_t i = 0; i < num_threads; i++) t[i].join();
delete ch;
} }
// This tests that closing a buffered channel also unblocks void ChannelCloseUnblocksSendersTest(Channel<int> *ch) {
// any senders waiting for channel to have write space using paddle::framework::details::Buffered;
TEST(Channel, BufferedChannelCloseUnblocksSendersTest) { using paddle::framework::details::UnBuffered;
auto ch = MakeChannel<int>(1);
size_t num_threads = 5; size_t num_threads = 5;
std::thread t[num_threads]; std::thread t[num_threads];
bool thread_ended[num_threads]; bool thread_ended[num_threads];
...@@ -259,34 +254,56 @@ TEST(Channel, BufferedChannelCloseUnblocksSendersTest) { ...@@ -259,34 +254,56 @@ TEST(Channel, BufferedChannelCloseUnblocksSendersTest) {
} }
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // wait std::this_thread::sleep_for(std::chrono::milliseconds(100)); // wait
// Verify that atleast 4 threads are blocked if (dynamic_cast<Buffered<int> *>(ch)) {
// If ch is Buffered, atleast 4 threads must be blocked.
int ct = 0; int ct = 0;
for (size_t i = 0; i < num_threads; i++) { for (size_t i = 0; i < num_threads; i++) {
if (thread_ended[i] == false) ct++; if (!thread_ended[i]) ct++;
} }
// Atleast 4 threads must be blocked
EXPECT_GE(ct, 4); EXPECT_GE(ct, 4);
} else {
// If ch is UnBuffered, all the threads should be blocked.
for (size_t i = 0; i < num_threads; i++) {
EXPECT_EQ(thread_ended[i], false);
}
}
// Explicitly close the thread // Explicitly close the thread
// This should unblock all senders // This should unblock all senders
CloseChannel(ch); CloseChannel(ch);
std::this_thread::sleep_for(std::chrono::milliseconds(200)); // wait std::this_thread::sleep_for(std::chrono::milliseconds(100)); // wait
// Verify that all threads got unblocked // Verify that all threads got unblocked
for (size_t i = 0; i < num_threads; i++) { for (size_t i = 0; i < num_threads; i++) {
EXPECT_EQ(thread_ended[i], true); EXPECT_EQ(thread_ended[i], true);
} }
if (dynamic_cast<Buffered<int> *>(ch)) {
// Verify that only 1 send was successful // Verify that only 1 send was successful
ct = 0; int ct = 0;
for (size_t i = 0; i < num_threads; i++) { for (size_t i = 0; i < num_threads; i++) {
if (send_success[i]) ct++; if (send_success[i]) ct++;
} }
// Only 1 send must be successful // Only 1 send must be successful
EXPECT_EQ(ct, 1); EXPECT_EQ(ct, 1);
}
for (size_t i = 0; i < num_threads; i++) t[i].join(); for (size_t i = 0; i < num_threads; i++) t[i].join();
}
// This tests that closing a buffered channel also unblocks
// any receivers waiting on the channel
TEST(Channel, BufferedChannelCloseUnblocksReceiversTest) {
auto ch = MakeChannel<int>(1);
ChannelCloseUnblocksReceiversTest(ch);
delete ch;
}
// This tests that closing a buffered channel also unblocks
// any senders waiting for channel to have write space
TEST(Channel, BufferedChannelCloseUnblocksSendersTest) {
auto ch = MakeChannel<int>(1);
ChannelCloseUnblocksSendersTest(ch);
delete ch; delete ch;
} }
...@@ -294,40 +311,7 @@ TEST(Channel, BufferedChannelCloseUnblocksSendersTest) { ...@@ -294,40 +311,7 @@ TEST(Channel, BufferedChannelCloseUnblocksSendersTest) {
// unblocks any receivers waiting for senders // unblocks any receivers waiting for senders
TEST(Channel, UnbufferedChannelCloseUnblocksReceiversTest) { TEST(Channel, UnbufferedChannelCloseUnblocksReceiversTest) {
auto ch = MakeChannel<int>(0); auto ch = MakeChannel<int>(0);
size_t num_threads = 5; ChannelCloseUnblocksReceiversTest(ch);
std::thread t[num_threads];
bool thread_ended[num_threads];
// Launches threads that try to read and are blocked becausew of no writers
for (size_t i = 0; i < num_threads; i++) {
thread_ended[i] = false;
t[i] = std::thread(
[&](bool *p) {
int data;
EXPECT_EQ(ch->Receive(&data), false);
*p = true;
},
&thread_ended[i]);
}
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // wait 0.5 sec
// Verify that all the threads are blocked
for (size_t i = 0; i < num_threads; i++) {
EXPECT_EQ(thread_ended[i], false);
}
// Explicitly close the thread
// This should unblock all receivers
CloseChannel(ch);
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // wait 0.5 sec
// Verify that all threads got unblocked
for (size_t i = 0; i < num_threads; i++) {
EXPECT_EQ(thread_ended[i], true);
}
for (size_t i = 0; i < num_threads; i++) t[i].join();
delete ch; delete ch;
} }
...@@ -335,40 +319,7 @@ TEST(Channel, UnbufferedChannelCloseUnblocksReceiversTest) { ...@@ -335,40 +319,7 @@ TEST(Channel, UnbufferedChannelCloseUnblocksReceiversTest) {
// unblocks any senders waiting for senders // unblocks any senders waiting for senders
TEST(Channel, UnbufferedChannelCloseUnblocksSendersTest) { TEST(Channel, UnbufferedChannelCloseUnblocksSendersTest) {
auto ch = MakeChannel<int>(0); auto ch = MakeChannel<int>(0);
size_t num_threads = 5; ChannelCloseUnblocksReceiversTest(ch);
std::thread t[num_threads];
bool thread_ended[num_threads];
// Launches threads that try to read and are blocked becausew of no writers
for (size_t i = 0; i < num_threads; i++) {
thread_ended[i] = false;
t[i] = std::thread(
[&](bool *p) {
int data = 10;
EXPECT_EQ(ch->Send(&data), false);
*p = true;
},
&thread_ended[i]);
}
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // wait 0.5 sec
// Verify that all the threads are blocked
for (size_t i = 0; i < num_threads; i++) {
EXPECT_EQ(thread_ended[i], false);
}
// Explicitly close the thread
// This should unblock all receivers
CloseChannel(ch);
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // wait 0.5 sec
// Verify that all threads got unblocked
for (size_t i = 0; i < num_threads; i++) {
EXPECT_EQ(thread_ended[i], true);
}
for (size_t i = 0; i < num_threads; i++) t[i].join();
delete ch; delete ch;
} }
......
...@@ -25,6 +25,14 @@ namespace paddle { ...@@ -25,6 +25,14 @@ namespace paddle {
namespace framework { namespace framework {
namespace details { namespace details {
// Four of the properties of Buffered Channel:
// - A send to a full channel blocks temporarily until a receive from the
// channel or the channel is closed.
// - A receive from an empty channel blocks temporarily until a send to the
// channel or the channel is closed.
// - A send to a closed channel returns false immediately.
// - A receive from a closed channel returns false immediately.
template <typename T> template <typename T>
class Buffered : public paddle::framework::Channel<T> { class Buffered : public paddle::framework::Channel<T> {
friend Channel<T>* paddle::framework::MakeChannel<T>(size_t); friend Channel<T>* paddle::framework::MakeChannel<T>(size_t);
......
...@@ -23,6 +23,13 @@ namespace paddle { ...@@ -23,6 +23,13 @@ namespace paddle {
namespace framework { namespace framework {
namespace details { namespace details {
// Four of the properties of UnBuffered Channel:
// - A send to a channel blocks temporarily until a receive from the
// channel or the channel is closed.
// - A receive from a channel blocks temporarily until a send to the
// channel or the channel is closed.
// - A send to a closed channel returns false immediately.
// - A receive from a closed channel returns false immediately.
template <typename T> template <typename T>
class UnBuffered : public paddle::framework::Channel<T> { class UnBuffered : public paddle::framework::Channel<T> {
friend Channel<T>* paddle::framework::MakeChannel<T>(size_t); friend Channel<T>* paddle::framework::MakeChannel<T>(size_t);
......
...@@ -4,19 +4,14 @@ cc_library(paddle_fluid_api ...@@ -4,19 +4,14 @@ cc_library(paddle_fluid_api
SRCS io.cc SRCS io.cc
DEPS ${FLUID_CORE_MODULES} ${GLOB_OP_LIB}) DEPS ${FLUID_CORE_MODULES} ${GLOB_OP_LIB})
# Merge all modules into a single static library # Create static library
cc_library(paddle_fluid DEPS paddle_fluid_api ${FLUID_CORE_MODULES} ${GLOB_OP_LIB}) cc_library(paddle_fluid DEPS paddle_fluid_api ${FLUID_CORE_MODULES} ${GLOB_OP_LIB})
# Create shared library # Create shared library
add_library(paddle_fluid_shared SHARED io.cc) cc_library(paddle_fluid_shared SHARED
SRCS io.cc
target_circle_link_libraries(paddle_fluid_shared DEPS ARCHIVE_START ${GLOB_OP_LIB} ${FLUID_CORE_MODULES} ARCHIVE_END)
ARCHIVE_START set_target_properties(paddle_fluid_shared PROPERTIES OUTPUT_NAME paddle_fluid)
${GLOB_OP_LIB}
${FLUID_CORE_MODULES}
ARCHIVE_END)
SET_TARGET_PROPERTIES(paddle_fluid_shared PROPERTIES OUTPUT_NAME paddle_fluid)
if(WITH_TESTING) if(WITH_TESTING)
add_subdirectory(tests/book) add_subdirectory(tests/book)
......
...@@ -5,23 +5,23 @@ function(inference_test TARGET_NAME) ...@@ -5,23 +5,23 @@ function(inference_test TARGET_NAME)
cmake_parse_arguments(inference_test "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(inference_test "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
set(PYTHON_TESTS_DIR ${PADDLE_SOURCE_DIR}/python/paddle/v2/fluid/tests) set(PYTHON_TESTS_DIR ${PADDLE_SOURCE_DIR}/python/paddle/v2/fluid/tests)
set(arg_list "")
if(inference_test_ARGS) if(inference_test_ARGS)
foreach(arg ${inference_test_ARGS}) foreach(arg ${inference_test_ARGS})
cc_test(test_inference_${TARGET_NAME}_${arg} list(APPEND arg_list "_${arg}")
SRCS test_inference_${TARGET_NAME}.cc
DEPS ARCHIVE_START paddle_fluid ARCHIVE_END
ARGS --dirname=${PYTHON_TESTS_DIR}/book/${TARGET_NAME}_${arg}.inference.model)
set_tests_properties(test_inference_${TARGET_NAME}_${arg}
PROPERTIES DEPENDS test_${TARGET_NAME})
endforeach() endforeach()
else() else()
cc_test(test_inference_${TARGET_NAME} list(APPEND arg_list "_")
endif()
foreach(arg ${arg_list})
string(REGEX REPLACE "^_$" "" arg "${arg}")
cc_test(test_inference_${TARGET_NAME}${arg}
SRCS test_inference_${TARGET_NAME}.cc SRCS test_inference_${TARGET_NAME}.cc
DEPS ARCHIVE_START paddle_fluid ARCHIVE_END DEPS ARCHIVE_START paddle_fluid ARCHIVE_END
ARGS --dirname=${PYTHON_TESTS_DIR}/book/${TARGET_NAME}.inference.model) ARGS --dirname=${PYTHON_TESTS_DIR}/book/${TARGET_NAME}${arg}.inference.model)
set_tests_properties(test_inference_${TARGET_NAME} set_tests_properties(test_inference_${TARGET_NAME}${arg}
PROPERTIES DEPENDS test_${TARGET_NAME}) PROPERTIES DEPENDS test_${TARGET_NAME})
endif() endforeach()
endfunction(inference_test) endfunction(inference_test)
inference_test(recognize_digits ARGS mlp) inference_test(recognize_digits ARGS mlp)
......
...@@ -47,27 +47,13 @@ def as_numpy(tensor): ...@@ -47,27 +47,13 @@ def as_numpy(tensor):
return [as_numpy(t) for t in tensor] return [as_numpy(t) for t in tensor]
assert isinstance(tensor, core.LoDTensor) assert isinstance(tensor, core.LoDTensor)
lod = tensor.lod() lod = tensor.lod()
tensor_data = np.array(tensor) if len(lod) > 0:
if len(lod) == 0: raise RuntimeError(
ans = tensor_data "Some of your featched tensors hold LoD information. \
else: They can not be completely cast to Python ndarray. \
raise RuntimeError("LoD Calculate lacks unit tests and buggy") Please set the parameter 'return_numpy' as 'False' to \
# elif len(lod) == 1: return LoDTensor itself directly.")
# ans = [] return np.array(tensor)
# idx = 0
# while idx < len(lod) - 1:
# ans.append(tensor_data[lod[idx]:lod[idx + 1]])
# idx += 1
# else:
# for l in reversed(lod):
# ans = []
# idx = 0
# while idx < len(l) - 1:
# ans.append(tensor_data[l[idx]:l[idx + 1]])
# idx += 1
# tensor_data = ans
# ans = tensor_data
return ans
def has_feed_operators(block, feed_targets, feed_holder_name): def has_feed_operators(block, feed_targets, feed_holder_name):
...@@ -306,7 +292,6 @@ class Executor(object): ...@@ -306,7 +292,6 @@ class Executor(object):
core.get_fetch_variable(scope, fetch_var_name, i) core.get_fetch_variable(scope, fetch_var_name, i)
for i in xrange(len(fetch_list)) for i in xrange(len(fetch_list))
] ]
if return_numpy: if return_numpy:
outs = as_numpy(outs) outs = as_numpy(outs)
return outs return outs
...@@ -740,6 +740,9 @@ class Block(object): ...@@ -740,6 +740,9 @@ class Block(object):
raise e raise e
self.desc.remove_op(start, end + 1) self.desc.remove_op(start, end + 1)
def slice_ops(self, start, end):
return list(self.ops)[start:end]
def prepend_op(self, *args, **kwargs): def prepend_op(self, *args, **kwargs):
op_desc = self.desc.prepend_op() op_desc = self.desc.prepend_op()
op = Operator(self, op_desc, *args, **kwargs) op = Operator(self, op_desc, *args, **kwargs)
......
...@@ -92,14 +92,13 @@ class ControlFlowGraph(object): ...@@ -92,14 +92,13 @@ class ControlFlowGraph(object):
live_in = defaultdict(set) live_in = defaultdict(set)
live_out = defaultdict(set) live_out = defaultdict(set)
while True: while True:
for i in range(self.op_size): for i in range(self.op_size, 0, -1):
live_in[i] = set(self._live_in[i]) live_in[i] = set(self._live_in[i])
live_out[i] = set(self._live_out[i]) live_out[i] = set(self._live_out[i])
self._live_in[i] = self._uses[i] | (
self._live_out[i] - self._defs[i])
for s in self._successors[i]: for s in self._successors[i]:
self._live_out[i] |= self._live_in[s] self._live_out[i] |= self._live_in[s]
self._live_in[i] = self._uses[i] | (
self._live_out[i] - self._defs[i])
if self._reach_fixed_point(live_in, live_out): if self._reach_fixed_point(live_in, live_out):
break break
......
...@@ -190,6 +190,8 @@ class Optimizer(object): ...@@ -190,6 +190,8 @@ class Optimizer(object):
# Create any accumulators # Create any accumulators
program = loss.block.program program = loss.block.program
with program_guard(program, startup_program): with program_guard(program, startup_program):
global_block = framework.default_main_program().global_block()
start = len(global_block.ops)
self.helper = LayerHelper(self.__class__.__name__) self.helper = LayerHelper(self.__class__.__name__)
self._create_accumulators(loss.block, self._create_accumulators(loss.block,
[p[0] for p in parameters_and_grads]) [p[0] for p in parameters_and_grads])
...@@ -203,19 +205,14 @@ class Optimizer(object): ...@@ -203,19 +205,14 @@ class Optimizer(object):
param_and_grad) param_and_grad)
optimize_ops.append(optimize_op) optimize_ops.append(optimize_op)
# Returned list of ops can include more ops in addition
# to optimization ops
return_ops = optimize_ops
# Get custom finish ops for subclasses # Get custom finish ops for subclasses
# FIXME: Need to fix this once we figure out how to handle dependencies # FIXME: Need to fix this once we figure out how to handle dependencies
finish_ops = self._finish_update(loss.block) self._finish_update(loss.block)
if finish_ops is not None:
return_ops += finish_ops
if self._global_step is not None: if self._global_step is not None:
return_ops.append(self._increment_global_step(loss.block)) self._increment_global_step(loss.block)
return return_ops end = len(global_block.ops)
return global_block.slice_ops(start, end)
def minimize(self, def minimize(self,
loss, loss,
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
import numpy as np import numpy as np
import paddle.v2 as paddle import paddle.v2 as paddle
import paddle.v2.fluid as fluid import paddle.v2.fluid as fluid
import math
import sys
# need to fix random seed and training data to compare the loss # need to fix random seed and training data to compare the loss
# value accurately calculated by the default and the memory optimization # value accurately calculated by the default and the memory optimization
...@@ -63,4 +65,6 @@ for pass_id in range(PASS_NUM): ...@@ -63,4 +65,6 @@ for pass_id in range(PASS_NUM):
if avg_loss_value[0] < 10.0: if avg_loss_value[0] < 10.0:
exit(0) # if avg cost less than 10.0, we think our code is good. exit(0) # if avg cost less than 10.0, we think our code is good.
if math.isnan(float(avg_loss_value)):
sys.exit("got NaN loss, training failed.")
exit(1) exit(1)
...@@ -18,6 +18,8 @@ import sys ...@@ -18,6 +18,8 @@ import sys
import paddle.v2 as paddle import paddle.v2 as paddle
import paddle.v2.fluid as fluid import paddle.v2.fluid as fluid
import math
import sys
# need to fix random seed and training data to compare the loss # need to fix random seed and training data to compare the loss
# value accurately calculated by the default and the memory optimization # value accurately calculated by the default and the memory optimization
...@@ -152,7 +154,10 @@ for pass_id in range(PASS_NUM): ...@@ -152,7 +154,10 @@ for pass_id in range(PASS_NUM):
print("loss:" + str(loss) + " acc:" + str(acc) + " pass_acc:" + str( print("loss:" + str(loss) + " acc:" + str(acc) + " pass_acc:" + str(
pass_acc)) pass_acc))
# this model is slow, so if we can train two mini batch, we think it works properly. # this model is slow, so if we can train two mini batch, we think it works properly.
if i > 2: if i > 2:
exit(0) exit(0)
if math.isnan(float(loss)):
sys.exit("got NaN loss, training failed.")
i += 1 i += 1
exit(1) exit(1)
...@@ -19,6 +19,8 @@ import paddle.v2.fluid.core as core ...@@ -19,6 +19,8 @@ import paddle.v2.fluid.core as core
import paddle.v2.fluid.framework as framework import paddle.v2.fluid.framework as framework
import paddle.v2.fluid.layers as layers import paddle.v2.fluid.layers as layers
from paddle.v2.fluid.executor import Executor from paddle.v2.fluid.executor import Executor
import math
import sys
dict_size = 30000 dict_size = 30000
source_dict_dim = target_dict_dim = dict_size source_dict_dim = target_dict_dim = dict_size
...@@ -137,6 +139,8 @@ def main(): ...@@ -137,6 +139,8 @@ def main():
" avg_cost=" + str(avg_cost_val)) " avg_cost=" + str(avg_cost_val))
if batch_id > 2: if batch_id > 2:
exit(0) exit(0)
if math.isnan(float(avg_cost_val)):
sys.exit("got NaN loss, training failed.")
batch_id += 1 batch_id += 1
......
...@@ -32,31 +32,43 @@ create_random_data_generator_op = block.append_op( ...@@ -32,31 +32,43 @@ create_random_data_generator_op = block.append_op(
"min": 0.0, "min": 0.0,
"max": 1.0 "max": 1.0
}) })
shuffle_reader = block.create_var(
type=fluid.core.VarDesc.VarType.READER, name="ShuffleReader")
shuffle_reader.desc.set_lod_levels([0, 0])
out1 = block.create_var( create_shuffle_reader_op = block.append_op(
type=fluid.core.VarDesc.VarType.LOD_TENSOR, type="create_shuffle_reader",
name="Out1", inputs={"UnderlyingReader": random_reader},
shape=[10, 2], outputs={"Out": shuffle_reader},
dtype="float32", attrs={"buffer_size": 7})
lod_level=1)
out2 = block.create_var( batch_reader = block.create_var(
type=fluid.core.VarDesc.VarType.LOD_TENSOR, type=fluid.core.VarDesc.VarType.READER, name="BatchReader")
name="Out2", batch_reader.desc.set_lod_levels([1, 1])
shape=[10, 1],
dtype="float32", create_batch_reader_op = block.append_op(
lod_level=1) type="create_batch_reader",
inputs={"UnderlyingReader": shuffle_reader},
outputs={"Out": batch_reader},
attrs={"batch_size": 10})
out1 = block.create_var(type=fluid.core.VarDesc.VarType.LOD_TENSOR, name="Out1")
out2 = block.create_var(type=fluid.core.VarDesc.VarType.LOD_TENSOR, name="Out2")
read_op = block.append_op( read_op = block.append_op(
type="read", type="read", inputs={"Reader": batch_reader},
inputs={"Reader": random_reader},
outputs={"Out": [out1, out2]}) outputs={"Out": [out1, out2]})
place = fluid.CPUPlace() place = fluid.CPUPlace()
exe = fluid.Executor(place) exe = fluid.Executor(place)
[res1, res2] = exe.run(prog, fetch_list=[out1, out2]) [res1, res2] = exe.run(prog, fetch_list=[out1, out2], return_numpy=False)
test_pass = res1.lod() == [range(0, 11)] and res1.lod() == [
range(0, 11)
] and np.array(res1).shape == (10, 2) and np.array(res2).shape == (10, 1)
if len(res1) == 0 or len(res2) == 0: if not test_pass:
exit(1) exit(1)
exit(0) exit(0)
...@@ -42,9 +42,9 @@ class TestOptimizer(unittest.TestCase): ...@@ -42,9 +42,9 @@ class TestOptimizer(unittest.TestCase):
type="mean", inputs={"X": mul_out}, outputs={"Out": mean_out}) type="mean", inputs={"X": mul_out}, outputs={"Out": mean_out})
sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.01) sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.01)
opts, _ = sgd_optimizer.minimize(mean_out, init_program) opts, _ = sgd_optimizer.minimize(mean_out, init_program)
self.assertEqual(len(opts), 1) self.assertEqual(len(opts), 3)
sgd_op = opts[0] self.assertEqual([op.type for op in opts],
self.assertEqual(sgd_op.type, "sgd") ["fill_constant", "elementwise_mul", "sgd"])
def test_sgd_optimizer_with_global_step(self): def test_sgd_optimizer_with_global_step(self):
init_program = framework.Program() init_program = framework.Program()
...@@ -72,11 +72,10 @@ class TestOptimizer(unittest.TestCase): ...@@ -72,11 +72,10 @@ class TestOptimizer(unittest.TestCase):
sgd_optimizer = optimizer.SGDOptimizer( sgd_optimizer = optimizer.SGDOptimizer(
learning_rate=learning_rate, global_step=global_step) learning_rate=learning_rate, global_step=global_step)
opts, _ = sgd_optimizer.minimize(mean_out, init_program) opts, _ = sgd_optimizer.minimize(mean_out, init_program)
self.assertEqual(len(opts), 2) self.assertEqual(len(opts), 4)
sgd_op = opts[0] self.assertEqual(
self.assertEqual(sgd_op.type, "sgd") [op.type for op in opts],
increment_op = opts[1] ["fill_constant", "elementwise_mul", "sgd", "increment"])
self.assertEqual(increment_op.type, "increment")
# Check init_program # Check init_program
init_ops = init_program.global_block().ops init_ops = init_program.global_block().ops
...@@ -121,9 +120,10 @@ class TestMomentumOptimizer(unittest.TestCase): ...@@ -121,9 +120,10 @@ class TestMomentumOptimizer(unittest.TestCase):
self.assertEqual(len(momentum_optimizer.get_accumulators()), 0) self.assertEqual(len(momentum_optimizer.get_accumulators()), 0)
opts = momentum_optimizer.create_optimization_pass( opts = momentum_optimizer.create_optimization_pass(
params_grads, mul_out, init_program) params_grads, mul_out, init_program)
self.assertEqual(len(opts), 1) self.assertEqual(len(opts), 3)
sgd_op = opts[0] sgd_op = opts[-1]
self.assertEqual(sgd_op.type, "momentum") self.assertEqual([op.type for op in opts],
["fill_constant", "elementwise_mul", "momentum"])
self.assertFalse(sgd_op.attr('use_nesterov')) self.assertFalse(sgd_op.attr('use_nesterov'))
# Check accumulators # Check accumulators
...@@ -170,9 +170,10 @@ class TestMomentumOptimizer(unittest.TestCase): ...@@ -170,9 +170,10 @@ class TestMomentumOptimizer(unittest.TestCase):
self.assertEqual(len(momentum_optimizer.get_accumulators()), 0) self.assertEqual(len(momentum_optimizer.get_accumulators()), 0)
opts = momentum_optimizer.create_optimization_pass( opts = momentum_optimizer.create_optimization_pass(
params_grads, mul_out, init_program) params_grads, mul_out, init_program)
self.assertEqual(len(opts), 1) self.assertEqual(len(opts), 3)
sgd_op = opts[0] sgd_op = opts[-1]
self.assertEqual(sgd_op.type, "momentum") self.assertEqual([op.type for op in opts],
["fill_constant", "elementwise_mul", "momentum"])
self.assertTrue(sgd_op.attr('use_nesterov')) self.assertTrue(sgd_op.attr('use_nesterov'))
# Check accumulators # Check accumulators
...@@ -228,9 +229,9 @@ class TestAdagradOptimizer(unittest.TestCase): ...@@ -228,9 +229,9 @@ class TestAdagradOptimizer(unittest.TestCase):
self.assertEqual(len(adagrad_optimizer.get_accumulators()), 0) self.assertEqual(len(adagrad_optimizer.get_accumulators()), 0)
opts = adagrad_optimizer.create_optimization_pass(params_grads, mul_out, opts = adagrad_optimizer.create_optimization_pass(params_grads, mul_out,
init_program) init_program)
self.assertEqual(len(opts), 1) self.assertEqual(len(opts), 3)
adagrad_op = opts[0] self.assertEqual([op.type for op in opts],
self.assertEqual(adagrad_op.type, "adagrad") ["fill_constant", "elementwise_mul", "adagrad"])
# Check accumulators # Check accumulators
accumulators = adagrad_optimizer.get_accumulators() accumulators = adagrad_optimizer.get_accumulators()
...@@ -288,9 +289,10 @@ class TestAdamOptimizer(unittest.TestCase): ...@@ -288,9 +289,10 @@ class TestAdamOptimizer(unittest.TestCase):
self.assertEqual(len(adam_optimizer.get_accumulators()), 0) self.assertEqual(len(adam_optimizer.get_accumulators()), 0)
opts = adam_optimizer.create_optimization_pass(params_grads, mul_out, opts = adam_optimizer.create_optimization_pass(params_grads, mul_out,
init_program) init_program)
self.assertEqual(len(opts), 3) self.assertEqual(len(opts), 5)
adam_op = opts[0] self.assertEqual(
self.assertEqual(adam_op.type, "adam") [op.type for op in opts],
["fill_constant", "elementwise_mul", "adam", "scale", "scale"])
# Check accumulators # Check accumulators
accumulators = adam_optimizer.get_accumulators() accumulators = adam_optimizer.get_accumulators()
...@@ -350,9 +352,10 @@ class TestAdamaxOptimizer(unittest.TestCase): ...@@ -350,9 +352,10 @@ class TestAdamaxOptimizer(unittest.TestCase):
self.assertEqual(len(adamax_optimizer.get_accumulators()), 0) self.assertEqual(len(adamax_optimizer.get_accumulators()), 0)
opts = adamax_optimizer.create_optimization_pass(params_grads, mul_out, opts = adamax_optimizer.create_optimization_pass(params_grads, mul_out,
init_program) init_program)
self.assertEqual(len(opts), 2) self.assertEqual(len(opts), 4)
adam_op = opts[0] self.assertEqual(
self.assertEqual(adam_op.type, "adamax") [op.type for op in opts],
["fill_constant", "elementwise_mul", "adamax", "scale"])
# Check accumulators # Check accumulators
accumulators = adamax_optimizer.get_accumulators() accumulators = adamax_optimizer.get_accumulators()
...@@ -409,9 +412,10 @@ class TestDecayedAdagradOptimizer(unittest.TestCase): ...@@ -409,9 +412,10 @@ class TestDecayedAdagradOptimizer(unittest.TestCase):
self.assertEqual(len(decayed_adagrad_optimizer.get_accumulators()), 0) self.assertEqual(len(decayed_adagrad_optimizer.get_accumulators()), 0)
opts = decayed_adagrad_optimizer.create_optimization_pass( opts = decayed_adagrad_optimizer.create_optimization_pass(
params_grads, mul_out, init_program) params_grads, mul_out, init_program)
self.assertEqual(len(opts), 1) self.assertEqual(len(opts), 3)
decayed_adagrad_op = opts[0] self.assertEqual(
self.assertEqual(decayed_adagrad_op.type, "decayed_adagrad") [op.type for op in opts],
["fill_constant", "elementwise_mul", "decayed_adagrad"])
# Check accumulators # Check accumulators
accumulators = decayed_adagrad_optimizer.get_accumulators() accumulators = decayed_adagrad_optimizer.get_accumulators()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册