// extern void TF_SetAttrTypeList(TF_OperationDescription* desc,
//                                const char* attr_name, const TF_DataType* values,
//                                int num_values);
static PHP_METHOD(TensorFlow_OperationDescription, setAttrTypeList)
{
    zend_string *name;
    zval* dtypes;

    ZEND_PARSE_PARAMETERS_START(2, 2)
        Z_PARAM_STR(name)
        Z_PARAM_ARRAY(dtypes)
    ZEND_PARSE_PARAMETERS_END();


    TF_DataType* tf_values = NULL;
    int tf_num_values = 0;

    HashTable *values_table = Z_ARRVAL_P(dtypes);
    tf_num_values = zend_hash_num_elements(values_table); // count of array

    if (tf_num_values > 0) {
        tf_values = (TF_DataType*)emalloc(sizeof(TF_DataType) * tf_num_values);

        HashPosition pos;
        zval* element;
        int index = 0;

        zend_hash_internal_pointer_reset_ex(values_table, &pos);
        while (zend_hash_has_more_elements_ex(values_table, &pos) == SUCCESS) {
            if (!(element = zend_hash_get_current_data_ex(values_table, &pos))) {
                zend_throw_exception(spl_ce_InvalidArgumentException, "dtypes something wrong", 0);
                return;
            }
            if (zval_get_type(element) != IS_LONG) {
                zend_throw_exception(spl_ce_InvalidArgumentException, "dtypes must be array of integer", 0);
                return;
            }
            if (!valid_dtype(Z_LVAL_P(element))) {
                zend_throw_exception(spl_ce_InvalidArgumentException, "each dtype must be from 1 to 20", 0);
                return;
            }
            // insert tf_values
            tf_values[index] = Z_LVAL_P(element);
            // php_printf("%d \n", element->value.lval);
            zend_hash_move_forward_ex(values_table, &pos);

            index++;
        }
    }

    // int i;
    // for (i = 0; i < tf_num_values; i++) {
    //     php_printf("dtypes[%d] ? %d\n", i, tf_values[i]);
    // }
    // php_printf("tf_num_values ? %d\n", tf_num_values);

    // this
    t_tf_operation_description_object* intern = TF_OPERATION_DESCRIPTION_P_ZV(getThis());
    t_tf_operation_description* node = intern->ptr;

    TF_SetAttrTypeList(node->src, name->val, tf_values, tf_num_values);
}
Example #2
0
/**
 * Construct an instance of the Channel class. If the $args array contains a
 * "credentials" key mapping to a ChannelCredentials object, a secure channel
 * will be created with those credentials.
 * @param string $target The hostname to associate with this channel
 * @param array $args The arguments to pass to the Channel (optional)
 */
PHP_METHOD(Channel, __construct) {
  wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis());
  zend_string *target;
  zval *args_array = NULL;
  grpc_channel_args args;
  HashTable *array_hash;
  zval *creds_obj = NULL;
  wrapped_grpc_channel_credentials *creds = NULL;

  /* "Sa" == 1 string, 1 array */
#ifndef FAST_ZPP
  if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sa", &target, &args_array)
      == FAILURE) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "Channel expects a string and an array", 1);
    return;
  }
#else
  ZEND_PARSE_PARAMETERS_START(2, 2)
    Z_PARAM_STR(target)
    Z_PARAM_ARRAY(args_array)
  ZEND_PARSE_PARAMETERS_END();
#endif

  array_hash = HASH_OF(args_array);
  if ((creds_obj = zend_hash_str_find(array_hash, "credentials",
                                      sizeof("credentials") - 1)) != NULL) {
    if (Z_TYPE_P(creds_obj) == IS_NULL) {
      creds = NULL;
      zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1);
    } else if (Z_OBJ_P(creds_obj)->ce != grpc_ce_channel_credentials) {
      zend_throw_exception(spl_ce_InvalidArgumentException,
                           "credentials must be a ChannelCredentials object",
                           1);
      return;
    } else {
      creds = Z_WRAPPED_GRPC_CHANNEL_CREDS_P(creds_obj);
      zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1);
    }
  }
  php_grpc_read_args_array(args_array, &args);
  if (creds == NULL) {
    channel->wrapped = grpc_insecure_channel_create(ZSTR_VAL(target),
                                                    &args, NULL);
  } else {
    channel->wrapped =
        grpc_secure_channel_create(creds->wrapped, ZSTR_VAL(target),
                                   &args, NULL);
  }
  efree(args.args);
}
Example #3
0
/**
 * Start a batch of RPC actions.
 * @param array batch Array of actions to take
 * @return object Object with results of all actions
 */
PHP_METHOD(Call, startBatch) {
  wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis());
  grpc_op ops[8];
  size_t op_num = 0;
  zval *array;
  zval *value;
  zval *inner_value;
  HashTable *array_hash;
  HashPosition array_pointer;
  HashTable *status_hash;
  HashTable *message_hash;
  zval *message_value;
  zval *message_flags;
  zend_string *key;
  zend_ulong index;
  
  grpc_metadata_array metadata;
  grpc_metadata_array trailing_metadata;
  grpc_metadata_array recv_metadata;
  grpc_metadata_array recv_trailing_metadata;
  grpc_status_code status;
  char *status_details = NULL;
  size_t status_details_capacity = 0;
  grpc_byte_buffer *message;
  int cancelled;
  grpc_call_error error;
  char *message_str;
  size_t message_len;
  zval recv_status;
  
  grpc_metadata_array_init(&metadata);
  grpc_metadata_array_init(&trailing_metadata);
  grpc_metadata_array_init(&recv_metadata);
  grpc_metadata_array_init(&recv_trailing_metadata);
  object_init(return_value);
  
  /* "a" == 1 array */
#ifndef FAST_ZPP
  if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "start_batch expects an array", 1);
    goto cleanup;
  }
#else
  ZEND_PARSE_PARAMETERS_START(1, 1)
    Z_PARAM_ARRAY(array)
  ZEND_PARSE_PARAMETERS_END();
#endif

  array_hash = HASH_OF(array);
  //TODO(thinkerou): why phpunit wrong when use ZEND_HASH_FOREACH_VAL marco?
  //ZEND_HASH_FOREACH_VAL(array_hash, value) {
  for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
       (value = zend_hash_get_current_data_ex(array_hash,
                                              &array_pointer)) != NULL;
       zend_hash_move_forward_ex(array_hash, &array_pointer)) {
    if (zend_hash_get_current_key_ex(array_hash, &key, &index,
                                     &array_pointer) != HASH_KEY_IS_LONG) {
      zend_throw_exception(spl_ce_InvalidArgumentException,
                           "batch keys must be integers", 1);
      goto cleanup;
    }
    switch(index) {
      case GRPC_OP_SEND_INITIAL_METADATA:
        if (!create_metadata_array(value, &metadata)) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Bad metadata value given", 1);
          goto cleanup;
        }
        ops[op_num].data.send_initial_metadata.count = metadata.count;
        ops[op_num].data.send_initial_metadata.metadata = metadata.metadata;
        break;
      case GRPC_OP_SEND_MESSAGE:
        if (Z_TYPE_P(value) != IS_ARRAY) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Expected an array for send message", 1);
          goto cleanup;
        }
        message_hash = HASH_OF(value);
        if ((message_flags = zend_hash_str_find(message_hash, "flags",
                                                sizeof("flags") - 1)) != NULL) {
          if (Z_TYPE_P(message_flags) != IS_LONG) {
            zend_throw_exception(spl_ce_InvalidArgumentException,
                                 "Expected an int for message flags", 1);
          }
          ops[op_num].flags = Z_LVAL_P(message_flags) & GRPC_WRITE_USED_MASK;
        }
        if ((message_value = zend_hash_str_find(
            message_hash, "message", sizeof("message") - 1)) == NULL ||
            Z_TYPE_P(message_value) != IS_STRING) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Expected a string for send message", 1);
          goto cleanup;
        }
        ops[op_num].data.send_message =
            string_to_byte_buffer(Z_STRVAL_P(message_value),
                                  Z_STRLEN_P(message_value));
        break;
      case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
        break;
      case GRPC_OP_SEND_STATUS_FROM_SERVER:
        status_hash = HASH_OF(value);
        if ((inner_value = zend_hash_str_find(
            status_hash, "metadata", sizeof("metadata") - 1)) != NULL) {
          if (!create_metadata_array(inner_value, &trailing_metadata)) {
            zend_throw_exception(spl_ce_InvalidArgumentException,
                                 "Bad trailing metadata value given", 1);
            goto cleanup;
          }
          ops[op_num].data.send_status_from_server.trailing_metadata =
              trailing_metadata.metadata;
          ops[op_num].data.send_status_from_server.trailing_metadata_count =
              trailing_metadata.count;
        }
        if ((inner_value = zend_hash_str_find(
            status_hash, "code", sizeof("code") - 1)) != NULL) {
          if (Z_TYPE_P(inner_value) != IS_LONG) {
            zend_throw_exception(spl_ce_InvalidArgumentException,
                                 "Status code must be an integer", 1);
            goto cleanup;
          }
          ops[op_num].data.send_status_from_server.status =
              Z_LVAL_P(inner_value);
        } else {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Integer status code is required", 1);
          goto cleanup;
        }
        if ((inner_value = zend_hash_str_find(
            status_hash, "details", sizeof("details") - 1)) != NULL) {
          if (Z_TYPE_P(inner_value) != IS_STRING) {
            zend_throw_exception(spl_ce_InvalidArgumentException,
                                 "Status details must be a string", 1);
            goto cleanup;
          }
          ops[op_num].data.send_status_from_server.status_details =
              Z_STRVAL_P(inner_value);
        } else {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "String status details is required", 1);
          goto cleanup;
        }
        break;
      case GRPC_OP_RECV_INITIAL_METADATA:
        ops[op_num].data.recv_initial_metadata = &recv_metadata;
        break;
      case GRPC_OP_RECV_MESSAGE:
        ops[op_num].data.recv_message = &message;
        break;
      case GRPC_OP_RECV_STATUS_ON_CLIENT:
        ops[op_num].data.recv_status_on_client.trailing_metadata =
            &recv_trailing_metadata;
        ops[op_num].data.recv_status_on_client.status = &status;
        ops[op_num].data.recv_status_on_client.status_details =
            &status_details;
        ops[op_num].data.recv_status_on_client.status_details_capacity =
            &status_details_capacity;
        break;
      case GRPC_OP_RECV_CLOSE_ON_SERVER:
        ops[op_num].data.recv_close_on_server.cancelled = &cancelled;
        break;
      default:
        zend_throw_exception(spl_ce_InvalidArgumentException,
                             "Unrecognized key in batch", 1);
        goto cleanup;
    }
    ops[op_num].op = (grpc_op_type)index;
    ops[op_num].flags = 0;
    ops[op_num].reserved = NULL;
    op_num++;
  }
  //ZEND_HASH_FOREACH_END();

  error = grpc_call_start_batch(call->wrapped, ops, op_num,
                                call->wrapped, NULL);
  if (error != GRPC_CALL_OK) {
    zend_throw_exception(spl_ce_LogicException,
                         "start_batch was called incorrectly",
                         (long)error);
    goto cleanup;
  }
  grpc_completion_queue_pluck(completion_queue, call->wrapped,
                              gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
  for (int i = 0; i < op_num; i++) {
    switch(ops[i].op) {
      case GRPC_OP_SEND_INITIAL_METADATA:
        add_property_bool(return_value, "send_metadata", true);
        break;
      case GRPC_OP_SEND_MESSAGE:
        add_property_bool(return_value, "send_message", true);
        break;
      case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
        add_property_bool(return_value, "send_close", true);
        break;
      case GRPC_OP_SEND_STATUS_FROM_SERVER:
        add_property_bool(return_value, "send_status", true);
        break;
      case GRPC_OP_RECV_INITIAL_METADATA:
        grpc_parse_metadata_array(&recv_metadata, array);
        add_property_zval(return_value, "metadata", array);
        //Z_DELREF_P(array);
        break;
      case GRPC_OP_RECV_MESSAGE:
        byte_buffer_to_string(message, &message_str, &message_len);
        if (message_str == NULL) {
          add_property_null(return_value, "message");
        } else {
          add_property_stringl(return_value, "message", message_str, message_len);
        }
        break;
      case GRPC_OP_RECV_STATUS_ON_CLIENT:
        object_init(&recv_status);
        grpc_parse_metadata_array(&recv_trailing_metadata, array);
        add_property_zval(&recv_status, "metadata", array);
        //Z_DELREF_P(array);
        add_property_long(&recv_status, "code", status);
        add_property_string(&recv_status, "details", status_details);
        add_property_zval(return_value, "status", &recv_status);
        //Z_DELREF_P(&recv_status);
        break;
      case GRPC_OP_RECV_CLOSE_ON_SERVER:
        add_property_bool(return_value, "cancelled", cancelled);
        break;
      default:
        break;
    }
  }

cleanup:
  grpc_metadata_array_destroy(&metadata);
  grpc_metadata_array_destroy(&trailing_metadata);
  grpc_metadata_array_destroy(&recv_metadata);
  grpc_metadata_array_destroy(&recv_trailing_metadata);
  if (status_details != NULL) {
    gpr_free(status_details);
  }
  for (int i = 0; i < op_num; i++) {
    if (ops[i].op == GRPC_OP_SEND_MESSAGE) {
      grpc_byte_buffer_destroy(ops[i].data.send_message);
    }
    if (ops[i].op == GRPC_OP_RECV_MESSAGE) {
      grpc_byte_buffer_destroy(message);
    }
  }
  RETURN_DESTROY_ZVAL(return_value);
}