[MXNET-145] Remove global PRNGs of numpy and python used in mx.image package #10575
Conversation
these are performance sensitive though. how much performance hit would this cause? |
@piiswrong Currently I have no measure. Is there any benchmark or example code that I can use? If not, I'll write my own. |
A simple benchmark using start = time.time()
data = mx.img.ImageIter(
batch_size=32,
data_shape=(3, 224, 224),
path_imgrec='caltech.rec', # 9144 image samples
rand_crop=True,
rand_resize=True,
rand_mirror=True,
rand_gray=0.5,
brightness=0.5,
contrast=0.5,
saturation=0.5)
for i in data:
pass
mx.nd.waitall()
end = time.time()
print("elapsed time: ", end - start) |
Replacing the python/numpy global RNGs with a mxnet specific instance of numpy RNG would be better in terms of the performance. Is it acceptable keeping a numpy RNG as an internal utility in |
I'm not sure what causes the slowdown. If it is the overhead of mxnet's operator calling mechanism, adding a simple function to generate a scalar random number, using mxnet's internal RNGs, to the random number API would be the solution. I'll test with this. |
I experimented with the following two functions. The first one takes 37s and the second one takes 28s to run the above // Faster than sampling operator but still slow
int rand(mx_float low, mx_float high, mx_float* out) {
API_BEGIN();
Context ctx = Context::CPU();
Engine::VarHandle var = Engine::Get()->NewVariable();
mxnet::Resource resource = mxnet::ResourceManager::Get()->Request(
ctx, ResourceRequest::kRandom);
Engine::Get()->PushSync([low, high, out, resource](RunContext rctx) {
mshadow::Random<mxnet::cpu, float> *prnd =
resource.get_random<mxnet::cpu, float>(rctx.get_stream<mxnet::cpu>());
mshadow::Tensor<mxnet::cpu, 1, float> tmp(out, mshadow::Shape1(1));
prnd->SampleUniform(&tmp, low, high);
}, ctx, {}, {var, resource.var},
FnProperty::kNormal, 0, PROFILER_MESSAGE_FUNCNAME);
Engine::Get()->WaitForVar(var);
Engine::Get()->DeleteVariable([](mxnet::RunContext) {}, mxnet::Context(), var);
API_END();
}
// Fast but not safe as `resource` is shared
int rand(mx_float low, mx_float high, mx_float* out) {
API_BEGIN();
Context ctx = Context::CPU();
mxnet::Resource resource = mxnet::ResourceManager::Get()->Request(
ctx, ResourceRequest::kRandom);
mshadow::Random<mxnet::cpu, float> *prnd =
resource.get_random<mxnet::cpu, float>(nullptr);
mshadow::Tensor<mxnet::cpu, 1, float> tmp(out, mshadow::Shape1(1));
prnd->SampleUniform(&tmp, low, high);
API_END();
} |
I think an instance of numpy rng inside mxnet python package is good enough |
Description
This PR replaces global random number generators of numpy and python used in mx.image package with mxnet's random number generators. This is a sequel of PR #10260.
Checklist
Essentials
Please feel free to remove inapplicable items for your PR.