| 24 | typedef MultiResponseGLMAccumulator<MutableRootContainer> MutableMultiResponseGLMState; |
| 25 | |
| 26 | AnyType |
| 27 | multi_response_glm_multinom_logit_transition::run(AnyType& args) { |
| 28 | MutableMultiResponseGLMState state = args[0].getAs<MutableByteString>(); |
| 29 | if (state.terminated || args[1].isNull() || args[2].isNull()) { |
| 30 | return args[0]; |
| 31 | } |
| 32 | double y = args[1].getAs<double>(); |
| 33 | MappedColumnVector x; |
| 34 | try { |
| 35 | MappedColumnVector xx = args[2].getAs<MappedColumnVector>(); |
| 36 | x.rebind(xx.memoryHandle(), xx.size()); |
| 37 | } catch (const ArrayWithNullException &e) { |
| 38 | return args[0]; |
| 39 | } |
| 40 | if (state.empty()) { |
| 41 | state.num_features = static_cast<uint16_t>(x.size()); |
| 42 | state.num_categories = args[4].getAs<uint16_t>(); |
| 43 | state.optimizer.num_coef = static_cast<uint16_t>( |
| 44 | state.num_features * (state.num_categories-1)); |
| 45 | |
| 46 | // MADLIB-667: GPDB limits the single array size to be 1GB, which means |
| 47 | // that the size of a double array cannot be large than 134217727 |
| 48 | // because (134217727 * 8) / (1024 * 1024) = 1023. And solve |
| 49 | // state_size = x^2 + 2^x + 6 <= 134217727 will give x <= 11584. |
| 50 | uint32_t state_size = 6 + |
| 51 | state.optimizer.num_coef * state.optimizer.num_coef + |
| 52 | 2 * state.optimizer.num_coef; |
| 53 | if(state_size > 134217727){ |
| 54 | throw std::runtime_error( |
| 55 | "The product of number of independent variables and number of " |
| 56 | "categories cannot be larger than 11584."); |
| 57 | } |
| 58 | |
| 59 | state.resize(); |
| 60 | if (!args[3].isNull()) { |
| 61 | MultiResponseGLMState prev_state = args[3].getAs<ByteString>(); |
| 62 | state = prev_state; |
| 63 | state.reset(); |
| 64 | } |
| 65 | } |
| 66 | state << MutableMultiResponseGLMState::tuple_type(x, y); |
| 67 | return state.storage(); |
| 68 | } |
| 69 | |
| 70 | // ------------------------------------------------------------------------ |
| 71 | |