CPLEX yields "CPLEX Error 1004: Null pointer for required data." when the function CPXcopylp is called with a non-empty set of empty constraints. Since this is a valid MIP, it is not unthinkable that somebody tries to load that, and in fact I did. (The reason was an issue from the previously used OSI interface which did not allow empty constraint sets but empty constraints. Note that loading a MIP with an empty set of constraints is accepted by CPLEX now, even though it is basically the same as loading a non-empty set of empty constraints.)
While I don't think we will stumble over this often in the future, I still think it might make sense to add some help for debugging this while we understand the problem. The suggestion which I discussed offline with Florian is to extend cplex_solver_interface.h as follows:
class CplexMatrix {
// ...
public:
// ...
bool empty() const {return coefficients.empty();}
}
// ...
void CplexSolverInterface::load_problem(const LinearProgram &lp) {
// ...
assert(!matrix.empty() || constraints.empty());
CPX_CALL(CPXcopylp, env, problem, variables.size(), constraints.size(), ...);
}
The member *coefficients* contains all non-zero entries of the matrix. If it is empty, the matrix has only zero entries. This can either be because there are no constraints or because all constraints are empty. By asserting that either the matrix (i.e., the non-zero coefficients) are not empty or that the constraints are empty, we disallow the case that triggers the CPLEX error. It is not a proper solution because we forbid a valid MIP, but it is currently our best suggestion.
|