Where to refactor
taichi/lang_util.cpp has quite a few functions (e.g., data_type_name, data_type_format) that uses a static std::map to store input-output mapping.
What's wrong with the current design
When multiple threads are calling the function with the static map uninitialized, there will be parallel writes to the "std::map". This may cause a segmentation fault.
How to refactor
Example
The code above should be changed into something like
std::string data_type_name(DataType t) {
switch (t) {
#define REGISTER_DATA_TYPE(i, j) \
case DataType::i: \
return #j;
REGISTER_DATA_TYPE(f16, float16);
REGISTER_DATA_TYPE(f32, float32);
REGISTER_DATA_TYPE(f64, float64);
REGISTER_DATA_TYPE(u1, int1);
REGISTER_DATA_TYPE(i8, int8);
REGISTER_DATA_TYPE(i16, int16);
REGISTER_DATA_TYPE(i32, int32);
REGISTER_DATA_TYPE(i64, int64);
REGISTER_DATA_TYPE(u8, uint8);
REGISTER_DATA_TYPE(u16, uint16);
REGISTER_DATA_TYPE(u32, uint32);
REGISTER_DATA_TYPE(u64, uint64);
REGISTER_DATA_TYPE(gen, generic);
REGISTER_DATA_TYPE(unknown, unknown);
#undef REGISTER_DATA_TYPE
default:
TI_NOT_IMPLEMENTED
}
}
Additional comments
This is a good starting point for newcomers. Please leave a note if you have contributed < 3 PRs and to take this :-)
Open a draft PR if you want early feedback. It is suggested to ask for a review from me after the first function is refactored before apply your modification to all functions in that file.
Hello! I've left one PR so far, and I'd be interested in taking this.
A lot of thanks to @aryansoman for refactoring most of the functions! Now we are almost there, the only function left is
Suggested solution:
Let's not use switch case in this special case.
Note that std::map<std::pair<DataType, DataType>, DataType> is safe for parallel reading but not parallel writing. We are good as long as we initialize a class TypePromotionMapping, which contains the std::map and initializes everything before we do any query. This can be done if we create a global variable TypePromotionMapping type_promotion_mapping so that its initializer is always called before promoted_type (which then calls something like type_promotion_mapping::query(DataType, DataType).
Hi, I think it is not a difficult work, let me take it! :)
This is fully done. A lot of thanks to @Hanke98 and @aryansoman!
Most helpful comment
Hello! I've left one PR so far, and I'd be interested in taking this.